import sys import signal import datetime import subprocess from ibapi.client import EClient from ibapi.wrapper import EWrapper from ibapi.utils import iswrapper import psycopg2 tgtAccts = [ 'U13232746' ] tgtTags = [ 'NetLiquidationByCurrency', 'UnrealizedPnL' ] maxLoss = -4000 # NOTE: WARNING: signed! do not put a positive number here! if maxLoss is not None and maxLoss > 0: raise Exception('maxLoss cannot be positive!') #maxLossScript = '/home/joseph/mon/closeout_mkt.py' # NOTE: this script must be runnable by 'python' maxLossScript = '/home/joseph/mon/closeout_fake.py' # NOTE: this script must be runnable by 'python' def get_db_connection(): return psycopg2.connect(host='127.0.0.1', database='live_acctval', user='joseph') class IBapi(EWrapper, EClient): def __init__(self): EClient.__init__(self, self) self.dbconn = get_db_connection() self.got = 0 self.maxLossHit = False @iswrapper def nextValidId(self, orderId:int): self.reqAccountSummary(9002, 'All', '$LEDGER') for i, acct in enumerate(tgtAccts): self.reqPnL(i, acct, ''); @iswrapper def accountSummary(self, reqId:int, account:str, tag:str, value:str, currency:str): print('account summary for %s' % account) tagged = {} if account in tgtAccts: if tag in tgtTags: #print('reqID %s account %s tag %s value %s currency %s' % (reqId, account, tag, value, currency)) tagged[tag] = value if len(tagged) > 0: taggedSorted = sorted(tagged.items()) print('accountSummary %s %s' % (datetime.datetime.now(), taggedSorted)) if taggedSorted[0][0] == 'NetLiquidationByCurrency': cur = self.dbconn.cursor() cur.execute("INSERT INTO acctval (created_at, val) VALUES (%s, %s)", ('NOW()', taggedSorted[0][1])) self.dbconn.commit() cur.close() @iswrapper def accountSummaryEnd(self, reqId:int): print('account summary done, reqID %s' % reqId) @iswrapper def pnl(self, reqId:int, dailyPnL, unrealizedPnL, realizedPnL): if self.got < 2: self.got += 1 return elif dailyPnL == 0 and unrealizedPnL == 0 and realizedPnL == 0: return print('%s LIVE pnl! %s %s %s %s' % (datetime.datetime.now(), reqId, dailyPnL, unrealizedPnL, realizedPnL)) if maxLoss is not None and dailyPnL <= maxLoss and (not self.maxLossHit): # we hit maxLoss print('*** WE HIT MAXLOSS, RUNNING SCRIPT ***') subprocess.run('python ' + maxLossScript, shell=True) self.maxLossHit = True cur = self.dbconn.cursor() cur.execute("INSERT INTO pnl_intra (created_at, pnl, pnl_unrealized, pnl_realized) VALUES (%s, %s, %s, %s)", ('NOW()', dailyPnL, unrealizedPnL, realizedPnL)) self.dbconn.commit() cur.close() print('PNL script starting at %s (UTC)' % datetime.datetime.now()) app = IBapi() def signal_handler(sig, frame): print('You pressed Ctrl+C!') app.disconnect() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) #app.connect('127.0.0.1', 7497, 123) app.connect('tws2', 7496, 123) app.run()