Esempio n. 1
0
 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_token_file(self, client_from_token_file):
        webdriver_func = MagicMock()
        client_from_token_file.return_value = self.token

        self.assertEquals(
            self.token,
            auth.easy_client(API_KEY, REDIRECT_URL, self.pickle_path))
Esempio n. 3
0
  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)
Esempio n. 4
0
    def authenticate(self):

        from selenium import webdriver
        from webdriver_manager.chrome import ChromeDriverManager

        with webdriver.Chrome(ChromeDriverManager().install()) as driver:
            self.client = easy_client(api_key=self.key,
                                      redirect_uri=self.callback_url,
                                      token_path=self.token_path,
                                      webdriver_func=driver)
Esempio n. 5
0
 def __init__(self, methodName):
     super().__init__(methodName)
     self.client = easy_client(
         api_key=os.getenv("TDA_API_KEY"),
         redirect_uri="http://localhost",
         token_path="/home/dkasabovn/Dev/python/ameritrade/token.pickle",
     )
     self.ticker = "AAPL"
     self.algo = TestImplementation(self.ticker)
     self.algo.temp_add_client(self.client)
    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)
Esempio n. 7
0
async def main():
    api_key = os.getenv("TDA_API_KEY")
    client = easy_client(
        api_key=api_key,
        redirect_uri="http://localhost",
        token_path="/home/dkasabovn/Dev/python/ameritrade/token.pickle",
        webdriver_func=make_webdriver)
    producer = GonseProducer(client, ["AAPL"])
    producer.initialize()
    await producer.stream()
Esempio n. 8
0
    def test_token_file_with_enums_enabled(self, client_from_token_file):
        self.write_token()

        webdriver_func = MagicMock()
        client_from_token_file.return_value = self.token

        self.assertEquals(
            self.token, auth.easy_client(API_KEY, REDIRECT_URL,
                                         self.json_path))
        client_from_token_file.assert_called_once_with(self.json_path,
                                                       API_KEY,
                                                       asyncio=False,
                                                       enforce_enums=True)
Esempio n. 9
0
    def __init__(self):
        def make_webdriver():
            from selenium import webdriver

            driver = webdriver.Chrome()
            atexit.register(lambda: driver.quit())
            return driver

        self.client = easy_client(
            api_key=api_key,
            redirect_uri=redirect_uri,
            token_path=token_path,
            webdriver_func=make_webdriver,
        )
Esempio n. 10
0
    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)
Esempio n. 11
0
def main():
    c = easy_client(api_key=client_id,
                    redirect_uri=redirect_uri,
                    token_path='/home/carmelo/Documents/StockMarket/StockCode/TOS/token.pickle')
    fpt = get_fpt(c, trades=4)
    buy_dict_day = 0
    downloaded = True
    bought_today = []
    if os.path.exists('TOS/positions.pickle'): p = get_positions()
    while True:
        day = get_day_params()
        day_condition = all([day[3] * 24 + day[4] / 60 >= 6 * 24 + 40 / 60, day[3] < 13])
        download_condition = all([16 <= day[3] < 23, not downloaded])
        if all([day[3] * 24 + day[4] / 60 >= 6 * 24 + 30 / 60, buy_dict_day != day[2]]):
            downloaded = False
            buy_dict = get_buy_list(c, 'SO', fpt)
            #buy_dict = get_buy_list(c, 'SO', fpt, buy_dict)
            buy_dict_day = day[2]
        try:
            account, round_trips, available_funds, num_trades_available = get_account_deets(c, funds_per_trade=fpt)
            num_trades_available = 0
            if num_trades_available > 0 and len(buy_dict) > 0 and day_condition:
                if len(buy_dict) >= num_trades_available:
                    buy_today = random.sample(list(buy_dict.keys()), num_trades_available)
                else:
                    buy_today = list(buy_dict.keys())
                buy_today = [bt for bt in buy_today if bt not in bought_today]
                p = buy(c, buy_dict, buy_today)
            if os.path.exists('TOS/positions.pickle'):
                for stock in p.keys():
                    if p[stock]['buy_status'] == 'FILLED' and p[stock]['sell_order_id'] == 0:
                        bought_today.append(stock)
                        p[stock] = update_fill_price(c, p[stock])
                        sell(c, stock, p)
                if day_condition:
                    p = monitor(c, p)
                status_bar(p)
        except Exception:
            print(traceback.format_exc())
            pass
        if day[3] > 13 or day[3] < 6:
            do_sleep(600, 601)
        else:
            do_sleep(44, 45)
        if download_condition:
            bought_today = []
            downloaded = True
            download_data()
            process_data()
Esempio n. 12
0
    def test_no_token_file_with_wd_func(self, client_from_token_file,
                                        client_from_login_flow):
        webdriver_func = MagicMock()
        client_from_token_file.side_effect = FileNotFoundError()
        client_from_login_flow.return_value = 'returned client'
        webdriver_func = MagicMock()

        self.assertEquals(
            'returned client',
            auth.easy_client(API_KEY,
                             REDIRECT_URL,
                             self.pickle_path,
                             webdriver_func=webdriver_func))

        webdriver_func.assert_called_once()
        client_from_login_flow.assert_called_once()
Esempio n. 13
0
    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)
Esempio n. 14
0
    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)
Esempio n. 15
0
    def test_no_token_file_with_wd_func_with_enums_enabled(
            self, client_from_token_file, client_from_login_flow):
        client_from_token_file.side_effect = SystemExit()
        client_from_login_flow.return_value = 'returned client'
        webdriver_func = MagicMock()

        self.assertEquals(
            'returned client',
            auth.easy_client(API_KEY,
                             REDIRECT_URL,
                             self.json_path,
                             webdriver_func=webdriver_func))

        webdriver_func.assert_called_once()
        client_from_login_flow.assert_called_once_with(_,
                                                       API_KEY,
                                                       REDIRECT_URL,
                                                       self.json_path,
                                                       asyncio=False,
                                                       enforce_enums=True)
Esempio n. 16
0
    DELETE FROM tda_stock_price_minute
""")
connection.commit()

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,
Esempio n. 17
0
import traceback
import httpx
from tda.auth import easy_client
from tda.auth import client_from_login_flow
from Resources.config import client_id, redirect_url
from selenium import webdriver
import pandas as pd

try:  # Tries to initialize tda client
    client = easy_client(api_key=client_id,
                         redirect_uri=redirect_url,
                         token_path='resources/token.txt',
                         webdriver_func=webdriver.Chrome)

except Exception as exc:  # Gets new token if previous token is expired
    client = client_from_login_flow(webdriver.Chrome(),
                                    api_key=client_id,
                                    redirect_url=redirect_url,
                                    token_path='resources/token.txt',
                                    redirect_wait_time_seconds=0.1,
                                    max_waits=3000,
                                    asyncio=False,
                                    token_write_func=None)
    traceback.print_exc(exc)


def get_price_history(symbol, start, end, frequencyType, periodType,
                      frequency):
    r = client.get_price_history(symbol,
                                 period_type=periodType,
                                 frequency=frequency,
Esempio n. 18
0
import asyncio
import psycopg2
from tda.auth import easy_client
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]}
Esempio n. 19
0
    def test_no_token_file_no_wd_func(self, client_from_token_file):
        webdriver_func = MagicMock()
        client_from_token_file.side_effect = FileNotFoundError()

        with self.assertRaises(FileNotFoundError):
            auth.easy_client(API_KEY, REDIRECT_URL, self.pickle_path)
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)
Esempio n. 21
0
def main():
    # Easy client with user account variables
    c = easy_client(consumer_key, redirect_uri, token_path, make_webdriver)

    # Set options to be hedged
    symbols_to_hedge = ['SPY_041621C495']
    # The threshold that  an option's delta is allowed to move before
    # rehedging. For example, if threshold = 5, delta can increase/decrease
    # by 5 before rehedging, an effective range of 10 delta.  This delta
    # is per 100 shares (delta * 100).  The larger the threshold
    # the less hedged you may be at a given time, however this also reduces
    # transaction costs incurred by adjusting the hedge.
    threshold = 5

    # Get positions for account
    account_info = c.get_account(
        account_id,
        fields=[c.Account.Fields.POSITIONS, c.Account.Fields.ORDERS])
    account_info_json = account_info.json()

    # Seperate equity and option positions into seperate dataframes
    equity_positions_list = []
    option_positions_list = []
    for entry in account_info_json['securitiesAccount']['positions']:
        if entry['instrument']['assetType'] == 'EQUITY':
            equity_positions_list.append(entry)
        elif entry['instrument']['assetType'] == 'OPTION':
            option_positions_list.append(entry)

    if equity_positions_list:
        equity_positions = pd.DataFrame(equity_positions_list)
        equ_pos_ticker_list = []
        equ_pos_cusip_list = []
        equ_pos_assetType_list = []
        for row in equity_positions['instrument']:
            equ_pos_ticker_list.append(row['symbol'])
            equ_pos_cusip_list.append(row['cusip'])
            equ_pos_assetType_list.append(row['assetType'])
        equity_positions['symbol'] = equ_pos_ticker_list
        equity_positions['cusip'] = equ_pos_cusip_list
        equity_positions['assetType'] = equ_pos_assetType_list
        equity_positions.drop(columns='instrument', inplace=True)
        equity_positions.set_index('symbol', inplace=True)

    if option_positions_list:
        option_positions = pd.DataFrame(option_positions_list)
        opt_pos_symbol_list = []
        opt_pos_description_list = []
        opt_pos_putCall_list = []
        opt_pos_assetType_list = []
        opt_pos_underlyingSymbol_list = []
        for row in option_positions['instrument']:
            opt_pos_symbol_list.append(row['symbol'])
            opt_pos_description_list.append(row['description'])
            opt_pos_putCall_list.append(row['putCall'])
            opt_pos_assetType_list.append(row['assetType'])
            opt_pos_underlyingSymbol_list.append(row['underlyingSymbol'])
        option_positions['symbol'] = opt_pos_symbol_list
        option_positions['description'] = opt_pos_description_list
        option_positions['putCall'] = opt_pos_putCall_list
        option_positions['assetType'] = opt_pos_assetType_list
        option_positions['underlyingSymbol'] = opt_pos_underlyingSymbol_list
        option_positions.drop(columns='instrument', inplace=True)
        option_positions.set_index('symbol', inplace=True)

    # Calculate total quantity of holdings for both equities and options
    equity_positions['totalQuantity'] = equity_positions[
        'longQuantity'] + equity_positions['shortQuantity']
    option_positions['totalQuantity'] = option_positions[
        'longQuantity'] + option_positions['shortQuantity']

    # Check if the underlying of an option is in current positions,
    # if it is then add the underlying's quantity to the option
    # positions df.  If it is not, then set quantity to 0 and
    # add to options positions df.
    for symbol in option_positions['underlyingSymbol']:
        if equity_positions.index.isin([symbol]).any():
            underlyingQuantity = equity_positions.loc[
                equity_positions.index == symbol, 'totalQuantity'].iloc[0]
            option_positions.loc[option_positions['underlyingSymbol'] ==
                                 symbol,
                                 'underlyingQuantity'] = underlyingQuantity
        else:
            option_positions.loc[option_positions['underlyingSymbol'] ==
                                 symbol, 'underlyingQuantity'] = 0

    # If option to hedge is in portfolio, then it is appended
    # to list, if it is not, it is appended to a different list
    # and a message is printed warning that you must purchase
    # the options before hedging them.
    symbols_to_hedge_in_holdings = []
    symbols_to_hedge_not_in_holdings = []
    for symbol in symbols_to_hedge:
        if option_positions.index.isin([symbol]).any():
            symbols_to_hedge_in_holdings.append(symbol)
        else:
            symbols_to_hedge_not_in_holdings.append(symbol)
            print(
                'Could not hedge the following options because they are not currently held in portfolio:',
                '\n', symbols_to_hedge_not_in_holdings)
            continue

    # Gets quotes for options that are in portfolio and
    # set to be hedged, then merges the quotes and option
    # positions df into a new option_positions_to_hedge df.
    option_quotes_resp = c.get_quotes(symbols=symbols_to_hedge_in_holdings)
    option_quotes_df = pd.DataFrame.from_dict(option_quotes_resp.json(),
                                              orient='index')
    option_positions_to_hedge = pd.merge(option_positions.loc[
        option_positions.index.isin(symbols_to_hedge_in_holdings)],
                                         option_quotes_df,
                                         left_index=True,
                                         right_index=True)

    # Finds the total greek exposure for each option
    # by multiplying the quantity of an option by
    # the given greek then multiplying by 100
    # and adds to the option_positions_to_hedge df
    greeks = ['delta', 'gamma', 'theta', 'vega']
    for greek in greeks:
        option_positions_to_hedge['total' + greek.capitalize()] = abs(
            option_positions_to_hedge[greek]
        ) * option_positions_to_hedge['totalQuantity'] * 100

    # A threaded function that places orders
    def place_orders(symbol):
        # Gets current date and time
        now = datetime.now().strftime('%d-%m-%y %I:%M:%S %p')
        # Finds the total deltas for options to be hedged on a particular underlying
        total_deltas_for_options_on_underlying = option_positions_to_hedge.loc[
            option_positions_to_hedge['underlyingSymbol'] ==
            symbol]['totalDelta'].sum()
        # Finds the total quantity for a particular underlying
        underlying_quantity = option_positions_to_hedge.loc[
            option_positions_to_hedge['underlyingSymbol'] ==
            symbol]['underlyingQuantity']
        # If the stock underlying an option to be hedged
        # is not owned, then the underlying quantity is set to 0.
        # If it is owned, then the quantity is set from the series as an integer
        if underlying_quantity.empty:
            underlying_quantity = 0
        else:
            underlying_quantity = int(underlying_quantity.iloc[0])
        # Determines the number of shares needed to be bought/sold to be delta neutral.
        # This is done by multiplying the total number of deltas for an option by -1,
        # then subtracting the quantity of the underlying for the options.
        shares_needed_to_hedge = int(total_deltas_for_options_on_underlying *
                                     -1 - underlying_quantity)
        # Place Orders, due to shorts and longs having seperate functions, it
        # complicates the order process, and it can be hard to follow.
        # The process itself is fairly straightforward, the number of shares
        # owned should be equal to the inverse of the total deltas on a particular
        # underlying.  So shares will either be purchased or sold to reach
        # this condition.  Adjustment is made when the total deltas
        # for the options on an underlying move past the previously set threshold,
        # either above or below.
        if shares_needed_to_hedge > threshold:
            if underlying_quantity < 0 and underlying_quantity + shares_needed_to_hedge < 0:
                #Buy to cover shares_needed_to_hedge
                order_specs = equities.equity_buy_to_cover_market(
                    symbol=symbol,
                    quantity=shares_needed_to_hedge).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order = c.place_order(account_id, order_specs)
                pprint(
                    pd.DataFrame(order_specs['orderLegCollection'],
                                 index=[now]))
            elif underlying_quantity < 0 and underlying_quantity + shares_needed_to_hedge > 0:
                #Buy to cover abs(underlying_quantity)
                order1_specs = equities.equity_buy_to_cover_market(
                    symbol=symbol,
                    quantity=abs(underlying_quantity)).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order1 = c.place_order(account_id, order1_specs)
                pprint(
                    pd.DataFrame(order1_specs['orderLegCollection'],
                                 index=[now]))
                #Buy shares_needed_to_hedge - abs(underlying_quantity)
                order2_specs = equities.equity_buy_market(
                    symbol=symbol,
                    quantity=shares_needed_to_hedge -
                    abs(underlying_quantity)).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order2 = c.place_order(account_id, order2_specs)
                pprint(
                    pd.DataFrame(order2_specs['orderLegCollection'],
                                 index=[now]))
            elif underlying_quantity > 0:
                #Buy shares_needed_to_hedge
                order_specs = equities.equity_buy_market(
                    symbol=symbol,
                    quantity=shares_needed_to_hedge).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order = c.place_order(account_id, order_specs)
                pprint(
                    pd.DataFrame(order_specs['orderLegCollection'],
                                 index=[now]))
        elif shares_needed_to_hedge < -threshold:
            if underlying_quantity > 0 and underlying_quantity + shares_needed_to_hedge > 0:
                #Sell abs(shares_needed_to_hedge)
                order_specs = equities.equity_sell_market(
                    symbol=symbol,
                    quantity=abs(shares_needed_to_hedge)).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order = c.place_order(account_id, order_specs)
                pprint(
                    pd.DataFrame(order_specs['orderLegCollection'],
                                 index=[now]))
            elif underlying_quantity > 0 and underlying_quantity + shares_needed_to_hedge < 0:
                #Sell underlying_quantity
                order1_specs = equities.equity_sell_market(
                    symbol=symbol, quantity=underlying_quantity).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order1 = c.place_order(account_id, order1_specs)
                pprint(
                    pd.DataFrame(order1_specs['orderLegCollection'],
                                 index=[now]))
                #Sell short abs(underlying_quantity + shares_needed_to_hedge)
                order2_specs = equities.equity_sell_short_market(
                    symbol=symbol,
                    quantity=abs(underlying_quantity +
                                 shares_needed_to_hedge)).set_duration(
                                     Duration.DAY).set_session(
                                         Session.SEAMLESS).build()
                order2 = c.place_order(account_id, order2_specs)
                pprint(
                    pd.DataFrame(order2_specs['orderLegCollection'],
                                 index=[now]))
            elif underlying_quantity < 0:
                #Sell to open abs(shares_needed_to_hedge)
                order_specs = equities.equity_sell_short_market(
                    symbol=symbol,
                    quantity=abs(shares_needed_to_hedge)).set_duration(
                        Duration.DAY).set_session(Session.SEAMLESS).build()
                order = c.place_order(account_id, order_specs)
                pprint(
                    pd.DataFrame(order_specs['orderLegCollection'],
                                 index=[now]))

    # Since each option has an underlying value in the
    # option_positions_to_hedge df, this can result in duplicated
    # symbols if there are multiple options on the same underlying
    # to be hedge.  This finds the unique underlyings in the
    # option_positions_to_hedge df, and appends to list.
    unique_symbols = option_positions_to_hedge['underlyingSymbol'].unique()
    # Iterate through the unique symbols in the unique symbols list
    # pass each one in a threaded process to the place_orders df.
    # This means that each stock is bought/sold as needed to neutralize
    # the delta of the options to be hedged. By running as a
    # threaded process this should provide significant speed
    # increases if there are many equities to iterate through.
    thread_list = []

    def thread_place_orders():
        for symbol in unique_symbols:
            threadProcess = threading.Thread(name='simplethread',
                                             target=place_orders,
                                             args=[symbol])
            thread_list.append(threadProcess)
        for thread in thread_list:
            thread.start()
        for thread in thread_list:
            thread.join()

    thread_place_orders()
Esempio n. 22
0
geckodriver_path = r'/Users/haydenrose/Webdrivers/geckodriver'


# Creates Webdriver for Selenium
def make_webdriver():
    # Import selenium here because it's slow to import
    from selenium import webdriver
    driver = webdriver.Firefox(executable_path=geckodriver_path)
    atexit.register(lambda: driver.quit())
    return driver


# Sets td-api Client Object.
# Will Create Refresh Token with OAUTH and Grab With Selenium
# if it Doesn't Exist in Working Folder.
c = easy_client(consumer_key, redirect_uri, token_path, make_webdriver)


def options_chain_cleaner(options_chain, only_type=False):
    """
    Takes unformatted option chain csv and returns cleaned up df.
    Specify only_type='Calls' or 'Puts' if only wanting one or other,
    specify False if wanting both and 2 dataframes will be returned,
    calls first and puts second.

    i.e. calls, puts = func('file.csv')
    """

    if only_type == 'Calls':
        Calls = options_chain['callExpDateMap'].values()
        call_option_list = []
Esempio n. 23
0
import pandas as pd
from tda.auth import easy_client
from fybot.common import config
from functions import *
from IPython.utils import io
from datetime import datetime, timedelta
from time import sleep

# from tda.client import client

# Creates connection with TDA database
c = easy_client(config.api_key, config.redirect_uri, config.token_path,
                make_webdriver)
print("Client Authorization process complete.")

#----------------------------------------------------------------
#downloads all 7-8k active tickers/symbols (review function for filters)
df = import_symbols(reference_path="../pages/datasets/")
symbols_list = df.index.to_list()

#----------------------------------------------------------------
#if a sigle quote is needed
s = 'AMD'
quote_df = get_quote_info(s, c)
print(quote_df)
print(f"The last price for {s.upper()} is {quote_df.loc['lastPrice'][0]}.")

#----------------------------------------------------------------
# for request with multiple symbols, breaks long lists into batches
batch_size = 250
symbols_batches = split_symbol_list(symbols_list, batch_size)
from tda.auth import easy_client
from tda.client import Client
from tda.streaming import StreamClient

import asyncio
import json
import config

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):
    print(json.dumps(msg, indent=4))


async def read_stream():
    await stream_client.login()
    await stream_client.quality_of_service(StreamClient.QOSLevel.DELAYED)
    await stream_client.nasdaq_book_subs(['GOOG'])

    stream_client.add_nasdaq_book_handler(order_book_handler)

    while True:
        await stream_client.handle_message()


asyncio.get_event_loop().run_until_complete(read_stream())