#=======================================================================================# from tda.auth import easy_client from tda.client import Client import tda.auth as auth import shelve as shl import threading as th import multiprocessing as mp import finplot as fplt import pandas as pd from pprint import pprint as pp #=======================================================================================# #=======================================================================================# # reading configuration for credentials. Create configurations using createConfig.py if # not available #=======================================================================================# with shl.open('.\data\config') as configData: APIKEY = configData['key'] redirect = configData['callback_url'] token_path = 'data/token.pickle' # Do NOT change this value #=======================================================================================# # Authentication. If token not available on system, will open a Chrome login window to # create one. Refreshing tokens' task is handled by the script itself :) #=======================================================================================# try: cli = auth.client_from_token_file(token_path, APIKEY) except FileNotFoundError: from selenium import webdriver with webdriver.Chrome() as driver: cli = auth.client_from_login_flow(driver, APIKEY, redirect, token_path) #=======================================================================================# # Price History Specific #=======================================================================================# # Change it to a symbol of your choice. Add new values if needed. Avoid entering too many # symbol names as API access is limited and TDA will start rejecting our requests if we # exceed the limit SYMBOLS = ['GOOG', 'AAPL'] PERIOD_TYPE = 'day' # possible options are 'month' & 'year'. Denotes unit of period to use. PERIOD = 10 # Number of periods. # values allowed for periods are # day: 1, 2, 3, 4, 5, 10* # month: 1*, 2, 3, 6 # year: 1*, 2, 3, 5, 10, 15, 20 # ytd: 1* FREQUENCY_TYPE = 'minute' # allowed values according to PERIOD_TYPE selected # day: minute* # month: daily, weekly* # year: daily, weekly, monthly* # ytd: daily, weekly* FREQUENCY = '1' # allowed values based on FREQUENCY_TYPE SELECTED # minute: 1*, 5, 10, 15, 30 # daily: 1* # weekly: 1* # monthly: 1* NEED_EXTENDED_HOURS_DATA = None # Change to True if extended market hours data needed. Else regular market hours data will be returned #=======================================================================================# # Do NOT change anything below this comment UNLESS you know what you're doing. # This part makes authenticated requests to fetch priceHistory data from TDA-API # for each symbol in the SYMBOLS list, draws candlestick charts for the data ( # one chart for each symbol ). Also writes the data to console (standard Output) # in human readable format. Uses multi-threading to perform tasks in parallel to # save time & use the resources available to their full cap. #=======================================================================================# def worker(symbol, PERIOD_TYPE, PERIOD, FREQUENCY_TYPE, FREQUENCY, NEED_EXTENDED_HOURS_DATA, cli, stdoutLock): def get_and_draw(): response = cli.get_price_history(symbol, period_type=PERIOD_TYPE, period=PERIOD, frequency_type=FREQUENCY_TYPE, frequency=FREQUENCY, need_extended_hours_data=NEED_EXTENDED_HOURS_DATA) prices = response.json() df = pd.DataFrame(prices['candles']).set_index('datetime') candles = df[['open', 'close', 'high', 'low']] volumes = df[['open', 'close', 'volume']] if len(plots) == 0: stdoutLock.acquire() print('=============================================================') pp(prices) print('=============================================================') stdoutLock.release() plots.append(fplt.candlestick_ochl(candles, ax=ax)) plots.append(fplt.volume_ocv(volumes, ax=ax2)) else: plots[0].update_data(candles) plots[1].update_data(volumes) plots = [] ax, ax2 = fplt.create_plot('Price History for '+ symbol + ' - ' + PERIOD + ' ' + PERIOD_TYPE + ' - Frequency = ' + FREQUENCY + ' ' + FREQUENCY_TYPE, rows=2) get_and_draw() fplt.timer_callback(get_and_draw, 60) # Updating graph data every minute fplt.show() #=======================================================================================# processes = [] stdoutLock = mp.Lock() for symbol in SYMBOLS: a = mp.Process(target=worker, args=(symbol, PERIOD_TYPE, PERIOD, FREQUENCY_TYPE, FREQUENCY, NEED_EXTENDED_HOURS_DATA, cli, stdoutLock,)) a.start() threads.append(a) for process in processes: process.join() print('COMPLETED :)') #======================================================================================#