Esempio n. 1
0
    def get_order(self, order_id):
        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        try:
            self.account_id
        except AttributeError:
            if self.verbose: print('account id not defined')
            raise utility_exceptions.AccountError(id_error=True)

        self.order_endpoint = r'https://api.tdameritrade.com/v1/accounts/{}/orders/{}'.format(
            self.account_id, order_id)

        self.account_reply = requests.get(url=self.order_endpoint,
                                          headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            # read out the status of the request
            if self.verbose: print(self.account_reply.status_code)
            return self.account_reply.json()
        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.order_endpoint,
                headers=self.order_access_header)
Esempio n. 2
0
    def place_order(self, payload):
        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        try:
            self.account_id
        except AttributeError:
            if self.verbose: print('account id not defined')
            raise utility_exceptions.AccountError(id_error=True)

        self.order_endpoint = r'https://api.tdameritrade.com/v1/accounts/{}/orders'.format(
            self.account_id)

        # add a line to describe the type of request to the website
        self.order_access_header = self.access_header.copy()
        self.order_access_header['Content-Type'] = 'application/json'

        # define the payload
        '''
        payload = {
            "complexOrderStrategyType": "NONE",
            "orderType": "LIMIT",
            "session": "NORMAL",
            "price": "6.45",
            "duration": "DAY",
            "orderStrategyType": "SINGLE",
            "orderLegCollection": [
                {
                    "instruction": "BUY_TO_OPEN",
                    "quantity": 10,
                    "instrument": {
                        "symbol": "XYZ_032015C49",
                        "assetType": "OPTION"
                    }
                }
                orderId: 1111111
            ]
        }
        '''

        # post the request
        self.account_reply = requests.post(url=self.order_endpoint,
                                           json=payload,
                                           headers=self.order_access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.order_success.value:
            # read out the status of the request
            if self.verbose: print(self.account_reply.status_code)
        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.order_endpoint,
                headers=self.order_access_header)

        # record whether the the order state has changed
        self.orders_state_has_changed = True

        return True
Esempio n. 3
0
    def delete_order(self, order_id):
        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        try:
            self.account_id
        except AttributeError:
            if self.verbose: print('account id not defined')
            raise utility_exceptions.AccountError(id_error=True)

        self.order_endpoint = r'https://api.tdameritrade.com/v1/accounts/{}/orders/{}'.format(
            self.account_id, order_id)
        # post the request
        self.account_reply = requests.delete(url=self.order_endpoint,
                                             headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            if self.verbose: print('deleted order'.format(order_id))
        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.order_endpoint,
                headers=self.access_header)

        # record whether the the order state has changed
        self.orders_state_has_changed = True
Esempio n. 4
0
    def access_single_account(self, account_id):
        '''
        Access the single account to get data

        :param account_id:
        :return:
        '''

        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        try:
            self.account_id
        except AttributeError:
            if self.verbose: print('account id not defined')
            raise utility_exceptions.AccountError(id_error=True)

        # define the accounts endpoint
        self.account_endpoint = r'https://api.tdameritrade.com/v1/accounts/{}'.format(
            account_id)

        # POST data to get access token
        self.account_reply = requests.get(url=self.account_endpoint,
                                          headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            self.account_data_dict[str(account_id)] = self.account_reply.json()
            if self.verbose: print(self.account_data)
        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.account_endpoint,
                headers=self.access_header)
Esempio n. 5
0
    def get_quote(self, symbol):
        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        self.quote_endpoint = r'https://api.tdameritrade.com/v1/marketdata/{}/quotes'.format(
            symbol)

        # add a line to describe the type of request to the website
        self.options_access_header = self.access_header.copy()
        self.options_access_header['Content-Type'] = 'application/json'

        # post the request
        self.account_reply = requests.get(url=self.quote_endpoint,
                                          headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            # read out the status of the request
            if self.verbose: print(self.account_reply.status_code)

            quote_dict = self.account_reply.json()
            sym, quote = list(quote_dict.items())[0]

            return quote

        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.options_chain_endpoint,
                headers=self.options_access_header)
Esempio n. 6
0
    def get_price_history(self, symbol, payload):
        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        self.price_history_endpoint = r'https://api.tdameritrade.com/v1/marketdata/{}/pricehistory'.format(
            symbol)

        self.account_reply = requests.get(url=self.price_history_endpoint,
                                          params=payload,
                                          headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            # read out the status of the request
            if self.verbose: print(self.account_reply.status_code)

            return self.account_reply.json()

        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.price_history_endpoint,
                params=payload)

        pass
Esempio n. 7
0
    def get_account_positions(self):
        '''
        Access the single account to get data

        :param account_id:
        :return:
        '''

        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        try:
            self.account_id
        except AttributeError:
            if self.verbose: print('account id not defined')
            raise utility_exceptions.AccountError(id_error=True)

        # define the accounts endpoint
        self.account_endpoint = r'https://api.tdameritrade.com/v1/accounts/{}'.format(
            self.account_id)

        # define payload
        payload = {'fields': 'positions'}

        # GET account data
        self.account_reply = requests.get(url=self.account_endpoint,
                                          params=payload,
                                          headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            if self.verbose: print(self.account_data)
            try:
                return self.account_reply.json(
                )['securitiesAccount']['positions']
            # TODO: catch json decode error here as well.
            except KeyError:
                # if no entry, then there are no positions, and return empty list.
                return []
        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.account_endpoint,
                headers=self.access_header)
Esempio n. 8
0
    def authenticate(self):
        '''
        Take the access key and get the access and refresh token for the account.

        :return:
        '''

        try:
            self.parse_url
        except AttributeError:
            if self.verbose: print('token url not parsed')
            raise utility_exceptions.AccountError(parse_url_error=True)

        # create access point url
        self.token_endpoint = r'https://api.tdameritrade.com/v1/oauth2/token'

        # define headers
        headers = {'content-type': "application/x-www-form-urlencoded"}

        # define payload
        payload = {
            'grant_type': 'authorization_code',
            'access_type': 'offline',
            'code': self.parse_url,
            'client_id': apikey,
            'redirect_uri': 'http://localhost/callback'
        }

        # POST data to get access token
        self.authenticate_reply = requests.post(url=self.token_endpoint,
                                                headers=headers,
                                                data=payload)
        if self.authenticate_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            # convert json reply to dictionary
            self.token_data = self.authenticate_reply.json()
            self.access_token = self.token_data['access_token']
            self.access_header = {
                'Authorization': "Bearer {}".format(self.access_token)
            }
            self.refresh_token = self.token_data['refresh_token']
            if self.verbose: print(self.access_header)

            self.utility_path = os.path.abspath(os.path.dirname(__file__))
            filepath = self.utility_path + '/' + self.refresh_token_filename
            file = open(filepath, mode='w')
            file.write(self.refresh_token)
            file.close()

            self.account_authenticated = True
            self.time_of_last_refresh = arrow.now('America/New_York')

        else:
            raise utility_exceptions.AccessError(url=self.token_endpoint,
                                                 headers=headers,
                                                 data=payload)
Esempio n. 9
0
    def refresh_authentication(self):
        '''
        Use the refresh token to get a new access_token

        :return:
        '''

        try:
            self.refresh_token
        except AttributeError:
            if self.verbose: print('refresh token not initialized')
            raise utility_exceptions.AccountError(refresh_token_error=True)

        # create access point url
        self.token_endpoint = r'https://api.tdameritrade.com/v1/oauth2/token'

        # define headers
        headers = {'content-type': "application/x-www-form-urlencoded"}

        # define payload
        payload = {
            'grant_type': 'refresh_token',
            'access_type': 'offline',
            'refresh_token': self.refresh_token,
            'client_id': apikey,
            'redirect_uri': 'http://localhost/callback'
        }

        # POST data to get access token
        self.authenticate_reply = requests.post(url=self.token_endpoint,
                                                headers=headers,
                                                data=payload)
        if self.authenticate_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            # convert json reply to dictionary
            self.token_data = self.authenticate_reply.json()
            self.access_token = self.token_data['access_token']
            self.access_header = {
                'Authorization': "Bearer {}".format(self.access_token)
            }
            if self.verbose: print(self.access_header)

            self.account_authenticated = True
            self.time_of_last_refresh = arrow.now('America/New_York')

        else:
            raise utility_exceptions.AccessError(
                url=self.token_endpoint,
                headers=headers,
                data=payload,
                ErrorCode=self.authenticate_reply.status_code)
Esempio n. 10
0
    def access_accounts(self):
        '''
        Access accounts to get the account ID

        :return:
        '''

        self.account_access_attempt = False

        try:
            self.access_header
        except AttributeError:
            if self.verbose: print('access header not defined')
            raise utility_exceptions.AccountError(header_error=True)

        # define the accounts endpoint
        self.accounts_endpoint = r'https://api.tdameritrade.com/v1/accounts'

        # POST data to get access token
        self.account_reply = requests.get(url=self.accounts_endpoint,
                                          headers=self.access_header)
        if self.account_reply.status_code == utility_exceptions.AccessSuccess.account_success.value:
            self.account_data = self.account_reply.json()
            self.account_id = self.account_data[0]['securitiesAccount'][
                'accountId']
            return self.account_data
            if self.verbose: print(self.account_data)
        elif self.account_reply.status_code == utility_exceptions.AccessSuccess.account_partial_success.value \
                and not self.account_access_attempt:
            # wait 5 seconds and then attempt again.
            time.sleep(5)
            if self.verbose:
                print('Account data partial success, calling again..')
            self.account_reply = requests.get(url=self.accounts_endpoint,
                                              headers=self.access_header)
            self.account_data = self.account_reply.json()
            self.account_id = self.account_data[0]['securitiesAccount'][
                'accountId']
            return self.account_data
            if self.verbose: print(self.account_data)
        else:
            raise utility_exceptions.AccessError(
                ErrorCode=self.account_reply.status_code,
                url=self.accounts_endpoint,
                headers=self.access_header)