I am trying to place limit orders with the interactive brokers python api. The limit price is based on the delayed market price. The code for this is the following:
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def tickPrice(self, reqId, tickType, price, attrib):
if tickType == 67 and reqId == 1:
print('The current ask price is: ', price)
def nextValidId(self, orderId):
self.nextOrderId = orderId
self.start()
def start(self):
contract = Contract()
contract.symbol = 'DAI'
contract.secType = 'STK'
contract.exchange = 'SMART'
contract.currency = "EUR"
contract.primaryExchange = "SMART"
self.reqMarketDataType(3)
self.reqMktData(1, contract, '', False, False, [])
time.sleep(1) # allows time for incoming price data
order = Order()
order.action = "Buy"
order.totalQuantity = 1
order.orderType = "LMT"
order.lmtPrice = (self.tickPrice(price) * 1.01)
self.placeOrder(self.nextOrderId, contract, order)
self.disconnect()
def main():
app = TestApp()
app.nextOrderId = 1
app.connect('127.0.0.1', 7497, 12)
app.run()
if __name__ == "__main__":
main()
I always get the error: NameError: name 'price' is not defined
for order.lmtPrice.
How can I take the price attribute from the tickPrice-function to use it for my price limit?
Also, if there are any code suggestions to replace time.sleep(1)
with something more accurate I would be very thankful.
I left a comment on one of your questions about the proper program flow, here is an example. I haven't tested it on a real connection so...
from ibapi.wrapper import EWrapper
from ibapi.client import EClient
from ibapi.contract import Contract
from ibapi.order import Order
contract = Contract()
contract.symbol = 'DAI'
contract.secType = 'STK'
contract.exchange = 'SMART'
contract.currency = "EUR"
contract.primaryExchange = "SMART"
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.data = []
self.workingOrders = {}
def error(self, reqId, errorCode, errorString):
print("Error Id:", reqId, "Code:", errorCode, "Msg:", errorString)
def nextValidId(self, orderId):
self.nextOrderId = orderId
self.start()
def start(self):
self.reqMarketDataType(3)
self.reqMktData(1, contract, '', False, False, [])
def tickPrice(self, reqId, tickType, price, attrib):
if tickType == 67 and reqId == 1:
print('The current ask price is: ', price)
self.checkLogic(price)
def checkLogic(self, ask):
self.data.append(ask)
if self.workingOrders: return
if ask > 10:
order = Order()
order.totalQuantity = 1
order.orderType = "LMT"
order.action = "Buy"
# should lower lmt for buy and you have to round to min price increment
order.lmtPrice = ask # * 1.01
print('placing ord', order)
self.placeOrder(self.nextOrderId, contract, order)
self.workingOrders[self.nextOrderId] = order
self.nextOrderId += 1
elif ask < 5:
print('too low')
def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId,
parentId, lastFillPrice, clientId, whyHeld, mktCapPrice):
print(orderId, status)
if status == 'Filled':
print (self.workingOrders.pop(orderId, "??"))
self.stop()
def stop(self):
print('bye')
self.disconnect()
def main():
app = TestApp()
###### simulate connection
app.nextValidId(100)
app.tickPrice(1, 67, 2, None)
app.tickPrice(1, 67, 20, None)
app.tickPrice(1, 67, 21, None)
app.orderStatus(100, 'Submitted', 1,1,1,1,1,1,1,1,1)
app.orderStatus(100, 'Filled', 1,1,1,1,1,1,1,1,1)
######
# app.connect('127.0.0.1', 7497, 12)
# app.run()
if __name__ == "__main__":
main()