def get_stats_from_strategy(strategy_type, train_ts, test_ts, commission_fee, compound, rf, periods): """Calculate backtesting statistics for a specific strategy. Args: strategy_type: A specific strategy. train_ts: Train data time series. test_ts: Test data time series. commission_fee: A number represents the commission fee. compound: A bool variable indicating whehter calculates compound return or not. rf: Risk free rate. periods: Scaling parameter to calculate annualized sharpe ratio. Returns: A summary statistics. """ if strategy_type == 'corpus': strat = strats[strategy_type](train_ts, n) else: strat = strats[strategy_type]() strat.get_vectorized_signals(test_ts) # accept signal and produce position port = EqualWeightPort() port.get_position(strat.signals.iloc[(n - 1):]) # backtest bt = Backtest(test_ts[port.positions.index], port.positions) stats = bt.output_summary_stats(rf=rf, periods=periods, compound=compound, commission_fee=commission_fee) return stats
def test_simulate(self): csv_dir = './tests/datasets/' symbol_list = [ 'BTC_ETC', ] initial_capital = 1000.0 heartbeat = 0.0 start_date = datetime(2017, 4, 21, 0, 0, 1) backtest = Backtest(csv_dir, symbol_list, initial_capital, heartbeat, start_date, HistoricCSVDataHandler, SimulatedExecutionHandler, NaivePortfolio, BuyAndHoldStrategy, fields=['open', 'high', 'low', 'close'], ticks_limit=2000) backtest.simulate_trading() backtest.portfolio.create_equity_curve_dataframe() stats = backtest.portfolio.output_summary_stats() self.assertEqual(stats, [('Total Return', '-0.00%'), ('Sharpe Ratio', '-17.72'), ('Max Drawdown', '0.00%'), ('Drawdown Duration', '2000')])
def __init__(self, prices, name, holdings = None, risk_mgmt_active = False, risk_mgmt_periods = None, risk_mgmt_inequality = None, risk_mgmt_method = None): Backtest.__init__(self, prices, name, holdings = None, risk_mgmt_active = False, risk_mgmt_periods = None, risk_mgmt_inequality = None, risk_mgmt_method = None):
def main(argv): #ENTER SOME VARIABLES -x exchange <poloniex, snp500> # -s test type <live, backtest> # -l length of sublists # -v find variance of sublists for each variable <t,f> # -n new data <t,f> # -g graph <t,f> graph = False newdata = False findVar = False length = 30 try: opts, args = getopt.getopt( argv, 'hp:s:l:v:n:g:x:', ) except getopt.GetoptError: sys.exit(2) for opt, arg in opts: if opt == 'h': print('trading-bot.py -p <period> -l <live/backtest>') sys.exit() #if -p followed by time period, sets the variable if opt in ('-s', '--state'): state = arg if opt in ('-x', '--exchange'): exchange = arg if opt in ('-l', '--length'): length = arg if opt in ('-n', '--newdata'): newdata = arg if newdata.lower() == 't': newdata = True else: newdata = False if opt in ('-g', '--graph'): graph = arg if graph.lower() == 't': graph = True else: graph = False if state.lower() == 'backtest': #FINDS PATTERNS patterns = Backtest(length, graph, newdata) patterns.find(exchange) if state.lower() == 'live': pass
def main(): csv_dir = os.getcwd() symbol_list = ['AAPL'] initial_capital = 100000.0 hearbeat = 0.0 start_date = datetime.datetime(1990, 1, 1, 0, 0, 0) backtest = Backtest(csv_dir, symbol_list, initial_capital, hearbeat, start_date, HistoricCSVDataHandler, SimulatedExecutionHandler, Portfolio, MovingAverageCrossStrategy) backtest.simulate_trading()
def rci_cross_backtest(ohlcv, rcilength, overBought, overSold, invrcilen): @lru_cache(maxsize=None) def cached_rci(period): return fastrci(ohlcv.close, period) # インジケーター作成 vrci = cached_rci(rcilength) # エントリー/イグジット buy_entry = crossover(vrci, overSold) buy_exit = crossover(vrci, overBought) sell_entry = crossunder(vrci, overBought) sell_exit = crossunder(vrci, overSold) ignore = int(max([rcilength])) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False # entry_exit = pd.DataFrame({'close':ohlcv.close, 'rci':vrci, 'inv-rci':vinvrci, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def channel_breakout_backtest(ohlcv, breakout_in, breakout_out, period, multi): # エントリー・エグジット # stop_buy_entry = highest(ohlcv.high, breakout_in) + 0.5 # stop_buy_exit = lowest(ohlcv.low, breakout_out) - 0.5 # stop_sell_entry = lowest(ohlcv.low, breakout_in) - 0.5 # stop_sell_exit = highest(ohlcv.high, breakout_out) + 0.5 range = atr(ohlcv.close, ohlcv.high, ohlcv.low, period) * multi stop_buy_entry = ohlcv.high + range stop_buy_exit = ohlcv.low - range stop_sell_entry = ohlcv.low - range stop_sell_exit = ohlcv.high + range # 値が確定するまでの間はノーポジ ignore = int(max([breakout_in, breakout_out, period])) stop_buy_entry[:ignore] = 0 stop_buy_exit[:ignore] = 0 stop_sell_entry[:ignore] = 0 stop_sell_exit[:ignore] = 0 # バックテスト実施 # entry_exit = pd.DataFrame({'close':ohlcv.close, 'open':ohlcv.open, # 'stop_buy_entry':stop_buy_entry, 'stop_buy_exit':stop_buy_exit, 'stop_sell_entry':stop_sell_entry, 'stop_sell_exit':stop_sell_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def rsi_backtest(ohlcv, rsilength, overBought, overSold, take_profit, stop_loss, trailing_stop): @lru_cache(maxsize=None) def cached_rsi(period): return rsi(ohlcv.close, period) # インジケーター作成 vrsi = cached_rsi(rsilength) # エントリー/イグジット buy_entry = crossover(vrsi, overSold) sell_entry = crossunder(vrsi, overBought) buy_exit = sell_entry sell_exit = buy_entry buy_entry_price = None buy_exit_price = None sell_entry_price = None sell_exit_price = None ignore = int(rsilength) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False # entry_exit = pd.DataFrame({'close':ohlcv.close, 'rsi':vrsi, 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def inago_backtest(ohlcv, buyth, sellth, eventh): # 売り買い優劣でエントリー if 0: buy_entry = (ohlcv.buy_volume > ohlcv.sell_volume) & ( (ohlcv.buy_volume - ohlcv.sell_volume).abs() > eventh) sell_entry = (ohlcv.buy_volume < ohlcv.sell_volume) & ( (ohlcv.buy_volume - ohlcv.sell_volume).abs() > eventh) buy_exit = sell_entry sell_exit = buy_entry # 売り買いサイズがN期間ATRを超えたらエントリー if 1: buy_atr = atr(ohlcv.buy_volume, ohlcv.buy_volume, ohlcv.buy_volume, buyth).shift(1) sell_atr = atr(ohlcv.buy_volume, ohlcv.buy_volume, ohlcv.buy_volume, sellth).shift(1) buy_entry = change(ohlcv.buy_volume) > buy_atr sell_entry = change(ohlcv.sell_volume) > sell_atr buy_exit = sell_entry sell_exit = buy_entry # entry_exit = pd.DataFrame({'close':ohlcv.close, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def sma_cross_backtest(ohlcv, fastlen, slowlen, filterlen, buyfilterth, sellfilterth, rsiperiod, overBought, overSold): # インジケーター作成 vfast = sma(change(ohlcv.close), fastlen) vslow = sma(change(ohlcv.close), slowlen) # エントリー/イグジット buy_entry = crossover(vfast, vslow) sell_entry = crossunder(vfast, vslow) buy_exit = sell_entry sell_exit = buy_entry # フィルター # vfilter = sma(ohlcv.close, filterlen) # vfilter = vfilter.diff() # buy_entry = buy_entry & (vfilter > buyfilterth) # sell_entry = sell_entry & (vfilter < -sellfilterth) # 利確 # buy_exit = buy_exit | (ohlcv.close > (slowlen * 1.01)) # sell_exit = sell_exit | (ohlcv.close < (slowlen * 0.99)) ignore = int(max(fastlen, slowlen)) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False # entry_exit = pd.DataFrame({'close':ohlcv.close, 'fast':vfast, 'slow':vslow, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit})#, index=ohlcv.index) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def main(argv): try: opts, args = getopt.getopt(argv, 'p:x:s:c:') #feed in input from cmd except: sys.exit(2) for opt, arg in opts: if opt in ('-p'): if arg.lower() in ['5m', '15m', '30m', '1h', '1d']: period = arg else: print('invalid period') sys.exit(2) if opt in ('-x'): if arg.lower() in ['poloniex', 'snp500']: exchange = arg else: print('invalid exchange') sys.exit(2) if opt in ('-s'): if arg.lower() in ['live', 'backtest']: state = arg else: print('invalid state') sys.exit(2) if opt in ('-c'): if exchange == 'poloniex' and arg in ['BTC/USDT', 'OMG/BTC']: currencey = arg elif exchange == 'snp500' and arg in ['GOOG']: currencey = arg else: print('invalid currency for this exchange') sys.exit(2) #Data Directory: directory = 'C:/Users/Billy/Documents/Code/MeanRevertingStrategy/Data/' #BACKTESTING if state == 'backtest': test_model = Backtest(exchange, currencey, period, directory) test_model.test_stationarity() #LIVE if state == 'live': model = Backtest( exchange, currencey, period, livePreScreen=True ) #live pre screen makes sure the given curency is indeed stationary & returns the parameters of the model
def macd_cross_backtest(ohlcv, fastlen, slowlen, siglen): @lru_cache(maxsize=None) def cached_sma(period): return ohlcv.close.rolling(int(period)).mean() @lru_cache(maxsize=None) def cached_macd(fastlen, slowlen, siglen): macd = cached_sma(fastlen) - cached_sma(slowlen) signal = macd.rolling(int(siglen)).mean() return (macd, signal, macd - signal) # インジケーター作成 vmacd, vsig, vhist = cached_macd(fastlen, slowlen, siglen) # エントリー/イグジット buy_entry = crossover(vmacd, vsig) sell_entry = crossunder(vmacd, vsig) buy_exit = sell_entry.copy() sell_exit = buy_entry.copy() ignore = int(max([fastlen, slowlen])) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False # ゼロラインフィルタ if 0: buy_entry[vsig > 0] = False sell_entry[vsig < 0] = False # ハイローフィルタ if 0: macd_high = highest(vmacd, smaslowlen) macd_low = lowest(vmacd, smafastlen) macd_middle = (macd_high + macd_low) / 2 buy_entry[vmacd > macd_middle] = False sell_entry[vmacd < macd_middle] = False buy_exit[vmacd < macd_middle] = False sell_exit[vmacd > macd_middle] = False # ATRによるSTOP注文 if 1: range = atr(ohlcv.close, ohlcv.high, ohlcv.low, 5) * 1.6 stop_buy_entry = ohlcv.high + range # stop_sell_entry = ohlcv.low - range # stop_buy_exit = ohlcv.low - range stop_sell_exit = ohlcv.high + range trendsfilter = ohlcv.close < sma(ohlcv.close, 120) stop_buy_entry[trendsfilter] = 0 stop_sell_exit[trendsfilter] = 0 # entry_exit = pd.DataFrame({'close':ohlcv.close, 'macd':vmacd, 'sig':vsig, #'fsma':fastsma, 'ssma':slowsma, 'buy_size':buy_size, 'sell_size':sell_size, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit})#, index=ohlcv.index) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def stoch_backtest(length, overBought, overSold, exit_length): # インジケーター作成 vstoch = stoch(ohlcv.close, ohlcv.high, ohlcv.low, length) long_stop = lowest(ohlcv.close, exit_length) short_stop = highest(ohlcv.close, exit_length) # エントリー/イグジット long_entry = crossover(vstoch, overSold) long_exit = crossunder(vstoch, overBought) short_entry = crossunder(vstoch, overBought) short_exit = crossover(vstoch, overSold) long_entry_price = None long_exit_price = long_stop short_entry_price = None short_exit_price = short_stop ignore = int(max(length, exit_length)) long_entry[:ignore] = False long_exit[:ignore] = False short_entry[:ignore] = False short_exit[:ignore] = False # long_entry_price[:ignore] = 0 # long_exit_price[:ignore] = 0 # short_entry_price[:ignore] = 0 # short_exit_price[:ignore] = 0 entry_exit = pd.DataFrame({ 'close': ohlcv.close, 'stoch': vstoch, 'long_entry_price': long_entry_price, 'long_exit_price': long_exit_price, 'long_entry': long_entry, 'long_exit': long_exit, 'short_entry_price': short_entry_price, 'short_entry': short_entry, 'short_exit_price': short_exit_price, 'short_exit': short_exit }) #, index=ohlcv.index) entry_exit.to_csv('entry_exit.csv') return Backtest(ohlcv, buy_entry=long_entry, sell_entry=short_entry, buy_exit=long_exit, sell_exit=short_exit, stop_buy_entry=long_entry_price, stop_sell_entry=short_entry_price, stop_buy_exit=long_exit_price, stop_sell_exit=short_exit_price, lots=1, spread=0, take_profit=0, stop_loss=0, slippage=0)
def receive_executions(self, pubnub, message): executions = self.executions2df(message) if executions.shape[0] < 10: return print("History loaded. start trading") df = Backtest.resample_candle(executions, exchange="bitflyer", freq="%sN" % self.candle_nsec) df = pd.concat([self.df, df]) df = df.drop_duplicates(subset='start', keep='first') self.df = df.iloc[:-1, :] self.backtest.action(self.df, self.strategy, self.params[self.strategy], self.step_action)
def main( pair: str, depth: int, theta: float, window_size: int, sleep_seconds: int, position_size: float, ): """ Load and log price information from kraken """ sobi_strategy = SobiStrategy(window_size=window_size, theta=theta, depth=depth, position_size=position_size) backtester = Backtest() data_center = DataCenter(pair=pair) while True: # query latest data from exchange market_state = data_center.get_market_data() # update indicators and signals sobi_strategy.update_market_state(current_state=market_state) desired_position = sobi_strategy.desired_position # create orders and calculate pnl backtester.update_market_state(market_state) backtester.rebalance_position(desired_position) pnl = backtester.get_current_profit() last_order = backtester.get_last_order() # log output to console log_info = dict( time_rfc=market_state["time"], midprice=market_state["order_book"].midprice, best_bid=market_state["order_book"].best_bid, best_ask=market_state["order_book"].best_ask, **sobi_strategy.indicators, **sobi_strategy.signals, last_order=last_order, pnl=pnl, ) log_msg = ut.get_log_msg(log_info) logging.info(log_msg) # conform to krakens call rate limit time.sleep(sleep_seconds)
def __init__(self): self.setting = config.get_setting() self.indicators = self.setting["indicator"] self.params = {} for k in self.indicators: self.params[k] = self.setting[k] self.result = [] self.trade_result = [] self.talib = False self.exchangename = self.setting["realtime"]["exchange"] self.pair = self.setting["realtime"]["pair"] self.currency = self.pair.split("_")[0] self.asset = self.pair.split("_")[1] self.strategy = self.setting["realtime"]["strategy"] print(self.setting["realtime"]) print(self.params[self.strategy]) self.exchange = getattr(exchange, self.exchangename)(self.setting) self.realtimeexchange = RealtimeExchange() self.backtest = Backtest() self.fee = self.exchange.get_fee() self.balance = self.exchange.getbalance() self.executions = None self.order_id = None self.is_dryrun = False
def unify_backtests(self): """ """ # Merging all the backtests df backtest = pd.concat([ x['backtest'].loc[:, 'Symbol':'Profit_pips'] for x in self.walkforwards ]) backtest.sort_values('Exit_time', inplace=True) backtest.index = range(len(backtest.index)) backtest = pd.concat([ backtest, Backtest.calculate_cumulative_stats(list(backtest.Profit_pips)) ], axis=1) self.backtestUnified = backtest
def main( pair: str, strategy: Strategy, ): """ Initialize context and run the given stragety """ backtester = Backtest() data_center = DataCenter(pair=pair) while True: run_iteration(pair=pair, strategy=strategy, engine=backtester, data_center=data_center)
def simple_market_make_backtest(ohlcv): def smm_logic1(O, H, L, C, n, strategy): maxsize = 0.1 buysize = sellsize = 0.1 spr = ohlcv.stdev[n] * 2.5 mid = (C + H + L) / 3 buy = mid - spr / 2 sell = mid + spr / 2 if strategy.position_size < maxsize: strategy.order('L', 'buy', qty=buysize, limit=buy) else: strategy.cancel('L') if strategy.position_size > -maxsize: strategy.order('S', 'sell', qty=sellsize, limit=sell) else: strategy.cancel('S') def smm_logic2(O, H, L, C, n, strategy): orders = [] pairs = [(0.04, 400, 3), (0.03, 200, 2), (0.02, 100, 1), (0.01, 50, 0)] maxsize = sum(p[0] for p in pairs) buymax = sellmax = strategy.position_size mid = (C + H + L) / 3 for pair in pairs: suffix = str(pair[2]) if buymax + pair[0] <= maxsize: buymax += pair[0] strategy.order('L' + suffix, 'buy', qty=pair[0], limit=mid - pair[1]) else: strategy.cancel('L' + suffix) if sellmax - pair[0] >= -maxsize: sellmax -= pair[0] strategy.order('S' + suffix, 'sell', qty=pair[0], limit=mid + pair[1]) else: strategy.cancel('S' + suffix) return orders # yourlogic = smm_logic1 yourlogic = smm_logic2 return Backtest(**locals())
def inago_backtest(ohlcv, buyth, sellth, eventh): # エントリー/イグジット cond = (ohlcv.buy_volume > buyth) & (ohlcv.sell_volume > sellth) & ( (ohlcv.buy_volume - ohlcv.sell_volume).abs() > eventh) buy_entry = (ohlcv.buy_volume > ohlcv.sell_volume) & cond & (change( ohlcv.close, 3) < 2000) sell_entry = (ohlcv.buy_volume < ohlcv.sell_volume) & cond & (change( ohlcv.close, 3) > -2000) buy_exit = sell_entry sell_exit = buy_entry # entry_exit = pd.DataFrame({'close':ohlcv.close, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def get_hisotry(self): candleSize = self.params[self.strategy]["candleSize"] historySize = self.params[self.strategy]["historySize"] self.candle_nsec = int(candleSize*6*10e9) # minute end nanosecond minutes = int(candleSize * historySize*10) from_date = datetime.datetime.today() - datetime.timedelta(minutes=minutes) trade = self.exchange.get_trade(from_date) candle = Backtest.resample_candle(trade, exchange="bitflyer", freq="%sN" % self.candle_nsec) candle.to_csv("data/realtime_bitflyer_%s_candle.csv" % self.pair, index=None) for col in "open,high,low,close,vwp,volume".split(","): candle[col] = candle[col].astype(np.float64) candle = candle.drop(candle.index[-1]) self.df = candle self.size = self.df.shape[0] self.indsize = len(self.indicators) self.col = {x: self.df.columns.tolist().index(x) for x in ["open", "high", "low", "close", "vwp", "volume", "start"]} self.candles = self.df.values return self.df
def bband_backtest(ohlcv, length, multi, sigmath): # インジケーター作成 upper, lower, basis, sigma = bband(ohlcv.close, length, multi) # エントリー/イグジット buy_entry = (change(upper)<0) & (sigma > sigmath) & (ohlcv.close < basis) sell_entry = (change(lower)>0) & (sigma > sigmath) & (ohlcv.close > basis) buy_exit = sell_entry sell_exit = buy_entry ignore = int(length) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False return Backtest(**locals())
def quote_backtest(ohlcv, asklength, bidlength): @lru_cache(maxsize=None) def cached_buysize(period): #buysize = change(ohlcv['buy_volume']) #return sma(buysize, period) buysize = (ohlcv['buy_volume']) return rsi(buysize, period) @lru_cache(maxsize=None) def cached_sellsize(period): #sellsize = change(ohlcv['sell_volume']) #return sma(sellsize, period) sellsize = (ohlcv['sell_volume']) return rsi(sellsize, period) # インジケーター作成 bid = cached_buysize(bidlength) ask = cached_sellsize(asklength) # エントリー/イグジット buy_entry = (bid > ask) sell_entry = (bid < ask) buy_exit = sell_entry sell_exit = buy_entry ignore = int(max(asklength, bidlength)) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False entry_exit = pd.DataFrame({ 'close': ohlcv.close, 'ask': ask, 'bid': bid, 'buy_entry': buy_entry, 'buy_exit': buy_exit, 'sell_entry': sell_entry, 'sell_exit': sell_exit }) entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def nanpin_backtest(ohlcv, period, overshoot, undershoot): # エントリー/イグジット buy_entry = change(ohlcv.close, period) < -(ohlcv.close * undershoot) sell_entry = change(ohlcv.close, period) > (ohlcv.close * overshoot) buy_exit = sell_entry sell_exit = buy_entry ignore = int(period) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False # entry_exit = pd.DataFrame({'close':ohlcv.close, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def simple_market_make_backtest(ohlcv): def smm_logic1(O, H, L, C, n, position_size, **others): orders = [] maxsize = 0.1 buysize = sellsize = 0.1 spr = ohlcv.stdev[n] * 2.5 mid = (C + H + L) / 3 buy = mid - spr / 2 sell = mid + spr / 2 if position_size < maxsize: orders.append((+1, buy, buysize, 'L')) else: orders.append((0, 0, 0, 'L')) if position_size > -maxsize: orders.append((-1, sell, sellsize, 'S')) else: orders.append((0, 0, 0, 'S')) return orders def smm_logic2(O, H, L, C, n, position_size, **others): orders = [] pairs = [(0.03, 200), (0.02, 100), (0.01, 50)] maxsize = sum(p[0] for p in pairs) buymax = sellmax = position_size mid = (C + H + L) / 3 for pair in pairs: suffix = str(pair[1]) buymax += pair[0] sellmax -= pair[0] if buymax <= maxsize: orders.append((+1, mid - pair[1], pair[0], 'L' + suffix)) else: orders.append((0, 0, 0, 'L' + suffix)) if sellmax >= -maxsize: orders.append((-1, mid + pair[1], pair[0], 'S' + suffix)) else: orders.append((0, 0, 0, 'S' + suffix)) return orders # yourlogic = smm_logic1 yourlogic = smm_logic2 return Backtest(**locals())
def sar_backtest(ohlcv, start, inc, max): # インジケーター作成 vsar = fastsar(ohlcv.high, ohlcv.low, start, inc, max) # エントリー/イグジット stop_buy_entry = vsar.copy() stop_sell_entry = vsar.copy() stop_buy_entry[vsar < ohlcv.high] = 0 stop_sell_entry[vsar > ohlcv.low] = 0 stop_buy_exit = stop_sell_entry stop_sell_exit = stop_buy_entry # entry_exit = pd.DataFrame({'close':ohlcv.close, 'high':ohlcv.high, 'low':ohlcv.low, 'sar':vsar, # 'stop_buy_entry':stop_buy_entry, 'stop_buy_exit':stop_buy_exit, # 'stop_sell_entry':stop_sell_entry, 'stop_sell_exit':stop_sell_exit, }) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def cog_backtest(ohlcv, fastlen, slowlen, filterlen, buyfilterth, sellfilterth, rsiperiod, overBought, overSold): ohlcv['hlc3'] = (ohlcv['close'] + ohlcv['high'] + ohlcv['low']) / 3.0 ohlcv['hl2'] = (ohlcv['high'] + ohlcv['low']) / 2.0 rolling_df_conf_window = roll(ohlcv, fastlen, ['hl2']) # can add other fields here as well ohlcv['WMA'] = rolling_df_conf_window.apply( lambda x: sum(float(i + 1) * x['hl2'][i] for i in range(x.size)) / float(sum(range(x.size + 1)))) ohlcv['SMA'] = rolling_df_conf_window.apply( lambda x: sum(x['hl2'][i] for i in range(x.size)) / float(x.size)) ohlcv['COG'] = (ohlcv['WMA'] / ohlcv['SMA']) - 1 # エントリー/イグジット buy_entry = crossover(ohlcv['COG'], ohlcv['COG'].shift(1)) sell_entry = crossunder(ohlcv['COG'], ohlcv['COG'].shift(1)) buy_exit = sell_entry sell_exit = buy_entry # フィルター # vfilter = sma(ohlcv.close, filterlen) # vfilter = vfilter.diff() # buy_entry = buy_entry & (vfilter > buyfilterth) # sell_entry = sell_entry & (vfilter < -sellfilterth) # 利確 # buy_exit = buy_exit | (ohlcv.close > (slowlen * 1.01)) # sell_exit = sell_exit | (ohlcv.close < (slowlen * 0.99)) ignore = int(fastlen) buy_entry[:ignore] = False buy_exit[:ignore] = False sell_entry[:ignore] = False sell_exit[:ignore] = False # entry_exit = pd.DataFrame({'close':ohlcv.close, 'fast':vfast, 'slow':vslow, # 'buy_entry':buy_entry, 'buy_exit':buy_exit, 'sell_entry':sell_entry, 'sell_exit':sell_exit})#, index=ohlcv.index) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def eth_macross_backtest(ohlcv, fastperiod, slowperiod): fst = sma(change(ohlcv.eth_close), fastperiod) slw = sma(change(ohlcv.eth_close), slowperiod) # fst = sma(ohlcv.eth_close, fastperiod) # slw = sma(ohlcv.eth_close, slowperiod) up = (fst > slw) down = (fst < slw) limit_buy_entry = ohlcv.close.copy() limit_buy_entry[down] = 0 limit_buy_exit = ohlcv.close.copy() limit_buy_exit[up] = 0 limit_sell_entry = ohlcv.close.copy() limit_sell_entry[up] = 0 limit_sell_exit = ohlcv.close.copy() limit_sell_exit[down] = 0 return Backtest(**locals())
def pivot_backtest(ohlcv, leftbars, rightbars): ignore = int(leftbars + rightbars) # ピボットハイ&ロー stop_buy_entry = pivothigh(ohlcv.high, leftbars, rightbars).ffill() stop_sell_entry = pivotlow(ohlcv.low, leftbars, rightbars).ffill() stop_buy_exit = stop_sell_entry stop_sell_exit = stop_buy_entry stop_buy_entry[:ignore] = 0 stop_buy_exit[:ignore] = 0 stop_sell_entry[:ignore] = 0 stop_sell_exit[:ignore] = 0 # バックテスト実施 # entry_exit = pd.DataFrame({'close':ohlcv.close, 'high':ohlcv.high, 'low':ohlcv.low, # 'stop_sell_entry':stop_sell_entry, 'short_entry':short_entry, 'stop_sell_exit':stop_sell_exit, 'short_exit':short_exit}) # entry_exit.to_csv('entry_exit.csv') return Backtest(**locals())
def test_create(self): csv_dir = './tests/datasets/' symbol_list = [ 'BTC_ETC', ] initial_capital = 1000.0 heartbeat = 0.0 start_date = datetime(2017, 4, 21, 0, 0, 1) backtest = Backtest(csv_dir, symbol_list, initial_capital, heartbeat, start_date, HistoricCSVDataHandler, SimulatedExecutionHandler, NaivePortfolio, BuyAndHoldStrategy, fields=['open', 'high', 'low', 'close']) self.assertEqual(backtest.heartbeat, 0.0) self.assertEqual(backtest.initial_capital, 1000.0) self.assertEqual(backtest.signals, 0) self.assertEqual(backtest.orders, 0) self.assertEqual(backtest.fills, 0) self.assertEqual(backtest.num_strats, 1.0)
#!/usr/bin/python # -*- coding: utf-8 -*- # intraday_mr_backtest from sys import path import os path.append(os.getcwd() + '/../engine') path.append(os.getcwd() + '/../') import datetime from backtest import Backtest from data import HistoricCSVDataHandler from execution import SimulatedExecutionHandler from portfolio import Portfolio from intraday_ols_mr import IntradayOLSMRStrategy if __name__ == "__main__": csv_dir = os.getcwd() + '/../csv' symbol_list = ['HOM14','NGM14'] initial_capital = 100000.0 heartbeat = 0.0 start_date = datetime.datetime(2006,1,3) backtest = Backtest( csv_dir, symbol_list, initial_capital, heartbeat, start_date, HistoricCSVDataHandler , SimulatedExecutionHandler, Portfolio, IntradayOLSMRStrategy, #periods , header_format = "yahoo", max_iters = None ) backtest.simulate_trading()
if __name__ == "__main__": if backtestIndicator and not liveIndicator: # conduct backtest print " *** BACKTEST *** " #CONVERT DATA TO PICKLE #backTest = Backtest("historical/EUR_USD_Week3.csv",backtestSettings,leverage,closeDictionary,backtestSettings['positions']) #output = backTest.resample("1Min") #exit() #GROUP RESAMPLE TO PICKLE #groupResample(2015, 1, 6, "1H", "EUR_USD") #exit() # READ PICKLE INTO DATAFRAME (prices) #backtest = Backtest("historical/EUR_USD_Week3.csv_1Min-OHLC.pkl",backtestSettings,leverage,closeDictionary,backtestSettings['positions']) backtest = Backtest("historical/EUR_USD_2015_1_through_12.pkl",backtestSettings,leverage,backtestPositions) #backtest = Backtest("historical/EUR_USD_2015_1_through_12.pkl",backtestSettings,leverage,closeDictionary,backtestSettings['positions']) prices = backtest.readPickle() # INSTANTIATE STRATEGY strategy = Strategy(backtestPositions, priceQueue, backtestSettings, strategySettings) # LOOP THROUGH PRICES i = 0 # for displaying trades in a scatterplot for index, row in prices: # SKIP ERRORS IN PICKLE if np.isnan(row['Buy']) or np.isnan(row['Sell']): continue # 0.A: ADD CURRENT PRICE TO QUEUE
if __name__ == "__main__": import sys if '../SqlConnWraper' not in sys.path: sys.path.append('../SqlConnWraper') from BuildSQLConnection import build_sql_conn cxcn = build_sql_conn('config.ini') symbol_list = ['AAPL'] initial_capital = 100000.0 heartbeat = 0.0 data_handler = SecurityMasterDataHandler(symbol_list, cxcn) start_date = data_handler.start_dt order_method = EquityWeightOrder backtest = Backtest( symbol_list, initial_capital, heartbeat, start_date, data_handler, SimulatedExecutionHandlerWithCommision, Portfolio, MovingAverageCrossStrategy, order_method ) backtest.simulate_trading() backtest.output_plot()
from backtest import Backtest from prices import FetchPrices, PricesFromDataFrame # cont_1m = Quandl.get("CHRIS/CBOE_VX1", trim_start=trimstart) # cont_2m = Quandl.get('CHRIS/CBOE_VX2', trim_start=trimstart) # vix = Quandl.get('CBOE/VIX', trim_start=trimstart) # l=list(df.columns.levels[0]) fetcher = FetchPrices() names=['vxx', 'xiv'] qts = fetcher.get_quotes() bt = Backtest(instruments=qts, data_handler=PricesFromDataFrame, strategy=TestStrategy, strategy_params=None, portfolio=None, execution=None) bt.start_backtest()