Help with simple strategy position size always 0
-
Hi! im new with backtrader and im traying to implement a simple strategy were it buys on SMA cross and sell on market close on an APPLE intraday data.
My problem is that there is not seems to be buy execution... self.position is always 0. (im using 10% of my portfoltio on every trader, at least that is the intention)
But on market close it seem to close the position and it gets negative values..
can you help me? i cant find whats missing...
here is the code for the strategy
class smacross(bt.Strategy): # list of parameters which are configurable for the strategy params = dict(pfast = 20, pslow=200) def __init__(self): sma1 = bt.ind.SMA(period=self.params.pfast) # fast moving average sma2 = bt.ind.SMA(period=self.params.pslow) # slow moving average self.crossover = bt.ind.CrossOver(sma1, sma2) # crossover signal def next(self): if not self.position: # not in the market if self.crossover > 0: # if fast crosses slow to the upside size= int(self.broker.getcash() / self.data) self.buy(size=size) # enter long print(self.position) elif self.data.datetime.time() >= datetime.time(16,50): #self.crossover < 0: # in the market & cross to the downside self.close() # close long position
and this is the general code
from estrategia import smacross import estrategia import pandas as pd # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(estrategia.smacross) # Create a Data Feed data = bt.feeds.GenericCSVData( dataname= "intra_AAPL_short.csv", datetime=0, timeframe=bt.TimeFrame.Minutes, dtformat=('%Y-%m-%d %H:%M:%S'), open=1, high=2, low=3, close=4, volume=5, openinterest=-1,) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(60000) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='mysharpe') thestrats = cerebro.run() thestrat = thestrats[0] print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) print('Sharpe Ratio:', thestrat.analyzers.mysharpe.get_analysis()) cerebro.plot()
The results are the following... i printed position.size an it always is in 0 size, position is closed and it get negative value...
Starting Portfolio Value: 60000.00
--- Position Begin- Size: 0
- Price: 0.0
- Price orig: 0.0
- Closed: 0
- Opened: 0
- Adjbase: None
--- Position End
--- Position Begin - Size: 0
- Price: 0.0
- Price orig: 42.1594074358
- Closed: -1423
- Opened: 0
- Adjbase: 41.949416179
--- Position End
--- Position Begin - Size: 0
- Price: 0.0
- Price orig: 42.1178975362
- Closed: -1417
- Opened: 0
- Adjbase: 42.6428756781
thanks in advanced, any help will be great!!
-
Hi Ramacap,
i think this forum would be more fitting for such a question:
https://community.backtrader.com/category/7/general-code-helpNonetheless, I think you should try to better understand whats going on by printing out each part of that statement
size= int(self.broker.getcash() / self.data)
A better way to get where you want is:
percent = 0.95 self.order = self.order_target_percent(target=percent)
-
You are printing the position right after the
buy
method is called. The position is not updated at this point - it will get it value only after the buy order will be completed.I've updated your code with:
def notify_order(self, order): print('{}: Order ref: {} / Type {} / Status {}'.format( self.data.datetime.date(0), order.ref, 'Buy' * order.isbuy() or 'Sell', order.getstatusname())) if order.status == order.Completed: print(self.position)
and the output is now:
Starting Portfolio Value: 60000.00 1999-09-16: Order ref: 1 / Type Buy / Status Submitted 1999-09-16: Order ref: 1 / Type Buy / Status Accepted 1999-09-16: Order ref: 1 / Type Buy / Status Completed --- Position Begin - Size: 1478 - Price: 40.53125 - Price orig: 0.0 - Closed: 0 - Opened: 1478 - Adjbase: 40.859375 --- Position End ...
( I was running your code on some yhoo-1996-2015 sample data)