forked from creack/ibweb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AppIB.py
148 lines (124 loc) · 4.82 KB
/
AppIB.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""@package AppIB
IB API Implementation app
"""
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.ext.TickType import TickType
from ib.opt import ibConnection, message
from Connect import Connect
from threading import Lock, Event
#from time import sleep
#import datetime
import pymongo
db = pymongo.MongoClient().ib
class AppIB():
"""IB API Implementation"""
def __init__(self):
"""Ctor"""
self.symbols = {}
self.ticks = {}
self.event = Event()
self.con = Connect("172.20.0.11", port = 7496, verbose = True)
handlers = {
self.errorHandler: message.Error,
self.tickPriceHandler: message.TickPrice,
self.tickSizeHandler: message.TickSize,
self.tickGenericHandler: message.TickGeneric,
self.tickStringHandler: message.TickString,
self.portfolioHandler: message.UpdatePortfolio,
self.accountValueHandler: message.UpdateAccountValue
}
for func, msg in handlers.iteritems():
self.con.register(func, msg)
def start(self):
"""Start the app."""
self.symbols["QQQ"] = self.createContract("QQQ")
self.symbols["MNST"] = self.createContract("MNST")
self.symbols["MSFT"] = self.createContract("MSFT")
self.con.reqMktData(self.symbols)
# con.addOrder("MNST", minQty = 100, orderType="MKT", outsideRTH = True)
# con.placeOrder()
def run(self):
"""Run the main loop"""
while True:
self.event.wait(30)
self.event.clear()
if 0:
continue
for key, id in self.symbols.items():
try:
print key, ":", self.ticks[id.m_conId]
except KeyError:
print key, ": No data"
print
def createContract(self, symbol, secType="STK",
exchange="SMART", currency="USD"):
"""Create and store a contact from the given symbol"""
c = Contract()
c.m_symbol = symbol
c.m_secType = secType
c.m_exchange = exchange
c.m_currency = currency
return c
def getSymbolFromId(self, id):
"""Return the string symbol for the given id.
@param id Integer Id of the wanted symbol.
@return String Symbol
"""
try:
return [v.m_symbol for v in self.symbols.values() if v.m_conId == id][0]
except IndexError:
return False
def tickGenericHandler(self, msg):
print "GENERIC--- [{2}] {0}: {1}.".format(
TickType.getField(msg.tickType), msg.value,
self.getSymbolFromId(msg.tickerId))
def tickStringHandler(self, msg):
print "STRING--- [{2}] {0}: {1}.".format(
TickType.getField(msg.tickType), msg.value,
self.getSymbolFromId(msg.tickerId))
def tickPriceHandler(self, msg):
"""Handle TickPrice messages from IB.
Remove the globals and implement a Producer/Consumer
@param msg ib.opt.message.TickPrice Message sent by IB
"""
self.ticks[msg.tickerId] = msg
symb = self.getSymbolFromId(msg.tickerId)
if symb:
db.tickers.update({"symbol": symb},
{"$set": {TickType.getField(msg.field): msg.price}},
upsert = True)
self.event.set()
def portfolioHandler(self, msg):
"""Handle UpdatePortfolio messages from IB.
@param msg ib.opt.message.UpdatePortfolio
"""
print "----", type(msg), msg
def accountValueHandler(self, msg):
"""Handle UpdateAccountValue messages from IB.
Store accout data in db
@param msg ib.opt.message.UpdateAccountValue Message sent by IB
"""
db.account.update({"account": msg.accountName,
msg.key: {"$exists": True}},
{"$set": {msg.key: msg.value,
"currency": msg.currency}},
upsert = True)
print "account: {0}: {1} [{2}] ({3})".format(
msg.key, msg.value, msg.currency, msg.accountName)
def tickSizeHandler(self, msg):
"""Handle TickSize messages from IB.
Store tick data in db
@param msg ib.opt.message.TickSize Message sent by IB
"""
symb = self.getSymbolFromId(msg.tickerId)
if symb:
#print "[{1}] {0}: {2}".format(symb, fieldType[msg.field], msg.size)
db.tickers.update({"symbol": symb},
{"$set": {TickType.getField(msg.field): msg.size}},
upsert = True)
def errorHandler(self, msg):
"""Error handler.
@param msg ib.opt.message.Error Message sent by IB
"""
print "ERROR:", msg