├── alert_telegram.py ├── available_ticktypes.py ├── calculate_20SMA_Pandas.py ├── calculate_20SMA_manually.py ├── create_order.py ├── disconnect_error_fix └── reader.py ├── implement_stoploss_bracketorder.py ├── retrieve_ask_price_AAPL.py ├── retrieve_ask_price_BTC_Futures.py ├── retrieve_ask_price_EURUSD.py ├── retrieve_ask_price_Gold_commodities.py ├── store_hourly_candles_EURUSD.py └── test_for_connectivity.py /alert_telegram.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | def send(pair, order, stop_order): 4 | #Replace token, chat_id & text variables 5 | text = f'A new trade has been placed in {pair} at {order.lmitPrice} with a stop at {stop_order.auxPrice}' 6 | 7 | token = 'xxx' 8 | params = {'chat_id': xxx, 'text': text, 'parse_mode': 'HTML'} 9 | resp = requests.post('https://api.telegram.org/bot{}/sendMessage'.format(token), params) 10 | 11 | send('EURUSD', order, stop_order) -------------------------------------------------------------------------------- /available_ticktypes.py: -------------------------------------------------------------------------------- 1 | from ibapi.ticktype import TickTypeEnum 2 | 3 | for i in range(91): 4 | print(TickTypeEnum.to_str(i), i) -------------------------------------------------------------------------------- /calculate_20SMA_Pandas.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | from ibapi.contract import Contract 4 | 5 | import threading 6 | import time 7 | 8 | class IBapi(EWrapper, EClient): 9 | def __init__(self): 10 | EClient.__init__(self, self) 11 | def historicalData(self, reqId, bar): 12 | print(f'Time: {bar.date} Close: {bar.close}') 13 | app.data.append([bar.date, bar.close]) 14 | 15 | def run_loop(): 16 | app.run() 17 | 18 | app = IBapi() 19 | app.connect('127.0.0.1', 7497, 123) 20 | 21 | #Start the socket in a thread 22 | api_thread = threading.Thread(target=run_loop, daemon=True) 23 | api_thread.start() 24 | 25 | time.sleep(1) #Sleep interval to allow time for connection to server 26 | 27 | #Create contract object 28 | eurusd_contract = Contract() 29 | eurusd_contract.symbol = 'EUR' 30 | eurusd_contract.secType = 'CASH' 31 | eurusd_contract.exchange = 'IDEALPRO' 32 | eurusd_contract.currency = 'USD' 33 | 34 | app.data = [] #Initialize variable to store candle 35 | 36 | #Request historical candles 37 | app.reqHistoricalData(1, eurusd_contract, '', '2 D', '1 hour', 'MIDPOINT', 0, 2, False, []) 38 | 39 | time.sleep(5) #sleep to allow enough time for data to be returned 40 | 41 | #Working with Pandas DataFrames 42 | import pandas 43 | 44 | df = pandas.DataFrame(app.data, columns=['DateTime', 'Close']) 45 | df['DateTime'] = pandas.to_datetime(df['DateTime'],unit='s') 46 | 47 | 48 | ### Calculate 20 SMA Using Pandas 49 | df['20SMA'] = df['Close'].rolling(20).mean() 50 | print(df.tail(10)) 51 | 52 | 53 | app.disconnect() -------------------------------------------------------------------------------- /calculate_20SMA_manually.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | from ibapi.contract import Contract 4 | 5 | import threading 6 | import time 7 | 8 | class IBapi(EWrapper, EClient): 9 | def __init__(self): 10 | EClient.__init__(self, self) 11 | def historicalData(self, reqId, bar): 12 | print(f'Time: {bar.date} Close: {bar.close}') 13 | app.data.append([bar.date, bar.close]) 14 | 15 | def run_loop(): 16 | app.run() 17 | 18 | app = IBapi() 19 | app.connect('127.0.0.1', 7497, 126) 20 | 21 | #Start the socket in a thread 22 | api_thread = threading.Thread(target=run_loop, daemon=True) 23 | api_thread.start() 24 | 25 | time.sleep(1) #Sleep interval to allow time for connection to server 26 | 27 | #Create contract object 28 | eurusd_contract = Contract() 29 | eurusd_contract.symbol = 'EUR' 30 | eurusd_contract.secType = 'CASH' 31 | eurusd_contract.exchange = 'IDEALPRO' 32 | eurusd_contract.currency = 'USD' 33 | 34 | app.data = [] #Initialize variable to store candle 35 | 36 | #Request historical candles 37 | app.reqHistoricalData(1, eurusd_contract, '', '2 D', '1 hour', 'MIDPOINT', 0, 1, False, []) 38 | 39 | time.sleep(5) #sleep to allow enough time for data to be returned 40 | 41 | 42 | ### Calculate 20 SMA without a library 43 | total = 0 44 | for i in app.data[-20:]: 45 | total += float(i[1]) 46 | 47 | print('20SMA =', round(total/20, 5)) 48 | 49 | 50 | app.disconnect() -------------------------------------------------------------------------------- /create_order.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | from ibapi.contract import Contract 4 | from ibapi.order import * 5 | from ibapi.utils import iswrapper 6 | 7 | import threading 8 | import time 9 | 10 | class IBapi(EWrapper, EClient): 11 | def __init__(self): 12 | EClient.__init__(self, self) 13 | 14 | def historicalData(self, reqId, bar): 15 | print(f'Time: {bar.date} Close: {bar.close}') 16 | app.data.append([bar.date, bar.close]) 17 | 18 | @iswrapper 19 | def nextValidId(self, orderId: int): 20 | super().nextValidId(orderId) 21 | self.nextorderId = orderId 22 | print('The next valid order id is: ', self.nextorderId) 23 | 24 | def orderStatus(self, orderId, status, filled, remaining, avgFullPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice): 25 | print('orderStatus - orderid:', orderId, 'status:', status, 'filled', filled, 'remaining', remaining, 'lastFillPrice', lastFillPrice) 26 | 27 | def openOrder(self, orderId, contract, order, orderState): 28 | print('openOrder id:', orderId, contract.symbol, contract.secType, '@', contract.exchange, ':', order.action, order.orderType, order.totalQuantity, orderState.status) 29 | 30 | def execDetails(self, reqId, contract, execution): 31 | print('Order Executed: ', reqId, contract.symbol, contract.secType, contract.currency, execution.execId, execution.orderId, execution.shares, execution.lastLiquidity) 32 | 33 | 34 | def run_loop(): 35 | app.run() 36 | 37 | #Function to create FX Order contract 38 | def FX_order(symbol): 39 | contract = Contract() 40 | contract.symbol = symbol[:3] 41 | contract.secType = 'CASH' 42 | contract.exchange = 'IDEALPRO' 43 | contract.currency = symbol[3:] 44 | return contract 45 | 46 | app = IBapi() 47 | app.connect('127.0.0.1', 7497, 123) 48 | 49 | app.nextorderId = None 50 | 51 | #Start the socket in a thread 52 | api_thread = threading.Thread(target=run_loop, daemon=True) 53 | api_thread.start() 54 | 55 | #Check if the API is connected via orderid 56 | while True: 57 | if isinstance(app.nextorderId, int): 58 | print('connected') 59 | print() 60 | break 61 | else: 62 | print('waiting for connection') 63 | time.sleep(1) 64 | 65 | #Create order object 66 | order = Order() 67 | order.action = 'BUY' 68 | order.totalQuantity = 1000 69 | order.orderType = 'LMT' 70 | order.lmtPrice = '1.10' 71 | 72 | #place order 73 | app.placeOrder(app.nextorderId, FX_order('EURUSD'), order) 74 | #app.nextorderId += 1 75 | 76 | time.sleep(3) 77 | 78 | #cancel order 79 | print('cancelling order') 80 | app.cancelOrder(app.nextorderId) 81 | 82 | time.sleep(3) 83 | app.disconnect() -------------------------------------------------------------------------------- /disconnect_error_fix/reader.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (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 | 6 | 7 | """ 8 | This code fix is by Thane Brooker. Link: https://idalpha-devops.blogspot.com/2019/11/interactive-brokers-tws-api-python.html 9 | 10 | The EReader runs in a separate threads and is responsible for receiving the 11 | incoming messages. 12 | It will read the packets from the wire, use the low level IB messaging to 13 | remove the size prefix and put the rest in a Queue. 14 | """ 15 | import time 16 | import logging 17 | from threading import Thread 18 | 19 | from ibapi import comm 20 | 21 | 22 | logger = logging.getLogger(__name__) 23 | 24 | 25 | class EReader(Thread): 26 | def __init__(self, conn, msg_queue): 27 | super().__init__() 28 | self.conn = conn 29 | self.msg_queue = msg_queue 30 | 31 | def run(self): 32 | try: 33 | buf = b"" 34 | while self.conn.isConnected(): 35 | 36 | try: 37 | data = self.conn.recvMsg() 38 | logger.debug("reader loop, recvd size %d", len(data)) 39 | buf += data 40 | 41 | except OSError as err: 42 | #If connection is disconnected, Windows will generate error 10038 43 | if err.errno == 10038: 44 | 45 | #Wait up to 1 second for disconnect confirmation 46 | waitUntil = time.time() + 1 47 | while time.time() < waitUntil: 48 | if not self.conn.isConnected(): 49 | break 50 | time.sleep(.1) 51 | 52 | if not self.conn.isConnected(): 53 | logger.debug("Ignoring OSError: {0}".format(err)) 54 | break 55 | 56 | #Disconnect wasn't received or error != 10038 57 | raise 58 | 59 | while len(buf) > 0: 60 | (size, msg, buf) = comm.read_msg(buf) 61 | #logger.debug("resp %s", buf.decode('ascii')) 62 | logger.debug("size:%d msg.size:%d msg:|%s| buf:%s|", size, 63 | len(msg), buf, "|") 64 | 65 | if msg: 66 | self.msg_queue.put(msg) 67 | else: 68 | logger.debug("more incoming packet(s) are needed ") 69 | break 70 | 71 | logger.debug("EReader thread finished") 72 | except: 73 | logger.exception('unhandled exception in EReader thread') 74 | 75 | -------------------------------------------------------------------------------- /implement_stoploss_bracketorder.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | from ibapi.contract import Contract 4 | from ibapi.order import * 5 | from ibapi.utils import iswrapper 6 | 7 | import threading 8 | import time 9 | 10 | class IBapi(EWrapper, EClient): 11 | 12 | def __init__(self): 13 | EClient.__init__(self, self) 14 | 15 | def historicalData(self, reqId, bar): 16 | print(f'Time: {bar.date} Close: {bar.close}') 17 | app.data.append([bar.date, bar.close]) 18 | 19 | @iswrapper 20 | def nextValidId(self, orderId: int): 21 | super().nextValidId(orderId) 22 | self.nextorderId = orderId 23 | print('The next valid order id is: ', self.nextorderId) 24 | 25 | def orderStatus(self, orderId, status, filled, remaining, avgFullPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice): 26 | print('orderStatus - orderid:', orderId, 'status:', status, 'filled', filled, 'remaining', remaining, 'lastFillPrice', lastFillPrice) 27 | 28 | def openOrder(self, orderId, contract, order, orderState): 29 | print('openOrder id:', orderId, contract.symbol, contract.secType, '@', contract.exchange, ':', order.action, order.orderType, order.totalQuantity, orderState.status) 30 | 31 | def execDetails(self, reqId, contract, execution): 32 | print('Order Executed: ', reqId, contract.symbol, contract.secType, contract.currency, execution.execId, execution.orderId, execution.shares, execution.lastLiquidity) 33 | 34 | 35 | def run_loop(): 36 | app.run() 37 | 38 | def FX_order(symbol): 39 | contract = Contract() 40 | contract.symbol = symbol[:3] 41 | contract.secType = 'CASH' 42 | contract.exchange = 'IDEALPRO' 43 | contract.currency = symbol[3:] 44 | return contract 45 | 46 | app = IBapi() 47 | app.connect('127.0.0.1', 7497, 123) 48 | 49 | app.nextorderId = None 50 | 51 | #Start the socket in a thread 52 | api_thread = threading.Thread(target=run_loop, daemon=True) 53 | api_thread.start() 54 | 55 | #Check if the API is connected via orderid 56 | while True: 57 | if isinstance(app.nextorderId, int): 58 | print('connected') 59 | print() 60 | break 61 | else: 62 | print('waiting for connection') 63 | time.sleep(1) 64 | 65 | #Create order object 66 | order = Order() 67 | order.action = 'BUY' 68 | order.totalQuantity = 1000 69 | order.orderType = 'LMT' 70 | order.lmtPrice = '1.10' 71 | order.orderId = app.nextorderId 72 | app.nextorderId += 1 73 | order.transmit = False 74 | 75 | #Create stop loss order object 76 | stop_order = Order() 77 | stop_order.action = 'SELL' 78 | stop_order.totalQuantity = 1000 79 | stop_order.orderType = 'STP' 80 | stop_order.auxPrice = '1.09' 81 | stop_order.orderId = app.nextorderId 82 | app.nextorderId += 1 83 | stop_order.parentId = order.orderId 84 | order.transmit = True 85 | 86 | #place orders 87 | app.placeOrder(order.orderId, FX_order('EURUSD'), order) 88 | app.placeOrder(stop_order.orderId, FX_order('EURUSD'), stop_order) 89 | time.sleep(10) 90 | 91 | #cancel order 92 | print() 93 | print('cancelling order') 94 | app.cancelOrder(order.orderId) 95 | 96 | time.sleep(3) 97 | app.disconnect() -------------------------------------------------------------------------------- /retrieve_ask_price_AAPL.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | import threading 4 | import time 5 | 6 | from ibapi.contract import Contract 7 | #from ibapi.ticktype import TickTypeEnum 8 | 9 | class IBapi(EWrapper, EClient): 10 | def __init__(self): 11 | EClient.__init__(self, self) 12 | def tickPrice(self, reqId, tickType, price, attrib): 13 | if tickType == 2 and reqId == 1: 14 | print('The current ask price is: ', price) 15 | 16 | def run_loop(): 17 | app.run() 18 | 19 | app = IBapi() 20 | app.connect('127.0.0.1', 7497, 58) 21 | 22 | #Start the socket in a thread 23 | api_thread = threading.Thread(target=run_loop, daemon=True) 24 | api_thread.start() 25 | 26 | time.sleep(1) #Sleep interval to allow time for connection to server 27 | 28 | #Create contract object 29 | apple_contract = Contract() 30 | apple_contract.symbol = 'AAPL' 31 | apple_contract.secType = 'STK' 32 | apple_contract.exchange = 'SMART' 33 | apple_contract.currency = 'USD' 34 | 35 | #Request Market Data 36 | app.reqMktData(1, apple_contract, '', False, False, []) 37 | 38 | time.sleep(10) #Sleep interval to allow time for incoming price data 39 | app.disconnect() -------------------------------------------------------------------------------- /retrieve_ask_price_BTC_Futures.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | import threading 4 | import time 5 | 6 | from ibapi.contract import Contract 7 | #from ibapi.ticktype import TickTypeEnum 8 | 9 | class IBapi(EWrapper, EClient): 10 | def __init__(self): 11 | EClient.__init__(self, self) 12 | def tickPrice(self, reqId, tickType, price, attrib): 13 | if tickType == 2 and reqId == 1: 14 | print('The current ask price is: ', price) 15 | 16 | def run_loop(): 17 | app.run() 18 | 19 | app = IBapi() 20 | app.connect('127.0.0.1', 7497, 123) 21 | 22 | #Start the socket in a thread 23 | api_thread = threading.Thread(target=run_loop, daemon=True) 24 | api_thread.start() 25 | 26 | time.sleep(1) #Sleep interval to allow time for connection to server 27 | 28 | #Create contract object 29 | BTC_futures__contract = Contract() 30 | BTC_futures__contract.symbol = 'BRR' 31 | BTC_futures__contract.secType = 'FUT' 32 | BTC_futures__contract.exchange = 'CMECRYPTO' 33 | BTC_futures__contract.lastTradeDateOrContractMonth = '202003' 34 | 35 | #Request Market Data 36 | app.reqMktData(1, BTC_futures__contract, '', False, False, []) 37 | 38 | time.sleep(10) #Sleep interval to allow time for incoming price data 39 | app.disconnect() -------------------------------------------------------------------------------- /retrieve_ask_price_EURUSD.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | import threading 4 | import time 5 | 6 | from ibapi.contract import Contract 7 | #from ibapi.ticktype import TickTypeEnum 8 | 9 | class IBapi(EWrapper, EClient): 10 | def __init__(self): 11 | EClient.__init__(self, self) 12 | def tickPrice(self, reqId, tickType, price, attrib): 13 | if tickType == 2 and reqId == 1: 14 | print('The current ask price is: ', price) 15 | 16 | def run_loop(): 17 | app.run() 18 | 19 | app = IBapi() 20 | app.connect('127.0.0.1', 7497, 58) 21 | 22 | #Start the socket in a thread 23 | api_thread = threading.Thread(target=run_loop, daemon=True) 24 | api_thread.start() 25 | 26 | time.sleep(1) #Sleep interval to allow time for connection to server 27 | 28 | #Create contract object 29 | eurusd_contract = Contract() 30 | eurusd_contract.symbol = 'EUR' 31 | eurusd_contract.secType = 'CASH' 32 | eurusd_contract.exchange = 'IDEALPRO' 33 | eurusd_contract.currency = 'USD' 34 | 35 | #Request Market Data 36 | app.reqMktData(1, eurusd_contract, '', False, False, []) 37 | 38 | time.sleep(10) #Sleep interval to allow time for incoming price data 39 | app.disconnect() -------------------------------------------------------------------------------- /retrieve_ask_price_Gold_commodities.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | import threading 4 | import time 5 | 6 | from ibapi.contract import Contract 7 | #from ibapi.ticktype import TickTypeEnum 8 | 9 | class IBapi(EWrapper, EClient): 10 | def __init__(self): 11 | EClient.__init__(self, self) 12 | def tickPrice(self, reqId, tickType, price, attrib): 13 | if tickType == 2 and reqId == 1: 14 | print('The current ask price is: ', price) 15 | 16 | def run_loop(): 17 | app.run() 18 | 19 | app = IBapi() 20 | app.connect('127.0.0.1', 7497, 123) 21 | 22 | #Start the socket in a thread 23 | api_thread = threading.Thread(target=run_loop, daemon=True) 24 | api_thread.start() 25 | 26 | time.sleep(1) #Sleep interval to allow time for connection to server 27 | 28 | #Create contract object 29 | XAUUSD_contract = Contract() 30 | XAUUSD_contract.symbol = 'XAUUSD' 31 | XAUUSD_contract.secType = 'CMDTY' 32 | XAUUSD_contract.exchange = 'SMART' 33 | XAUUSD_contract.currency = 'USD' 34 | 35 | #Request Market Data 36 | app.reqMktData(1, XAUUSD_contract, '', False, False, []) 37 | 38 | time.sleep(10) #Sleep interval to allow time for incoming price data 39 | app.disconnect() -------------------------------------------------------------------------------- /store_hourly_candles_EURUSD.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | from ibapi.contract import Contract 4 | 5 | import threading 6 | import time 7 | 8 | class IBapi(EWrapper, EClient): 9 | def __init__(self): 10 | EClient.__init__(self, self) 11 | def historicalData(self, reqId, bar): 12 | print(f'Time: {bar.date} Close: {bar.close}') 13 | app.data.append([bar.date, bar.close]) 14 | 15 | def run_loop(): 16 | app.run() 17 | 18 | app = IBapi() 19 | app.connect('127.0.0.1', 7497, 123) 20 | 21 | #Start the socket in a thread 22 | api_thread = threading.Thread(target=run_loop, daemon=True) 23 | api_thread.start() 24 | 25 | time.sleep(1) #Sleep interval to allow time for connection to server 26 | 27 | #Create contract object 28 | eurusd_contract = Contract() 29 | eurusd_contract.symbol = 'EUR' 30 | eurusd_contract.secType = 'CASH' 31 | eurusd_contract.exchange = 'IDEALPRO' 32 | eurusd_contract.currency = 'USD' 33 | 34 | app.data = [] #Initialize variable to store candle 35 | 36 | #Request historical candles 37 | app.reqHistoricalData(1, eurusd_contract, '', '2 D', '1 hour', 'MIDPOINT', 0, 2, False, []) 38 | 39 | time.sleep(5) #sleep to allow enough time for data to be returned 40 | 41 | #Working with Pandas DataFrames 42 | import pandas 43 | 44 | df = pandas.DataFrame(app.data, columns=['DateTime', 'Close']) 45 | df['DateTime'] = pandas.to_datetime(df['DateTime'],unit='s') 46 | df.to_csv('EURUSD_Hourly.csv') 47 | 48 | print(df) 49 | 50 | 51 | app.disconnect() -------------------------------------------------------------------------------- /test_for_connectivity.py: -------------------------------------------------------------------------------- 1 | from ibapi.client import EClient 2 | from ibapi.wrapper import EWrapper 3 | 4 | class IBapi(EWrapper, EClient): 5 | def __init__(self): 6 | EClient.__init__(self, self) 7 | 8 | app = IBapi() 9 | app.connect('127.0.0.1', 7497, 123) 10 | app.run() 11 | 12 | ''' 13 | #Uncomment this section if unable to connect 14 | #and to prevent errors on a reconnect 15 | 16 | import time 17 | time.sleep(2) 18 | app.disconnect() 19 | ''' 20 | --------------------------------------------------------------------------------