backtest double opening & calculating cash incorrectly
-
hey team, first want to thank you for putting together such an amazing package. really loving backtrader.
i'm having a little issue ive spent a while trying to figure out. i will leave all code below + data + a walkthrough video. if you can see what is going on, please help :)
problem -
when i run my backtest on the strategy attached, it does multiple open orders as buys, which it shouldnt as im going 95% all in. ive been tracking the cash amount, and it goes down after the first buy but the second, and third buy, it still tries to buy the same size as before as if it still had that much cashin this instance, im using ethereum price and an example of the over buying is shown in the first few buys.. it will buy 1,006 eth on one day, and show the cash balance go from 1,000,000 --> 18,931 as im using the all in sizer at 95%.. but then it will go ahead and buy again for the same amount of 1,006 eth even though it shows the cash balance can't afford that. it will repeat this process 2-6 times, and then finally put in a close order
question-
how do i make it so the backtest only does one opening order, and then a closing order of that same amount?video overview- i made this short video to show the problem
https://www.dropbox.com/s/iqyd274vwki278l/bt_bug_video.mov?dl=0data: https://www.dropbox.com/s/pcs098zwwvb1zed/bt_data.csv?dl=0
console dump: https://www.dropbox.com/s/c74reugk0geb6gl/consoledump.txt?dl=0
code:
''' this back tester does not seem to be working it double buys and when it sells even at a loss, the cash balance goes up ''' from datetime import datetime import backtrader as bt import backtrader.analyzers as btanalyzers import pandas as pd import backtrader.feeds as btfeeds from backtrader.feeds import GenericCSVData import pprint import sys # I used this and at the bottom to output data into a txt file to debug #sys.stdout = open('live_strategies/june22/consoledump.txt', 'w') pause = 0 class Strategy(bt.SignalStrategy): params = (('closeThreshold', pause),) def __init__(self): food = 1 def next(self): since_trade = self.params.closeThreshold if since_trade >= pause: if self.data.close[0] > self.data.sma20[0]: print(' ') print('----') size = int(self.broker.getcash()) print(f'this is our current cash amount {size}') #print(f'this is our position: {self.position}') print('open') print(self.buy()) # printing the below to debug print(self.data.close[0]) print(self.data.sma20[0]) elif self.data.close[0]< self.data.sma41[0]: print(' ') print('----') size = int(self.broker.getcash()) print(f'this is our current cash amount {size}') #print(f'this is our position: {self.position}') print('close') print(self.close()) # how to close whole # printing the below to debug print(self.data.close[0]) print(self.data.sma41[0]) self.params.closeThreshold = 0 self.params.closeThreshold += 1 cerebro = bt.Cerebro() cerebro.addstrategy(Strategy) class GenericCSV_PE(GenericCSVData): lines = ( 'sma41', 'vzz_pc', 'sma20') params = (('sma41', 12), ('vzz_pc', 6) ,('sma20', 13)) data0 = GenericCSV_PE( dataname = 'live_strategies/june22/bt_data.csv', fromdate=datetime(2018, 2, 16), # todate = datetime(2022, 5, 2), todate = datetime(2019, 5, 15), reverse = False, datetime = 0, close = 1, gw = 3, volume = 2, sma41 = 12, sma20=13, xx_pc = 5, vzz_pc = 6, openinterst = -1, dtformat = "%Y-%m-%d", order = -1, ) cerebro.broker.set_cash(1000000) cerebro.addobserver( bt.observers.BuySell, barplot=True, bardist=0.1) cerebro.broker.setcommission(commission=0.001) cerebro.adddata(data0) cerebro.addsizer(bt.sizers.AllInSizer, percents=95) cerebro.addanalyzer(btanalyzers.SharpeRatio, _name = 'sharpe') # this is the transactions analyzer cerebro.addanalyzer(btanalyzers.Transactions, _name = 'tx') # this is the trade analyzer cerebro.addanalyzer(btanalyzers.TradeAnalyzer, _name = 'trades') # analyze DD cerebro.addanalyzer(bt.analyzers.DrawDown, _name="dd") cerebro.addanalyzer(btanalyzers.SQN, _name='sqn') # class backtrader.analyzers.SQN() cerebro.run() back = cerebro.run() endvalue = cerebro.broker.getvalue() sharpe = back[0].analyzers.sharpe.get_analysis()['sharperatio'] dd = back[0].analyzers.dd.get_analysis()['drawdown'] sharpe = round(float(sharpe),3) txs = back[0].analyzers.tx.get_analysis() trades = back[0].analyzers.trades.get_analysis() pp = pprint.PrettyPrinter(indent=4) pp.pprint(txs) txamount = len(txs) value = int(cerebro.broker.getvalue()) final = "{:,}".format(value) print(f"pause: {pause} | vwma index: None | sharpe: {sharpe} | txs: {txamount} | final: ${final} dd: {dd} ") #sys.stdout.close() #cerebro.plot()
-
you can close this thread. the problem was some orders would get rejected