Why is the self.position always zero ?
-
Dear friend, I use a minute level data to backtest , I set the buy condition: if not self.position , but the position is always zero,but if I use the dayly level data, there are no problem. The data is from the sample . I can 't find the cause. can you help me? Thanks a lot.
from __future__ import (absolute_import, division, print_function,unicode_literals) import backtrader as bt import backtrader.indicators as btind import backtrader.feeds as btfeeds import datetime import os.path import sys class Mytest(bt.Strategy): params = (('fast',5),('slow',20),) lines = ('fast','slow',) def log(self,txt,dt = None): '''log function for this strategy''' dt = dt or self.data.datetime[0] if isinstance(dt,float): dt = bt.num2date(dt) print('%s %s' % (dt.isoformat(),txt)) def __init__(self): # To control operation entries self.order = None self.lines.fast = btind.SimpleMovingAverage(period = self.p.fast) self.lines.slow = btind.SimpleMovingAverage( period = self.p.slow) self.buysig = btind.CrossOver(self.lines.fast,self.lines.slow) def notify_order(self,order): if order.status in [order.Submitted, order.Accepted]: #buy/sell order have been submitted, nothing to do return self.order = None def next(self): if self.order: return # if an order is active, no new orders are allowed self.log(self.getposition().size)# always get the zero result. why? if not self.position: if self.buysig[0] > 0: self.order = self.buy(size = 100) self.log('buy') else: if self.buysig[0] < 0: self.order = self.sell(size = 100) self.log('sell') def runstrategy(): #args = parse_args() #create a cerebro cerebro = bt.Cerebro() #get the dates from the args #fromdate = datetime.datetime.striptime(args.fromdate,'%Y-%m-%d') fromdate = datetime.datetime(2006,1,2) #today = datetime.datetime.striptime(args.today,'%Y-%m-%d') today = datetime.datetime(2006,2,10) modpath=os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.join(modpath,'datas/2006-01-02-volume-min-001.txt') #datapath = os.path.join(modpath,'datas/yhoo-1996-2015.txt') data = btfeeds.BacktraderCSVData( dataname = datapath, frmodate = fromdate, today = today, timeframe=bt.TimeFrame.Minutes, compression = 1 ) #cerebro.adddata(data) cerebro.resampledata(data, timeframe = bt.TimeFrame.Minutes, compression = 60, ) cerebro.addstrategy(Mytest) cerebro.broker.setcash(10000) cerebro.broker.setcommission(0.01) #cerebro.addsizer(bt.sizers.FixedSize,stake = 100) cerebro.run() cerebro.plot() if __name__ == '__main__': runstrategy()
-
self.position
is always zero because the position is never open. it can be variety of reasons: you can't buy/sell 100 shares due to lack of funds, SMA don't cross etc. Get more outputs and check what is going on. -
I changed the cash 100000. and the log is :
2006-01-06T12:00:00 buy
2006-01-06T12:00:00 0
2006-01-09T22:00:00 buy
2006-01-09T22:00:00 0
2006-01-11T11:00:00 buy
2006-01-11T11:00:00 0
2006-01-12T18:00:00 buy
2006-01-12T18:00:00 0
2006-01-16T14:00:00 buy
2006-01-16T14:00:00 0
2006-01-19T12:00:00 buy
2006-01-19T12:00:00 0
2006-01-24T11:00:00 buy
2006-01-24T11:00:00 0
2006-01-31T19:00:00 buy
2006-01-31T19:00:00 0
2006-02-03T21:00:00 buy
2006-02-03T21:00:00 0
2006-02-08T17:00:00 buy
2006-02-08T17:00:00 0
2006-02-13T18:00:00 buy
2006-02-13T18:00:00 0
2006-02-15T17:00:00 buy
2006-02-15T17:00:00 0
2006-02-16T13:00:00 buy
2006-02-16T13:00:00 0
2006-02-20T20:00:00 buy
2006-02-20T20:00:00 0
2006-02-22T15:00:00 buy
2006-02-22T15:00:00 0 -
Your trying to buy 100 shares at 3,600 per share with $10,000. That's always going to be a problem. Try using 1 share or putting a lot of money in the account.
Try adding in these to get more information:
def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do return # Check if an order has been completed # Attention: broker could reject order if not enougth cash if order.status in [order.Canceled, order.Margin]: if order.isbuy(): self.log("BUY FAILED, Cancelled or Margin") self.log if order.status in [order.Completed, order.Canceled, order.Margin]: if order.isbuy(): self.log( "BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f" % (order.executed.price, order.executed.value, order.executed.comm) ) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log( "SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f" % (order.executed.price, order.executed.value, order.executed.comm) ) self.bar_executed = len(self) # Write down: no pending order self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log("OPERATION PROFIT, GROSS %.2f, NET %.2f" % (trade.pnl, trade.pnlcomm))
Also maybe print out a OHLC log like this:
self.log( "o {:5.2f}\th {:5.2f}\tl {:5.2f}\tc {:5.2f}\tv {:5.0f}".format( self.datas[0].open[0], self.datas[0].high[0], self.datas[0].low[0], self.datas[0].close[0], self.datas[0].volume[0], ) )
Finally, if you just want to close out your long position, use self.close, not self.sell.
-
Thank You ! I got it .
I run as your code , the log is :
2006-01-06T12:00:00 buy
2006-01-06T13:00:00 Buy Execute, Price: 3670,Cost:3670,Comm 36.70 ,position 1
2006-01-09T22:00:00 Sell Execute, Price: 3684,Cost:3670,Comm 36.84 position 0
2006-01-09T22:00:00 OPERATION PROFIT ,GROSS 14.00,Net -59.54
2006-01-09T22:00:00 buy
2006-01-10T10:00:00 Buy Execute, Price: 3676,Cost:3676,Comm 36.76 ,position 1
2006-01-10T11:00:00 Sell Execute, Price: 3663,Cost:3676,Comm 36.63 position 0
2006-01-10T11:00:00 OPERATION PROFIT ,GROSS -13.00,Net -86.39
2006-01-11T11:00:00 buy
2006-01-11T12:00:00 Buy Execute, Price: 3677,Cost:3677,Comm 36.77 ,position 1
2006-01-12T15:00:00 Sell Execute, Price: 3670,Cost:3677,Comm 36.70 position 0
2006-01-12T15:00:00 OPERATION PROFIT ,GROSS -7.00,Net -80.47
2006-01-12T18:00:00 buy
2006-01-12T19:00:00 Buy Execute, Price: 3687,Cost:3687,Comm 36.87 ,position 1
2006-01-13T10:00:00 Sell Execute, Price: 3666,Cost:3687,Comm 36.66 position 0
2006-01-13T10:00:00 OPERATION PROFIT ,GROSS -21.00,Net -94.53
2006-01-16T14:00:00 buy
2006-01-16T15:00:00 Buy Execute, Price: 3647,Cost:3647,Comm 36.47 ,position 1
2006-01-17T13:00:00 Sell Execute, Price: 3624,Cost:3647,Comm 36.24 position 0
2006-01-17T13:00:00 OPERATION PROFIT ,GROSS -23.00,Net -95.71
2006-01-19T12:00:00 buy
2006-01-19T13:00:00 Buy Execute, Price: 3597,Cost:3597,Comm 35.97 ,position 1
2006-01-20T17:00:00 Sell Execute, Price: 3592,Cost:3597,Comm 35.92 position 0
2006-01-20T17:00:00 OPERATION PROFIT ,GROSS -5.00,Net -76.89 -
Awesome!