コード例 #1
0
ファイル: ALLTD.py プロジェクト: JChaiTea/Chia
class tdAction(object):
    def __init__(self):
        """Constructor"""
        self.conKey = CONSUMER_KEY
        self.redirect = REDIRECT_URL
        self.acct = ACCT_NUM
        self.tdClient = TDClient(client_id=self.conKey,
                                 redirect_uri=self.redirect)
        self.tdClient.login()

    def quote(self, tickerList):
        """Grab quotes"""
        retDict = {}
        quotes = self.tdClient.get_quotes(instruments=tickerList)
        for key in quotes:
            if type(quotes[key]['lastPrice']) is not None:
                retDict[key] = quotes[key]['lastPrice']
        return retDict

    def history(self, tickerList):
        """Create real time data for a given list of tickers"""
        retDict = {}
        for item in tickerList:
            tickerHistory = self.tdClient.get_price_history(symbol=item,
                                                            period_type='year')
            priceHistory = []
            for data in tickerHistory['candles']:
                priceHistory.append(data['close'])
            df = DataFrame({item: priceHistory})
            retDict[item] = df
        return retDict
コード例 #2
0
def history(symbol):
    quotes = TDClient.get_price_history(TDSession, symbol=symbol, period_type='day',
                                        period=1, frequency_type='minute', frequency=1,
                                        extended_hours=False)
    # start_date = 1606086000000, end_date = 1606341600000,

    return quotes
コード例 #3
0
def history(symbol, period, p_type, freq, f_type):
    quotes = TDClient.get_price_history(TDSession,
                                        symbol=symbol,
                                        period=period,
                                        period_type=p_type,
                                        frequency=freq,
                                        frequency_type=f_type,
                                        extended_hours=False,
                                        start_date=1606086000000)
    # start_date=1606086000000, end_date = 1606341600000,

    return quotes
コード例 #4
0
def dt_signal_prices(candle_minutes, symbols):
    TDSession = TDClient(client_id=config.client_id,
                         redirect_uri='http://localhost/test',
                         credentials_path='td_state.json')

    TDSession.login()

    cur_day = datetime.datetime.now(tz=pytz.timezone('US/Eastern'))
    price_end_date = str(int(round(cur_day.timestamp() * 1000)))
    price_start_date = str(
        int(
            round(
                datetime.datetime(cur_day.year, cur_day.month,
                                  cur_day.day - 1).timestamp() * 1000)))

    candle_list = []

    for symbol in symbols:
        p_hist = TDSession.get_price_history(symbol,
                                             period_type='day',
                                             frequency_type='minute',
                                             frequency=str(candle_minutes),
                                             end_date=price_end_date,
                                             start_date=price_start_date)

        for candle in p_hist['candles']:
            candle_list.append([
                symbol,
                datetime.datetime.fromtimestamp(candle['datetime'] / 1000),
                candle['open'], candle['close'], candle['high'], candle['low']
            ])

    df_dt = pd.DataFrame(
        candle_list,
        columns=['Symbol', 'Date', 'Open', 'Close', 'High', 'Low'])

    # Calculate moving average
    df_dt['SMA_9'] = df_dt.groupby('Symbol')['Close'].rolling(
        9).mean().reset_index(0, drop=True)

    return df_dt
コード例 #5
0
    for frequency_period in frequency_periods.keys():
        possible_values = frequency_periods[frequency_period]

        for value in possible_values:

            # Define the dynamic arguments - I want 5 DAYS of historical 1-minute bars.
            hist_periodType = frequency_period
            hist_period = value
            hist_frequencyType = frequency_type
            hist_frequency = 1

            # make the request
            historical_1_minute = TDSession.get_price_history(
                symbol=hist_symbol,
                period_type=hist_periodType,
                period=hist_period,
                frequency_type=hist_frequencyType,
                frequency=hist_frequency,
                extended_hours=hist_needExtendedHoursData)
"""
    CUSTOM RANGE
"""

# The max look back period for minute data is 31 Days.
lookback_period = 31

# Define today.
today_00 = datetime.now()

# Define 300 days ago.
today_ago = datetime.now() - timedelta(days=lookback_period)
コード例 #6
0
ファイル: request.py プロジェクト: rrrudolph/old-and-lame
def request_data():
    # Create a new session
    td_client = TDClient(
        client_id='AZ2BZPRDVDNFBHUB5ADYDAPMD2CLG9RG',
        redirect_uri='https://localhost/first',
        credentials_path='C:/Users/R/Desktop/code/2nd-tda-api/td_state.json')

    # Login to a new session
    td_client.login()
    print('td client logged in')

    # ... Backfill data ...
    ''' This is for filling in data from overnight or
        whenever the program hasn't been running during
        market hours '''
    for symbol in symbols:
        print(symbol)
        ext_hours = True  # extended hours
        period_type = 'month'
        period = 3
        frequency_type = 'daily'
        frequency = 1

        # Make request
        backfill = td_client.get_price_history(symbol=symbol,
                                               period_type=period_type,
                                               period=period,
                                               frequency_type=frequency_type,
                                               frequency=frequency,
                                               extended_hours=ext_hours)

        # returns a dictionary with 3 items: candles (a list), empty, and symbol
        # found a typo:  http://prntscr.com/sw8dtq
        # Remove symbol prefix if present
        if symbol[0] == '$' or symbol[0] == '/':
            symbol = symbol[1:]

        # in case I get bad data that causes an error
        # (log something too)
        print('backfill requested')
        try:
            # Save the OHLC data
            s = backfill['candles']
            new_data = pd.DataFrame(s)
            new_data['datetime'] = pd.to_datetime(new_data['datetime'],
                                                  unit='ms',
                                                  origin='unix')
            new_data.rename(columns={"datetime": "dt"}, inplace=True)
            # new_data.set_index('dt', inplace=True)
            new_data = new_data[[
                'dt', 'open', 'high', 'low', 'close', 'volume'
            ]]
            f = open(
                'C:/Users/R/Desktop/code/2nd-tda-api/data/{}_1d.csv'.format(
                    symbol), 'w+')
            # append to existing raw data and delete duplicates
            old_data = pd.DataFrame(f)
            df = old_data.append(new_data)
            df.drop_duplicates(inplace=True)
            df.fillna(method='ffill', inplace=True)
            df.to_csv(
                'C:/Users/R/Desktop/code/2nd-tda-api/data/{}_1d.csv'.format(
                    symbol),
                index=True)
            f.close()
            print('backfill saved!!!!')
        except Exception as e:
            print(e)
            #log someting maybe
            pass
class TDSession(TestCase):
    """Will perform a unit test for the TD session."""
    def setUp(self) -> None:
        """Set up the `TDClient`."""

        # Grab configuration values.
        config = ConfigParser()
        config.read('config/config.ini')

        # Load the values.
        CLIENT_ID = config.get('main', 'CLIENT_ID')
        REDIRECT_URI = config.get('main', 'REDIRECT_URI')
        JSON_PATH = config.get('main', 'JSON_PATH')
        ACCOUNT_NUMBER = config.get('main', 'ACCOUNT_NUMBER')

        # Initalize the session.
        self.td_session = TDClient(client_id=CLIENT_ID,
                                   redirect_uri=REDIRECT_URI,
                                   credentials_path=JSON_PATH,
                                   account_number=ACCOUNT_NUMBER)

    def test_creates_instance_of_session(self):
        """Create an instance and make sure it's a `TDClient` object."""

        self.assertIsInstance(self.td_session, TDClient)

    def test_login(self):
        """Test whether the session is authenticated or not."""

        self.assertTrue(self.td_session.login())
        self.assertTrue(self.td_session.authstate)

    def test_state(self):
        """Make sure the state is updated."""

        self.assertIsNotNone(self.td_session.state['refresh_token'])
        self.assertIsNotNone(self.td_session.state['access_token'])

        self.assertNotEqual(self.td_session.state['refresh_token_expires_at'],
                            0)
        self.assertNotEqual(self.td_session.state['access_token_expires_at'],
                            0)

    def test_single_get_quotes(self):
        """Test Getting a Single quote."""

        # Grab a single quote.
        quotes = self.td_session.get_quotes(instruments=['MSFT'])

        # See if the Symbol is in the Quotes.
        self.assertIn('MSFT', quotes)

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_single_quotes.jsonc',
                      'w+') as data_file:
                json.dump(obj=quotes, fp=data_file, indent=3)

    def test_get_quotes(self):
        """Test Getting Multiple Quotes."""

        # Grab multiple Quotes.
        quotes = self.td_session.get_quotes(instruments=['MSFT', 'AAPL'])

        # See if the Symbols are in the Quotes.
        self.assertTrue(set(['MSFT', 'AAPL']).issuperset(set(quotes.keys())))

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_multiple_quotes.jsonc',
                      'w+') as data_file:
                json.dump(obj=quotes, fp=data_file, indent=3)

    def test_get_accounts(self):
        """Test Get Accounts."""

        accounts = self.td_session.get_accounts(account='all',
                                                fields=['orders', 'positions'])

        self.assertIn('positions', accounts[0]['securitiesAccount'])
        self.assertIn('currentBalances', accounts[0]['securitiesAccount'])
        # self.assertIn('orderStrategies', accounts[0]['securitiesAccount'])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_accounts.jsonc',
                      'w+') as data_file:
                json.dump(obj=accounts, fp=data_file, indent=3)

    def test_create_stream_session(self):
        """Test Creating a new streaming session."""

        stream_session = self.td_session.create_streaming_session()
        self.assertIsInstance(stream_session, TDStreamerClient)

    def test_get_transactions(self):
        """Test getting transactions."""

        # `get_transactions` Endpoint. Should not return an error
        transaction_data_multi = self.td_session.get_transactions(
            account=self.td_session.account_number, transaction_type='ALL')

        # Make sure it's a list.
        self.assertIsInstance(transaction_data_multi, list)
        self.assertIn('type', transaction_data_multi[0])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_transaction_data.jsonc',
                      'w+') as data_file:
                json.dump(obj=transaction_data_multi, fp=data_file, indent=3)

    def test_get_market_hours(self):
        """Test get market hours."""

        # `get_market_hours` Endpoint with multiple values
        market_hours_multi = self.td_session.get_market_hours(
            markets=['EQUITY', 'FOREX'], date=datetime.today().isoformat())

        # If it's a weekend nothing is returned, so raise an error.
        if datetime.today().weekday() in (5, 6):

            # Make sure it's a list.
            self.assertIsInstance(market_hours_multi, dict)
            self.assertIn('isOpen', market_hours_multi['equity']['equity'])

        else:
            # Make sure it's a list.
            self.assertIsInstance(market_hours_multi, dict)
            self.assertIn('isOpen', market_hours_multi['equity']['EQ'])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_market_hours.jsonc',
                      'w+') as data_file:
                json.dump(obj=market_hours_multi, fp=data_file, indent=3)

    def test_get_instrument(self):
        """Test getting an instrument."""

        # `get_instruments` Endpoint.
        get_instrument = self.td_session.get_instruments(cusip='594918104')

        # Make sure it's a list.
        self.assertIsInstance(get_instrument, list)
        self.assertIn('cusip', get_instrument[0])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_instrument.jsonc',
                      'w+') as data_file:
                json.dump(obj=get_instrument, fp=data_file, indent=3)

    def test_chart_history(self):
        """Test getting historical prices."""

        # Define a list of all valid periods
        valid_values = {
            'minute': {
                'day': [1, 2, 3, 4, 5, 10]
            },
            'daily': {
                'month': [1, 2, 3, 6],
                'year': [1, 2, 3, 5, 10, 15, 20],
                'ytd': [1]
            },
            'weekly': {
                'month': [1, 2, 3, 6],
                'year': [1, 2, 3, 5, 10, 15, 20],
                'ytd': [1]
            },
            'monthly': {
                'year': [1, 2, 3, 5, 10, 15, 20]
            }
        }

        # Define the static arguments.
        hist_symbol = 'MSFT'
        hist_needExtendedHoursData = False

        for frequency_type in valid_values.keys():
            frequency_periods = valid_values[frequency_type]

            for frequency_period in frequency_periods.keys():
                possible_values = frequency_periods[frequency_period]

                for value in possible_values:

                    # Define the dynamic arguments - I want 5 DAYS of historical 1-minute bars.
                    hist_periodType = frequency_period
                    hist_period = value
                    hist_frequencyType = frequency_type
                    hist_frequency = 1

                    # make the request
                    historical_prices = self.td_session.get_price_history(
                        symbol=hist_symbol,
                        period_type=hist_periodType,
                        period=hist_period,
                        frequency_type=hist_frequencyType,
                        frequency=hist_frequency,
                        extended_hours=hist_needExtendedHoursData)

                    self.assertIsInstance(historical_prices, dict)
                    self.assertFalse(historical_prices['empty'])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_historical_prices.jsonc',
                      'w+') as data_file:
                json.dump(obj=historical_prices, fp=data_file, indent=3)

    def test_custom_historical_prices(self):
        """Test getting historical prices for a custom date range."""

        # The max look back period for minute data is 31 Days.
        lookback_period = 10

        # Define today.
        today_00 = datetime.now()

        # Define 300 days ago.
        today_ago = datetime.now() - timedelta(days=lookback_period)

        # The TD API expects a timestamp in milliseconds. However, the timestamp() method only returns to seconds so multiply it by 1000.
        today_00 = str(int(round(today_00.timestamp() * 1000)))
        today_ago = str(int(round(today_ago.timestamp() * 1000)))

        # These values will now be our startDate and endDate parameters.
        hist_startDate = today_ago
        hist_endDate = today_00

        # Define the dynamic arguments.
        hist_periodType = 'day'
        hist_frequencyType = 'minute'
        hist_frequency = 1

        # Make the request
        historical_custom = self.td_session.get_price_history(
            symbol='MSFT',
            period_type=hist_periodType,
            frequency_type=hist_frequencyType,
            start_date=hist_startDate,
            end_date=hist_endDate,
            frequency=hist_frequency,
            extended_hours=True)

        self.assertIsInstance(historical_custom, dict)
        self.assertFalse(historical_custom['empty'])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_historical_prices.jsonc',
                      'w+') as data_file:
                json.dump(obj=historical_custom, fp=data_file, indent=3)

    def test_search_instruments(self):
        """Test Searching for Instruments."""

        # `search_instruments` Endpoint
        instrument_search_data = self.td_session.search_instruments(
            symbol='MSFT', projection='symbol-search')

        self.assertIsInstance(instrument_search_data, dict)
        self.assertIn('MSFT', instrument_search_data)

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_search_instrument.jsonc',
                      'w+') as data_file:
                json.dump(obj=instrument_search_data, fp=data_file, indent=3)

    def test_get_movers(self):
        """Test getting Market movers."""

        # `get_movers` Endpoint
        movers_data = self.td_session.get_movers(market='$DJI',
                                                 direction='up',
                                                 change='value')

        if datetime.today().weekday() in (5, 6):
            self.assertIsInstance(movers_data, list)
            self.assertFalse(movers_data)
        else:
            self.assertIsInstance(movers_data, list)
            self.assertIn('symbol', movers_data[0])

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_movers.jsonc',
                      'w+') as data_file:
                json.dump(obj=movers_data, fp=data_file, indent=3)

    def test_get_user_preferences(self):
        """Test getting user preferences."""

        # `get_preferences` endpoint. Should not return an error
        preference_data = self.td_session.get_preferences(
            account=self.td_session.account_number)

        self.assertIsInstance(preference_data, dict)
        self.assertIn('expressTrading', preference_data)

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_account_preferences.jsonc',
                      'w+') as data_file:
                json.dump(obj=preference_data, fp=data_file, indent=3)

    def test_get_user_principals(self):
        """Test getting user principals."""

        # `get_preferences` endpoint. Should not return an error
        user_principals = self.td_session.get_user_principals(
            fields=['preferences', 'surrogateIds'])

        self.assertIsInstance(user_principals, dict)
        self.assertIn('userId', user_principals)

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_user_principals.jsonc',
                      'w+') as data_file:
                json.dump(obj=user_principals, fp=data_file, indent=3)

    def test_get_streamer_keys(self):
        """Test getting user preferences."""

        # `get_subscription_keys` endpoint. Should not return an error
        streamer_keys = self.td_session.get_streamer_subscription_keys(
            accounts=[self.td_session.account_number])

        self.assertIsInstance(streamer_keys, dict)
        self.assertIn('keys', streamer_keys)

        # Save the data.
        if SAVE_FLAG:
            with open('samples/responses/sample_streamer_keys.jsonc',
                      'w+') as data_file:
                json.dump(obj=streamer_keys, fp=data_file, indent=3)

    def tearDown(self) -> None:
        """Teardown the Robot."""

        self.td_session = None
def grab_candle_data(pull_from_td: bool) -> list[dict]:
    """A function that grabs candle data from TD Ameritrade,
    cleans up the data, and saves it to a JSON file, so we can
    use it later.

    ### Parameters
    ----------
    pull_from_td : bool
        If `True`, pull fresh candles from the TD
        Ameritrade API. If `False`, load the data
        from the JSON file.

    ### Returns
    -------
    list[dict]
        A list of candle dictionaries with cleaned
        dates, and additional values.
    """

    if pull_from_td:

        # Grab configuration values.
        config = ConfigParser()
        config.read('config/config.ini')

        # Read the Config File.
        CLIENT_ID = config.get('main', 'CLIENT_ID')
        REDIRECT_URI = config.get('main', 'REDIRECT_URI')
        JSON_PATH = config.get('main', 'JSON_PATH')
        ACCOUNT_NUMBER = config.get('main', 'ACCOUNT_NUMBER')

        # Create a new session
        TDSession = TDClient(client_id=CLIENT_ID,
                             redirect_uri=REDIRECT_URI,
                             credentials_path=JSON_PATH,
                             account_number=ACCOUNT_NUMBER)

        # Login to the session
        TDSession.login()

        # Initialize the list to store candles.
        all_candles = []

        # Loop through each Ticker.
        for ticker in ['AAPL', 'NIO', 'FIT', 'TSLA', 'MSFT', 'AMZN', 'IBM']:

            # Grab the Quotes.
            quotes = TDSession.get_price_history(symbol=ticker,
                                                 period_type='day',
                                                 period='10',
                                                 frequency_type='minute',
                                                 frequency=1,
                                                 extended_hours=False)

            # Grab the Candles.
            candles = quotes['candles']

            # Loop through each candle.
            for candle in candles:

                # Calculate the Range.
                candle['range'] = round(candle['high'] - candle['low'], 5)

                # Add the Symbol.
                candle['symbol'] = quotes['symbol']

                # Convert to ISO String.
                candle['datetime_iso'] = datetime.fromtimestamp(
                    candle['datetime'] / 1000).isoformat()

                # Conver to a Timestamp non-milliseconds.
                candle['datetime_non_milli'] = int(candle['datetime'] / 1000)

                all_candles.append((candle))

        # Save it to a JSON File.
        with open(file='data/candles.json', mode='w+') as candle_file:
            json.dump(obj=all_candles, fp=candle_file, indent=4)

    elif pull_from_td is False and pathlib.Path('data/candles.json').exists():

        # Save it to a JSON File.
        with open(file='data/candles.json', mode='r') as candle_file:
            all_candles = json.load(fp=candle_file)

    return all_candles