def execute_on(self,price_book): self.log.debug("executing_on: %s: %s" % (price_book.last_timestamp, price_book.keys())) for symbol in price_book.keys(): price_data = price_book[symbol] ## pos = Position(symbol,qty,price) ## pos == None: no activity in this symbol yet pos = self.positions.get(symbol,None) opens = self.open_orders(symbol) mo1 = self.indicator_map[symbol]['mo1'] mo2 = self.indicator_map[symbol]['mo2'] mo3 = self.indicator_map[symbol]['mo3'] duration = self.indicator_map[symbol]['duration'] self.log.debug('pushing: %s close= %s' % (symbol, price_data.close)) mo1.push(price_data.close) mo2.push(price_data.close) mo3.push(price_data.close) if not opens: if pos == None or pos.qty == 0: if mo1.size() > 1 and mo2.size() > 0 and mo3.size(): ## mo = tuple(pt momentum, pct momentum) p_value = mo1[0][0] y_value = mo1[1][0] self.log.debug('%s indicator time: %s' % (symbol, price_data.timestamp)) if p_value > 0 and y_value <= 0 and mo2[0] > 0 and mo3[0] > 0: qty = self.get_size(symbol,price_data.close) self.log.debug("__BUY %s qty = %d" % (symbol,qty)) if qty: self.send_order(Order(self.name,symbol,Order.BUY,qty,Order.MARKET,None,None)) ## clear the historical price counter duration.reset() if p_value < 0 and y_value >= 0 and mo2[0] < 0 and mo3[0] < 0: qty = self.get_size(symbol,price_data.close) self.log.debug("__SHORT %s qty = %d" % (symbol,qty)) if qty: self.send_order(Order(self.name,symbol,Order.SELL,qty,Order.MARKET,None,None)) ## clear the historical price counter duration.reset() elif pos.qty > 0: ## keep track of time we have been in the trade ## exit after holding period or mid term momentum turns negative duration.push(price_data.close) if duration.size() >= duration.capacity or mo2[0] < 0: self.log.debug("__SELL LONG %s qty = %d" % (symbol,pos.qty)) self.send_order(Order(self.name,symbol,Order.SELL,pos.qty,Order.MARKET,None,None)) elif pos.qty < 0: ## keep track of time we have been in the trade ## exit after holding period or mid term momentum turns positive duration.push(price_data.close) if duration.size() >= duration.capacity or mo2[0] > 0: self.log.debug("__COVER SHORT %s qty = %d" % (symbol,pos.qty)) self.send_order(Order(self.name,symbol,Order.BUY,abs(pos.qty),Order.MARKET,None,None))
def test_strategy_order_update(): ## do partial fill and update, both sides latch = DataLatch(1) s1_order_q = DQueue() s1_fill_q = DQueue() ts = datetime.datetime(2014, 8, 16, 12, 30, 0) strategy = MStrategy('test_strategy', strategy_params={'length': 10}) strategy.IN_fills = s1_fill_q strategy.OUT_orders = s1_order_q strategy.latch = latch strategy.start() o1 = Order(strategy.name, 'AAPL', Order.SELL, 100, Order.MARKET, None, None) o2 = Order(strategy.name, 'AAPL', Order.SELL, 200, Order.MARKET, None, None) p1 = Order(strategy.name, 'AAPL', Order.BUY, 100, Order.MARKET, None, None) p2 = Order(strategy.name, 'AAPL', Order.BUY, 200, Order.MARKET, None, None) strategy.send_order(o1) strategy.send_order(o2) strategy.send_order(p1) strategy.send_order(p2) # allow time for orders to be sent time.sleep(2) s1_fill_q.put(Fill('AAPL', 100.00, 100, Order.SELL, ts, o1.order_id)) s1_fill_q.put( Fill('AAPL', 101.50, 50, Order.SELL, ts, o2.order_id, qty_left=150)) s1_fill_q.put(Fill('AAPL', 104.00, 100, Order.BUY, ts, p1.order_id)) s1_fill_q.put( Fill('AAPL', 105.50, 70, Order.BUY, ts, p2.order_id, qty_left=130)) time.sleep(2) strategy.shutdown() strategy.join()
def cleanup(self): for symbol, position in self.positions.iteritems(): qty = position.qty if qty == 0: continue side = Order.SELL if qty < 0: side = Order.BUY ## send closing orders self.send_order( Order(self.name, symbol, side, qty, Order.MARKET, None, None))
def execute_on(self, price_book): self.log.debug("executing_on: %s: %s" % (price_book.last_timestamp, price_book.keys())) for symbol in price_book.keys(): price_data = price_book[symbol] ## pos = Position(symbol,qty,price) ## pos == None: no activity in this symbol yet pos = self.positions.get(symbol, None) opens = self.open_orders(symbol) momentum = self.indicator_map[symbol]['momentum'] duration = self.indicator_map[symbol]['duration'] self.log.debug('pushing: %s close= %s' % (symbol, price_data.close)) momentum.push(price_data.close) duration.push(price_data.close) if momentum.size() > 0: self.log.debug("MO= %f" % momentum[0][0]) if duration.size() > 0: self.log.debug("Duration= %d" % duration.size()) if not opens: if pos == None or pos.qty == 0: if momentum.size() > 1: ## mo = tuple(pt momentum, pct momentum) p_value = momentum[0][0] y_value = momentum[1][0] self.log.debug('%s indicator time: %s' % (symbol, price_data.timestamp)) if p_value > 0 and y_value <= 0: qty = self.get_size(symbol, price_data.close) self.log.debug("__BUY %s qty = %d" % (symbol, qty)) if qty: self.send_order( Order(self.name, symbol, Order.BUY, qty, Order.MARKET, None, None)) duration.reset() if p_value < 0 and y_value >= 0: qty = self.get_size(symbol, price_data.close) self.log.debug("__SHORT %s qty = %d" % (symbol, qty)) if qty: self.send_order( Order(self.name, symbol, Order.SELL, qty, Order.MARKET, None, None)) duration.reset() elif pos.qty > 0: if duration.size() >= duration.capacity: self.log.debug("__SELL LONG %s qty = %d" % (symbol, pos.qty)) self.send_order( Order(self.name, symbol, Order.SELL, pos.qty, Order.MARKET, None, None)) elif pos.qty < 0: if duration.size() >= duration.capacity: self.log.debug("__COVER SHORT %s qty = %d" % (symbol, pos.qty)) self.send_order( Order(self.name, symbol, Order.BUY, abs(pos.qty), Order.MARKET, None, None)) if self.capture_data: moo = None if momentum.size() > 0: moo = momentum[0][0] snapshot = dict(date=price_data.timestamp, close=price_data.close, momentum=moo, duration=duration[0]) self.time_series.push(snapshot)
def execute_on(self,price_book): self.log.debug("executing_on: %s: %s" % (price_book.last_timestamp, price_book.keys())) ## record current momentum values for all names in the universe for symbol in price_book.keys(): price_data = price_book[symbol] momentum = self.indicator_map[symbol]['momentum'] self.log.debug('pushing: %s close= %s' % (symbol, price_data.close)) momentum.push(price_data.close) rebalance = (self.rebalance_count == self.rebalance_limit) if not self.portfolio or rebalance: old_portfolio = self.portfolio[:] del self.portfolio[:] ## build new portfolio for mo_value, symbol in self.rank_universe(): opens = self.open_orders(symbol) if not opens: pos = self.positions.get(symbol,Position(None,0,0)) curr = pos.qty tgt = self.get_size(symbol,price_data.close) if mo_value < 0: tgt = -tgt self.log.debug("%s: current qty = %d, tgt = %d" % (symbol,curr,tgt)) qty = tgt - curr if qty > 0: self.log.debug("__BUY %s qty = %d" % (symbol,qty)) self.send_order(Order(self.name,symbol,Order.BUY,qty,Order.MARKET,None,None)) elif qty < 0: qty = abs(qty) self.log.debug("__SHORT %s qty = %d" % (symbol,qty)) self.send_order(Order(self.name,symbol,Order.SELL,qty,Order.MARKET,None,None)) self.portfolio.append(symbol) ## clean up positions not in the new portfolio remains = [x for x in old_portfolio if x not in self.portfolio] for symbol in remains: opens = self.open_orders(symbol) if not opens: pos = self.positions.get(symbol,Position(None,0,0)) if pos.qty > 0: self.log.debug("__EXIT_SELL %s qty = %d" % (symbol,qty)) self.send_order(Order(self.name,symbol,Order.SELL,qty,Order.MARKET,None,None)) elif pos.qty < 0: self.log.debug("__EXIT_BUY %s qty = %d" % (symbol,qty)) self.send_order(Order(self.name,symbol,Order.BUY,abs(qty),Order.MARKET,None,None)) self.rebalance_count = 0 elif self.portfolio and not rebalance: ## count the periods to rebalance self.rebalance_count += 1
def execute_on(self, price_book): self.log.debug("executing_on: %s: %s" % (price_book.last_timestamp, price_book.keys())) for symbol in price_book: price_data = price_book[symbol] ## pos = Position(symbol,qty,price) ## pos == None: no activity in this symbol yet pos = self.positions.get(symbol, None) opens = self.open_orders(symbol) rsi = self.indicator_map[symbol]['rsi'] duration = self.indicator_map[symbol]['duration'] self.log.debug('pushing: %s close= %s' % (symbol, price_data.close)) px = (price_data.high + price_data.low + price_data.close) / 3.0 rsi.push(px) duration.push(px) ## use trend filter if given trend_up = trend_down = True average = self.indicator_map[symbol].get('average', None) if average: average.push(px) if average.size() > 1: if px > average[1]: trend_down = False else: trend_up = False if rsi.size() > 0: self.log.debug("RSI= %f" % rsi[0]) if average and average.size() > 0: self.log.debug("AVG= %f" % average[0]) if duration.size() > 0: self.log.debug("Duration= %d" % duration.size()) if not opens: if pos == None or pos.qty == 0: if rsi.size() > 1: ## mo = tuple(pt momentum, pct momentum) p_value = rsi[0] y_value = rsi[1] self.log.debug('%s indicator time: %s' % (symbol, price_data.timestamp)) if p_value > y_value and y_value <= self.btm and trend_up: qty = self.get_size(symbol, price_data.close) self.log.debug("__BUY %s qty = %d" % (symbol, qty)) if qty: self.send_order( Order(self.name, symbol, Order.BUY, qty, Order.MARKET, None, None)) duration.reset() if p_value < y_value and y_value >= self.top and trend_down: qty = self.get_size(symbol, price_data.close) self.log.debug("__SHORT %s qty = %d" % (symbol, qty)) if qty: self.send_order( Order(self.name, symbol, Order.SELL, qty, Order.MARKET, None, None)) duration.reset() elif pos.qty > 0: if duration.size() >= duration.capacity: self.log.debug("__SELL LONG %s qty = %d" % (symbol, pos.qty)) self.send_order( Order(self.name, symbol, Order.SELL, pos.qty, Order.MARKET, None, None)) elif pos.qty < 0: if duration.size() >= duration.capacity: self.log.debug("__COVER SHORT %s qty = %d" % (symbol, pos.qty)) self.send_order( Order(self.name, symbol, Order.BUY, abs(pos.qty), Order.MARKET, None, None)) if self.capture_data: ## x = y = None ## if rsi.size() > 0: x = rsi[0] ## if average and average.size() > 0: y = average[0] snapshot = dict(date=price_data.timestamp, close=price_data.close, avp=px, rsi=rsi[0], avg=average[0], duration=duration[0]) self.time_series.push(snapshot)
def test_exchange(): latch = DataLatch(1) ## exchange queues order_q = DQueue() fill_q = DQueue() exchange = Exchange() exchange.latch = latch ## bind exchange and portfolio together tester = Tester() exchange.IN_orders = order_q exchange.OUT_fills = fill_q tester.IN_queue = fill_q exchange.start() tester.start() o1 = Order('test', 'AAPL', Order.BUY, 100, Order.MARKET, None, None) o1.stamp_time(parse_date("20140311")) order_q.put(o1) o2 = Order('test', 'AAPL', Order.BUY, 200, Order.MARKET, None, None) o2.stamp_time(parse_date("20140816")) order_q.put(o2) o3 = Order('test', 'AAPL', Order.SELL, 300, Order.MARKET, None, None) o3.stamp_time(parse_date("20140101")) order_q.put(o3) simData = DataFeedDaily('AAPL.csv') for market_data in simData: latch.trap(market_data) exchange.on_data(market_data) exchange.shutdown() tester.shutdown() exchange.join() tester.join()