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 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 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 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 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 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 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 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 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 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 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)
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 main(beginning_date="2021-01-04", duration=10, strategy_option=5, backtest_option=1, take_profit=2, cut_loss=1, long_duration=0, long_duration_period=20, backtest_comparison="Close", strategies_backtest={}): current_time = datetime.now() # format_current_time = current_time.strftime("%d%b%Y_%H_") format_date_time = current_time.strftime("%Y-%m-%d_%H%M%S") print(format_date_time) df_main_strategy_result = pd.DataFrame df_main_backtest_result = pd.DataFrame list_strategy_result = [] list_backtest_result = [] list_strategy_dateposition = [] path, dirs, files = next(os.walk(CONST_JSON)) total_stock = len(files) scanned_stock = 0 stock_found = 0 counter_result = [] list_test_date_result_price = [] list_test_date_result_date = [] ndayafter_price = [] list_cl_tp_sell = [] list_price_cl_tp_sell = [] list_date_cl_tp_sell = [] # define our clear function def clear(): # for windows if name == 'nt': _ = system('cls') # for mac and linux(here, os.name is 'posix') else: _ = system('clear') first_time = True # for _index, _file in enumerate(sorted(os.listdir(CONST_JSON), key=len)): for _index, _file in enumerate(os.listdir(CONST_JSON)): symbol, stock, code = _file.split('_') code = code[:-5] df_main = pd.read_json(os.path.join(CONST_JSON, _file), orient='index', convert_axes=False, dtype=object) df_main.reset_index(inplace=True) df_main.rename(columns={'index': 'Date'}, inplace=True) df_main.sort_values('Date', inplace=True, ascending=True) df_main = df_main[['Date', 'Open', 'High', 'Low', 'Close', 'Volume']] df_main = df_main.apply(pd.to_numeric, errors='ignore') df_main.reset_index(drop=True, inplace=True) if (testdatefullstring not in df_main['Date'].tolist()): continue dateposition_positive = df_main[df_main['Date'] == testdatefullstring].index.tolist()[0] df_main = df_main[['Date', 'Open', 'High', 'Low', 'Close', 'Volume']] total_row = len(df_main.index) dateposition = -abs(total_row - dateposition_positive) scanned_stock = scanned_stock + 1 progression = scanned_stock / total_stock * 100 print("Scanning", str(scanned_stock), "of", str(total_stock), "stock(s)") print("Progression:", str(round(progression, 2)), "%") print("Current Scanning Stock", stock) clear() if (strategy_option == 1): list_strategy_result = Strategy(df_main).poa_strategy( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass elif (strategy_option == 2): list_strategy_result = Strategy(df_main).ms_strategy( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass elif (strategy_option == 3): list_strategy_result = Strategy(df_main)._3m_stoch_rsi_strategy( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass elif (strategy_option == 4): list_strategy_result = Strategy(df_main).ema_rsi_strategy( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass elif (strategy_option == 5): list_strategy_result = Strategy(df_main).shortTerm_swing_strategy( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass elif (strategy_option == 6): list_strategy_result = Strategy(df_main).midTerm_swing_strategy( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass elif (strategy_option == 7): list_strategy_result = Strategy(df_main).threeMA_n_MACD( stock, duration, dateposition, long_duration, long_duration_period) if list_strategy_result: df_main_strategy_result = (pd.DataFrame(list_strategy_result)) # print(df_main_strategy_result) else: pass if (backtest_option != 0): if (backtest_option == 1): if list_strategy_result: backtest_result = Backtest( df_main, df_main_strategy_result).btst_backtest( duration, long_duration, long_duration_period, backtest_comparison) if first_time: list_backtest_result = backtest_result first_time = False else: for _index, data in enumerate(list_backtest_result): data.extend(backtest_result[_index]) # df_main_backtest_result = (pd.DataFrame(list_backtest_result)).T # print(df_main_backtest_result) else: pass elif (backtest_option == 2): if list_strategy_result: backtest_result = Backtest( df_main, df_main_strategy_result).max_swing_profit_backtest( duration, long_duration, long_duration_period, backtest_comparison) if first_time: list_backtest_result = backtest_result first_time = False else: for _index, data in enumerate(list_backtest_result): data.extend(backtest_result[_index]) # df_main_backtest_result = (pd.DataFrame(list_backtest_result)).T # print(df_main_backtest_result) else: pass elif (backtest_option == 3): if list_strategy_result: backtest_result = Backtest( df_main, df_main_strategy_result).trading_plan( duration, take_profit, cut_loss, long_duration, long_duration_period, backtest_comparison) if first_time: list_backtest_result = backtest_result first_time = False else: for _index, data in enumerate(list_backtest_result): data.extend(backtest_result[_index]) # df_main_backtest_result = (pd.DataFrame(list_backtest_result)).T # print(df_main_backtest_result) else: pass else: if list_strategy_result: if ((strategy_option == 2) | (strategy_option == 3) | (strategy_option == 4)): list_strategy_result = [[item[0]] for item in list_strategy_result] backtest_result = list_strategy_result if first_time: list_backtest_result = backtest_result first_time = False else: for _index, data in enumerate(list_backtest_result): data.extend(backtest_result[_index]) ##---- Display Result ----## df_main_backtest_result = pd.DataFrame() # beginning_date, duration, strategy_option=1, backtest_option=1, take_profit=2, cut_loss=1, long_duration=0, long_duration_period=20 _1_backtest_comparison = "T1_" + backtest_comparison N_backtest_comparison = "TN_" + backtest_comparison if (backtest_option == 0): if list_backtest_result: df_main_result = (pd.DataFrame(list_backtest_result)).T df_main_result.columns = ['Stock', 'T0_Date', 'T0_Close'] df_main_result.sort_values(by='Stock', inplace=True, ascending=True) df_main_result.round({'T0_Close': 3}) df_main_result.to_csv( os.path.join( CONST_RESULT_NOT_BACKTESTED, "START_" + str(beginning_date) + '_Strategy-' + strategies_backtest['Strategy'][strategy_option] + '_' + str(long_duration_period) + '_days_' + format_date_time + '.csv')) print(df_main_result) else: print("No result is found!") elif (backtest_option == 1): if list_backtest_result: df_main_backtest_result = (pd.DataFrame(list_backtest_result)).T df_main_backtest_result.columns = [ 'Stock', 'T0_Date', 'T0_Close', 'Action', 'T1_Date', _1_backtest_comparison ] df_main_backtest_result.sort_values(by=['T0_Date', 'Stock'], inplace=True, ascending=True) df_main_backtest_result.reset_index(drop=True, inplace=True) df_main_backtest_result['Change'], df_main_backtest_result[ 'Change(%)'] = ( df_main_backtest_result[_1_backtest_comparison] - df_main_backtest_result['T0_Close']), ( (df_main_backtest_result[_1_backtest_comparison] - df_main_backtest_result['T0_Close']) / df_main_backtest_result['T0_Close'] * 100) df_main_backtest_result['Result'] = ( ((df_main_backtest_result['Change(%)'] > 0) & (df_main_backtest_result['Action'] == 'SELL')) | (df_main_backtest_result['Action'] == 'TP')) * 1 # total_tp = df_main_backtest_result[(df_main_backtest_result['Action'] == 'TP')].shape[0] # total_cl = df_main_backtest_result[(df_main_backtest_result['Action'] == 'CL')].shape[0] # total_sell = df_main_backtest_result[(df_main_backtest_result['Action'] == 'SELL')].shape[0] # total_win = df_main_backtest_result[(df_main_backtest_result['Result'] > 0)].shape[0] # total_loss = len(df_main_backtest_result.index) - total_win # total_stock = len(df_main_backtest_result.index) # print("Total TP", total_tp) # print("Total CL", total_cl) # print("Total SELL", total_sell) # print("Total Win", total_win) # print("Total Loss", total_loss) # print("Total Stock", total_stock) # list_total_result = [] # list_total_result += [['', '', '', '', '', '', '', 'Total TP', total_tp]] # list_total_result += [['', '', '', '', '', '', '', 'Total CL', total_cl]] # list_total_result += [['', '', '', '', '', '', '', 'Total SELL', total_sell]] # list_total_result += [['', '', '', '', '', '', '', 'Total Win', total_win]] # list_total_result += [['', '', '', '', '', '', '', 'Total Loss', total_loss]] # list_total_result += [['', '', '', '', '', '', '', 'Total Stock', total_stock]] # df_main_backtest_result = df_main_backtest_result.append(pd.DataFrame(list_total_result, columns=df_main_backtest_result.columns.tolist()), ignore_index=True) # print(df_main_backtest_result) else: print("No result is found!") elif (backtest_option == 2): if list_backtest_result: df_main_backtest_result = (pd.DataFrame(list_backtest_result)).T df_main_backtest_result.columns = [ 'Stock', 'T0_Date', 'T0_Close', 'Action', 'TN_Date', N_backtest_comparison ] df_main_backtest_result.sort_values(by=['T0_Date', 'Stock'], inplace=True, ascending=True) df_main_backtest_result.reset_index(drop=True, inplace=True) df_main_backtest_result['Change'], df_main_backtest_result[ 'Change(%)'] = ( df_main_backtest_result[N_backtest_comparison] - df_main_backtest_result['T0_Close']), ( (df_main_backtest_result[N_backtest_comparison] - df_main_backtest_result['T0_Close']) / df_main_backtest_result['T0_Close'] * 100) df_main_backtest_result['Result'] = ( ((df_main_backtest_result['Change(%)'] > 0) & (df_main_backtest_result['Action'] == 'SELL')) | (df_main_backtest_result['Action'] == 'TP')) * 1 else: print("No result is found!") elif (backtest_option == 3): if list_backtest_result: df_main_backtest_result = (pd.DataFrame(list_backtest_result)).T df_main_backtest_result.columns = [ 'Stock', 'T0_Date', 'T0_Close', 'Action', 'TN_Date', N_backtest_comparison ] df_main_backtest_result.sort_values(by=['T0_Date', 'Stock'], inplace=True, ascending=True) df_main_backtest_result.reset_index(drop=True, inplace=True) df_main_backtest_result['Change'], df_main_backtest_result[ 'Change(%)'] = ( df_main_backtest_result[N_backtest_comparison] - df_main_backtest_result['T0_Close']), ( (df_main_backtest_result[N_backtest_comparison] - df_main_backtest_result['T0_Close']) / df_main_backtest_result['T0_Close'] * 100) df_main_backtest_result['Result'] = ( ((df_main_backtest_result['Change(%)'] > 0) & (df_main_backtest_result['Action'] == 'SELL')) | (df_main_backtest_result['Action'] == 'TP')) * 1 else: print("No result is found!") if (len(df_main_backtest_result) != 0): df_main_backtest_result.round({ 'T0_Close': 3, _1_backtest_comparison: 3, N_backtest_comparison: 3, 'Change': 3, 'Change(%)': 2 }) total_tp = df_main_backtest_result[( df_main_backtest_result['Action'] == 'TP')].shape[0] total_cl = df_main_backtest_result[( df_main_backtest_result['Action'] == 'CL')].shape[0] total_sell = df_main_backtest_result[( df_main_backtest_result['Action'] == 'SELL')].shape[0] total_win = df_main_backtest_result[(df_main_backtest_result['Result'] > 0)].shape[0] total_loss = len(df_main_backtest_result.index) - total_win total_stock = len(df_main_backtest_result.index) print("Total TP", total_tp) print("Total CL", total_cl) print("Total SELL", total_sell) print("Total Win", total_win) print("Total Loss", total_loss) print("Total Stock", total_stock) list_total_result = [] list_total_result += [[ '', '', '', '', '', '', '', 'Total TP', total_tp ]] list_total_result += [[ '', '', '', '', '', '', '', 'Total CL', total_cl ]] list_total_result += [[ '', '', '', '', '', '', '', 'Total SELL', total_sell ]] list_total_result += [[ '', '', '', '', '', '', '', 'Total Win', total_win ]] list_total_result += [[ '', '', '', '', '', '', '', 'Total Loss', total_loss ]] list_total_result += [[ '', '', '', '', '', '', '', 'Total Stock', total_stock ]] df_main_backtest_result = df_main_backtest_result.append( pd.DataFrame(list_total_result, columns=df_main_backtest_result.columns.tolist()), ignore_index=True) df_main_backtest_result.to_csv( os.path.join( CONST_RESULT_BACKTESTED, "START_" + str(beginning_date) + '_Strategy-' + strategies_backtest['Strategy'][strategy_option] + '_' + str(long_duration_period) + '_days' + '_Backtest-' + strategies_backtest['Backtest'][backtest_option] + '_' + str(duration) + '_days_' + format_date_time + '.csv')) print(df_main_backtest_result) print("END")
strategy_id = 1 if short_sma > long_sma and self.bought[symbol] == "OUT": sig_dir = 'LONG' signal = SignalEvent(strategy_id, symbol, dt, sig_dir, strength) self.events.put(signal) self.bought[symbol] = 'LONG' elif short_sma < long_sma and self.bought[symbol] == "LONG": sig_dir = 'EXIT' signal = SignalEvent(strategy_id, symbol, dt, sig_dir, strength) self.events.put(signal) self.bought[symbol] = 'OUT' if __name__ == "__main__": csv_dir = REPLACE_WITH_YOUR_CSV_DIR_HERE symbol_list = ['AAPL'] initial_capital = 100000.0 start_date = datetime.datetime(1990, 1, 1, 0, 0, 0) heartbeat = 0.0 backtest = Backtest(csv_dir, symbol_list, initial_capital, heartbeat, start_date, HistoricCSVDataHandler, SimulatedExecutionHandler, Portfolio, MovingAverageCrossStrategy) backtest.simulate_trading()
'Lag1': lags[1] * 100.0, 'Lag2': lags[2] * 100.0 }) pred_reshape = pred_series.values.reshape(1, -1) pred = self.model.predict(pred_reshape) if pred > 0 and not self.long_market: self.long_market = True signal = SignalEvent(1, sym, cur_date, 'LONG', 1.0) self.events.put(signal) if pred < 0 and self.long_market: self.long_market = False signal = SignalEvent(1, sym, cur_date, 'EXIT', 1.0) self.events.put(signal) if __name__ == "__main__": csv_dir = '/Users/josephgross/Desktop/csv_dir' symbol_list = ['SPY'] initial_capital = 100000.0 hearbeat = 0.0 start_date = dt.datetime(2017, 1, 3) backtest = Backtest(csv_dir, symbol_list, initial_capital, hearbeat, start_date, HistoricCSVDataHandler, SimulatedExecutionHandler, Portfolio, SPYDailyForecastStrategy) backtest.simulate_trading()
Created on Mon Apr 23 16:46:25 2018 @author: rl17174 """ import os os.chdir('/Users/sunrukawa/Desktop/python/qishi_qr/bin/') from strategy import CorpusStrategy from data import OHLCData from portfolio import EqualWeightPort from backtest import Backtest n = 6 # process data OHLC = OHLCData() data_dir = '../data/OHLC data/000001.SS.csv' OHLC.read(data_dir) price_ts = OHLC.get_clean_price_ts('Adj Close') train_ts = price_ts['1995':'2004'] test_ts = price_ts['2005':'2013'] # create strategy strat = CorpusStrategy(train_ts, n) strat.get_vectorized_signal(test_ts) # accept signal and produce position port = EqualWeightPort() port.get_position(strat.signals.iloc[(n - 1):]) # backtest my_bt = Backtest(test_ts[port.positions.index], port.positions) stats = my_bt.output_summary_stats(rf=0.02)