def createBracketOrder(origOrder, oID, tif, orderType,price):
#cc = copy.copy(origContract)
bracketoptOrder = Utils.makeOptOrder( Side.flipside(origOrder.m_action), oID, tif, orderType,price,origOrder.m_totalQuantity)
bracketoptOrder.m_parentId = origOrder.m_orderId
return bracketoptOrder
# Example of a IBpy TWS bracker order submission# Derek M Tishler, 2016# DMTishler at gmail dot com
# sample function to create basic contractdef make_contract(self, symbol, sec_type, exch, prim_exch, curr): Contract.m_symbol = symbol Contract.m_secType = sec_type Contract.m_exchange = exch Contract.m_primaryExch = prim_exch Contract.m_currency = curr return Contract
def make_order(self, action, qty, limit = None, profit_take_percent=None, training_stop_percent=None, transmit=True, parentId=None): order = Order()
# is child order? if parentId is not None: order.m_parentId = parentId order.m_action = action order.m_totalQuantity = qty
if profit_take_percent is not None: # This will set up out profit take order.m_orderType = 'LMT' if action == 'BUY': # Rounding is due to FX, we cannot create an order with bad price, and FX book increments at 0.00005 only! order.m_lmtPrice = limit - int(np.around((limit*profit_take_percent)/100.0, 5)/0.00005)*0.00005 elif action == 'SELL': order.m_lmtPrice = limit + int(np.around((limit*profit_take_percent)/100.0, 5)/0.00005)*0.00005 elif training_stop_percent is not None: # This will set up out trailing stop order.m_orderType = 'TRAIL' order.m_training_stop_percent = training_stop_percent elif limit is not None: # A simple limit order order.m_orderType = 'LMT' order.m_lmtPrice = limit else: # A simple market order order.m_orderType = 'MKT' # Important that we only send the order when all children are formed. order.m_transmit = transmit
return order
############### Actual order creation ###################### Same inputs, usualy set up programatically and tracked in order to update orders on the flysymbol = 'EUR.USD'secType = 'CASH'exchange = 'IDEALPRO'oid = 1 #You need to request a valid order id(reqIDs), and also manage them better than order+1 for child orders?ammount = 1000 #1k shareslimit = 1.00000 #limit priceaction = 'BUY'counter_action = 'SELL'
# create parent order(entry)CONTRACT = self.make_contract(symbol, secType, exchange, exchange, 'USD')ORDER = self.make_order(action, abs(int(ammount)), limit, transmit=False)self.con.placeOrder(oid, CONTRACT, ORDER)
# create a profit take order of some kindORDER = self.make_order(counter_action, abs(int(ammount)), limit, profit_take_percent=0.0125, parentId=oid, transmit=False) self.con.placeOrder(oid+1, CONTRACT, ORDER)
# create astop loss order, and THEN transmit(set transmit to true) the entire order by placing this last child order(note inTWS it looks like a tree with parent order and two sub orders inside)ORDER = self.make_order(counter_action, abs(int(ammount)), limit, training_stop_percent=0.5, parentId=oid, transmit=True)self.con.placeOrder(oid+2, CONTRACT, ORDER)
"""
README
======
This file contains Python codes.
Desc : Implementation of Bracket Order, Long with IBPy and a simple order id management
Author: remroc inspired by DerekT and many more ;)
======
"""
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection, message
import time
import datetime as dt
class System:
def __init__(self, symbol, secType, exchange, primary_exchange, currency,
nbshares, action, counter_action,
port=7496):
self.client_id = 1
self.order_ids = [-1]
self.qty = nbshares
self.nbshares = nbshares
self.symbol_id, self.symbol = 0, symbol
self.port = port
self.tws_conn = None
self.bid_price, self.ask_price = 0, 0
self.is_position_opened = False
self.position = 0
self.account_code = None
self.unrealized_pnl, self.realized_pnl = 0, 0
self.secType, self.exchange, self.primary_exchange, self.currency = secType, exchange, primary_exchange, currency
self.limit, self.action, self.counter_action = 0, action, counter_action
def error_handler(self, msg):
if msg.typeName == "error" and msg.id != -1:
print "Server Error:", msg
def server_handler(self, msg):
if msg.typeName == "nextValidId":
self.order_id = msg.orderId
elif msg.typeName == "managedAccounts":
self.account_code = msg.accountsList
elif msg.typeName == "updatePortfolio" \
and msg.contract.m_symbol == self.symbol:
self.unrealized_pnl = msg.unrealizedPNL
self.realized_pnl = msg.realizedPNL
self.position = msg.position
elif msg.typeName == "error" and msg.id != -1:
return
def next_order_id(self):
return self.order_ids[-1]
def save_order_id(self,msg):
if self.order_ids[-1] < msg.orderId:
self.order_ids.append(msg.orderId)
print "self.order_ids = '[%s]'" % ', '.join(map(str, self.order_ids))
elif not self.order_ids[-1] < msg.orderId:
self.tws_conn.reqIds(1)
def tick_event(self, msg):
if msg.field == 1:
self.bid_price = msg.price
elif msg.field == 2:
self.ask_price = msg.price
print ("%s - self.ask_price '%s', self.bid_price '%s', " % (dt.datetime.now(), self.ask_price, self.bid_price) )
self.perform_trade_logic()
def perform_trade_logic(self):
if (self.is_position_opened == False and self.next_order_id() > -1):
self.limit=self.bid_price
print("dans trade logic avec self.bid_price = '%s'" % self.limit)
# create parent order(entry)
CONTRACT = self.create_contract(self.symbol, self.secType, self.exchange, self.primary_exchange, self.currency)
ORDER = self.create_bracketorder(self.action, abs(int(self.nbshares)), self.limit+150, transmit=False)
self.tws_conn.placeOrder(self.next_order_id(), CONTRACT, ORDER)
print("2/Bracket order - parent orderId = '%s'" % self.next_order_id())
# create a profit take order of some kind
ORDER = self.create_bracketorder(self.counter_action, abs(int(self.nbshares)), self.limit, profit_price=self.limit+300, parentId=self.next_order_id(),
transmit=False)
self.tws_conn.placeOrder(self.next_order_id()+1, CONTRACT, ORDER)
# create astop loss order, and THEN transmit(set transmit to true) the entire order by placing this last child order(note inTWS it looks like a tree with parent order and two sub orders inside)
ORDER = self.create_bracketorder(self.counter_action, abs(int(self.nbshares)), self.limit, stop_price=self.limit, parentId=self.next_order_id(),
transmit=True)
self.tws_conn.placeOrder(self.next_order_id()+2, CONTRACT, ORDER)
self.is_position_opened = True
elif self.is_position_opened:
self.monitor_position()
def monitor_position(self):
print 'Position:%s UPnL:%s RPnL:%s' % (self.position,
self.unrealized_pnl,
self.realized_pnl)
def create_contract(self, symbol, sec_type, exch, prim_exch, curr):
contract = Contract()
contract.m_symbol = symbol
contract.m_secType = sec_type
contract.m_exchange = exch
contract.m_primaryExch = prim_exch
contract.m_currency = curr
return contract
def create_order(self, order_type, quantity, action):
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
def create_bracketorder(self, action, qty, limit=None, profit_price=None, stop_price=None,
transmit=True, parentId=None):
# https://www.interactivebrokers.com/en/software/api/apiguide/tables/supported_order_types.htm
# https://www.interactivebrokers.com/en/software/api/apiguide/java/order.htm
order = Order()
# is child order?
if parentId is not None:
order.m_parentId = parentId
order.m_action = action
order.m_totalQuantity =
qty
if profit_price is not None:
# This will set up out profit take
order.m_orderType = 'LMT'
if action == 'BUY':
# Precise the LMT price to close profit
order.m_lmtPrice = profit_price
elif action == 'SELL':
order.m_lmtPrice = profit_price
print("4/Bracket order - stop profit price = '%s'" % order.m_lmtPrice)
elif stop_price is not None:
# This will set up out trailing stop
order.m_orderType = 'Stop'
if action == 'BUY':
# Precise the Stop Loss price
order.m_auxPrice = stop_price
elif action == 'SELL':
order.m_auxPrice = stop_price
print("3/Bracket order - stop loss price = '%s'" % order.m_auxPrice)
elif limit is not None:
# A simple limit order
order.m_orderType = 'STP'
if action == 'BUY':
# Precise the STP price to invest
order.m_auxPrice = limit
elif action == 'SELL':
order.m_auxPrice = limit
print("1/Bracket order - invest price = '%s'" % order.m_auxPrice)
else:
# A simple market order
order.m_orderType = 'MKT'
# Important that we only send the order when all children are formed.
order.m_transmit = transmit
return
order
def request_market_data(self, symbol_id, symbol):
contract = self.create_contract(symbol,
secType,
exchange,
primary_exchange,
currency)
self.tws_conn.reqMktData(symbol_id, contract, '', False)
time.sleep(1)
def cancel_market_data(self, symbol):
self.tws_conn.cancelMktData(symbol)
time.sleep(1)
def request_account_updates(self, account_code):
self.tws_conn.reqAccountUpdates(True, account_code)
def connect_to_tws(self):
self.tws_conn = Connection.create(port=self.port,
clientId=self.client_id)
self.tws_conn.connect()
def disconnect_from_tws(self):
if self.tws_conn is not None:
self.tws_conn.disconnect()
def register_callback_functions(self):
# Assign server messages handling function.
self.tws_conn.registerAll(self.server_handler)
# Assign error handling function.
self.tws_conn.register(self.error_handler, 'Error')
# Handle Order ID sent by Server
self.tws_conn.register(self.save_order_id, 'NextValidId')
# Register market data events.
self.tws_conn.register(self.tick_event,
message.tickPrice,
message.tickSize)
def start(self):
try:
self.connect_to_tws()
self.tws_conn.reqIds(1)
self.register_callback_functions()
self.request_market_data(self.symbol_id, self.symbol)
self.request_account_updates(self.account_code)
while True:
time.sleep(1)
except Exception, e:
print "Error:", e
self.cancel_market_data(self.symbol)
finally:
print "disconnected"
self.disconnect_from_tws()
if __name__ == "__main__":
symbol = "IBDE30"
secType = 'CFD'
exchange = 'SMART'
primary_exchange = 'SMART'
currency = 'EUR'
nbshares = 1
action = 'BUY'
counter_action = 'SELL'
system = System(symbol, secType, exchange, primary_exchange, currency,
nbshares, action, counter_action
)
system.start()
--
You received this message because you are subscribed to the Google Groups "IbPy Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ibpy-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ibpy-discuss/208767d0-9044-4d42-a512-6a11df75952fn%40googlegroups.com.