85 lines
3.2 KiB
Python
85 lines
3.2 KiB
Python
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() |