· 6 years ago · Dec 05, 2019, 06:42 AM
1"""
2Copyright (C) 2019 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
3 and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable.
4"""
5
6import argparse
7import datetime
8import collections
9import inspect
10
11import logging
12import time
13import os.path
14
15from ibapi import wrapper
16from ibapi import utils
17from ibapi.client import EClient
18from ibapi.utils import iswrapper
19
20# types
21from ibapi.common import * # @UnusedWildImport
22from ibapi.order_condition import * # @UnusedWildImport
23from ibapi.contract import * # @UnusedWildImport
24from ibapi.order import * # @UnusedWildImport
25from ibapi.order_state import * # @UnusedWildImport
26from ibapi.execution import Execution
27from ibapi.execution import ExecutionFilter
28from ibapi.commission_report import CommissionReport
29from ibapi.ticktype import * # @UnusedWildImport
30from ibapi.tag_value import TagValue
31
32from ibapi.account_summary_tags import *
33
34from ContractSamples import ContractSamples
35from OrderSamples import OrderSamples
36from AvailableAlgoParams import AvailableAlgoParams
37from ScannerSubscriptionSamples import ScannerSubscriptionSamples
38from FaAllocationSamples import FaAllocationSamples
39from ibapi.scanner import ScanData
40
41
42def SetupLogger():
43 if not os.path.exists("log"):
44 os.makedirs("log")
45
46 time.strftime("pyibapi.%Y%m%d_%H%M%S.log")
47
48 recfmt = '(%(threadName)s) %(asctime)s.%(msecs)03d %(levelname)s %(filename)s:%(lineno)d %(message)s'
49
50 timefmt = '%y%m%d_%H:%M:%S'
51
52 # logging.basicConfig( level=logging.DEBUG,
53 # format=recfmt, datefmt=timefmt)
54 logging.basicConfig(filename=time.strftime("log/pyibapi.%y%m%d_%H%M%S.log"),
55 filemode="w",
56 level=logging.INFO,
57 format=recfmt, datefmt=timefmt)
58 logger = logging.getLogger()
59 console = logging.StreamHandler()
60 console.setLevel(logging.ERROR)
61 logger.addHandler(console)
62
63
64def printWhenExecuting(fn):
65 def fn2(self):
66 print(" doing", fn.__name__)
67 fn(self)
68 print(" done w/", fn.__name__)
69
70 return fn2
71
72def printinstance(inst:Object):
73 attrs = vars(inst)
74 print(', '.join("%s: %s" % item for item in attrs.items()))
75
76class Activity(Object):
77 def __init__(self, reqMsgId, ansMsgId, ansEndMsgId, reqId):
78 self.reqMsdId = reqMsgId
79 self.ansMsgId = ansMsgId
80 self.ansEndMsgId = ansEndMsgId
81 self.reqId = reqId
82
83
84class RequestMgr(Object):
85 def __init__(self):
86 # I will keep this simple even if slower for now: only one list of
87 # requests finding will be done by linear search
88 self.requests = []
89
90 def addReq(self, req):
91 self.requests.append(req)
92
93 def receivedMsg(self, msg):
94 pass
95
96
97# ! [socket_declare]
98class TestClient(EClient):
99 def __init__(self, wrapper):
100 EClient.__init__(self, wrapper)
101 # ! [socket_declare]
102
103 # how many times a method is called to see test coverage
104 self.clntMeth2callCount = collections.defaultdict(int)
105 self.clntMeth2reqIdIdx = collections.defaultdict(lambda: -1)
106 self.reqId2nReq = collections.defaultdict(int)
107 self.setupDetectReqId()
108
109 def countReqId(self, methName, fn):
110 def countReqId_(*args, **kwargs):
111 self.clntMeth2callCount[methName] += 1
112 idx = self.clntMeth2reqIdIdx[methName]
113 if idx >= 0:
114 sign = -1 if 'cancel' in methName else 1
115 self.reqId2nReq[sign * args[idx]] += 1
116 return fn(*args, **kwargs)
117
118 return countReqId_
119
120 def setupDetectReqId(self):
121
122 methods = inspect.getmembers(EClient, inspect.isfunction)
123 for (methName, meth) in methods:
124 if methName != "send_msg":
125 # don't screw up the nice automated logging in the send_msg()
126 self.clntMeth2callCount[methName] = 0
127 # logging.debug("meth %s", name)
128 sig = inspect.signature(meth)
129 for (idx, pnameNparam) in enumerate(sig.parameters.items()):
130 (paramName, param) = pnameNparam # @UnusedVariable
131 if paramName == "reqId":
132 self.clntMeth2reqIdIdx[methName] = idx
133
134 setattr(TestClient, methName, self.countReqId(methName, meth))
135
136 # print("TestClient.clntMeth2reqIdIdx", self.clntMeth2reqIdIdx)
137
138
139# ! [ewrapperimpl]
140class TestWrapper(wrapper.EWrapper):
141 # ! [ewrapperimpl]
142 def __init__(self):
143 wrapper.EWrapper.__init__(self)
144
145 self.wrapMeth2callCount = collections.defaultdict(int)
146 self.wrapMeth2reqIdIdx = collections.defaultdict(lambda: -1)
147 self.reqId2nAns = collections.defaultdict(int)
148 self.setupDetectWrapperReqId()
149
150 # TODO: see how to factor this out !!
151
152 def countWrapReqId(self, methName, fn):
153 def countWrapReqId_(*args, **kwargs):
154 self.wrapMeth2callCount[methName] += 1
155 idx = self.wrapMeth2reqIdIdx[methName]
156 if idx >= 0:
157 self.reqId2nAns[args[idx]] += 1
158 return fn(*args, **kwargs)
159
160 return countWrapReqId_
161
162 def setupDetectWrapperReqId(self):
163
164 methods = inspect.getmembers(wrapper.EWrapper, inspect.isfunction)
165 for (methName, meth) in methods:
166 self.wrapMeth2callCount[methName] = 0
167 # logging.debug("meth %s", name)
168 sig = inspect.signature(meth)
169 for (idx, pnameNparam) in enumerate(sig.parameters.items()):
170 (paramName, param) = pnameNparam # @UnusedVariable
171 # we want to count the errors as 'error' not 'answer'
172 if 'error' not in methName and paramName == "reqId":
173 self.wrapMeth2reqIdIdx[methName] = idx
174
175 setattr(TestWrapper, methName, self.countWrapReqId(methName, meth))
176
177 # print("TestClient.wrapMeth2reqIdIdx", self.wrapMeth2reqIdIdx)
178
179
180# this is here for documentation generation
181"""
182#! [ereader]
183 # You don't need to run this in your code!
184 self.reader = reader.EReader(self.conn, self.msg_queue)
185 self.reader.start() # start thread
186#! [ereader]
187"""
188
189# ! [socket_init]
190class TestApp(TestWrapper, TestClient):
191 def __init__(self):
192 TestWrapper.__init__(self)
193 TestClient.__init__(self, wrapper=self)
194 # ! [socket_init]
195 self.nKeybInt = 0
196 self.started = False
197 self.nextValidOrderId = None
198 self.permId2ord = {}
199 self.reqId2nErr = collections.defaultdict(int)
200 self.globalCancelOnly = False
201 self.simplePlaceOid = None
202
203 def dumpTestCoverageSituation(self):
204 for clntMeth in sorted(self.clntMeth2callCount.keys()):
205 logging.debug("ClntMeth: %-30s %6d" % (clntMeth,
206 self.clntMeth2callCount[clntMeth]))
207
208 for wrapMeth in sorted(self.wrapMeth2callCount.keys()):
209 logging.debug("WrapMeth: %-30s %6d" % (wrapMeth,
210 self.wrapMeth2callCount[wrapMeth]))
211
212 def dumpReqAnsErrSituation(self):
213 logging.debug("%s\t%s\t%s\t%s" % ("ReqId", "#Req", "#Ans", "#Err"))
214 for reqId in sorted(self.reqId2nReq.keys()):
215 nReq = self.reqId2nReq.get(reqId, 0)
216 nAns = self.reqId2nAns.get(reqId, 0)
217 nErr = self.reqId2nErr.get(reqId, 0)
218 logging.debug("%d\t%d\t%s\t%d" % (reqId, nReq, nAns, nErr))
219
220 @iswrapper
221 # ! [connectack]
222 def connectAck(self):
223 if self.asynchronous:
224 self.startApi()
225
226 # ! [connectack]
227
228 @iswrapper
229 # ! [nextvalidid]
230 def nextValidId(self, orderId: int):
231 super().nextValidId(orderId)
232
233 logging.debug("setting nextValidOrderId: %d", orderId)
234 self.nextValidOrderId = orderId
235 print("NextValidId:", orderId)
236 # ! [nextvalidid]
237
238 # we can start now
239 self.start()
240
241 def start(self):
242 if self.started:
243 return
244
245 self.started = True
246
247 if self.globalCancelOnly:
248 print("Executing GlobalCancel only")
249 self.reqGlobalCancel()
250 else:
251 print("Executing requests")
252 #self.reqGlobalCancel()
253 #self.marketDataTypeOperations()
254 self.accountOperations_req()
255 #self.tickDataOperations_req()
256 #self.marketDepthOperations_req()
257 #self.realTimeBarsOperations_req()
258 #self.historicalDataOperations_req()
259 #self.optionsOperations_req()
260 #self.marketScannersOperations_req()
261 #self.fundamentalsOperations_req()
262 #self.bulletinsOperations_req()
263 #self.contractOperations()
264 #self.newsOperations_req()
265 #self.miscelaneousOperations()
266 #self.linkingOperations()
267 #self.financialAdvisorOperations()
268 # self.orderOperations_req()
269 #self.rerouteCFDOperations()
270 #self.marketRuleOperations()
271 #self.pnlOperations_req()
272 #self.histogramOperations_req()
273 #self.continuousFuturesOperations_req()
274 #self.historicalTicksOperations()
275 #self.tickByTickOperations_req()
276 #self.whatIfOrderOperations()
277
278 print("Executing requests ... finished")
279
280 def keyboardInterrupt(self):
281 self.nKeybInt += 1
282 if self.nKeybInt == 1:
283 self.stop()
284 else:
285 print("Finishing test")
286 self.done = True
287
288 def stop(self):
289 print("Executing cancels")
290 #self.orderOperations_cancel()
291 #self.accountOperations_cancel()
292 #self.tickDataOperations_cancel()
293 self.marketDepthOperations_cancel()
294 #self.realTimeBarsOperations_cancel()
295 #self.historicalDataOperations_cancel()
296 #self.optionsOperations_cancel()
297 #self.marketScanners_cancel()
298 #self.fundamentalsOperations_cancel()
299 #self.bulletinsOperations_cancel()
300 #self.newsOperations_cancel()
301 #self.pnlOperations_cancel()
302 #self.histogramOperations_cancel()
303 #self.continuousFuturesOperations_cancel()
304 #self.tickByTickOperations_cancel()
305 print("Executing cancels ... finished")
306
307 def nextOrderId(self):
308 oid = self.nextValidOrderId
309 self.nextValidOrderId += 1
310 return oid
311
312 @iswrapper
313 # ! [error]
314 def error(self, reqId: TickerId, errorCode: int, errorString: str):
315 super().error(reqId, errorCode, errorString)
316 print("Error. Id:", reqId, "Code:", errorCode, "Msg:", errorString)
317
318 # ! [error] self.reqId2nErr[reqId] += 1
319
320
321 @iswrapper
322 def winError(self, text: str, lastError: int):
323 super().winError(text, lastError)
324
325 @iswrapper
326 # ! [openorder]
327 def openOrder(self, orderId: OrderId, contract: Contract, order: Order,
328 orderState: OrderState):
329 super().openOrder(orderId, contract, order, orderState)
330 print("OpenOrder. PermId: ", order.permId, "ClientId:", order.clientId, " OrderId:", orderId,
331 "Account:", order.account, "Symbol:", contract.symbol, "SecType:", contract.secType,
332 "Exchange:", contract.exchange, "Action:", order.action, "OrderType:", order.orderType,
333 "TotalQty:", order.totalQuantity, "CashQty:", order.cashQty,
334 "LmtPrice:", order.lmtPrice, "AuxPrice:", order.auxPrice, "Status:", orderState.status)
335
336 order.contract = contract
337 self.permId2ord[order.permId] = order
338 # ! [openorder]
339
340 @iswrapper
341 # ! [openorderend]
342 def openOrderEnd(self):
343 super().openOrderEnd()
344 print("OpenOrderEnd")
345
346 logging.debug("Received %d openOrders", len(self.permId2ord))
347 # ! [openorderend]
348
349 @iswrapper
350 # ! [orderstatus]
351 def orderStatus(self, orderId: OrderId, status: str, filled: float,
352 remaining: float, avgFillPrice: float, permId: int,
353 parentId: int, lastFillPrice: float, clientId: int,
354 whyHeld: str, mktCapPrice: float):
355 super().orderStatus(orderId, status, filled, remaining,
356 avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice)
357 print("OrderStatus. Id:", orderId, "Status:", status, "Filled:", filled,
358 "Remaining:", remaining, "AvgFillPrice:", avgFillPrice,
359 "PermId:", permId, "ParentId:", parentId, "LastFillPrice:",
360 lastFillPrice, "ClientId:", clientId, "WhyHeld:",
361 whyHeld, "MktCapPrice:", mktCapPrice)
362 # ! [orderstatus]
363
364
365 @printWhenExecuting
366 def accountOperations_req(self):
367 # Requesting managed accounts
368 # ! [reqmanagedaccts]
369 # self.reqManagedAccts()
370 # ! [reqmanagedaccts]
371
372 # Requesting family codes
373 # ! [reqfamilycodes]
374 # self.reqFamilyCodes()
375 # ! [reqfamilycodes]
376
377 # Requesting accounts' summary
378 # ! [reqaaccountsummary]
379 self.reqAccountSummary(9001, "All", AccountSummaryTags.AllTags)
380 # ! [reqaaccountsummary]
381
382 # ! [reqaaccountsummaryledger]
383 # self.reqAccountSummary(9002, "All", "$LEDGER")
384 # ! [reqaaccountsummaryledger]
385
386 # ! [reqaaccountsummaryledgercurrency]
387 # self.reqAccountSummary(9003, "All", "$LEDGER:EUR")
388 # ! [reqaaccountsummaryledgercurrency]
389
390 # ! [reqaaccountsummaryledgerall]
391 # self.reqAccountSummary(9004, "All", "$LEDGER:ALL")
392 # ! [reqaaccountsummaryledgerall]
393
394 # Subscribing to an account's information. Only one at a time!
395 # ! [reqaaccountupdates]
396 # self.reqAccountUpdates(True, self.account)
397 # ! [reqaaccountupdates]
398
399 # ! [reqaaccountupdatesmulti]
400 # self.reqAccountUpdatesMulti(9005, self.account, "", True)
401 # ! [reqaaccountupdatesmulti]
402
403 # Requesting all accounts' positions.
404 # ! [reqpositions]
405 # self.reqPositions()
406 # ! [reqpositions]
407
408 # ! [reqpositionsmulti]
409 # self.reqPositionsMulti(9006, self.account, "")
410 # ! [reqpositionsmulti]
411
412 @printWhenExecuting
413 def accountOperations_cancel(self):
414 # ! [cancelaaccountsummary]
415 self.cancelAccountSummary(9001)
416 self.cancelAccountSummary(9002)
417 self.cancelAccountSummary(9003)
418 self.cancelAccountSummary(9004)
419 # ! [cancelaaccountsummary]
420
421 # ! [cancelaaccountupdates]
422 self.reqAccountUpdates(False, self.account)
423 # ! [cancelaaccountupdates]
424
425 # ! [cancelaaccountupdatesmulti]
426 self.cancelAccountUpdatesMulti(9005)
427 # ! [cancelaaccountupdatesmulti]
428
429 # ! [cancelpositions]
430 self.cancelPositions()
431 # ! [cancelpositions]
432
433 # ! [cancelpositionsmulti]
434 self.cancelPositionsMulti(9006)
435 # ! [cancelpositionsmulti]
436
437 def pnlOperations_req(self):
438 # ! [reqpnl]
439 self.reqPnL(17001, "DU111519", "")
440 # ! [reqpnl]
441
442 # ! [reqpnlsingle]
443 self.reqPnLSingle(17002, "DU111519", "", 8314);
444 # ! [reqpnlsingle]
445
446 def pnlOperations_cancel(self):
447 # ! [cancelpnl]
448 self.cancelPnL(17001)
449 # ! [cancelpnl]
450
451 # ! [cancelpnlsingle]
452 self.cancelPnLSingle(17002);
453 # ! [cancelpnlsingle]
454
455 def histogramOperations_req(self):
456 # ! [reqhistogramdata]
457 self.reqHistogramData(4002, ContractSamples.USStockAtSmart(), False, "3 days");
458 # ! [reqhistogramdata]
459
460 def histogramOperations_cancel(self):
461 # ! [cancelhistogramdata]
462 self.cancelHistogramData(4002);
463 # ! [cancelhistogramdata]
464
465 def continuousFuturesOperations_req(self):
466 # ! [reqcontractdetailscontfut]
467 self.reqContractDetails(18001, ContractSamples.ContFut())
468 # ! [reqcontractdetailscontfut]
469
470 # ! [reqhistoricaldatacontfut]
471 timeStr = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d %H:%M:%S')
472 self.reqHistoricalData(18002, ContractSamples.ContFut(), timeStr, "1 Y", "1 month", "TRADES", 0, 1, False, []);
473 # ! [reqhistoricaldatacontfut]
474
475 def continuousFuturesOperations_cancel(self):
476 # ! [cancelhistoricaldatacontfut]
477 self.cancelHistoricalData(18002);
478 # ! [cancelhistoricaldatacontfut]
479
480 @iswrapper
481 # ! [managedaccounts]
482 def managedAccounts(self, accountsList: str):
483 super().managedAccounts(accountsList)
484 print("Account list:", accountsList)
485 # ! [managedaccounts]
486
487 self.account = accountsList.split(",")[0]
488
489 @iswrapper
490 # ! [accountsummary]
491 def accountSummary(self, reqId: int, account: str, tag: str, value: str,
492 currency: str):
493 super().accountSummary(reqId, account, tag, value, currency)
494 print("AccountSummary. ReqId:", reqId, "Account:", account,
495 "Tag: ", tag, "Value:", value, "Currency:", currency)
496 # ! [accountsummary]
497
498 @iswrapper
499 # ! [accountsummaryend]
500 def accountSummaryEnd(self, reqId: int):
501 super().accountSummaryEnd(reqId)
502 print("AccountSummaryEnd. ReqId:", reqId)
503 # ! [accountsummaryend]
504
505 @iswrapper
506 # ! [updateaccountvalue]
507 def updateAccountValue(self, key: str, val: str, currency: str,
508 accountName: str):
509 super().updateAccountValue(key, val, currency, accountName)
510 print("UpdateAccountValue. Key:", key, "Value:", val,
511 "Currency:", currency, "AccountName:", accountName)
512 # ! [updateaccountvalue]
513
514 @iswrapper
515 # ! [updateportfolio]
516 def updatePortfolio(self, contract: Contract, position: float,
517 marketPrice: float, marketValue: float,
518 averageCost: float, unrealizedPNL: float,
519 realizedPNL: float, accountName: str):
520 super().updatePortfolio(contract, position, marketPrice, marketValue,
521 averageCost, unrealizedPNL, realizedPNL, accountName)
522 print("UpdatePortfolio.", "Symbol:", contract.symbol, "SecType:", contract.secType, "Exchange:",
523 contract.exchange, "Position:", position, "MarketPrice:", marketPrice,
524 "MarketValue:", marketValue, "AverageCost:", averageCost,
525 "UnrealizedPNL:", unrealizedPNL, "RealizedPNL:", realizedPNL,
526 "AccountName:", accountName)
527 # ! [updateportfolio]
528
529 @iswrapper
530 # ! [updateaccounttime]
531 def updateAccountTime(self, timeStamp: str):
532 super().updateAccountTime(timeStamp)
533 print("UpdateAccountTime. Time:", timeStamp)
534 # ! [updateaccounttime]
535
536 @iswrapper
537 # ! [accountdownloadend]
538 def accountDownloadEnd(self, accountName: str):
539 super().accountDownloadEnd(accountName)
540 print("AccountDownloadEnd. Account:", accountName)
541 # ! [accountdownloadend]
542
543 @iswrapper
544 # ! [position]
545 def position(self, account: str, contract: Contract, position: float,
546 avgCost: float):
547 super().position(account, contract, position, avgCost)
548 print("Position.", "Account:", account, "Symbol:", contract.symbol, "SecType:",
549 contract.secType, "Currency:", contract.currency,
550 "Position:", position, "Avg cost:", avgCost)
551 # ! [position]
552
553 @iswrapper
554 # ! [positionend]
555 def positionEnd(self):
556 super().positionEnd()
557 print("PositionEnd")
558 # ! [positionend]
559
560 @iswrapper
561 # ! [positionmulti]
562 def positionMulti(self, reqId: int, account: str, modelCode: str,
563 contract: Contract, pos: float, avgCost: float):
564 super().positionMulti(reqId, account, modelCode, contract, pos, avgCost)
565 print("PositionMulti. RequestId:", reqId, "Account:", account,
566 "ModelCode:", modelCode, "Symbol:", contract.symbol, "SecType:",
567 contract.secType, "Currency:", contract.currency, ",Position:",
568 pos, "AvgCost:", avgCost)
569 # ! [positionmulti]
570
571 @iswrapper
572 # ! [positionmultiend]
573 def positionMultiEnd(self, reqId: int):
574 super().positionMultiEnd(reqId)
575 print("PositionMultiEnd. RequestId:", reqId)
576 # ! [positionmultiend]
577
578 @iswrapper
579 # ! [accountupdatemulti]
580 def accountUpdateMulti(self, reqId: int, account: str, modelCode: str,
581 key: str, value: str, currency: str):
582 super().accountUpdateMulti(reqId, account, modelCode, key, value,
583 currency)
584 print("AccountUpdateMulti. RequestId:", reqId, "Account:", account,
585 "ModelCode:", modelCode, "Key:", key, "Value:", value,
586 "Currency:", currency)
587 # ! [accountupdatemulti]
588
589 @iswrapper
590 # ! [accountupdatemultiend]
591 def accountUpdateMultiEnd(self, reqId: int):
592 super().accountUpdateMultiEnd(reqId)
593 print("AccountUpdateMultiEnd. RequestId:", reqId)
594 # ! [accountupdatemultiend]
595
596 @iswrapper
597 # ! [familyCodes]
598 def familyCodes(self, familyCodes: ListOfFamilyCode):
599 super().familyCodes(familyCodes)
600 print("Family Codes:")
601 for familyCode in familyCodes:
602 print("FamilyCode.", familyCode)
603 # ! [familyCodes]
604
605 @iswrapper
606 # ! [pnl]
607 def pnl(self, reqId: int, dailyPnL: float,
608 unrealizedPnL: float, realizedPnL: float):
609 super().pnl(reqId, dailyPnL, unrealizedPnL, realizedPnL)
610 print("Daily PnL. ReqId:", reqId, "DailyPnL:", dailyPnL,
611 "UnrealizedPnL:", unrealizedPnL, "RealizedPnL:", realizedPnL)
612 # ! [pnl]
613
614 @iswrapper
615 # ! [pnlsingle]
616 def pnlSingle(self, reqId: int, pos: int, dailyPnL: float,
617 unrealizedPnL: float, realizedPnL: float, value: float):
618 super().pnlSingle(reqId, pos, dailyPnL, unrealizedPnL, realizedPnL, value)
619 print("Daily PnL Single. ReqId:", reqId, "Position:", pos,
620 "DailyPnL:", dailyPnL, "UnrealizedPnL:", unrealizedPnL,
621 "RealizedPnL:", realizedPnL, "Value:", value)
622 # ! [pnlsingle]
623
624 def marketDataTypeOperations(self):
625 # ! [reqmarketdatatype]
626 # Switch to live (1) frozen (2) delayed (3) delayed frozen (4).
627 self.reqMarketDataType(MarketDataTypeEnum.DELAYED)
628 # ! [reqmarketdatatype]
629
630 @iswrapper
631 # ! [marketdatatype]
632 def marketDataType(self, reqId: TickerId, marketDataType: int):
633 super().marketDataType(reqId, marketDataType)
634 print("MarketDataType. ReqId:", reqId, "Type:", marketDataType)
635 # ! [marketdatatype]
636
637 @printWhenExecuting
638 def tickDataOperations_req(self):
639 self.reqMarketDataType(MarketDataTypeEnum.DELAYED_FROZEN)
640
641 # Requesting real time market data
642
643 # ! [reqmktdata]
644 self.reqMktData(1000, ContractSamples.USStockAtSmart(), "", False, False, [])
645 self.reqMktData(1001, ContractSamples.StockComboContract(), "", False, False, [])
646 # ! [reqmktdata]
647
648 # ! [reqmktdata_snapshot]
649 self.reqMktData(1002, ContractSamples.FutureComboContract(), "", True, False, [])
650 # ! [reqmktdata_snapshot]
651
652 # ! [regulatorysnapshot]
653 # Each regulatory snapshot request incurs a 0.01 USD fee
654 self.reqMktData(1003, ContractSamples.USStock(), "", False, True, [])
655 # ! [regulatorysnapshot]
656
657 # ! [reqmktdata_genticks]
658 # Requesting RTVolume (Time & Sales), shortable and Fundamental Ratios generic ticks
659 self.reqMktData(1004, ContractSamples.USStockAtSmart(), "233,236,258", False, False, [])
660 # ! [reqmktdata_genticks]
661
662 # ! [reqmktdata_contractnews]
663 # Without the API news subscription this will generate an "invalid tick type" error
664 self.reqMktData(1005, ContractSamples.USStockAtSmart(), "mdoff,292:BRFG", False, False, [])
665 self.reqMktData(1006, ContractSamples.USStockAtSmart(), "mdoff,292:BRFG+DJNL", False, False, [])
666 self.reqMktData(1007, ContractSamples.USStockAtSmart(), "mdoff,292:BRFUPDN", False, False, [])
667 self.reqMktData(1008, ContractSamples.USStockAtSmart(), "mdoff,292:DJ-RT", False, False, [])
668 # ! [reqmktdata_contractnews]
669
670
671 # ! [reqmktdata_broadtapenews]
672 self.reqMktData(1009, ContractSamples.BRFGbroadtapeNewsFeed(), "mdoff,292", False, False, [])
673 self.reqMktData(1010, ContractSamples.DJNLbroadtapeNewsFeed(), "mdoff,292", False, False, [])
674 self.reqMktData(1011, ContractSamples.DJTOPbroadtapeNewsFeed(), "mdoff,292", False, False, [])
675 self.reqMktData(1012, ContractSamples.BRFUPDNbroadtapeNewsFeed(), "mdoff,292", False, False, [])
676 # ! [reqmktdata_broadtapenews]
677
678 # ! [reqoptiondatagenticks]
679 # Requesting data for an option contract will return the greek values
680 self.reqMktData(1013, ContractSamples.OptionWithLocalSymbol(), "", False, False, [])
681 self.reqMktData(1014, ContractSamples.FuturesOnOptions(), "", False, False, []);
682
683 # ! [reqoptiondatagenticks]
684
685 # ! [reqfuturesopeninterest]
686 self.reqMktData(1015, ContractSamples.SimpleFuture(), "mdoff,588", False, False, [])
687 # ! [reqfuturesopeninterest]
688
689 # ! [reqmktdatapreopenbidask]
690 self.reqMktData(1016, ContractSamples.SimpleFuture(), "", False, False, [])
691 # ! [reqmktdatapreopenbidask]
692
693 # ! [reqavgoptvolume]
694 self.reqMktData(1017, ContractSamples.USStockAtSmart(), "mdoff,105", False, False, [])
695 # ! [reqavgoptvolume]
696
697 # ! [reqsmartcomponents]
698 # Requests description of map of single letter exchange codes to full exchange names
699 self.reqSmartComponents(1018, "a6")
700 # ! [reqsmartcomponents]
701
702
703 @printWhenExecuting
704 def tickDataOperations_cancel(self):
705 # Canceling the market data subscription
706 # ! [cancelmktdata]
707 self.cancelMktData(1000)
708 self.cancelMktData(1001)
709 # ! [cancelmktdata]
710
711 self.cancelMktData(1004)
712
713 self.cancelMktData(1005)
714 self.cancelMktData(1006)
715 self.cancelMktData(1007)
716 self.cancelMktData(1008)
717
718 self.cancelMktData(1009)
719 self.cancelMktData(1010)
720 self.cancelMktData(1011)
721 self.cancelMktData(1012)
722
723 self.cancelMktData(1013)
724 self.cancelMktData(1014)
725
726 self.cancelMktData(1015)
727
728 self.cancelMktData(1016)
729
730 self.cancelMktData(1017)
731
732 @iswrapper
733 # ! [tickprice]
734 def tickPrice(self, reqId: TickerId, tickType: TickType, price: float,
735 attrib: TickAttrib):
736 super().tickPrice(reqId, tickType, price, attrib)
737 print("TickPrice. TickerId:", reqId, "tickType:", tickType,
738 "Price:", price, "CanAutoExecute:", attrib.canAutoExecute,
739 "PastLimit:", attrib.pastLimit, end=' ')
740 if tickType == TickTypeEnum.BID or tickType == TickTypeEnum.ASK:
741 print("PreOpen:", attrib.preOpen)
742 else:
743 print()
744 # ! [tickprice]
745
746 @iswrapper
747 # ! [ticksize]
748 def tickSize(self, reqId: TickerId, tickType: TickType, size: int):
749 super().tickSize(reqId, tickType, size)
750 print("TickSize. TickerId:", reqId, "TickType:", tickType, "Size:", size)
751 # ! [ticksize]
752
753 @iswrapper
754 # ! [tickgeneric]
755 def tickGeneric(self, reqId: TickerId, tickType: TickType, value: float):
756 super().tickGeneric(reqId, tickType, value)
757 print("TickGeneric. TickerId:", reqId, "TickType:", tickType, "Value:", value)
758 # ! [tickgeneric]
759
760 @iswrapper
761 # ! [tickstring]
762 def tickString(self, reqId: TickerId, tickType: TickType, value: str):
763 super().tickString(reqId, tickType, value)
764 print("TickString. TickerId:", reqId, "Type:", tickType, "Value:", value)
765 # ! [tickstring]
766
767 @iswrapper
768 # ! [ticksnapshotend]
769 def tickSnapshotEnd(self, reqId: int):
770 super().tickSnapshotEnd(reqId)
771 print("TickSnapshotEnd. TickerId:", reqId)
772 # ! [ticksnapshotend]
773
774 @iswrapper
775 # ! [rerouteMktDataReq]
776 def rerouteMktDataReq(self, reqId: int, conId: int, exchange: str):
777 super().rerouteMktDataReq(reqId, conId, exchange)
778 print("Re-route market data request. ReqId:", reqId, "ConId:", conId, "Exchange:", exchange)
779 # ! [rerouteMktDataReq]
780
781 @iswrapper
782 # ! [marketRule]
783 def marketRule(self, marketRuleId: int, priceIncrements: ListOfPriceIncrements):
784 super().marketRule(marketRuleId, priceIncrements)
785 print("Market Rule ID: ", marketRuleId)
786 for priceIncrement in priceIncrements:
787 print("Price Increment.", priceIncrement)
788 # ! [marketRule]
789
790 @printWhenExecuting
791 def tickByTickOperations_req(self):
792 # Requesting tick-by-tick data (only refresh)
793 # ! [reqtickbytick]
794 self.reqTickByTickData(19001, ContractSamples.EuropeanStock2(), "Last", 0, True)
795 self.reqTickByTickData(19002, ContractSamples.EuropeanStock2(), "AllLast", 0, False)
796 self.reqTickByTickData(19003, ContractSamples.EuropeanStock2(), "BidAsk", 0, True)
797 self.reqTickByTickData(19004, ContractSamples.EurGbpFx(), "MidPoint", 0, False)
798 # ! [reqtickbytick]
799
800 # Requesting tick-by-tick data (refresh + historicalticks)
801 # ! [reqtickbytickwithhist]
802 self.reqTickByTickData(19005, ContractSamples.EuropeanStock2(), "Last", 10, False)
803 self.reqTickByTickData(19006, ContractSamples.EuropeanStock2(), "AllLast", 10, False)
804 self.reqTickByTickData(19007, ContractSamples.EuropeanStock2(), "BidAsk", 10, False)
805 self.reqTickByTickData(19008, ContractSamples.EurGbpFx(), "MidPoint", 10, True)
806 # ! [reqtickbytickwithhist]
807
808 @printWhenExecuting
809 def tickByTickOperations_cancel(self):
810 # ! [canceltickbytick]
811 self.cancelTickByTickData(19001)
812 self.cancelTickByTickData(19002)
813 self.cancelTickByTickData(19003)
814 self.cancelTickByTickData(19004)
815 # ! [canceltickbytick]
816
817 # ! [canceltickbytickwithhist]
818 self.cancelTickByTickData(19005)
819 self.cancelTickByTickData(19006)
820 self.cancelTickByTickData(19007)
821 self.cancelTickByTickData(19008)
822 # ! [canceltickbytickwithhist]
823
824 @iswrapper
825 # ! [orderbound]
826 def orderBound(self, orderId: int, apiClientId: int, apiOrderId: int):
827 super().orderBound(orderId, apiClientId, apiOrderId)
828 print("OrderBound.", "OrderId:", orderId, "ApiClientId:", apiClientId, "ApiOrderId:", apiOrderId)
829 # ! [orderbound]
830
831 @iswrapper
832 # ! [tickbytickalllast]
833 def tickByTickAllLast(self, reqId: int, tickType: int, time: int, price: float,
834 size: int, tickAtrribLast: TickAttribLast, exchange: str,
835 specialConditions: str):
836 super().tickByTickAllLast(reqId, tickType, time, price, size, tickAtrribLast,
837 exchange, specialConditions)
838 if tickType == 1:
839 print("Last.", end='')
840 else:
841 print("AllLast.", end='')
842 print(" ReqId:", reqId,
843 "Time:", datetime.datetime.fromtimestamp(time).strftime("%Y%m%d %H:%M:%S"),
844 "Price:", price, "Size:", size, "Exch:" , exchange,
845 "Spec Cond:", specialConditions, "PastLimit:", tickAtrribLast.pastLimit, "Unreported:", tickAtrribLast.unreported)
846 # ! [tickbytickalllast]
847
848 @iswrapper
849 # ! [tickbytickbidask]
850 def tickByTickBidAsk(self, reqId: int, time: int, bidPrice: float, askPrice: float,
851 bidSize: int, askSize: int, tickAttribBidAsk: TickAttribBidAsk):
852 super().tickByTickBidAsk(reqId, time, bidPrice, askPrice, bidSize,
853 askSize, tickAttribBidAsk)
854 print("BidAsk. ReqId:", reqId,
855 "Time:", datetime.datetime.fromtimestamp(time).strftime("%Y%m%d %H:%M:%S"),
856 "BidPrice:", bidPrice, "AskPrice:", askPrice, "BidSize:", bidSize,
857 "AskSize:", askSize, "BidPastLow:", tickAttribBidAsk.bidPastLow, "AskPastHigh:", tickAttribBidAsk.askPastHigh)
858 # ! [tickbytickbidask]
859
860 # ! [tickbytickmidpoint]
861 @iswrapper
862 def tickByTickMidPoint(self, reqId: int, time: int, midPoint: float):
863 super().tickByTickMidPoint(reqId, time, midPoint)
864 print("Midpoint. ReqId:", reqId,
865 "Time:", datetime.datetime.fromtimestamp(time).strftime("%Y%m%d %H:%M:%S"),
866 "MidPoint:", midPoint)
867 # ! [tickbytickmidpoint]
868
869 @printWhenExecuting
870 def marketDepthOperations_req(self):
871 # Requesting the Deep Book
872 # ! [reqmarketdepth]
873 self.reqMktDepth(2001, ContractSamples.EurGbpFx(), 5, False, [])
874 # ! [reqmarketdepth]
875
876 # ! [reqmarketdepth]
877 self.reqMktDepth(2002, ContractSamples.EuropeanStock(), 5, True, [])
878 # ! [reqmarketdepth]
879
880 # Request list of exchanges sending market depth to UpdateMktDepthL2()
881 # ! [reqMktDepthExchanges]
882 self.reqMktDepthExchanges()
883 # ! [reqMktDepthExchanges]
884
885 @printWhenExecuting
886 def marketDepthOperations_cancel(self):
887 # Canceling the Deep Book request
888 # ! [cancelmktdepth]
889 self.cancelMktDepth(2001, False)
890 self.cancelMktDepth(2002, True)
891 # ! [cancelmktdepth]
892
893 @iswrapper
894 # ! [updatemktdepth]
895 def updateMktDepth(self, reqId: TickerId, position: int, operation: int,
896 side: int, price: float, size: int):
897 super().updateMktDepth(reqId, position, operation, side, price, size)
898 print("UpdateMarketDepth. ReqId:", reqId, "Position:", position, "Operation:",
899 operation, "Side:", side, "Price:", price, "Size:", size)
900 # ! [updatemktdepth]
901
902 @iswrapper
903 # ! [updatemktdepthl2]
904 def updateMktDepthL2(self, reqId: TickerId, position: int, marketMaker: str,
905 operation: int, side: int, price: float, size: int, isSmartDepth: bool):
906 super().updateMktDepthL2(reqId, position, marketMaker, operation, side,
907 price, size, isSmartDepth)
908 print("UpdateMarketDepthL2. ReqId:", reqId, "Position:", position, "MarketMaker:", marketMaker, "Operation:",
909 operation, "Side:", side, "Price:", price, "Size:", size, "isSmartDepth:", isSmartDepth)
910
911 # ! [updatemktdepthl2]
912
913 @iswrapper
914 # ! [rerouteMktDepthReq]
915 def rerouteMktDepthReq(self, reqId: int, conId: int, exchange: str):
916 super().rerouteMktDataReq(reqId, conId, exchange)
917 print("Re-route market depth request. ReqId:", reqId, "ConId:", conId, "Exchange:", exchange)
918 # ! [rerouteMktDepthReq]
919
920 @printWhenExecuting
921 def realTimeBarsOperations_req(self):
922 # Requesting real time bars
923 # ! [reqrealtimebars]
924 self.reqRealTimeBars(3001, ContractSamples.EurGbpFx(), 5, "MIDPOINT", True, [])
925 # ! [reqrealtimebars]
926
927 @iswrapper
928 # ! [realtimebar]
929 def realtimeBar(self, reqId: TickerId, time:int, open_: float, high: float, low: float, close: float,
930 volume: int, wap: float, count: int):
931 super().realtimeBar(reqId, time, open_, high, low, close, volume, wap, count)
932 print("RealTimeBar. TickerId:", reqId, RealTimeBar(time, -1, open_, high, low, close, volume, wap, count))
933 # ! [realtimebar]
934
935 @printWhenExecuting
936 def realTimeBarsOperations_cancel(self):
937 # Canceling real time bars
938 # ! [cancelrealtimebars]
939 self.cancelRealTimeBars(3001)
940 # ! [cancelrealtimebars]
941
942 @printWhenExecuting
943 def historicalDataOperations_req(self):
944 # Requesting historical data
945 # ! [reqHeadTimeStamp]
946 self.reqHeadTimeStamp(4101, ContractSamples.USStockAtSmart(), "TRADES", 0, 1)
947 # ! [reqHeadTimeStamp]
948
949 # ! [reqhistoricaldata]
950 queryTime = (datetime.datetime.today() - datetime.timedelta(days=180)).strftime("%Y%m%d %H:%M:%S")
951 self.reqHistoricalData(4102, ContractSamples.EurGbpFx(), queryTime,
952 "1 M", "1 day", "MIDPOINT", 1, 1, False, [])
953 self.reqHistoricalData(4103, ContractSamples.EuropeanStock(), queryTime,
954 "10 D", "1 min", "TRADES", 1, 1, False, [])
955 self.reqHistoricalData(4104, ContractSamples.EurGbpFx(), "",
956 "1 M", "1 day", "MIDPOINT", 1, 1, True, [])
957 # ! [reqhistoricaldata]
958
959 @printWhenExecuting
960 def historicalDataOperations_cancel(self):
961 # ! [cancelHeadTimestamp]
962 self.cancelHeadTimeStamp(4101)
963 # ! [cancelHeadTimestamp]
964
965 # Canceling historical data requests
966 # ! [cancelhistoricaldata]
967 self.cancelHistoricalData(4102)
968 self.cancelHistoricalData(4103)
969 self.cancelHistoricalData(4104)
970 # ! [cancelhistoricaldata]
971
972 @printWhenExecuting
973 def historicalTicksOperations(self):
974 # ! [reqhistoricalticks]
975 self.reqHistoricalTicks(18001, ContractSamples.USStockAtSmart(),
976 "20170712 21:39:33", "", 10, "TRADES", 1, True, [])
977 self.reqHistoricalTicks(18002, ContractSamples.USStockAtSmart(),
978 "20170712 21:39:33", "", 10, "BID_ASK", 1, True, [])
979 self.reqHistoricalTicks(18003, ContractSamples.USStockAtSmart(),
980 "20170712 21:39:33", "", 10, "MIDPOINT", 1, True, [])
981 # ! [reqhistoricalticks]
982
983 @iswrapper
984 # ! [headTimestamp]
985 def headTimestamp(self, reqId:int, headTimestamp:str):
986 print("HeadTimestamp. ReqId:", reqId, "HeadTimeStamp:", headTimestamp)
987 # ! [headTimestamp]
988
989 @iswrapper
990 # ! [histogramData]
991 def histogramData(self, reqId:int, items:HistogramDataList):
992 print("HistogramData. ReqId:", reqId, "HistogramDataList:", "[%s]" % "; ".join(map(str, items)))
993 # ! [histogramData]
994
995 @iswrapper
996 # ! [historicaldata]
997 def historicalData(self, reqId:int, bar: BarData):
998 print("HistoricalData. ReqId:", reqId, "BarData.", bar)
999 # ! [historicaldata]
1000
1001 @iswrapper
1002 # ! [historicaldataend]
1003 def historicalDataEnd(self, reqId: int, start: str, end: str):
1004 super().historicalDataEnd(reqId, start, end)
1005 print("HistoricalDataEnd. ReqId:", reqId, "from", start, "to", end)
1006 # ! [historicaldataend]
1007
1008 @iswrapper
1009 # ! [historicalDataUpdate]
1010 def historicalDataUpdate(self, reqId: int, bar: BarData):
1011 print("HistoricalDataUpdate. ReqId:", reqId, "BarData.", bar)
1012 # ! [historicalDataUpdate]
1013
1014 @iswrapper
1015 # ! [historicalticks]
1016 def historicalTicks(self, reqId: int, ticks: ListOfHistoricalTick, done: bool):
1017 for tick in ticks:
1018 print("HistoricalTick. ReqId:", reqId, tick)
1019 # ! [historicalticks]
1020
1021 @iswrapper
1022 # ! [historicalticksbidask]
1023 def historicalTicksBidAsk(self, reqId: int, ticks: ListOfHistoricalTickBidAsk,
1024 done: bool):
1025 for tick in ticks:
1026 print("HistoricalTickBidAsk. ReqId:", reqId, tick)
1027 # ! [historicalticksbidask]
1028
1029 @iswrapper
1030 # ! [historicaltickslast]
1031 def historicalTicksLast(self, reqId: int, ticks: ListOfHistoricalTickLast,
1032 done: bool):
1033 for tick in ticks:
1034 print("HistoricalTickLast. ReqId:", reqId, tick)
1035 # ! [historicaltickslast]
1036
1037 @printWhenExecuting
1038 def optionsOperations_req(self):
1039 # ! [reqsecdefoptparams]
1040 self.reqSecDefOptParams(0, "IBM", "", "STK", 8314)
1041 # ! [reqsecdefoptparams]
1042
1043 # Calculating implied volatility
1044 # ! [calculateimpliedvolatility]
1045 self.calculateImpliedVolatility(5001, ContractSamples.OptionAtBOX(), 5, 85, [])
1046 # ! [calculateimpliedvolatility]
1047
1048 # Calculating option's price
1049 # ! [calculateoptionprice]
1050 self.calculateOptionPrice(5002, ContractSamples.OptionAtBOX(), 0.22, 85, [])
1051 # ! [calculateoptionprice]
1052
1053 # Exercising options
1054 # ! [exercise_options]
1055 self.exerciseOptions(5003, ContractSamples.OptionWithTradingClass(), 1,
1056 1, self.account, 1)
1057 # ! [exercise_options]
1058
1059 @printWhenExecuting
1060 def optionsOperations_cancel(self):
1061 # Canceling implied volatility
1062 self.cancelCalculateImpliedVolatility(5001)
1063 # Canceling option's price calculation
1064 self.cancelCalculateOptionPrice(5002)
1065
1066 @iswrapper
1067 # ! [securityDefinitionOptionParameter]
1068 def securityDefinitionOptionParameter(self, reqId: int, exchange: str,
1069 underlyingConId: int, tradingClass: str, multiplier: str,
1070 expirations: SetOfString, strikes: SetOfFloat):
1071 super().securityDefinitionOptionParameter(reqId, exchange,
1072 underlyingConId, tradingClass, multiplier, expirations, strikes)
1073 print("SecurityDefinitionOptionParameter.",
1074 "ReqId:", reqId, "Exchange:", exchange, "Underlying conId:", underlyingConId, "TradingClass:", tradingClass, "Multiplier:", multiplier,
1075 "Expirations:", expirations, "Strikes:", str(strikes))
1076 # ! [securityDefinitionOptionParameter]
1077
1078 @iswrapper
1079 # ! [securityDefinitionOptionParameterEnd]
1080 def securityDefinitionOptionParameterEnd(self, reqId: int):
1081 super().securityDefinitionOptionParameterEnd(reqId)
1082 print("SecurityDefinitionOptionParameterEnd. ReqId:", reqId)
1083 # ! [securityDefinitionOptionParameterEnd]
1084
1085 @iswrapper
1086 # ! [tickoptioncomputation]
1087 def tickOptionComputation(self, reqId: TickerId, tickType: TickType,
1088 impliedVol: float, delta: float, optPrice: float, pvDividend: float,
1089 gamma: float, vega: float, theta: float, undPrice: float):
1090 super().tickOptionComputation(reqId, tickType, impliedVol, delta,
1091 optPrice, pvDividend, gamma, vega, theta, undPrice)
1092 print("TickOptionComputation. TickerId:", reqId, "TickType:", tickType,
1093 "ImpliedVolatility:", impliedVol, "Delta:", delta, "OptionPrice:",
1094 optPrice, "pvDividend:", pvDividend, "Gamma: ", gamma, "Vega:", vega,
1095 "Theta:", theta, "UnderlyingPrice:", undPrice)
1096
1097 # ! [tickoptioncomputation]
1098
1099
1100 @printWhenExecuting
1101 def contractOperations(self):
1102 # ! [reqcontractdetails]
1103 self.reqContractDetails(210, ContractSamples.OptionForQuery())
1104 self.reqContractDetails(211, ContractSamples.EurGbpFx())
1105 self.reqContractDetails(212, ContractSamples.Bond())
1106 self.reqContractDetails(213, ContractSamples.FuturesOnOptions())
1107 self.reqContractDetails(214, ContractSamples.SimpleFuture())
1108 # ! [reqcontractdetails]
1109
1110 # ! [reqmatchingsymbols]
1111 self.reqMatchingSymbols(211, "IB")
1112 # ! [reqmatchingsymbols]
1113
1114 @printWhenExecuting
1115 def newsOperations_req(self):
1116 # Requesting news ticks
1117 # ! [reqNewsTicks]
1118 self.reqMktData(10001, ContractSamples.USStockAtSmart(), "mdoff,292", False, False, []);
1119 # ! [reqNewsTicks]
1120
1121 # Returns list of subscribed news providers
1122 # ! [reqNewsProviders]
1123 self.reqNewsProviders()
1124 # ! [reqNewsProviders]
1125
1126 # Returns body of news article given article ID
1127 # ! [reqNewsArticle]
1128 self.reqNewsArticle(10002,"BRFG", "BRFG$04fb9da2", [])
1129 # ! [reqNewsArticle]
1130
1131 # Returns list of historical news headlines with IDs
1132 # ! [reqHistoricalNews]
1133 self.reqHistoricalNews(10003, 8314, "BRFG", "", "", 10, [])
1134 # ! [reqHistoricalNews]
1135
1136 # ! [reqcontractdetailsnews]
1137 self.reqContractDetails(10004, ContractSamples.NewsFeedForQuery())
1138 # ! [reqcontractdetailsnews]
1139
1140 @printWhenExecuting
1141 def newsOperations_cancel(self):
1142 # Canceling news ticks
1143 # ! [cancelNewsTicks]
1144 self.cancelMktData(10001);
1145 # ! [cancelNewsTicks]
1146
1147 @iswrapper
1148 #! [tickNews]
1149 def tickNews(self, tickerId: int, timeStamp: int, providerCode: str,
1150 articleId: str, headline: str, extraData: str):
1151 print("TickNews. TickerId:", tickerId, "TimeStamp:", timeStamp,
1152 "ProviderCode:", providerCode, "ArticleId:", articleId,
1153 "Headline:", headline, "ExtraData:", extraData)
1154 #! [tickNews]
1155
1156 @iswrapper
1157 #! [historicalNews]
1158 def historicalNews(self, reqId: int, time: str, providerCode: str,
1159 articleId: str, headline: str):
1160 print("HistoricalNews. ReqId:", reqId, "Time:", time,
1161 "ProviderCode:", providerCode, "ArticleId:", articleId,
1162 "Headline:", headline)
1163 #! [historicalNews]
1164
1165 @iswrapper
1166 #! [historicalNewsEnd]
1167 def historicalNewsEnd(self, reqId:int, hasMore:bool):
1168 print("HistoricalNewsEnd. ReqId:", reqId, "HasMore:", hasMore)
1169 #! [historicalNewsEnd]
1170
1171 @iswrapper
1172 #! [newsProviders]
1173 def newsProviders(self, newsProviders: ListOfNewsProviders):
1174 print("NewsProviders: ")
1175 for provider in newsProviders:
1176 print("NewsProvider.", provider)
1177 #! [newsProviders]
1178
1179 @iswrapper
1180 #! [newsArticle]
1181 def newsArticle(self, reqId: int, articleType: int, articleText: str):
1182 print("NewsArticle. ReqId:", reqId, "ArticleType:", articleType,
1183 "ArticleText:", articleText)
1184 #! [newsArticle]
1185
1186 @iswrapper
1187 # ! [contractdetails]
1188 def contractDetails(self, reqId: int, contractDetails: ContractDetails):
1189 super().contractDetails(reqId, contractDetails)
1190 printinstance(contractDetails)
1191 # ! [contractdetails]
1192
1193 @iswrapper
1194 # ! [bondcontractdetails]
1195 def bondContractDetails(self, reqId: int, contractDetails: ContractDetails):
1196 super().bondContractDetails(reqId, contractDetails)
1197 printinstance(contractDetails)
1198 # ! [bondcontractdetails]
1199
1200 @iswrapper
1201 # ! [contractdetailsend]
1202 def contractDetailsEnd(self, reqId: int):
1203 super().contractDetailsEnd(reqId)
1204 print("ContractDetailsEnd. ReqId:", reqId)
1205 # ! [contractdetailsend]
1206
1207 @iswrapper
1208 # ! [symbolSamples]
1209 def symbolSamples(self, reqId: int,
1210 contractDescriptions: ListOfContractDescription):
1211 super().symbolSamples(reqId, contractDescriptions)
1212 print("Symbol Samples. Request Id: ", reqId)
1213
1214 for contractDescription in contractDescriptions:
1215 derivSecTypes = ""
1216 for derivSecType in contractDescription.derivativeSecTypes:
1217 derivSecTypes += derivSecType
1218 derivSecTypes += " "
1219 print("Contract: conId:%s, symbol:%s, secType:%s primExchange:%s, "
1220 "currency:%s, derivativeSecTypes:%s" % (
1221 contractDescription.contract.conId,
1222 contractDescription.contract.symbol,
1223 contractDescription.contract.secType,
1224 contractDescription.contract.primaryExchange,
1225 contractDescription.contract.currency, derivSecTypes))
1226 # ! [symbolSamples]
1227
1228 @printWhenExecuting
1229 def marketScannersOperations_req(self):
1230 # Requesting list of valid scanner parameters which can be used in TWS
1231 # ! [reqscannerparameters]
1232 self.reqScannerParameters()
1233 # ! [reqscannerparameters]
1234
1235 # Triggering a scanner subscription
1236 # ! [reqscannersubscription]
1237 self.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), [], [])
1238
1239 # Generic Filters
1240 tagvalues = []
1241 tagvalues.append(TagValue("usdMarketCapAbove", "10000"))
1242 tagvalues.append(TagValue("optVolumeAbove", "1000"))
1243 tagvalues.append(TagValue("avgVolumeAbove", "10000"));
1244
1245 self.reqScannerSubscription(7002, ScannerSubscriptionSamples.HotUSStkByVolume(), [], tagvalues) # requires TWS v973+
1246 # ! [reqscannersubscription]
1247
1248 # ! [reqcomplexscanner]
1249 AAPLConIDTag = [TagValue("underConID", "265598")]
1250 self.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), [], AAPLConIDTag) # requires TWS v975+
1251
1252 # ! [reqcomplexscanner]
1253
1254
1255 @printWhenExecuting
1256 def marketScanners_cancel(self):
1257 # Canceling the scanner subscription
1258 # ! [cancelscannersubscription]
1259 self.cancelScannerSubscription(7001)
1260 self.cancelScannerSubscription(7002)
1261 self.cancelScannerSubscription(7003)
1262 # ! [cancelscannersubscription]
1263
1264 @iswrapper
1265 # ! [scannerparameters]
1266 def scannerParameters(self, xml: str):
1267 super().scannerParameters(xml)
1268 open('log/scanner.xml', 'w').write(xml)
1269 print("ScannerParameters received.")
1270 # ! [scannerparameters]
1271
1272 @iswrapper
1273 # ! [scannerdata]
1274 def scannerData(self, reqId: int, rank: int, contractDetails: ContractDetails,
1275 distance: str, benchmark: str, projection: str, legsStr: str):
1276 super().scannerData(reqId, rank, contractDetails, distance, benchmark,
1277 projection, legsStr)
1278# print("ScannerData. ReqId:", reqId, "Rank:", rank, "Symbol:", contractDetails.contract.symbol,
1279# "SecType:", contractDetails.contract.secType,
1280# "Currency:", contractDetails.contract.currency,
1281# "Distance:", distance, "Benchmark:", benchmark,
1282# "Projection:", projection, "Legs String:", legsStr)
1283 print("ScannerData. ReqId:", reqId, ScanData(contractDetails.contract, rank, distance, benchmark, projection, legsStr))
1284 # ! [scannerdata]
1285
1286 @iswrapper
1287 # ! [scannerdataend]
1288 def scannerDataEnd(self, reqId: int):
1289 super().scannerDataEnd(reqId)
1290 print("ScannerDataEnd. ReqId:", reqId)
1291 # ! [scannerdataend]
1292
1293 @iswrapper
1294 # ! [smartcomponents]
1295 def smartComponents(self, reqId:int, smartComponentMap:SmartComponentMap):
1296 super().smartComponents(reqId, smartComponentMap)
1297 print("SmartComponents:")
1298 for smartComponent in smartComponentMap:
1299 print("SmartComponent.", smartComponent)
1300 # ! [smartcomponents]
1301
1302 @iswrapper
1303 # ! [tickReqParams]
1304 def tickReqParams(self, tickerId:int, minTick:float,
1305 bboExchange:str, snapshotPermissions:int):
1306 super().tickReqParams(tickerId, minTick, bboExchange, snapshotPermissions)
1307 print("TickReqParams. TickerId:", tickerId, "MinTick:", minTick,
1308 "BboExchange:", bboExchange, "SnapshotPermissions:", snapshotPermissions)
1309 # ! [tickReqParams]
1310
1311 @iswrapper
1312 # ! [mktDepthExchanges]
1313 def mktDepthExchanges(self, depthMktDataDescriptions:ListOfDepthExchanges):
1314 super().mktDepthExchanges(depthMktDataDescriptions)
1315 print("MktDepthExchanges:")
1316 for desc in depthMktDataDescriptions:
1317 print("DepthMktDataDescription.", desc)
1318 # ! [mktDepthExchanges]
1319
1320 @printWhenExecuting
1321 def fundamentalsOperations_req(self):
1322 # Requesting Fundamentals
1323 # ! [reqfundamentaldata]
1324 self.reqFundamentalData(8001, ContractSamples.USStock(), "ReportsFinSummary", [])
1325 # ! [reqfundamentaldata]
1326
1327 # ! [fundamentalexamples]
1328 self.reqFundamentalData(8002, ContractSamples.USStock(), "ReportSnapshot", []); # for company overview
1329 self.reqFundamentalData(8003, ContractSamples.USStock(), "ReportRatios", []); # for financial ratios
1330 self.reqFundamentalData(8004, ContractSamples.USStock(), "ReportsFinStatements", []); # for financial statements
1331 self.reqFundamentalData(8005, ContractSamples.USStock(), "RESC", []); # for analyst estimates
1332 self.reqFundamentalData(8006, ContractSamples.USStock(), "CalendarReport", []); # for company calendar
1333 # ! [fundamentalexamples]
1334
1335 @printWhenExecuting
1336 def fundamentalsOperations_cancel(self):
1337 # Canceling fundamentalsOperations_req request
1338 # ! [cancelfundamentaldata]
1339 self.cancelFundamentalData(8001)
1340 # ! [cancelfundamentaldata]
1341
1342 # ! [cancelfundamentalexamples]
1343 self.cancelFundamentalData(8002)
1344 self.cancelFundamentalData(8003)
1345 self.cancelFundamentalData(8004)
1346 self.cancelFundamentalData(8005)
1347 self.cancelFundamentalData(8006)
1348 # ! [cancelfundamentalexamples]
1349
1350 @iswrapper
1351 # ! [fundamentaldata]
1352 def fundamentalData(self, reqId: TickerId, data: str):
1353 super().fundamentalData(reqId, data)
1354 print("FundamentalData. ReqId:", reqId, "Data:", data)
1355 # ! [fundamentaldata]
1356
1357 @printWhenExecuting
1358 def bulletinsOperations_req(self):
1359 # Requesting Interactive Broker's news bulletinsOperations_req
1360 # ! [reqnewsbulletins]
1361 self.reqNewsBulletins(True)
1362 # ! [reqnewsbulletins]
1363
1364 @printWhenExecuting
1365 def bulletinsOperations_cancel(self):
1366 # Canceling IB's news bulletinsOperations_req
1367 # ! [cancelnewsbulletins]
1368 self.cancelNewsBulletins()
1369 # ! [cancelnewsbulletins]
1370
1371 @iswrapper
1372 # ! [updatenewsbulletin]
1373 def updateNewsBulletin(self, msgId: int, msgType: int, newsMessage: str,
1374 originExch: str):
1375 super().updateNewsBulletin(msgId, msgType, newsMessage, originExch)
1376 print("News Bulletins. MsgId:", msgId, "Type:", msgType, "Message:", newsMessage,
1377 "Exchange of Origin: ", originExch)
1378 # ! [updatenewsbulletin]
1379
1380 def ocaSample(self):
1381 # OCA ORDER
1382 # ! [ocasubmit]
1383 ocaOrders = [OrderSamples.LimitOrder("BUY", 1, 10), OrderSamples.LimitOrder("BUY", 1, 11),
1384 OrderSamples.LimitOrder("BUY", 1, 12)]
1385 OrderSamples.OneCancelsAll("TestOCA_" + str(self.nextValidOrderId), ocaOrders, 2)
1386 for o in ocaOrders:
1387 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), o)
1388 # ! [ocasubmit]
1389
1390 def conditionSamples(self):
1391 # ! [order_conditioning_activate]
1392 mkt = OrderSamples.MarketOrder("BUY", 100)
1393 # Order will become active if conditioning criteria is met
1394 mkt.conditions.append(
1395 OrderSamples.PriceCondition(PriceCondition.TriggerMethodEnum.Default,
1396 208813720, "SMART", 600, False, False))
1397 mkt.conditions.append(OrderSamples.ExecutionCondition("EUR.USD", "CASH", "IDEALPRO", True))
1398 mkt.conditions.append(OrderSamples.MarginCondition(30, True, False))
1399 mkt.conditions.append(OrderSamples.PercentageChangeCondition(15.0, 208813720, "SMART", True, True))
1400 mkt.conditions.append(OrderSamples.TimeCondition("20160118 23:59:59", True, False))
1401 mkt.conditions.append(OrderSamples.VolumeCondition(208813720, "SMART", False, 100, True))
1402 self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), mkt)
1403 # ! [order_conditioning_activate]
1404
1405 # Conditions can make the order active or cancel it. Only LMT orders can be conditionally canceled.
1406 # ! [order_conditioning_cancel]
1407 lmt = OrderSamples.LimitOrder("BUY", 100, 20)
1408 # The active order will be cancelled if conditioning criteria is met
1409 lmt.conditionsCancelOrder = True
1410 lmt.conditions.append(
1411 OrderSamples.PriceCondition(PriceCondition.TriggerMethodEnum.Last,
1412 208813720, "SMART", 600, False, False))
1413 self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), lmt)
1414 # ! [order_conditioning_cancel]
1415
1416 def bracketSample(self):
1417 # BRACKET ORDER
1418 # ! [bracketsubmit]
1419 bracket = OrderSamples.BracketOrder(self.nextOrderId(), "BUY", 100, 30, 40, 20)
1420 for o in bracket:
1421 self.placeOrder(o.orderId, ContractSamples.EuropeanStock(), o)
1422 self.nextOrderId() # need to advance this we'll skip one extra oid, it's fine
1423 # ! [bracketsubmit]
1424
1425 def hedgeSample(self):
1426 # F Hedge order
1427 # ! [hedgesubmit]
1428 # Parent order on a contract which currency differs from your base currency
1429 parent = OrderSamples.LimitOrder("BUY", 100, 10)
1430 parent.orderId = self.nextOrderId()
1431 parent.transmit = False
1432 # Hedge on the currency conversion
1433 hedge = OrderSamples.MarketFHedge(parent.orderId, "BUY")
1434 # Place the parent first...
1435 self.placeOrder(parent.orderId, ContractSamples.EuropeanStock(), parent)
1436 # Then the hedge order
1437 self.placeOrder(self.nextOrderId(), ContractSamples.EurGbpFx(), hedge)
1438 # ! [hedgesubmit]
1439
1440 def algoSamples(self):
1441 # ! [scale_order]
1442 scaleOrder = OrderSamples.RelativePeggedToPrimary("BUY", 70000, 189, 0.01);
1443 AvailableAlgoParams.FillScaleParams(scaleOrder, 2000, 500, True, .02, 189.00, 3600, 2.00, True, 10, 40);
1444 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), scaleOrder);
1445 # ! [scale_order]
1446
1447 time.sleep(1)
1448
1449 # ! [algo_base_order]
1450 baseOrder = OrderSamples.LimitOrder("BUY", 1000, 1)
1451 # ! [algo_base_order]
1452
1453 # ! [arrivalpx]
1454 AvailableAlgoParams.FillArrivalPriceParams(baseOrder, 0.1, "Aggressive", "09:00:00 CET", "16:00:00 CET", True, True, 100000)
1455 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1456 # ! [arrivalpx]
1457
1458 # ! [darkice]
1459 AvailableAlgoParams.FillDarkIceParams(baseOrder, 10, "09:00:00 CET", "16:00:00 CET", True, 100000)
1460 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1461 # ! [darkice]
1462
1463 # ! [place_midprice]
1464 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), OrderSamples.Midprice("BUY", 1, 150))
1465 # ! [place_midprice]
1466
1467 # ! [ad]
1468 # The Time Zone in "startTime" and "endTime" attributes is ignored and always defaulted to GMT
1469 AvailableAlgoParams.FillAccumulateDistributeParams(baseOrder, 10, 60, True, True, 1, True, True, "20161010-12:00:00 GMT", "20161010-16:00:00 GMT")
1470 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1471 # ! [ad]
1472
1473 # ! [twap]
1474 AvailableAlgoParams.FillTwapParams(baseOrder, "Marketable", "09:00:00 CET", "16:00:00 CET", True, 100000)
1475 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1476 # ! [twap]
1477
1478 # ! [vwap]
1479 AvailableAlgoParams.FillVwapParams(baseOrder, 0.2, "09:00:00 CET", "16:00:00 CET", True, True, 100000)
1480 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1481 # ! [vwap]
1482
1483 # ! [balanceimpactrisk]
1484 AvailableAlgoParams.FillBalanceImpactRiskParams(baseOrder, 0.1, "Aggressive", True)
1485 self.placeOrder(self.nextOrderId(), ContractSamples.USOptionContract(), baseOrder)
1486 # ! [balanceimpactrisk]
1487
1488 # ! [minimpact]
1489 AvailableAlgoParams.FillMinImpactParams(baseOrder, 0.3)
1490 self.placeOrder(self.nextOrderId(), ContractSamples.USOptionContract(), baseOrder)
1491 # ! [minimpact]
1492
1493 # ! [adaptive]
1494 AvailableAlgoParams.FillAdaptiveParams(baseOrder, "Normal")
1495 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1496 # ! [adaptive]
1497
1498 # ! [closepx]
1499 AvailableAlgoParams.FillClosePriceParams(baseOrder, 0.4, "Neutral", "20180926-06:06:49", True, 100000)
1500 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1501 # ! [closepx]
1502
1503 # ! [pctvol]
1504 AvailableAlgoParams.FillPctVolParams(baseOrder, 0.5, "12:00:00 EST", "14:00:00 EST", True, 100000)
1505 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1506 # ! [pctvol]
1507
1508 # ! [pctvolpx]
1509 AvailableAlgoParams.FillPriceVariantPctVolParams(baseOrder, 0.1, 0.05, 0.01, 0.2, "12:00:00 EST", "14:00:00 EST", True, 100000)
1510 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1511 # ! [pctvolpx]
1512
1513 # ! [pctvolsz]
1514 AvailableAlgoParams.FillSizeVariantPctVolParams(baseOrder, 0.2, 0.4, "12:00:00 EST", "14:00:00 EST", True, 100000)
1515 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1516 # ! [pctvolsz]
1517
1518 # ! [pctvoltm]
1519 AvailableAlgoParams.FillTimeVariantPctVolParams(baseOrder, 0.2, 0.4, "12:00:00 EST", "14:00:00 EST", True, 100000)
1520 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), baseOrder)
1521 # ! [pctvoltm]
1522
1523 # ! [jeff_vwap_algo]
1524 AvailableAlgoParams.FillJefferiesVWAPParams(baseOrder, "10:00:00 EST", "16:00:00 EST", 10, 10, "Exclude_Both", 130, 135, 1, 10, "Patience", False, "Midpoint")
1525 self.placeOrder(self.nextOrderId(), ContractSamples.JefferiesContract(), baseOrder)
1526 # ! [jeff_vwap_algo]
1527
1528 # ! [csfb_inline_algo]
1529 AvailableAlgoParams.FillCSFBInlineParams(baseOrder, "10:00:00 EST", "16:00:00 EST", "Patient", 10, 20, 100, "Default", False, 40, 100, 100, 35)
1530 self.placeOrder(self.nextOrderId(), ContractSamples.CSFBContract(), baseOrder)
1531 # ! [csfb_inline_algo]
1532
1533 # ! [qbalgo_strobe_algo]
1534 AvailableAlgoParams.FillQBAlgoInLineParams(baseOrder, "10:00:00 EST", "16:00:00 EST", -99, "TWAP", 0.25, True)
1535 self.placeOrder(self.nextOrderId(), ContractSamples.QBAlgoContract(), baseOrder)
1536 # ! [qbalgo_strobe_algo]
1537
1538 @printWhenExecuting
1539 def financialAdvisorOperations(self):
1540 # Requesting FA information
1541 # ! [requestfaaliases]
1542 self.requestFA(FaDataTypeEnum.ALIASES)
1543 # ! [requestfaaliases]
1544
1545 # ! [requestfagroups]
1546 self.requestFA(FaDataTypeEnum.GROUPS)
1547 # ! [requestfagroups]
1548
1549 # ! [requestfaprofiles]
1550 self.requestFA(FaDataTypeEnum.PROFILES)
1551 # ! [requestfaprofiles]
1552
1553 # Replacing FA information - Fill in with the appropriate XML string.
1554 # ! [replacefaonegroup]
1555 self.replaceFA(FaDataTypeEnum.GROUPS, FaAllocationSamples.FaOneGroup)
1556 # ! [replacefaonegroup]
1557
1558 # ! [replacefatwogroups]
1559 self.replaceFA(FaDataTypeEnum.GROUPS, FaAllocationSamples.FaTwoGroups)
1560 # ! [replacefatwogroups]
1561
1562 # ! [replacefaoneprofile]
1563 self.replaceFA(FaDataTypeEnum.PROFILES, FaAllocationSamples.FaOneProfile)
1564 # ! [replacefaoneprofile]
1565
1566 # ! [replacefatwoprofiles]
1567 self.replaceFA(FaDataTypeEnum.PROFILES, FaAllocationSamples.FaTwoProfiles)
1568 # ! [replacefatwoprofiles]
1569
1570 # ! [reqSoftDollarTiers]
1571 self.reqSoftDollarTiers(14001)
1572 # ! [reqSoftDollarTiers]
1573
1574 @iswrapper
1575 # ! [receivefa]
1576 def receiveFA(self, faData: FaDataType, cxml: str):
1577 super().receiveFA(faData, cxml)
1578 print("Receiving FA: ", faData)
1579 open('log/fa.xml', 'w').write(cxml)
1580 # ! [receivefa]
1581
1582 @iswrapper
1583 # ! [softDollarTiers]
1584 def softDollarTiers(self, reqId: int, tiers: list):
1585 super().softDollarTiers(reqId, tiers)
1586 print("SoftDollarTiers. ReqId:", reqId)
1587 for tier in tiers:
1588 print("SoftDollarTier.", tier)
1589 # ! [softDollarTiers]
1590
1591 @printWhenExecuting
1592 def miscelaneousOperations(self):
1593 # Request TWS' current time
1594 self.reqCurrentTime()
1595 # Setting TWS logging level
1596 self.setServerLogLevel(1)
1597
1598 @printWhenExecuting
1599 def linkingOperations(self):
1600 # ! [querydisplaygroups]
1601 self.queryDisplayGroups(19001)
1602 # ! [querydisplaygroups]
1603
1604 # ! [subscribetogroupevents]
1605 self.subscribeToGroupEvents(19002, 1)
1606 # ! [subscribetogroupevents]
1607
1608 # ! [updatedisplaygroup]
1609 self.updateDisplayGroup(19002, "8314@SMART")
1610 # ! [updatedisplaygroup]
1611
1612 # ! [subscribefromgroupevents]
1613 self.unsubscribeFromGroupEvents(19002)
1614 # ! [subscribefromgroupevents]
1615
1616 @iswrapper
1617 # ! [displaygrouplist]
1618 def displayGroupList(self, reqId: int, groups: str):
1619 super().displayGroupList(reqId, groups)
1620 print("DisplayGroupList. ReqId:", reqId, "Groups", groups)
1621 # ! [displaygrouplist]
1622
1623 @iswrapper
1624 # ! [displaygroupupdated]
1625 def displayGroupUpdated(self, reqId: int, contractInfo: str):
1626 super().displayGroupUpdated(reqId, contractInfo)
1627 print("DisplayGroupUpdated. ReqId:", reqId, "ContractInfo:", contractInfo)
1628 # ! [displaygroupupdated]
1629
1630 @printWhenExecuting
1631 def whatIfOrderOperations(self):
1632 # ! [whatiflimitorder]
1633 whatIfOrder = OrderSamples.LimitOrder("SELL", 5, 70)
1634 whatIfOrder.whatIf = True
1635 self.placeOrder(self.nextOrderId(), ContractSamples.USStockAtSmart(), whatIfOrder)
1636 # ! [whatiflimitorder]
1637 time.sleep(2)
1638
1639 @printWhenExecuting
1640 def orderOperations_req(self):
1641 # Requesting the next valid id
1642 # ! [reqids]
1643 # The parameter is always ignored.
1644 self.reqIds(-1)
1645 # ! [reqids]
1646
1647 # Requesting all open orders
1648 # ! [reqallopenorders]
1649 self.reqAllOpenOrders()
1650 # ! [reqallopenorders]
1651
1652 # Taking over orders to be submitted via TWS
1653 # ! [reqautoopenorders]
1654 self.reqAutoOpenOrders(True)
1655 # ! [reqautoopenorders]
1656
1657 # Requesting this API client's orders
1658 # ! [reqopenorders]
1659 self.reqOpenOrders()
1660 # ! [reqopenorders]
1661
1662
1663 # Placing/modifying an order - remember to ALWAYS increment the
1664 # nextValidId after placing an order so it can be used for the next one!
1665 # Note if there are multiple clients connected to an account, the
1666 # order ID must also be greater than all order IDs returned for orders
1667 # to orderStatus and openOrder to this client.
1668
1669 # ! [order_submission]
1670 self.simplePlaceOid = self.nextOrderId()
1671 self.placeOrder(self.simplePlaceOid, ContractSamples.USStock(),
1672 OrderSamples.LimitOrder("SELL", 1, 50))
1673 # ! [order_submission]
1674
1675 # ! [faorderoneaccount]
1676 faOrderOneAccount = OrderSamples.MarketOrder("BUY", 100)
1677 # Specify the Account Number directly
1678 faOrderOneAccount.account = "DU119915"
1679 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(), faOrderOneAccount)
1680 # ! [faorderoneaccount]
1681
1682 # ! [faordergroupequalquantity]
1683 faOrderGroupEQ = OrderSamples.LimitOrder("SELL", 200, 2000)
1684 faOrderGroupEQ.faGroup = "Group_Equal_Quantity"
1685 faOrderGroupEQ.faMethod = "EqualQuantity"
1686 self.placeOrder(self.nextOrderId(), ContractSamples.SimpleFuture(), faOrderGroupEQ)
1687 # ! [faordergroupequalquantity]
1688
1689 # ! [faordergrouppctchange]
1690 faOrderGroupPC = OrderSamples.MarketOrder("BUY", 0)
1691 # You should not specify any order quantity for PctChange allocation method
1692 faOrderGroupPC.faGroup = "Pct_Change"
1693 faOrderGroupPC.faMethod = "PctChange"
1694 faOrderGroupPC.faPercentage = "100"
1695 self.placeOrder(self.nextOrderId(), ContractSamples.EurGbpFx(), faOrderGroupPC)
1696 # ! [faordergrouppctchange]
1697
1698 # ! [faorderprofile]
1699 faOrderProfile = OrderSamples.LimitOrder("BUY", 200, 100)
1700 faOrderProfile.faProfile = "Percent_60_40"
1701 self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), faOrderProfile)
1702 # ! [faorderprofile]
1703
1704 # ! [modelorder]
1705 modelOrder = OrderSamples.LimitOrder("BUY", 200, 100)
1706 modelOrder.account = "DF12345"
1707 modelOrder.modelCode = "Technology" # model for tech stocks first created in TWS
1708 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(), modelOrder)
1709 # ! [modelorder]
1710
1711 self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtBOX(),
1712 OrderSamples.Block("BUY", 50, 20))
1713 self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtBOX(),
1714 OrderSamples.BoxTop("SELL", 10))
1715 self.placeOrder(self.nextOrderId(), ContractSamples.FutureComboContract(),
1716 OrderSamples.ComboLimitOrder("SELL", 1, 1, False))
1717 self.placeOrder(self.nextOrderId(), ContractSamples.StockComboContract(),
1718 OrderSamples.ComboMarketOrder("BUY", 1, True))
1719 self.placeOrder(self.nextOrderId(), ContractSamples.OptionComboContract(),
1720 OrderSamples.ComboMarketOrder("BUY", 1, False))
1721 self.placeOrder(self.nextOrderId(), ContractSamples.StockComboContract(),
1722 OrderSamples.LimitOrderForComboWithLegPrices("BUY", 1, [10, 5], True))
1723 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1724 OrderSamples.Discretionary("SELL", 1, 45, 0.5))
1725 self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtBOX(),
1726 OrderSamples.LimitIfTouched("BUY", 1, 30, 34))
1727 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1728 OrderSamples.LimitOnClose("SELL", 1, 34))
1729 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1730 OrderSamples.LimitOnOpen("BUY", 1, 35))
1731 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1732 OrderSamples.MarketIfTouched("BUY", 1, 30))
1733 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1734 OrderSamples.MarketOnClose("SELL", 1))
1735 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1736 OrderSamples.MarketOnOpen("BUY", 1))
1737 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1738 OrderSamples.MarketOrder("SELL", 1))
1739 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1740 OrderSamples.MarketToLimit("BUY", 1))
1741 self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtIse(),
1742 OrderSamples.MidpointMatch("BUY", 1))
1743 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1744 OrderSamples.MarketToLimit("BUY", 1))
1745 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1746 OrderSamples.Stop("SELL", 1, 34.4))
1747 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1748 OrderSamples.StopLimit("BUY", 1, 35, 33))
1749 self.placeOrder(self.nextOrderId(), ContractSamples.SimpleFuture(),
1750 OrderSamples.StopWithProtection("SELL", 1, 45))
1751 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1752 OrderSamples.SweepToFill("BUY", 1, 35))
1753 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1754 OrderSamples.TrailingStop("SELL", 1, 0.5, 30))
1755 self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1756 OrderSamples.TrailingStopLimit("BUY", 1, 2, 5, 50))
1757 self.placeOrder(self.nextOrderId(), ContractSamples.USOptionContract(),
1758 OrderSamples.Volatility("SELL", 1, 5, 2))
1759
1760 self.bracketSample()
1761
1762 self.conditionSamples()
1763
1764 self.hedgeSample()
1765
1766 # NOTE: the following orders are not supported for Paper Trading
1767 # self.placeOrder(self.nextOrderId(), ContractSamples.USStock(), OrderSamples.AtAuction("BUY", 100, 30.0))
1768 # self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtBOX(), OrderSamples.AuctionLimit("SELL", 10, 30.0, 2))
1769 # self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtBOX(), OrderSamples.AuctionPeggedToStock("BUY", 10, 30, 0.5))
1770 # self.placeOrder(self.nextOrderId(), ContractSamples.OptionAtBOX(), OrderSamples.AuctionRelative("SELL", 10, 0.6))
1771 # self.placeOrder(self.nextOrderId(), ContractSamples.SimpleFuture(), OrderSamples.MarketWithProtection("BUY", 1))
1772 # self.placeOrder(self.nextOrderId(), ContractSamples.USStock(), OrderSamples.PassiveRelative("BUY", 1, 0.5))
1773
1774 # 208813720 (GOOG)
1775 # self.placeOrder(self.nextOrderId(), ContractSamples.USStock(),
1776 # OrderSamples.PeggedToBenchmark("SELL", 100, 33, True, 0.1, 1, 208813720, "ISLAND", 750, 650, 800))
1777
1778 # STOP ADJUSTABLE ORDERS
1779 # Order stpParent = OrderSamples.Stop("SELL", 100, 30)
1780 # stpParent.OrderId = self.nextOrderId()
1781 # self.placeOrder(stpParent.OrderId, ContractSamples.EuropeanStock(), stpParent)
1782 # self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), OrderSamples.AttachAdjustableToStop(stpParent, 35, 32, 33))
1783 # self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), OrderSamples.AttachAdjustableToStopLimit(stpParent, 35, 33, 32, 33))
1784 # self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), OrderSamples.AttachAdjustableToTrail(stpParent, 35, 32, 32, 1, 0))
1785
1786 # Order lmtParent = OrderSamples.LimitOrder("BUY", 100, 30)
1787 # lmtParent.OrderId = self.nextOrderId()
1788 # self.placeOrder(lmtParent.OrderId, ContractSamples.EuropeanStock(), lmtParent)
1789 # Attached TRAIL adjusted can only be attached to LMT parent orders.
1790 # self.placeOrder(self.nextOrderId(), ContractSamples.EuropeanStock(), OrderSamples.AttachAdjustableToTrailAmount(lmtParent, 34, 32, 33, 0.008))
1791 self.algoSamples()
1792
1793 self.ocaSample()
1794
1795 # Request the day's executions
1796 # ! [reqexecutions]
1797 self.reqExecutions(10001, ExecutionFilter())
1798 # ! [reqexecutions]
1799
1800 # Requesting completed orders
1801 # ! [reqcompletedorders]
1802 self.reqCompletedOrders(False)
1803 # ! [reqcompletedorders]
1804
1805
1806 def orderOperations_cancel(self):
1807 if self.simplePlaceOid is not None:
1808 # ! [cancelorder]
1809 self.cancelOrder(self.simplePlaceOid)
1810 # ! [cancelorder]
1811
1812 # Cancel all orders for all accounts
1813 # ! [reqglobalcancel]
1814 self.reqGlobalCancel()
1815 # ! [reqglobalcancel]
1816
1817 def rerouteCFDOperations(self):
1818 # ! [reqmktdatacfd]
1819 self.reqMktData(16001, ContractSamples.USStockCFD(), "", False, False, [])
1820 self.reqMktData(16002, ContractSamples.EuropeanStockCFD(), "", False, False, []);
1821 self.reqMktData(16003, ContractSamples.CashCFD(), "", False, False, []);
1822 # ! [reqmktdatacfd]
1823
1824 # ! [reqmktdepthcfd]
1825 self.reqMktDepth(16004, ContractSamples.USStockCFD(), 10, False, []);
1826 self.reqMktDepth(16005, ContractSamples.EuropeanStockCFD(), 10, False, []);
1827 self.reqMktDepth(16006, ContractSamples.CashCFD(), 10, False, []);
1828 # ! [reqmktdepthcfd]
1829
1830 def marketRuleOperations(self):
1831 self.reqContractDetails(17001, ContractSamples.USStock())
1832 self.reqContractDetails(17002, ContractSamples.Bond())
1833
1834 # ! [reqmarketrule]
1835 self.reqMarketRule(26)
1836 self.reqMarketRule(239)
1837 # ! [reqmarketrule]
1838
1839 @iswrapper
1840 # ! [execdetails]
1841 def execDetails(self, reqId: int, contract: Contract, execution: Execution):
1842 super().execDetails(reqId, contract, execution)
1843 print("ExecDetails. ReqId:", reqId, "Symbol:", contract.symbol, "SecType:", contract.secType, "Currency:", contract.currency, execution)
1844 # ! [execdetails]
1845
1846 @iswrapper
1847 # ! [execdetailsend]
1848 def execDetailsEnd(self, reqId: int):
1849 super().execDetailsEnd(reqId)
1850 print("ExecDetailsEnd. ReqId:", reqId)
1851 # ! [execdetailsend]
1852
1853 @iswrapper
1854 # ! [commissionreport]
1855 def commissionReport(self, commissionReport: CommissionReport):
1856 super().commissionReport(commissionReport)
1857 print("CommissionReport.", commissionReport)
1858 # ! [commissionreport]
1859
1860 @iswrapper
1861 # ! [currenttime]
1862 def currentTime(self, time:int):
1863 super().currentTime(time)
1864 print("CurrentTime:", datetime.datetime.fromtimestamp(time).strftime("%Y%m%d %H:%M:%S"))
1865 # ! [currenttime]
1866
1867 @iswrapper
1868 # ! [completedorder]
1869 def completedOrder(self, contract: Contract, order: Order,
1870 orderState: OrderState):
1871 super().completedOrder(contract, order, orderState)
1872 print("CompletedOrder. PermId:", order.permId, "ParentPermId:", utils.longToStr(order.parentPermId), "Account:", order.account,
1873 "Symbol:", contract.symbol, "SecType:", contract.secType, "Exchange:", contract.exchange,
1874 "Action:", order.action, "OrderType:", order.orderType, "TotalQty:", order.totalQuantity,
1875 "CashQty:", order.cashQty, "FilledQty:", order.filledQuantity,
1876 "LmtPrice:", order.lmtPrice, "AuxPrice:", order.auxPrice, "Status:", orderState.status,
1877 "Completed time:", orderState.completedTime, "Completed Status:" + orderState.completedStatus)
1878 # ! [completedorder]
1879
1880 @iswrapper
1881 # ! [completedordersend]
1882 def completedOrdersEnd(self):
1883 super().completedOrdersEnd()
1884 print("CompletedOrdersEnd")
1885 # ! [completedordersend]
1886
1887def main():
1888 SetupLogger()
1889 logging.debug("now is %s", datetime.datetime.now())
1890 logging.getLogger().setLevel(logging.ERROR)
1891
1892 cmdLineParser = argparse.ArgumentParser("api tests")
1893 # cmdLineParser.add_option("-c", action="store_True", dest="use_cache", default = False, help = "use the cache")
1894 # cmdLineParser.add_option("-f", action="store", type="string", dest="file", default="", help="the input file")
1895 cmdLineParser.add_argument("-p", "--port", action="store", type=int,
1896 dest="port", default=7497, help="The TCP port to use")
1897 cmdLineParser.add_argument("-C", "--global-cancel", action="store_true",
1898 dest="global_cancel", default=False,
1899 help="whether to trigger a globalCancel req")
1900 args = cmdLineParser.parse_args()
1901 print("Using args", args)
1902 logging.debug("Using args %s", args)
1903 # print(args)
1904
1905
1906 # enable logging when member vars are assigned
1907 from ibapi import utils
1908 Order.__setattr__ = utils.setattr_log
1909 Contract.__setattr__ = utils.setattr_log
1910 DeltaNeutralContract.__setattr__ = utils.setattr_log
1911 TagValue.__setattr__ = utils.setattr_log
1912 TimeCondition.__setattr__ = utils.setattr_log
1913 ExecutionCondition.__setattr__ = utils.setattr_log
1914 MarginCondition.__setattr__ = utils.setattr_log
1915 PriceCondition.__setattr__ = utils.setattr_log
1916 PercentChangeCondition.__setattr__ = utils.setattr_log
1917 VolumeCondition.__setattr__ = utils.setattr_log
1918
1919 # from inspect import signature as sig
1920 # import code code.interact(local=dict(globals(), **locals()))
1921 # sys.exit(1)
1922
1923 # tc = TestClient(None)
1924 # tc.reqMktData(1101, ContractSamples.USStockAtSmart(), "", False, None)
1925 # print(tc.reqId2nReq)
1926 # sys.exit(1)
1927
1928 try:
1929 app = TestApp()
1930 if args.global_cancel:
1931 app.globalCancelOnly = True
1932 # ! [connect]
1933 app.connect("127.0.0.1", args.port, clientId=0)
1934 # ! [connect]
1935 print("serverVersion:%s connectionTime:%s" % (app.serverVersion(),
1936 app.twsConnectionTime()))
1937
1938 # ! [clientrun]
1939 app.run()
1940 # ! [clientrun]
1941 except:
1942 raise
1943 finally:
1944 app.dumpTestCoverageSituation()
1945 app.dumpReqAnsErrSituation()
1946
1947
1948if __name__ == "__main__":
1949 main()