def __init__(self, name, strategy_setup=None, strategy_params=None): super(MStrategy, self).__init__(name, strategy_setup, strategy_params) ## base config = general setup ## this can be in the form of an .ini file ## config = ConfigParser() ## config.read(base_config) ## config._sections (is the dict form of ini file) ## or a dict self.capital = 1000000.0 * 10 #self.bar_interval = 300 ## seconds self.bar_interval = 0 ## in this case - since I have a single indicator ## strategy_params defines the parameters for the MO indicator ## as defined in the Indicators.py module - # ## constructor for MO = MO(length=value) ## - therefore strategy_params = dict(length=value) ## - i.e the MO indicator is constructed as MO(**strategy_params) ## Indicator map takes a list of indicator definitions: ## (local_name, clas_name, kwargs for class_name(**kwargs) constructor) self.indicator_map = IndicatorMap([ dict(name='momentum', class_name='MO', kwargs=dict(length=strategy_params['length'])) ])
def __init__(self, name, strategy_setup=None, strategy_params=None): super(RSIStrategy, self).__init__(name, strategy_setup, strategy_params) ## base config = general setup ## this can be in the form of an .ini file ## config = ConfigParser() ## config.read(base_config) ## config._sections (is the dict form of ini file) ## or a dict self.capital = 1000000.0 * 10 ## self.bar_interval is used for aggregating tick data into bars (specifically if the strategy is ## to handle real-time, tick by tick feeds...) ## bar_interval = 0, means take each data element on its own, do data aggregation is to occur self.bar_interval = 0 ## threshold overbought/oversold levels as integers (0-100) self.top = strategy_params['top'] / 100.0 self.btm = strategy_params['btm'] / 100.0 ## Indicator map takes a list of indicator definitions: ## (local_name, clas_name, kwargs for class_name(**kwargs) constructor) indicators = [ dict(name='rsi', class_name='RSI', kwargs=dict(length=strategy_params['rsi'])), dict(name='duration', class_name='TimeSeries', kwargs=dict(capacity=strategy_params['duration'])) ] ## optional moving average filter if 'average' in strategy_params: indicators.append( dict(name='average', class_name='SMA', kwargs=dict(length=strategy_params['average']))) self.indicator_map = IndicatorMap(indicators) self.capture_data = False self.time_series = TimeSeries()
def __init__(self, name, strategy_setup=None, strategy_params=None): super(RetraceStrategy,self).__init__(name,strategy_setup,strategy_params) self.bar_interval = 0 ## Indicator map takes a list of indicator definitions: ## (local_name, class_name, kwargs for class_name(**kwargs) constructor) indicators = [ dict(name='momentum', class_name='MO', kwargs=dict(length=strategy_params['momentum'])), dict(name='average', class_name='SMA', kwargs=dict(length=strategy_params['average'])), dict(name='duration', class_name='TimeSeries', kwargs=dict(capacity=strategy_params['duration'])) ] self.indicator_map = IndicatorMap(indicators) self.capture_data = False self.time_series = TimeSeries()
def __init__(self, name, strategy_setup=None, strategy_params=None): super(TripleStrategy,self).__init__(name,strategy_setup,strategy_params) self.bar_interval = 1 ## seconds ## parameter space to search over ## mo1 = short term momentum crossover ## mo2 = medium term mo filter ## mo3 = long term mo filter ## duration = trade holding period params = strategy_params indicators = [ dict(name='mo1',class_name='MO',kwargs=dict(length=params['mo1'])), dict(name='mo2',class_name='MO',kwargs=dict(length=params['mo2'])), dict(name='mo3',class_name='MO',kwargs=dict(length=params['mo3'])), dict(name='duration',class_name='TimeSeries',kwargs=dict(capacity=params['duration'])) ] self.indicator_map = IndicatorMap(indicators)
class MStrategy2(StrategyBase): def __init__(self, name, strategy_setup=None, strategy_params=None): super(MStrategy2, self).__init__(name, strategy_setup, strategy_params) ## base config = general setup ## this can be in the form of an .ini file ## config = ConfigParser() ## config.read(base_config) ## config._sections (is the dict form of ini file) ## or a dict self.capital = 1000000.0 * 10 #self.bar_interval = 300 ## seconds self.bar_interval = 0 ## in this case - since I have a single indicator ## strategy_params defines the parameters for the MO indicator ## as defined in the Indicators.py module - # ## constructor for MO = MO(length=value) ## - therefore strategy_params = dict(length=value) ## - i.e the MO indicator is constructed as MO(**strategy_params) ## Indicator map takes a list of indicator definitions: ## (local_name, clas_name, kwargs for class_name(**kwargs) constructor) indicators = [ dict(name='momentum', class_name='MO', kwargs=dict(length=strategy_params['length'])), dict(name='duration', class_name='TimeSeries', kwargs=dict(capacity=strategy_params['duration'])) ] self.indicator_map = IndicatorMap(indicators) self.capture_data = False self.time_series = TimeSeries() def get_size(self, symbol, price): return 100 def reset(self): self.indicator_map.reset() def dump_data(self): if self.capture_data: import pandas if self.time_series.series: return pandas.DataFrame(list( self.time_series.series.reverse())) else: return None else: print "capture_data = False. nothing captured" ## override this to implement strategy 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)
class RetraceStrategy(StrategyBase): def __init__(self, name, strategy_setup=None, strategy_params=None): super(RetraceStrategy,self).__init__(name,strategy_setup,strategy_params) self.bar_interval = 0 ## Indicator map takes a list of indicator definitions: ## (local_name, class_name, kwargs for class_name(**kwargs) constructor) indicators = [ dict(name='momentum', class_name='MO', kwargs=dict(length=strategy_params['momentum'])), dict(name='average', class_name='SMA', kwargs=dict(length=strategy_params['average'])), dict(name='duration', class_name='TimeSeries', kwargs=dict(capacity=strategy_params['duration'])) ] self.indicator_map = IndicatorMap(indicators) self.capture_data = False self.time_series = TimeSeries() def get_size(self,symbol,price): return 100 def reset(self): self.indicator_map.reset() def dump_data(self): if self.capture_data: import pandas if self.time_series.series: return pandas.DataFrame(list(self.time_series.series.reverse())) else: return None else: print "capture_data = False. nothing captured" ## override this to implement strategy 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'] m_avg = self.indicator_map[symbol]['average'] duration = self.indicator_map[symbol]['duration'] self.log.debug('pushing: %s close= %s' % (symbol, price_data.close)) momentum.push(price_data.close) m_avg.push(price_data.close) if not opens: if pos == None or pos.qty == 0: if momentum.size() > 1 and m_avg.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 and price_data.close > m_avg[1]: 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 price_data.close < m_avg[1]: 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 duration.push(price_data.close) 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: ## keep track of time we have been in the trade duration.push(price_data.close) 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, average=m_avg[0], momentum=moo, duration=duration[0]) self.time_series.push(snapshot)
class MPStrategy(StrategyBase): def __init__(self, name, strategy_setup=None, strategy_params=None): super(MPStrategy,self).__init__(name,strategy_setup,strategy_params) ## base config = general setup ## this can be in the form of an .ini file ## config = ConfigParser() ## config.read(base_config) ## config._sections (is the dict form of ini file) ## or a dict self.capital = 1000000.0 * 10 #self.bar_interval = 300 ## seconds self.bar_interval = 0 ## in this case - since I have a single indicator ## strategy_params defines the parameters for the MO indicator ## as defined in the Indicators.py module - # ## constructor for MO = MO(length=value) ## - therefore strategy_params = dict(length=value) ## - i.e the MO indicator is constructed as MO(**strategy_params) ## Indicator map takes a list of indicator definitions: ## (local_name, clas_name, kwargs for class_name(**kwargs) constructor) indicators = [dict(name='momentum',class_name='MO', kwargs=dict(length=strategy_params['length']))] self.indicator_map = IndicatorMap(indicators) ## holds the long/short momentum portfolio self.portfolio = list() self.number_of_longs = strategy_params['longs'] self.number_of_shorts = strategy_params['shorts'] self.rebalance_count = 0 self.rebalance_limit = int(strategy_params['duration']) def get_size(self,symbol,price): return 100 def reset(self): self.indicator_map.reset() ## grab top momentum longs and bottom momentum shorts def rank_universe(self): ranks = [] for symbol, indicators in self.indicator.iteritems(): ## momentum return a series of tuples (mo, return) ## do ranking based on return mo_value = indicators['momentum'][1][0] if mo_value: ranks.append((mo_value,symbol)) ## buy only longs with positive momentum ## sell only short with negative momentum ## this prevents sales in markets where he universe to completely bullish ## or buys when the market is completely bearish if ranks: ranks.sort() longs = [x for x in ranks[:self.number_of_longs] if x[0] > 0] shorts = [x for x in ranks[:-self.self.number_of_shorts] if x[0] < 0] return longs + shorts else: return [] ## override this to implement strategy 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
from MarketObjects import IndicatorMap ''' testing the build of a dynamic indicator map indicator map allows for independent indicators fro indiviudal symbols allows a strategy to trade multiple symbols at the same time ''' indicators = [] ## indicator key_name, classname, parameters needed to define the indicator indicators.append(('momentum', 'MO', {'length': 10})) indicators.append(('sma', 'SMA', {'length': 20})) indicator_map = IndicatorMap(indicators) overrides = [('SPY', 'momentum', { 'length': 20 }), ('IVV', 'momentum', { 'length': 5 })] indicator_map.override(overrides) momentum_a = indicator_map['AAPL']['momentum'] momentum_b = indicator_map['SPY']['momentum'] momentum_c = indicator_map['IVV']['momentum'] sma_c = indicator_map['IVV']['sma'] print 'AAPL', momentum_a.length print 'SPY', momentum_b.length print 'IVV', momentum_c.length
class RSIStrategy(StrategyBase): def __init__(self, name, strategy_setup=None, strategy_params=None): super(RSIStrategy, self).__init__(name, strategy_setup, strategy_params) ## base config = general setup ## this can be in the form of an .ini file ## config = ConfigParser() ## config.read(base_config) ## config._sections (is the dict form of ini file) ## or a dict self.capital = 1000000.0 * 10 ## self.bar_interval is used for aggregating tick data into bars (specifically if the strategy is ## to handle real-time, tick by tick feeds...) ## bar_interval = 0, means take each data element on its own, do data aggregation is to occur self.bar_interval = 0 ## threshold overbought/oversold levels as integers (0-100) self.top = strategy_params['top'] / 100.0 self.btm = strategy_params['btm'] / 100.0 ## Indicator map takes a list of indicator definitions: ## (local_name, clas_name, kwargs for class_name(**kwargs) constructor) indicators = [ dict(name='rsi', class_name='RSI', kwargs=dict(length=strategy_params['rsi'])), dict(name='duration', class_name='TimeSeries', kwargs=dict(capacity=strategy_params['duration'])) ] ## optional moving average filter if 'average' in strategy_params: indicators.append( dict(name='average', class_name='SMA', kwargs=dict(length=strategy_params['average']))) self.indicator_map = IndicatorMap(indicators) self.capture_data = False self.time_series = TimeSeries() def get_size(self, symbol, price): return 100 def reset(self): self.indicator_map.reset() def dump_data(self): if self.capture_data: import pandas if self.time_series.series: return pandas.DataFrame(list( self.time_series.series.reverse())) else: return None else: print "capture_data = False. nothing captured" ## override this to implement strategy 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)