0

The e-trade people provided some sample API code which provides a working example of fetching a portfolio, which I implemented, and which met my needs, until I owned >50 stocks, then suddenly I started noticing incomplete portfolio retrievals.

How can I get more than 50 stocks at a time?

This is a pagination issue.

Their API documentation describes a "count" parameter that lets you increase the page size:

https://apisb.etrade.com/docs/api/account/api-portfolio-v1.html

I simply want to increase it to 60 so I can get my complete portfolio, but for the life of me, adding "?count=60" to the URL gives me a Response [401] and 0 portfolio info at all.

Any idea what I'm doing wrong?

def portfolio(self):                                                                                      
    """
    Call portfolio API to retrieve a list of positions held in the specified account

    :param self: Passes in parameter authenticated session and information on selected account
    """

    # URL for the API endpoint
    url =self.base_url + "/v1/accounts/" + self.account["accountIdKey"] + "/portfolio.json"
    **#url += "?count=60"   This failed miserably!**

    # Make API call for GET request
    response = self.session.get(url, header_auth=True)
    logger.debug("Request Header: %s", response.request.headers)

    print("\nPortfolio:")

    # Handle and parse response
    if response is not None and response.status_code == 200:
        parsed = json.loads(response.text)
        logger.debug("Response Body: %s", json.dumps(parsed, indent=4, sort_keys=True))
        data = response.json()

        if data is not None and "PortfolioResponse" in data and "AccountPortfolio" in data["PortfolioResponse"]:
            # Display balance information
            for acctPortfolio in data["PortfolioResponse"]["AccountPortfolio"]:
                if acctPortfolio is not None and "Position" in acctPortfolio:
                    for position in acctPortfolio["Position"]:
                        print_str = ""
                        if position is not None and "symbolDescription" in position:
                            print_str = print_str + "Symbol: " + str(position["symbolDescription"])
                        if position is not None and "quantity" in position:
                            print_str = print_str + " | " + "Quantity #: " + str(position["quantity"])
                        if position is not None and "Quick" in position and "lastTrade" in position["Quick"]:
                            print_str = print_str + " | " + "Last Price: " \
                                        + str('${:,.2f}'.format(position["Quick"]["lastTrade"]))
                        if position is not None and "pricePaid" in position:
                            print_str = print_str + " | " + "Price Paid $: " \
                                        + str('${:,.2f}'.format(position["pricePaid"]))
                        if position is not None and "totalGain" in position:
                            print_str = print_str + " | " + "Total Gain $: " \
                                        + str('${:,.2f}'.format(position["totalGain"]))
                        if position is not None and "marketValue" in position:
                            print_str = print_str + " | " + "Value $: " \
                                        + str('${:,.2f}'.format(position["marketValue"]))
                        print(print_str)
                else:
                    print("None")
        else:
            # Handle errors
            logger.debug("Response Body: %s", response.text)
            if response is not None and "headers" in response and "Content-Type" in response.headers \
                    and response.headers['Content-Type'] == 'application/json' \
                    and "Error" in response.json() and "message" in response.json()["Error"] \
                    and response.json()["Error"]["message"] is not None:
                print("Error: " + response.json()["Error"]["message"])
            else:
                print("Error: Portfolio API service error")
    elif response is not None and response.status_code == 204:
        print("None")
    else:
        # Handle errors
        logger.debug("Response Body: %s", response.text)
        if response is not None and "headers" in response and "Content-Type" in response.headers \
                and response.headers['Content-Type'] == 'application/json' \
                and "Error" in response.json() and "message" in response.json()["Error"] \
                and response.json()["Error"]["message"] is not None:
            print("Error: " + response.json()["Error"]["message"])
        else:
            print("Error: Portfolio API service error")
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
ClioCJS
  • 64
  • 3
  • 11

0 Answers0