Git Product home page Git Product logo

td-ameritrade-api's Introduction

Unofficial TD Ameritrade Python API Library

Table of Contents

Overview

Current Version: 0.1.1

The unofficial Python API client library for TD Ameritrade allows individuals with TD Ameritrade accounts to manage trades, pull historical and real-time data, manage their accounts, create and modify orders all using the Python programming language.

To learn more about the TD Ameritrade API, please refer to the official documentation.

Setup

Setup - Requirements Install:*

For this particular project, you only need to install the dependencies, to use the project. The dependencies are listed in the requirements.txt file and can be installed by running the following command:

pip install -r requirements.txt

After running that command, the dependencies should be installed.

Setup - Local Install:

If you are planning to make modifications to this project or you would like to access it before it has been indexed on PyPi. I would recommend you either install this project in editable mode or do a local install. For those of you, who want to make modifications to this project. I would recommend you install the library in editable mode.

If you want to install the library in editable mode, make sure to run the setup.py file, so you can install any dependencies you may need. To run the setup.py file, run the following command in your terminal.

pip install -e .

If you don't plan to make any modifications to the project but still want to use it across your different projects, then do a local install.

pip install .

This will install all the dependencies listed in the setup.py file. Once done you can use the library wherever you want.

Setup - PyPi Install:

To install the library, run the following command from the terminal.

pip install py-tda-api

Setup - PyPi Upgrade:

To upgrade the library, run the following command from the terminal.

pip install --upgrade py-tda-api

Usage

Here is a simple example of using the td library.

from pprint import pprint
from configparser import ConfigParser
from td.credentials import TdCredentials
from td.client import TdAmeritradeClient


# Initialize the Parser.
config = ConfigParser()

# Read the file.
config.read('config/config.ini')

# Get the specified credentials.
client_id = config.get('main', 'client_id')
redirect_uri = config.get('main', 'redirect_uri')

# Intialize our `Credentials` object.
td_credentials = TdCredentials(
    client_id=client_id,
    redirect_uri=redirect_uri,
    credential_file='config/td_credentials.json'
)

# Initalize the `TdAmeritradeClient`
td_client = TdAmeritradeClient(
    credentials=td_credentials
)

# Initialize the Quotes service.
quote_service = td_client.quotes()

# Grab a single quote.
pprint(
    quote_service.get_quote(instrument='AAPL')
)

# Grab multiple quotes.
pprint(
    quote_service.get_quotes(instruments=['AAPL', 'SQ'])
)

Support These Projects

Patreon: Help support this project and future projects by donating to my Patreon Page. I'm always looking to add more content for individuals like yourself, unfortuantely some of the APIs I would require me to pay monthly fees.

YouTube: If you'd like to watch more of my content, feel free to visit my YouTube channel Sigma Coding.

Questions: If you have questions please feel free to reach out to me at [email protected]

Authentication Workflow

Step 1 - Start the Script:

While in Visual Studio Code, right click anywhere in the code editor while in the file that contains your code. The following dropdown will appear:

Terminal Dropdown

From the dropdown, click Run Python file in Terminal, this will start the python script.

Step 2 - Go to Redirect URL:

The TD Library will automatically generate the redirect URL that will navigate you to the TD website for for you authentication. You can either copy the link and paste it into a browser manually or if you're using Visual Studio Code you can press CTRL + Click to have Visual Studio Code navigate you to the URL immeditately.

Redirect URI

Step 3 - Login to the TD API:

Once you've arrived at the login screen, you'll need to provide your credentials to authenticate the session. Please provide your Account Username and Account Password in the userform and then press enter. As a reminder these, are the same username/password combination you use to login to your regular TD Account.

"TD Login

Step 4 - Accept the Terms:

Accept the Terms of the API by clicking Allow, this will redirect you.

TD Terms

Step 5 - Copy the Authorization Code:

After accepting the terms, you'll be taken to the URL that you provided as your redirect URI. However, at the end of that URL will be authorization code. To complete the authentication workflow, copy the URL as it appears below. Don't worry if the numbers don't match, as you will have a different code.

Auth Code

Step 6 - Paste the Authorization Code in the Terminal:

Take the URL and copy it into the Terminal, after you have pasted it, press Enter. The authentication workflow will complete and the script will start running. At this stage, we are exchanging your authorization code for an access token. That access token is valid only for 30 minutes. However, a refresh token is also stored that will refresh your access token when it expires.

Paste URL

After, that the script should run. Additionally, if you go to the location you specified in the credentials_path arugment you will now see td_state.json file. This file contains all the info used during a session. Please DO NOT DELETE THIS FILE OR ELSE YOU WILL NEED TO GO THROUGH THE STEPS ABOVE.

td-ameritrade-api's People

Contributors

areed1192 avatar csaleman avatar jelneo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

td-ameritrade-api's Issues

Not saving new credentials file to path when generating new refresh_token

When creating new credentials with new refresh_token, you set is_access_token_expired to False, and than it doesn't save it to the json file path. so one repeats generating new credentials over and over again.

In file credentials.py added after the first if statement:

def validate_token(self) -> None:
        """Validates the access token and refresh token.

        ### Overview
        ----
        A TD Ameritrade Access token is only valid for 30 minutes,
        and a TD Ameritrade Refresh token is only valid for 90 days.
        When an access token expires, a new one is retrieved using the
        refresh token. If the refresh token is expired the oAuth workflow
        starts again.
        """

        if self.is_refresh_token_expired:
            print("Refresh Token Expired, initiating oAuth workflow...")
            self.from_workflow()

            # save to json file
            if self._loaded_from_file:
                self.to_credential_file(file_path=self._file_path)

        if self.is_access_token_expired:
            print("Access Token Expired, refreshing access token...")
            token_dict = self.grab_access_token()
            self.from_token_dict(token_dict=token_dict)

            if self._loaded_from_file:
                self.to_credential_file(file_path=self._file_path)

http exception when getting access_token with refresh_token

I put some logging statements in the credentials.py file to see what's going on:

Access Token Expired, refreshing access token...
the data below comes from my td_credentials.json file, which is posted to TD API to get access_token

data:  {'client_id': 'CV72580QKIEV4MOLPDGFXMDJC1YLSJ7I', 'grant_type': 'access_token', 'access_type': 'offline', 'refresh_token': 'redacted-----HkvASvG100MQuG4LYrgoVi/JHHvlO8IGgyu3fLRYaZKUDDce+CwdqwI7pVI8NW2owQFhIVg1sdpqQuZpuZtAeToZ63bxrELM5TEgpF/C6BoQNY2T0pkn22zgJnVduGAJvgzHOzybjzBasHkfO0d37ppqC0Cdr9urd4a4Rycp195EJLBpc8k3TnCkQ3d3dq9SjCoIdPvMVemeOcAbFmDZgM0KhDQtjJOuJA4QBvYBnhyB3FKDPlm3OnvajRTEHxzvNswfEWiZ/yWbZzK+hdO3ZWCwsM/70cyZ1phM0mE6Hat/oQYTj2M8VcDsrKxyWyFX4swgAQYDGgvCw5L'}

I got response 400 meaning the request is a bad request
response: <Response [400]>

Traceback (most recent call last):
  File "/Users/user1/temp/v2/test8.py", line 4, in <module>
    tos_client = TOSClient('my-app-consumer-key', '/Users/user1/temp/v2/project/tokens.json')
  File "/Users/user1/temp/v2/project/server/toolbox/TOSClient.py", line 23, in __init__
    td_credentials = TdCredentials(
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 62, in __init__
    self.from_credential_file(file_path=credential_file)
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 377, in from_credential_file
    self.from_token_dict(token_dict=token_dict)
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 248, in from_token_dict
    self.validate_token()
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 580, in validate_token
    token_dict = self.grab_access_token()
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 560, in grab_access_token
    raise requests.HTTPError()
requests.exceptions.HTTPError

I installed this library using pip install btw. Is there any known issue?

this below method in credentials.py throws the exception above:

    def grab_access_token(self) -> dict:
        """Refreshes the current access token.

        This takes a valid refresh token and refreshes
        an expired access token. This is different from
        exchanging a code for an access token.

        ### Returns
        ----
        dict:
            The dictionary contain all the token
            info.
        """

        # build the parameters of our request
        data = {
            'client_id': self.client_id,
            'grant_type': 'refresh_token',
            'access_type': 'offline',
            'refresh_token': self.refresh_token
        }

        # Make the request.
        response = requests.post(
            url="https://api.tdameritrade.com/v1/oauth2/token",
            headers={
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data=data
        )

        if response.ok:
            return response.json()
        print('data: ', data)
        print('response: ', response)

        raise requests.HTTPError()

I cannot find the requirements.txt file

I think that the requirements file is missing. Am I wrong?
When I try to run a test like this:

(myenv3.7.3) (base) Alejandro-2:tests alejandrosantillaniturres$ python test_client.py 
Traceback (most recent call last):
  File "test_client.py", line 4, in <module>
    from td.credentials import TdCredentials
ModuleNotFoundError: No module named 'td'

I did:

pip install td

and a module installed, but it is not the module the test_client.py is requesting. Which is the correct module to install?

I did:

pip install tdameritrade

but again, is not the right module. Please help!

exchange_code_for_token

I am pasting the full URL (http://localhost/?code=xxxx) when I get prompted to enter it after I am starting the workflow by running use_oauth.py but seem to be running into this error. It doesn't provide any other HTTP error codes etc.

One thing I noticed was that the browser that gets launched also gives me an invalid_client error. I think the problem is with the encoding of the url that gets pasted on the browser. So I manually correct it and launch it like

https://auth.tdameritrade.com/auth?response_type=code&redirect_uri=http://localhost&client_id=PRIVATE%40AMER.OAUTHAP

It prompts me for the user/app and after i allow it gives me the full url back which I paste in the terminal

Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/samples/use_ouath.py", line 16, in <module>
    td_credentials = TdCredentials(
  File "/home/pi/tos/td-ameritrade-api/td/credentials.py", line 69, in __init__
    self.from_workflow()
  File "/home/pi/tos/td-ameritrade-api/td/credentials.py", line 361, in from_workflow
    token_dict = self.exchange_code_for_token(return_refresh_token=True)
  File "/home/pi/tos/td-ameritrade-api/td/credentials.py", line 517, in exchange_code_for_token
    raise requests.HTTPError()
requests.exceptions.HTTPError

configparser.NoSectionError: No section: 'main'

I cannot get the web page authentication to pop up when I try to run td.client.py in VS Code. There is no error after the python interpreter calls the script, just returns to the terminal.

Python 3.9.12

pi@raspberrypi:~/tos/td-ameritrade-api $ /usr/bin/python /home/pi/tos/td-ameritrade-api/td/client.py
pi@raspberrypi:~/tos/td-ameritrade-api $ 

All tests subsequently fail but pasting here in case this puts more context around the errors.

pi@raspberrypi:~/tos/td-ameritrade-api $ /usr/bin/python /home/pi/tos/td-ameritrade-api/tests/test_client.py
EEEEEEEEEEEE
======================================================================
ERROR: test_creates_instance_of_accounts (__main__.TestTdClient)
Create an instance and make sure it's a `Accounts` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_client (__main__.TestTdClient)
Create an instance and make sure it's a `TdAmeritradeClient` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_instruments (__main__.TestTdClient)
Create an instance and make sure it's a `Instruments` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_market_hours (__main__.TestTdClient)
Create an instance and make sure it's a `MarketHours` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_mover (__main__.TestTdClient)
Create an instance and make sure it's a `Movers` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_options_chain (__main__.TestTdClient)
Create an instance and make sure it's a `OptionsChain` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_orders (__main__.TestTdClient)
Create an instance and make sure it's a `Orders` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_price_history (__main__.TestTdClient)
Create an instance and make sure it's a `PriceHistory` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_quote (__main__.TestTdClient)
Create an instance and make sure it's a `Quotes` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_saved_orders (__main__.TestTdClient)
Create an instance and make sure it's a `SavedOrders` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_user_info (__main__.TestTdClient)
Create an instance and make sure it's a `UserInfo` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

======================================================================
ERROR: test_creates_instance_of_watchlists (__main__.TestTdClient)
Create an instance and make sure it's a `Watchlists` object.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/tos/td-ameritrade-api/tests/test_client.py", line 34, in setUp
    client_id = config.get('main', 'client_id')
  File "/usr/local/lib/python3.9/configparser.py", line 781, in get
    d = self._unify_values(section, vars)
  File "/usr/local/lib/python3.9/configparser.py", line 1152, in _unify_values
    raise NoSectionError(section) from None
configparser.NoSectionError: No section: 'main'

----------------------------------------------------------------------
Ran 12 tests in 0.024s

FAILED (errors=12)
pi@raspberrypi:~/tos/td-ameritrade-api $ 

Unable to pass in Enum to get_market_hours in rest/market_hours.py

This code outside the market_hours file works as expected, we get the enum replaced with its value.

class Markets(Enum):
    """Represents the different markets you can request
    hours for the `MarketHours` service.

    ### Usage
    ----
        >>> from td.enums import Markets
        >>> Markets.Bond.Value
    """

    Bond = 'BOND'
    Equity = 'EQUITY'
    Option = 'OPTION'
    Forex = 'FOREX'
    Futures = 'FUTURES'
def get_market_hours(market):
    from enum import Enum
    if isinstance(market, Enum):
        market = market.value
    content = f"marketdata/{market}/hours"
    return content
print(get_market_hours(Markets.Bond))

However, this code doesn't work:

    def get_market_hours(
        self,
        market: Union[str, Enum],
        date_time: Union[str, datetime] = None
    ) -> dict:
        """Returns the market hours for the specified market.

        ### Documentation
        ----
        https://developer.tdameritrade.com/market-hours/apis

        ### Parameters
        ----
        market: Union[str, Enum]
            A list of market IDs you want to return hours for.
            Possible values are: `EQUITY`, `OPTION`, `FUTURE`,
            `BOND`, or `FOREX`.

        date: Union[str, datetime, date]
            The date you wish to recieve market hours for. 
            Valid ISO-8601 formats are: yyyy-MM-dd and 
            yyyy-MM-dd'T'HH:mm:ssz

        ### Usage
        ----
            >>> from td.enums import Markets
            >>> market_hours_service = td_client.market_hours()
            >>> market_hours_service.get_market_hours(
                markets='EQUITY',
                date='2021-12-31'
            )
        """
        if isinstance(market, Enum):
            market = market.value

        # Grab the date_time.
        if isinstance(date_time, datetime):
            date_time = date_time.date().isoformat()
        elif isinstance(date_time, date):
            date_time = date_time.isoformat()

        params = {
            'date': date_time
        }

        content = self.session.make_request(
            method='get',
            endpoint=f'marketdata/{market}/hours',
            params=params
        )

        return content

called with

# Grab the hours for a specific market.
pprint(
    market_hours_service.get_market_hours(
        market=Markets.Bond,
        date_time=datetime.now()
    )
)

an http error is thrown. logging shows:

"response_body": {
    "timestamp": "2021-10-23",
    "status": 400,
    "error": "Bad Request",
    "message": "Market name not recognized",
    "path": "/markethours-v1/markets/Markets.Bond"
},

Not sure of the issue. Usage of isinstance to cast enum is similar to other code and to the other market_hours method, get_multiple_market_hours, which works fine.

Session HTTPError

Breaks on 3.11?

td_credentials = TdCredentials(
    client_id=client_id,
    redirect_uri=redirect_uri,
    credential_file='td_credentials.json'
)

td_client = TdAmeritradeClient(td_credentials)

market = td_client.market_hours().get_market_hours('EQUITY', trade_date)
print(market)
Traceback (most recent call last):
  File "sandbox.py", line 140, in <module>
    market = td_client.market_hours().get_market_hours('EQUITY', trade_date)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/td/rest/market_hours.py", line 125, in get_market_hours
    content = self.session.make_request(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/td/session.py", line 194, in make_request
    raise requests.HTTPError()
requests.exceptions.HTTPError

start_date of get_price_history does not actually change anything

I have this code to get a price history

start = int((time.time()*1000)-1)  # For some reason this value doesn't actually change the output?
end = int(time.time()*1000)

def get_prices(symbol=str):  # as the program goes on the list gets longer and longer. No idea why. Maybe ext hours?
     raw_prices = td_client.get_price_history(
          symbol=symbol,
          start_date=start,
          end_date=end,
          frequency_type='minute',
          frequency='1',
          extended_hours='True')
     prices = pd.DataFrame(data=raw_prices['candles'], columns=['close'])
     return prices

The start date does not affect the output. If i use SPY (a 24 hour stock) as the symbol it gets prices starting at 7 am today no matter what. I Figure this is a bug somewhere

Error with Old HTTP: closewrite error

This package currently runs afoul of closewrite being defined in multiple packages per this issue:
https://discourse.julialang.org/t/http-request-closewrite/86583

However it's easily fixed by just updating the dependencies and updating Mux and HTTP. I altered the Project.toml in a local cloned copy to have the compatibility section look like:

[compat]
HTTP = "0.8, 0.9, 1.5"
JSON3 = "1.1, 1.12.0"
Pipe = "1.3"
julia = "1"

Now I'm using the later HTTP and JSON3 in this project to good effect and the closewrite error is gone.

A Few Suggestions

First thank you for for this API. Took me way too long to get the td_credentials.json file. So here is a list of issues I found.

  1. The instructions don't show an example of the config.init file.
    [main]
    client_id = MY-OWN-CLIENT-ID
    redirect_uri = MY-REDIRECT-URI

  2. The example fails to generate a credential.json in order to initiate the oauth workflow the line below needs to be omitted.

    credential_file='config/td_credentials.json'

  3. URL was not showing, I'm developing on a VM without a web browser. So I added a print(url) on credentials.py right after line 468

    webbrowser.open(url=url)
    print(url)

  4. After entering the code, nothing actually got saved, The token file was available but not saved. So I added the

td_credentials.to_credential_file('config/td_credentials.json')

# Initialize the Parser.
config = ConfigParser()

# Read the file.
config.read('config/config.ini')

# Get the specified credentials.
client_id = config.get('main', 'client_id')
redirect_uri = config.get('main', 'redirect_uri')

# Intialize our `Credentials` object.
td_credentials = TdCredentials(
    client_id=client_id,
    redirect_uri=redirect_uri
)

td_credentials.to_credential_file('config/td_credentials.json')

options strangle orders with trigger? and should I just switch to a better api broker like IB or Etrade?

Hello,
I am full aware of the absurd lack of documentation on the api orders schema and what works and what doesn't. I kind of wonder if it is better to switch to a different broker with better api support. That said, I've spent enough time trying to figure out how to place an options trigger order for a strangle trade. There are no examples out there and I have copied existing templates for equities, but I'm just wasting my time at this point. This template doesn't work either. I have thinkorswim open to tell me if an order is placed or rejected right away, and this one is not getting a rejection or anything but the http 400 response:

trigger_order = {
  "orderType": "NET_DEBIT",
  "session": "NORMAL",
  "price": "1.97",
  "duration": "DAY",
  "orderStrategyType": "TRIGGER",
  "orderLegCollection": [
    {
      "instruction": "BUY_TO_OPEN",
      "quantity": 10,
      "instrument": {
        "symbol": "QQQ_051822P305",
        "assetType": "OPTION"
      }
    }
  ],
  "childOrderStrategies": [
    {
      "orderType": "NET_CREDIT",
      "session": "NORMAL",
      "price": "2.03",
      "duration": "DAY",
      "orderStrategyType": "SINGLE",
      "orderLegCollection": [
        {
          "instruction": "SELL_TO_CLOSE",
          "quantity": 10,
          "instrument": {
            "symbol": "QQQ_051822C308",
            "assetType": "OPTION"
          }
        }
      ]
    }
  ]
}

Any help?

start up issue

File "/home/andy/Documents/python_algorithm/tdameritrade4.py", line 30, in
td_client=tdameritrade.get_login()

File "/home/andy/Documents/python_algorithm/tdameritrade.py", line 39, in get_login
td_client = TdAmeritradeClient(credentials=td_credentials)

File "/home/andy/anaconda3/lib/python3.8/site-packages/td/client.py", line 36, in init
self.td_session = TdAmeritradeSession(td_client=self)

File "/home/andy/anaconda3/lib/python3.8/site-packages/td/session.py", line 43, in init
logging.basicConfig(

File "/home/andy/anaconda3/lib/python3.8/logging/init.py", line 2005, in basicConfig
raise ValueError('Unrecognised argument(s): %s' % keys)

ValueError: Unrecognised argument(s): encoding

The next will execute fine. On start up, I found this error both times I tried running the code. I am pretty sure I have all the dependencies.

cannot import name 'TDClient' from 'td.client'

Hello, I am having the following issue when I run the example from GIT:

runfile('C:/Users/iomega15/Desktop/td_example/using_td_library_git.py', wdir='C:/Users/iomega15/Desktop/td_example')
Reloaded modules: config, iomega15
Traceback (most recent call last):

File "C:\Users\iomega15\Desktop\td_example\using_td_library_git.py", line 25, in
client_id = config.get('main', 'client_id')

File "C:\Users\iomega15\anaconda3\lib\configparser.py", line 781, in get
d = self._unify_values(section, vars)

File "C:\Users\iomega15\anaconda3\lib\configparser.py", line 1149, in _unify_values
raise NoSectionError(section) from None

NoSectionError: No section: 'main'

runfile('C:/Users/iomega15/Desktop/td_example/using_td_library.py', wdir='C:/Users/iomega15/Desktop/td_example')
Traceback (most recent call last):

File "C:\Users\iomega15\Desktop\td_example\using_td_library.py", line 15, in
from td.client import TDClient

ImportError: cannot import name 'TDClient' from 'td.client' (C:\Users\iomega15\anaconda3\Lib\site-packages\td\client.py)

I have also tried running it the youtube video way, but I get this issue:

ImportError: cannot import name 'TDClient' from 'td.client' (C:\Users\iomega15\anaconda3\Lib\site-packages\td\client.py)

I saw in the comments that it was a bug in the older version, but that was like a year ago and I just installed/updated the latest (as far as I can tell) from github: Successfully installed td-ameritrade-python-api-0.3.5

Though, I am a bit confused what the actual latest version is, because the github website says:
image

And in your youtube comments from a year ago you mentioned upgrading to 0.2.8 to eliminate this issue...

KeyError: 'code' after I paste the authorization code

I installed the td-ameritrade-api library through pip install td-ameritrade-api on my mac.

I used this code as an example to get my access and refresh token: https://github.com/areed1192/td-ameritrade-api/blob/master/samples/use_ouath.py

But when I paste my authorization code in my terminal,

Please Paste the Authorization Code Here: kKMpPxk1GWougVO5Zz7ylBRTGqQhU2sE%2BX5G2rqvaS2UBYBJQz01EZWq6w5%2F2bvo%2BDetIRlW4gG4eQEPVuJCnjJXUQMRqYFPLttct01SwVRRADOW1VX2MzRWPZ5WxF4%2FNjoH3C5CAHR7fnA%2F21hJH%2F5IZvotgDUKFX8hLQPpMJ8brksP%2FijXPuKksDHKmA2KlkvpqXXj3TV6Q3aqGQdhi24xU%2FxqrHrcTBR4mABzjgonEVrw5qemE2SKbbi9N1d7RSgiQ2sa7rMVJcJTBuzvgVjx6VSm4w0l4gQU1wruYronOUZWYh4AyMOYqWI16oukGB1aMU0BIb%2FTZHkuPGQCwr1f1QWJ6k01lrIsTP2piz6QRjIeBU3%2FT2YMtaFee8t1zPqxBk%2FDS2%2BCS57XrxZicbFkJswB8wayrUTWLBtWmziQ2nwlKOB8c9OoHjs100MQuG4LYrgoVi%2FJHHvlw7elSTjHMhz4QqYuSfaMSpPhZVYqsKbTdaElOMaPwpgNBMXIH4zsWBhpq%2BXU%2BZMh3l%2BtNhFE%2FWEWUTXvtmjnX1zZNEtDp4ERur9%2FwmtzS0rUYoi2JE6ggmEyXzAlEjx3HuTrr1eHxjiWbQ3kuOegSUla1vblemZCi1oQ9%2BOiQXbwOIw5Or3url77WbZBNFjxpVnbEoShnWtXYQhsFaZJ8lI5zNN1SeUE99a8kQte7MznbTE1X2%2F2EIp8cZ%2FFsa0lhkywT0JKpdljZjqpCmNglzTrvAzDu5GmWQLxnQGTqgfezcmU6WYjIFj2qJ1YbY4431t6zXSIrhm18UO0DlCRjqKdZTbAIfEXwcNCfC0lHgs%2B%2Be4TEqZSlatyiwV10WUOJF53s0mod3oJvC0QgeU2%2FIWNxnr7viG7mPk22xxWLoStdIb5TbXrKCLay0E%3D212FD3x19z9sWBHDJAxxxx

I got following error: KeyError: 'code':

Traceback (most recent call last):
  File "/Users/user1/test8.py", line 4, in <module>
    tos_client = TOSClient('xxxsfdsfasdfsadfs', '/Users/user1/project/server/toolbox/tos_tokens.json')
  File "/Users/user1/project/server/toolbox/TOSClient.py", line 23, in __init__
    td_credentials = TdCredentials(
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 68, in __init__
    self.from_workflow()
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 361, in from_workflow
    self.grab_authorization_code()
  File "/Users/user1/env/lib/python3.9/site-packages/td/credentials.py", line 475, in grab_authorization_code
    self.authorization_code = parse_code['code'][0]
KeyError: 'code'

did anyone see such error? how to fix it? thank you

Transition to Schwab's Trader API

Hi Alex, a general question:
TD Ameritrade announced that they will make a transition to Schwab's Trader API (After Charles Schwab acquired TD Ameritrade in 2019)
How/Will it affect your project?

With great appreciation,
Assaf

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.