def __init__(self): try: #Global variables API_KEY = '@AMER.OAUTHAP' ### INSERT YOUR PRIVATE API KEY ### REDIRECT_URI = 'http://localhost:8080' ### INSERT localhost address ### TOKEN_PATH = 'token.pickle' #New client self.client = tda.auth.easy_client(API_KEY, REDIRECT_URI, TOKEN_PATH, self.make_webdriver) #Account ID r = self.client.get_accounts() assert r.status_code == 200, r.raise_for_status() data = r.json() self.account_id = data[0]['securitiesAccount']['accountId'] self.accountSize = data[0]['securitiesAccount']['currentBalances']['cashBalances'] self.stream_client = StreamClient(self.client, account_id=self.account_id) print("You are logged in to your TD Ameritrade Account.") #Get symbol info self.symbol = input("Enter the ticker you want to trade : ") #Get candle stick self.barsize = int(input("Enter the barsize you want to trade in minutes : ")) self.stream_client = StreamClient(self.client, account_id=self.account_id) #run program asynchronously asyncio.run(self.read_stream()) except Exception as e: print(e)
def initialize(self): self.tda_client = easy_client( api_key=self.api_key, redirect_uri="http://localhost", token_path="/home/dkasabovn/Dev/python/ameritrade/token.pickle", webdriver_func=make_webdriver) self.stream_client = StreamClient(self.tda_client, account_id=self.account_id) self.stream_client.add_chart_equity_handler(self.handle_ohlc)
def initialize(self): """ Create the clients and log in. Using easy_client, we can get new creds from the user via the web browser if necessary """ self.tda_client = easy_client(api_key=self.api_key, redirect_uri='https://localhost:8080', token_path=self.credentials_path) self.stream_client = StreamClient(self.tda_client, account_id=self.account_id) # The streaming client wants you to add a handler for every service type self.stream_client.add_timesale_equity_handler( self.handle_timesale_equity)
def get_stream_client(self): easy_client = auth.easy_client( api_key=self.customer_key, redirect_uri=self.callback_url, token_path=self.token_path + "/token", ) return StreamClient(easy_client, account_id=self.account_id)
def test_streaming(self): print() print('##########################################################') print() print('Testing stream connection and handling...') stream_client = StreamClient(self.client, account_id=self.account_id) async def read_stream(): await stream_client.login() await stream_client.quality_of_service( StreamClient.QOSLevel.EXPRESS) stream_client.add_nasdaq_book_handler( lambda msg: print(json.dumps(msg, indent=4))) await stream_client.nasdaq_book_subs(['GOOG']) # Handle one message and then declare victory await stream_client.handle_message() asyncio.run(read_stream()) print() print('##########################################################') print()
async def stream_account_activity(self): client = easy_client( api_key=self._apiKey, redirect_uri=REDIRECT_URI, token_path=self._loginDataPath, webdriver_func=lambda: webdriver.Chrome(ChromeDriverManager().install())) stream_client = StreamClient(client, account_id=int(self._accountID)) await self.read_stream(self.send_message, stream_client)
def initialize(self): """ Create the clients and log in. Using easy_client, we can get new creds from the user via the web browser if necessary """ self.tda_client = easy_client( # You can customize your browser here webdriver_func=lambda: webdriver.Chrome(), #webdriver_func=lambda: webdriver.Firefox(), #webdriver_func=lambda: webdriver.Safari(), #webdriver_func=lambda: webdriver.Ie(), api_key=self.api_key, redirect_uri='https://localhost:8080', token_path=self.credentials_path) self.stream_client = StreamClient(self.tda_client, account_id=self.account_id) # The streaming client wants you to add a handler for every service type self.stream_client.add_timesale_equity_handler( self.handle_timesale_equity)
def __init__(self): self.account_id = '275356186' self.key = 'FA3ISKLEGYIFXQRSUJQCB93AKXFRGZUK' self.callback_url = 'https://localhost:8080' self.token_path = '../doc/token' # Setup client try: self.client = easy_client(api_key=self.key, redirect_uri=self.callback_url, token_path=self.token_path) except FileNotFoundError: self.authenticate() # Setup stream self.stream = StreamClient(self.client, account_id=self.account_id)
def tda_stream(self, symbol: str): client = self.client account_id = int(Encryption().decrypt(S.TDA_ACCOUNT_E)) stream_client = StreamClient(client, account_id=account_id) async def read_stream(s): await stream_client.login() await stream_client.quality_of_service( StreamClient.QOSLevel.EXPRESS) # Always add handlers before subscribing because many streams start # sending data immediately after success, and messages with no # handlers are dropped. stream_client.add_nasdaq_book_handler( lambda msg: print(json.dumps(msg, indent=4))) await stream_client.nasdaq_book_subs([s]) while True: await stream_client.handle_message() asyncio.run(read_stream(s=symbol))
def initialize(self): self._sc = StreamClient(self._c, account_id=self.account_id) self._sc.add_chart_equity_handler(self.handle_updates)
from selenium import webdriver import asyncio import json import logging logging.getLogger("").addHandler(logging.StreamHandler()) # client = easy_client( # api_key=API_KEY, # redirect_uri=REDIRECT_URI, # token_path=TOKEN_PATH, # webdriver_func=lambda: webdriver.Chrome()) try: client = auth.client_from_token_file(TOKEN_PATH, API_KEY) stream_client = StreamClient(client, account_id=int(ACCOUNT_ID)) except FileNotFoundError: from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager with webdriver.Chrome(ChromeDriverManager().install()) as driver: client = auth.client_from_login_flow(driver, API_KEY, REDIRECT_URI, TOKEN_PATH) stream_client = StreamClient(client, account_id=int(ACCOUNT_ID)) async def read_stream(handler: Callable[[Dict[Any, Any]], None], symbols: Iterable[str]): await stream_client.login() await stream_client.quality_of_service(StreamClient.QOSLevel.EXPRESS) await stream_client.chart_equity_subs(symbols=symbols, )
from tda.streaming import StreamClient import pandas as pd import config CONN = psycopg2.connect(host=config.DB_HOST, database=config.DB_NAME, user=config.DB_USER, password=config.DB_PASS) CURSOR = CONN.cursor() CLIENT = easy_client(api_key=config.api_key, redirect_uri=config.redirect_uri, token_path=config.token_path) STREAM_CLIENT = StreamClient(CLIENT, account_id=config.account_id) def order_book_handler(msg): """ This is the Message Handler, and store streaming Data in Timescale DB """ count = len(msg['content']) CONN.commit() try: for i in range(count): dict2 = {**msg['content'][i]} # print(dict2) cols = dict2.keys() cols_str = ','.join(cols)
class GonseProducer: def __init__(self, client, tickers): super().__init__() self._c = client self._p = KafkaProducer( bootstrap_servers='localhost:9092', api_version=(2, 0, 2), value_serializer=lambda x: json.dumps(x).encode('utf-8')) self._sc = None self.symbols = tickers self.account_id = os.getenv("TDA_ACCOUNT_NUMBER") self.queue = asyncio.Queue(1) def initialize(self): self._sc = StreamClient(self._c, account_id=self.account_id) self._sc.add_chart_equity_handler(self.handle_updates) async def stream(self): loop = asyncio.get_event_loop() signals = (SIGHUP, SIGTERM, SIGINT, SIGQUIT) for s in signals: loop.add_signal_handler( s, lambda s=s: asyncio.create_task(self.shutdown(s, loop))) await self._sc.login() await self._sc.quality_of_service(StreamClient.QOSLevel.EXPRESS) await self._sc.chart_equity_subs(self.symbols) while True: await self._sc.handle_message() sleep(1) self._p.flush() self._p.close() return async def shutdown(self, signal, loop): tasks = [ t for t in asyncio.all_tasks() if t is not asyncio.current_task() ] [task.cancel() for task in tasks] await asyncio.gather(*tasks) loop.stop() async def test_produce(self): loop = asyncio.get_event_loop() signals = (SIGHUP, SIGTERM, SIGINT, SIGQUIT) for s in signals: loop.add_signal_handler( s, lambda s=s: asyncio.create_task(self.shutdown(s, loop))) while True: await self.handle_updates( {"content": [{ "key": "AAPL", "data": "test" }]}) print("Sent message") await asyncio.sleep(2) self._p.flush() self._p.close() return async def handle_updates(self, msg): for update in msg["content"]: ticker = update["key"] print(update) self._p.send(ticker, value=update)
class MyStreamConsumer: """ We use a class to enforce good code organization practices """ def __init__(self, api_key, account_id, queue_size=1, credentials_path='./ameritrade-credentials.pickle'): """ We're storing the configuration variables within the class for easy access later in the code! """ self.api_key = api_key self.account_id = account_id self.credentials_path = credentials_path self.tda_client = None self.stream_client = None self.symbols = [ 'GOOG', 'GOOGL', 'BP', 'CVS', 'ADBE', 'CRM', 'SNAP', 'AMZN', 'BABA', 'DIS', 'TWTR', 'M', 'USO', 'AAPL', 'NFLX', 'GE', 'TSLA', 'F', 'SPY', 'FDX', 'UBER', 'ROKU', 'X', 'FB', 'BIDU', 'FIT' ] # Create a queue so we can queue up work gathered from the client self.queue = asyncio.Queue(queue_size) def initialize(self): """ Create the clients and log in. Using easy_client, we can get new creds from the user via the web browser if necessary """ self.tda_client = easy_client(api_key=self.api_key, redirect_uri='https://localhost:8080', token_path=self.credentials_path) self.stream_client = StreamClient(self.tda_client, account_id=self.account_id) # The streaming client wants you to add a handler for every service type self.stream_client.add_timesale_equity_handler( self.handle_timesale_equity) async def stream(self): await self.stream_client.login() # Log into the streaming service await self.stream_client.quality_of_service( StreamClient.QOSLevel.EXPRESS) await self.stream_client.timesale_equity_subs(self.symbols) # Kick off our handle_queue function as an independent coroutine asyncio.ensure_future(self.handle_queue()) # Continuously handle inbound messages while True: await self.stream_client.handle_message() async def handle_timesale_equity(self, msg): """ This is where we take msgs from the streaming client and put them on a queue for later consumption. We use a queue to prevent us from wasting resources processing old data, and falling behind. """ # if the queue is full, make room if self.queue.full(): await self.queue.get() await self.queue.put(msg) async def handle_queue(self): """ Here we pull messages off the queue and process them. """ while True: msg = await self.queue.get() pprint.pprint(msg)
cursor.execute(""" SELECT symbol, name FROM stock JOIN stock_strategy ON stock_strategy.stock_id = stock.id """) stocks = cursor.fetchall() symbols = [stock['symbol'] for stock in stocks] logging.info(symbols) client = easy_client(api_key=config.tda_api_key, redirect_uri=config.tda_redirect_uri, token_path=config.tda_token_path) stream_client = StreamClient(client, account_id=config.tda_account_id) async def insert_stream_data(msg, symbols): data = json.loads(msg) with sqlite3.connect(config.DB_FILE) as conn: conn.execute("""CREATE TABLE IF NOT EXISTS tda_stock_price_minute ( seq INTEGER, key TEXT, open REAL, high REAL, low REAL, close REAL, volume INTEGER, sequence INTEGER,
class TempGonseRunner: # ! Will deprecate when kafka backend is done def __init__(self, *args): self.api_key = os.getenv("TDA_API_KEY") self.account_id = os.getenv("TDA_ACCOUNT_NUMBER") self.tda_client = None self.stream_client = None self.symbols = symbols self.queue = asyncio.Queue(1) self._consumers = *args def initialize(self): self.tda_client = easy_client( api_key=self.api_key, redirect_uri="http://localhost", token_path="/home/dkasabovn/Dev/python/ameritrade/token.pickle", webdriver_func=make_webdriver) self.stream_client = StreamClient(self.tda_client, account_id=self.account_id) self.stream_client.add_chart_equity_handler(self.handle_ohlc) async def stream(self): loop = asyncio.get_event_loop() signals = (SIGHUP, SIGTERM, SIGINT, SIGQUIT) for s in signals: loop.add_signal_handler( s, lambda s=s: asyncio.create_task(self.shutdown(s, loop))) await self.stream_client.login() await self.stream_client.quality_of_service( StreamClient.QOSLevel.EXPRESS) await self.stream_client.chart_equity_subs(self.symbols) asyncio.ensure_future(self.handle_queue()) while True: await self.stream_client.handle_message() async def shutdown(self, signal, loop): tasks = [ t for t in asyncio.all_tasks() if t is not asyncio.current_task() ] [task.cancel() for task in tasks] await asyncio.gather(*tasks) loop.stop() async def handle_ohlc(self, msg): if self.queue.full(): await self.queue.get() await self.queue.put(msg) async def handle_queue(self): while True: msg = await self.queue.get() for update in msg["content"]: ticker = update["key"] self._consumers
from tda.auth import easy_client from tda.streaming import StreamClient import login.config as config #create the client to talk to td ameritrade #initialize a session client = easy_client(config.API_KEY, config.REDIRECT_URI, config.TOKEN_PATH) stream_client = StreamClient(client, account_id=config.ACCOUNT_ID) stream_client2 = StreamClient(client, account_id=config.ACCOUNT_ID)
class Bot(): barsize = 1 currentBar = Bar() bars = [] client = '' account_id = 0 accountSize = 10000 firstTime = True inPosition = False #Common Indicators rsi = [] vol = [] ema50 = [] ema200 = [] min_vol = 99999999 #Parameters risPeriod = 14 stream_client = '' status = None initialbartime = datetime.datetime.now() #.astimezone(pytz.timezone()) #Connect to TD Ameritrade def __init__(self): try: #Global variables API_KEY = '@AMER.OAUTHAP' ### INSERT YOUR PRIVATE API KEY ### REDIRECT_URI = 'http://localhost:8080' ### INSERT localhost address ### TOKEN_PATH = 'token.pickle' #New client self.client = tda.auth.easy_client(API_KEY, REDIRECT_URI, TOKEN_PATH, self.make_webdriver) #Account ID r = self.client.get_accounts() assert r.status_code == 200, r.raise_for_status() data = r.json() self.account_id = data[0]['securitiesAccount']['accountId'] self.accountSize = data[0]['securitiesAccount']['currentBalances']['cashBalances'] self.stream_client = StreamClient(self.client, account_id=self.account_id) print("You are logged in to your TD Ameritrade Account.") #Get symbol info self.symbol = input("Enter the ticker you want to trade : ") #Get candle stick self.barsize = int(input("Enter the barsize you want to trade in minutes : ")) self.stream_client = StreamClient(self.client, account_id=self.account_id) #run program asynchronously asyncio.run(self.read_stream()) except Exception as e: print(e) #Stream realtime updates async def read_stream(self): try: await self.stream_client.login() await self.stream_client.quality_of_services(StreamClient.QOSLevel.EXPRESS) await self.stream_client.chart_equity_subs([self.symbol]) self.stream_client.add_chart_equity_handler(self.onBarUpdate) print("Streaming real-time date now.") while True: try: await self.stream_client.handle_message() except Exception as e: print(e) except Exception as e: print(e) #Update everytime there is a bar def OnBarUpdates(self, msg): try: msg = json.dumps(msg, indent=4) msg = json.loads(msn) #Retrieve Bar for bar in msg['content']: #Check The Strategy bartime = datetime.datetime.fromtimestamp(msg['timestamp'] / 1000) #.astimezone(pytz.timezone()) minutes_diff = (bartime-self.initialbartime).total_seconds() / 60.0 self.currentBar.date = bartime #On Bar Close if (minutes_diff > 0 and math.floor(minutes_diff) % self.barsize == 0): self.initialbartime = bartime """ INSERT ENTRY AND EXIT STRATEGY """ #Investment strategy based on RSI #Calculate RSI closes = [] for histbar in self.bars: closes.append(histbar.close) self.close_array = pd.Series(np.asarray(closes)) if len(self.bars) > 0: #Calculate RSI on bar close self.rsi = ta.momentum.rsi(self.close_array, self.rsiPeriod, True) #Print last rsi print(self.rsi[len(self.rsi)-1]) """ If the rsi <= 30 and we are not in position, buy If the rsi >= 70 and we are in position, sell """ if self.rsi[len(self.rsi)-1] <= 30 and not inPosition: order = tda.orders.equities.equity_buy_market(self.symbol,1) inPosition = True if self.rsi[len(self.rsi)-1] >= 70 and inPosition: order = tda.orders.equities.equity_sell_market(self.symbol,1) inPosition = False """ ALTERNATIVE STRATEGY """ #Investment strategy based on EMA #Calculate ema50 and ema200 on bar close # self.ema50 = ta.trend.EMAIndicator(self.close_array,50,True) # self.ema200 = ta.trend.EMAIndicator(self.close_array,200,True) """ If ema50 > ema200 and today's volume is > 7 bar volume min and we are not in position, buy If price < ema50 and we are in position, sell """ # if self.ema50[len(self.ema50)-1] > self.ema200[len(self.ema200)-1] \ # and self.currentBar.volume > self.min_vol and not inPosition: # order = tda.orders.equities.equity_buy_market(self.symbol,1) # inPosition = True # if self.ema50[len(self.ema50)-1] <= self.ema200[len(self.ema200)-1] and inPosition: # order = tda.orders.equities.equity_sell_market(self.symbol,1) # inPosition = False #Bar closed append self.currentBar.close = bar['CLOSE_PRICE'] print("New bar!") self.bars.append(self.currentBar) self.currentBar = Bar() self.currentBar.open = bar['OPEN_PRICE'] #Build realtime bar if self.currentBar.open == 0: self.currentBar.open = bar['OPEN_PRICE'] if self.currentBar.open == 0 or bar['HIGH_PRICE'] > self.currentBar.high: self.currentBar.open = bar['HIGH_PRICE'] if self.currentBar.open == 0 or bar['LOW_PRICE'] < self.currentBar.low: self.currentBar.open = bar['LOW_PRICE'] #Volume append self.currentBar.volume += bar['VOLUME'] #Set minimum volume for bar in self.bars[-7:-1]: if bar.volume < self.min_vol: self.min_vol = bar.volume except Exception as e: print(e) #Connect to TD Ameritrade OAUTH Login def make_webdriver(self): #from selenium import webdriver here if slow to import driver = webdriver.Chrome(ChromeDriverManager().install()) atexit.register(lambda: driver.quit()) return driver