def enterPositions(self, weights, execution_sleep=True): print "----------------------MAKING TRADES ON IB---------------------------" # Instantiate our callback object callback = self.PlaceOrderExample() # Instantiate a socket object, allowing us to call TWS directly. Pass our # callback object so TWS can respond. tws = EPosixClientSocket(callback) # Connect to tws running on localhost tws.eConnect("", 7496, 42) # account updates tws.reqAccountUpdates(True, self.accountNumber) sleep(1) print "available funds: %s" % (self.availableFunds) print "net liquidation value: %s" % (self.netLiquidationValue) ###DELAY UNTIL MARKET HOURS if execution_sleep: day_of_week = datetime.now().isoweekday() # if weekday, and we scanned after midnight, set execution time to this morning at 10:30 am time_now = datetime.now() if ( day_of_week in range(1, 6) and (time_now.hour >= 0 and time_now.hour < 10) and (time_now.minute >= 0 and time_now.minute < 30) ): execution_time = datetime( year=time_now.year, month=time_now.month, day=time_now.day, hour=10, minute=30 ) # otherwise, set to next trading day, morning at 10:30am else: execution_time = datetime.now() execution_time = execution_time + dt.timedelta(days=1) while execution_time.isoweekday() > 5: execution_time = execution_time + dt.timedelta(days=1) execution_time = datetime( year=execution_time.year, month=execution_time.month, day=execution_time.day, hour=10, minute=30 ) to_sleep = (execution_time - datetime.now()).total_seconds() print "----------sleeping until execution time of %s---------------" % (execution_time) # sleep until that time sleep(to_sleep) for stock in weights: print ("\n=====================================================================") print (" Trading " + stock) print ("=====================================================================\n") stock_price = Trader.get_quote([stock])[0][self.QUOTE_LAST] print "%s last stock price: %s" % (stock, stock_price) contract = Contract() contract.symbol = stock contract.secType = "STK" contract.exchange = "SMART" contract.currency = "USD" if self.orderId is None: print ("Waiting for valid order id") sleep(1) while self.orderId is None: print ("Still waiting for valid order id...") sleep(1) # Order details order = Order() order.action = "BUY" # order.lmtPrice = 140 order.orderType = "MKT" dollar_value = self.availableFunds * weights[stock] order.totalQuantity = int(round(dollar_value / stock_price, 0)) # order.algoStrategy = "AD" order.tif = "DAY" # order.algoParams = algoParams order.transmit = True print ( "Placing order for %d %s's, dollar value $%s (id: %d)" % (order.totalQuantity, contract.symbol, dollar_value, self.orderId) ) # Place the order tws.placeOrder(self.orderId, contract, order) # orderId, # contract, # order print ("\n=====================================================================") print (" Order placed, waiting for TWS responses") print ("=====================================================================\n") sleep(3) # reset orderid for next self.orderId = self.orderId + 1 print ("\n=====================================================================") print (" Trade done.") print ("=====================================================================\n") print ("******************* Press ENTER to quit when done *******************\n") input() print ("\nDisconnecting...") tws.eDisconnect()
class TradeManager(object): def __init__(self): self.accountNumber = '' self.optionExpiry = '20121221' # This needs manual updating! self.maxAskBidRatio = 1.25 self.maxAskLastPriceRatio = 1.02 self.maxOrderQueueLength = 3 # Create a file for TWS logging self.twslog_fh = open('/home/mchan/git/Artemis/twslog.txt', 'a', 0) self.twslog_fh.write("Session Started " + str(datetime.datetime.now()) + "\n") self.callback = ArtemisIBWrapperSilent.ArtemisIBWrapper() self.tws = EPosixClientSocket(self.callback) self.orderIdCount = 1 # This will be updated automatically self.requestIdCount = 1 self.invested = False self.maxLimitPriceFactor = 1.02 # No limit orders above 2% of current ask price # Connect the socket self.socketnum = 30 self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) # Strategy Generic object, has methods for interpreting consensus out/under performance self.Strat = strategy.Strategy() # Queue for orders self.orderQueue = [] # Setup DB connector self.db = dbutil.db(h='127.0.0.1', schema='mchan') # Query Cash Account Balance self.updateBuyingPowerNextId() def updateBuyingPowerNextId(self): self.callback.myNextValidId = None self.callback.buyingPower = None self.tws.reqAccountUpdates(1, self.accountNumber) while (self.callback.buyingPower is None or self.callback.myNextValidId is None): pass self.buyingPower = float(self.callback.buyingPower) self.orderIdCount = int(self.callback.myNextValidId) print "Buying Power recognized: ", self.buyingPower, " Next valid id recognized: ", self.orderIdCount self.tws.reqAccountUpdates(0, self.accountNumber) def calcInvSize(self): ''' Calculates proper investment size ''' # We take the total size of the portfolio, cash plus stock, and we divide by four # The reasoning is that we want to avoid the day pattern trader restriction # Dividing our portfolio size by four ensures that we have enough capital # to trade for the four trading opportunities that will happen until we can # finally sell our positions # This also allows for diversification self.updateBuyingPowerNextId() portfolioList = self.getPortfolio() secMarketPositions = 0 for myContract, myPosition, myMarketValue in portfolioList: secMarketPositions += myMarketValue totalPortfolioSize = secMarketPositions + self.buyingPower investmentSize = min(self.buyingPower, (totalPortfolioSize / 4.0)) print "CALCULATE INVESTMENT SIZE: ", str(investmentSize) return investmentSize def twsReconnect(self): print "Reconnecting TWS" self.twslog_fh.write("Reconnecting TWS" + str(datetime.datetime.now()) + '\n') self.tws.eDisconnect() try: self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) except TWSError, e: print e print "Attempting to reconnect:" for i in range(0, 5): time.sleep(5) print "Try ", i try: self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) break except TWSError, e: print e
class TradeManager(object): def __init__(self): self.accountNumber = '' self.optionExpiry = '20121221' # This needs manual updating! self.maxAskBidRatio = 1.25 self.maxAskLastPriceRatio = 1.02 self.maxOrderQueueLength = 3 # Create a file for TWS logging self.twslog_fh = open('/home/mchan/git/Artemis/twslog.txt', 'a', 0) self.twslog_fh.write("Session Started " + str(datetime.datetime.now()) + "\n") self.callback = ArtemisIBWrapperSilent.ArtemisIBWrapper() self.tws = EPosixClientSocket(self.callback) self.orderIdCount = 1 # This will be updated automatically self.requestIdCount = 1 self.invested = False self.maxLimitPriceFactor = 1.02 # No limit orders above 2% of current ask price # Connect the socket self.socketnum = 30 self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) # Strategy Generic object, has methods for interpreting consensus out/under performance self.Strat = strategy.Strategy() # Queue for orders self.orderQueue = [] # Setup DB connector self.db = dbutil.db(h='127.0.0.1', schema='mchan') # Query Cash Account Balance self.updateBuyingPowerNextId() def updateBuyingPowerNextId(self): self.callback.myNextValidId = None self.callback.buyingPower = None self.tws.reqAccountUpdates(1, self.accountNumber) while (self.callback.buyingPower is None or self.callback.myNextValidId is None): pass self.buyingPower = float(self.callback.buyingPower) self.orderIdCount = int(self.callback.myNextValidId) print "Buying Power recognized: ", self.buyingPower, " Next valid id recognized: ", self.orderIdCount self.tws.reqAccountUpdates(0, self.accountNumber) def calcInvSize(self): ''' Calculates proper investment size ''' # We take the total size of the portfolio, cash plus stock, and we divide by four # The reasoning is that we want to avoid the day pattern trader restriction # Dividing our portfolio size by four ensures that we have enough capital # to trade for the four trading opportunities that will happen until we can # finally sell our positions # This also allows for diversification self.updateBuyingPowerNextId() portfolioList = self.getPortfolio() secMarketPositions = 0 for myContract, myPosition, myMarketValue in portfolioList: secMarketPositions += myMarketValue totalPortfolioSize = secMarketPositions + self.buyingPower investmentSize = min(self.buyingPower, (totalPortfolioSize/4.0)) print "CALCULATE INVESTMENT SIZE: ", str(investmentSize) return investmentSize def twsReconnect(self): print "Reconnecting TWS" self.twslog_fh.write("Reconnecting TWS" + str(datetime.datetime.now()) + '\n') self.tws.eDisconnect() try: self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) except TWSError, e: print e print "Attempting to reconnect:" for i in range(0,5): time.sleep(5) print "Try ", i try: self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) break except TWSError, e: print e
order.clientId = 46 order.action = "SELL" order.totalQuantity = 78 # may have to calculate a smarter number order.orderType = "MKT" order.tif = "DAY" order.transmit = True order.sweepToFill = False order.outsideRth = True callback.accountEnd = False portfolioList = [] callback.portfolioContract = None callback.portfolioPosition = None tws.reqAccountUpdates(1, accountNumber) #while (not callback.accountEnd): # callback.portfolioContract = None # callback.portfolioPosition = None # max_wait = timedelta(seconds=6) + datetime.now() # while (callback.portfolioPosition is None or callback.portfolioContract is None): # if datetime.now() > max_wait: # break # if callback.portfolioPosition is not None and callback.portfolioContract is not None: # myContract = Contract() # myContract.exchange = "SMART" # myContract.currency = "USD" # myContract.symbol = callback.portfolioContractSymbol # myContract.conId = callback.portfolioContractConId # myContract.secType = callback.portfolioContractSecType # myContract.strike = callback.portfolioContractStrike