#!/usr/bin/env python from trading.ibstate import IBstate import trading.portfolio import config.portfolios import config.strategy from trading.account import Account from core.utility import notify_send from time import sleep import schedule import sys import traceback from core.logger import get_logger from functools import partial logger = get_logger('scheduler') p = trading.portfolio.Portfolio(instruments=config.portfolios.p_trade) i = p.instruments def init_ib(): ib = IBstate() ib.connect() print("connecting") while not ib.is_ready(): print("Not ready") sleep(5) if len(ib.open_orders()>0): print('Open orders:', ib.open_orders()) print_net(ib.accounts) jobs = [] jobs.append(schedule.every(6).hours.do(partial(print_net, ib.accounts))) jobs.append(schedule.every(15).seconds.do(ib.connect)) jobs.append(schedule.every(15).seconds.do(ib.update_open_orders)) return ib, jobs def sync_trades(): ib, ib_jobs = init_ib() print(1) accs = [a for a in ib.accounts.values() if a.name.startswith(('U', 'DU'))] notify('Running Sync Trades for {0} accounts: {1}'.format(len(accs), [a.name for a in accs])) trade = False if "--dryrun" in sys.argv else True p.cache_clear() # print("Starting validation") # validate = p.validate()[['carry_forecast', 'currency_age', 'panama_age', 'price_age', 'weighted_forecast']] # logger.info('\n' + str(validate)) # do for all accounts for a in accs: print_net(a) notify('Running Sync Trades for account %s' % a.name) try: ib.sync_portfolio(p, acc=a, trade=trade) except AssertionError: notify('No sync for account %s, validation failed' % a.name, level='warning') continue notify('Portfolio synced') print_net(a) # cancel ib-specific scheduler jobs [schedule.cancel_job(j) for j in ib_jobs] def print_net(accs): """ :param accs: Account object, or dict, or None """ if isinstance(accs, Account): accs = {accs.name: accs} for a in accs.values(): notify('Net liquidation for account %s: %.2f %s ' % (a.name, a.net, a.base_currency)) def set_schedule(time): schedule.every().monday.at(time).do(sync_trades) schedule.every().tuesday.at(time).do(sync_trades) schedule.every().wednesday.at(time).do(sync_trades) schedule.every().thursday.at(time).do(sync_trades) schedule.every().friday.at(time).do(sync_trades) def main(): # width = pd.util.terminal.get_terminal_size() # find the width of the user's terminal window # rows, columns = os.popen('stty size', 'r').read().split() # pd.set_option('display.width', width[0]) # set that as the max width in Pandas # pd.set_option('display.width', int(columns)) # set that as the max width in Pandas set_schedule(config.strategy.portfolio_sync_time) if "--now" in sys.argv: sync_trades() if "--quit" not in sys.argv: while True: schedule.run_pending() sleep(1) def notify(msg, level='info'): notify_send(level, msg) try: getattr(logger, level)(msg) except: logger.info(msg) if __name__ == "__main__": try: main() except KeyboardInterrupt: print("Shutdown requested...exiting") except Exception as e: traceback.print_exc(file=sys.stdout) logger.exception(e, exc_info=True) sys.exit(0)