Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. Michael172
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    M
    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 16
    • Best 2
    • Controversial 0
    • Groups 0

    Michael172

    @Michael172

    2
    Reputation
    563
    Profile views
    16
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Michael172 Unfollow Follow

    Best posts made by Michael172

    • RE: Pairs Trading example error

      Just curious to know how did you solve it? I get the same error when I run it. My data is definitely shorter than 10000 lines (even though there is no such limit anyway).. I am also studying paris trading. What is the problem and solution ?

      thanks

      Michael

      posted in General Code/Help
      M
      Michael172
    • RE: Pairs Trading example error

      Right, I have searched the forum and saw you guys had a lot of discussion on this back in Dec, 2016 and made many changes along the way. I'll keep reading and researching, but is there a github depository or somewhere else where the latest working version of this example reside? That would save a lot of time.

      thanks

      Michael

      posted in General Code/Help
      M
      Michael172

    Latest posts made by Michael172

    • RE: Stop Orders behaving strangely, what's missing??!!

      After some further digging, it looks like that the stop orders were not expiring as expected. So, they were executed at much later than designed. My understanding of "valid" parameter is not exactly correct.... probably. Anyway, I explicitly specified the valid parameter to 1 day as such:

      self.sell(data=d, size=self.pos[d], exectype = bt.Order.Stop, price = self.longTrailStop[d], valid = validTime)
      

      where validTime is defined as:

      validTime = self.data.datetime.date(0) + datetime.timedelta(days=self.params.valid)
      

      After this change, the stop orderes are expiring as expected, see below:

      ### 2018-01-08 IH.CFE current positions: 143.66, trade length: 3, ATR: 41.765, trade high: 2943.39, trade low: 2901.99, close: 2934.186, longStop: 2901.622, shortStop: 2946.551
      2018-01-09, Status Submitted: Ref: 275, Size: -143.66, Price: 2901.62178
      2018-01-09, Status Accepted: Ref: 275, Size: -143.66, Price: 2901.62178
      ### 2018-01-09 IH.CFE current positions: 143.66, trade length: 4, ATR: 41.765, trade high: 2963.79, trade low: 2901.99, close: 2963.786, longStop: 2922.022, shortStop: 2946.551
      2018-01-10, Status Submitted: Ref: 276, Size: -143.66, Price: 2922.02178
      2018-01-10, Status Accepted: Ref: 276, Size: -143.66, Price: 2922.02178
      2018-01-10, Status Expired: Ref: 275, Size: -143.66, Price: 2901.62178
      ### 2018-01-10 IH.CFE current positions: 143.66, trade length: 5, ATR: 41.765, trade high: 2987.39, trade low: 2901.99, close: 2984.386, longStop: 2945.622, shortStop: 2946.551
      2018-01-11, Status Submitted: Ref: 277, Size: -143.66, Price: 2945.62178
      2018-01-11, Status Accepted: Ref: 277, Size: -143.66, Price: 2945.62178
      2018-01-11, Status Expired: Ref: 276, Size: -143.66, Price: 2922.02178
      

      thanks all... !

      posted in General Code/Help
      M
      Michael172
    • Stop Orders behaving strangely, what's missing??!!

      Hi, I am using 'Order.Stop' in the following code for a simple strategy. But, the stops orders are not executing as expected after the first two trades. I am including the minimal reproducible code here first and then I'll describe the problem in detail.

      
      import backtrader as bt
      import pandas as pd
      pd.core.common.is_list_like = pd.api.types.is_list_like
      import datetime as dt
      import matplotlib
      from tabulate import tabulate
      
      
      print  (matplotlib.rcParams['backend'])
      
      ### main strategy: 
      class maCross(bt.Strategy):
          '''
      
          oneplot = Force all datas to plot on the same master.
          '''
          params = (
          ('sma1', 10),
          ('sma2', 50),
          ('newMinMax', 10),  # period for new close's highs or lows
          ('oneplot', True),
          ('atrPeriod', 20),
          ('lPerc', 0.01),
          ('sPerc', 0.015),
          ('tPerc', 0.02),
          ('RiskPerc', 0.006)
          )
       
          def __init__(self):
              
              
              self.o = dict()  # orders per data (main, stop, limit, manual-close)
              self.holding = dict()  # holding periods per data
              self.tradeHigh = dict() # high during the current trade
              self.tradeLow = dict() # low during the current trade
              self.tempHigh = dict() # temperory variable
              self.tempLow = dict() # temperory variable
              self.tradeATR = dict()
              self.longTrailStop = dict()
              self.shortTrailStop = dict()
              self.pos = dict()
              self.tradePrice = dict()
              self.atBarOpen = {}
              
      
              '''
              Create an dictionary of indicators so that we can dynamically add the
              indicators to the strategy using a loop. This mean the strategy will
              work with any numner of data feeds. 
              '''
              self.inds = dict()
              for i, d in enumerate(self.datas):
                  self.inds[d] = dict()
                  self.inds[d]['sma1'] = bt.indicators.SimpleMovingAverage(
                      d.close, period=self.params.sma1)
                  self.inds[d]['sma2'] = bt.indicators.SimpleMovingAverage(
                      d.close, period=self.params.sma2)
      
                  self.inds[d]['upTrend'] =  self.inds[d]['sma1'] > self.inds[d]['sma2']
                  self.inds[d]['downTrend'] = self.inds[d]['sma1'] < self.inds[d]['sma2']
      
                  self.inds[d]['newLow'] = bt.ind.Lowest(d.close, period = self.params.newMinMax)
                  self.inds[d]['newHigh'] = bt.ind.Highest(d.close, period = self.params.newMinMax)
                  self.inds[d]['ATR'] = bt.ind.ATR(d, period = self.params.atrPeriod)
                  
                  self.atBarOpen[d._name] = None
      
                  if i > 0: #Check we are not on the first loop of data feed:
                      if self.p.oneplot == True:
                          d.plotinfo.plotmaster = self.datas[0]
          
          def next(self):
              
              
              for i, d in enumerate(self.datas):
                  dt, dn = self.datetime.date(), d._name
                  self.pos[d] = self.getposition(d).size         
                  
                  if  self.pos[d] == 0:  # no existing positions:
                      
                       self.tradeHigh[d] = self.tempHigh[d] = 0
                       self.tradeLow[d] = self.tempLow[d] = 10000000
                       self.tradeATR[d] = self.inds[d]['ATR'][-1]
                       qty = 1000000 * self.params.RiskPerc / self.tradeATR[d]
                       qty = round (qty, 1)
                       
       #                if  self.getdatabyname(dn).close[0] >= self.inds[d]['newHigh'][0]:
                       if    self.inds[d]['upTrend'][0] ==1 and d.close[0] >= self.inds[d]['newHigh'][0]: 
                                 print("______________")
                                 print("{}: time to buy on this date: {}" .format(dn, dt) ) 
                                 self.buy(data=d, size=qty)       
                                
                       elif self.inds[d]['downTrend'][0] ==1 and d.close[0] <= self.inds[d]['newLow'][0]: 
                               # print(self.inds[d]['downTrend'][0])
                               print("______________")
                               print("{}: time to sell on this date: {}" .format(dn, dt) ) 
                               self.sell(data=d, size=qty)  
                                
                       else:
      #                     print("No trades today: {}" .format(dt))
                           notrade = 1
                         
                          
                  else:       # already have a position:
                       
      
                       self.tradeLen = len(self) - self.atBarOpen[d._name]
      
                       if self.tradeLen ==0 :
                           self.tradePrice[d] = d.open[0]
                           self.longTrailStop[d] = self.tradePrice[d] - self.tradeATR[d]
                           self.shortTrailStop[d] = self.tradePrice[d] + self.tradeATR[d]
                           print('\r\n $$$ New trade initiated for: {} on {} -- current positions: {},opened at: {}' 
                             .format (dn, dt, round(self.pos[d],2), round(self.tradePrice[d],3 )))
                        
                          
                       else:
                          self.tradeHigh[d] = max(d.high[0], self.tradeHigh[d], self.tradePrice[d])     
                          self.tradeLow[d] = min(self.tradeLow[d], d.low[0], self.tradePrice[d])
                          
                          if d.close[0] >= self.longTrailStop[d] + self.tradeATR[d]:
                              self.longTrailStop[d] = self.tradeHigh[d] - self.tradeATR[d]
      
                          if d.close[0] <= self.shortTrailStop[d] - self.tradeATR[d]:
                              self.shortTrailStop[d] = self.tradeLow[d] + self.tradeATR[d]
                       
                       print('\r\n ### {} {} current positions: {}, trade length: {}, ATR: {}, trade high: {}, 
                              trade low: {}, close: {}, longStop: {}, shortStop: {}' 
                             .format (dt, dn, round(self.pos[d],2), self.tradeLen, round(self.tradeATR[d],3),  
                                      round(self.tradeHigh[d],2), round(self.tradeLow[d],2), round(d.close[0],3), 
                                      round(self.longTrailStop[d], 3), round(self.shortTrailStop[d],3) ))
                       
      
                       if self.order is None:
                           
                       
                           if (self.pos[d] > 0 and self.tradeLen >0 ):
                                self.sell(data=d, size=self.pos[d], exectype = bt.Order.Stop, 
                                                   price = self.longTrailStop[d], valid = 0)
                     
                           if (self.pos[d] < 0 and  self.tradeLen >0 ):
                                self.buy(data=d, size=-self.pos[d], exectype = bt.Order.Stop, 
                                                   price = self.shortTrailStop[d], valid =0)
                                
      
          
          def log(self, txt, dt=None):
              ''' Logging function fot this strategy'''
              dt = dt or self.datas[0].datetime.date(0)
              
              print('%s, %s' % (dt.isoformat(), txt))
              
          def notify_order(self, order):
              dt = self.data.datetime.date()
              if order.status in [order.Submitted, order.Accepted]:           
                  print('\r\n {}, Status {}: Ref: {}, Size: {}, Price: {}'.format(
      				dt,
      				order.Status[order.status],
      				order.ref,
      				round(order.size, 2),
      				'NA' if not order.price else round(order.price,5)
      			))
      
                  # 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 enough cash
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(' BUY EXECUTED, %.2f' % order.executed.price )
                      self.log(' Just completed BUY order with ref id: %d' % order.ref)
                  elif order.issell():
                      self.log(' SELL EXECUTED, %.2f' % order.executed.price)
                      self.log(' Just completed SELL order with ref id: %d' % order.ref)
      
                  self.bar_executed = len(self)
                  # print (self.bar_executed)
                  
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
      
              # Write down: no pending order
              self.order = None
      
              
          def notify_trade(self, trade):
              dt = self.data.datetime.date()
              self.atBarOpen[trade.data._name] = trade.baropen
      
      
              if trade.isopen:
                  
                  tradeLength = trade.barlen
                  tradeDuration = len(trade.data)
                  print ('\r\n +++Openning Trade Notification: {} opened on bar {}  at price: {} trade duration: {} 
                          at bar no.: {}' .format(trade.data._name, self.atBarOpen[trade.data._name], 
                           round( trade.price,3), tradeLength, tradeDuration) )
              
              
              if trade.isclosed:
                  print('\r\n ---Closing Trade Notification: {} {} Opened at {}, Current Valuet {}: PnL Gross {}, Net {}'
                    .format(                            dt,
                                                      trade.data._name,
                                                      round(trade.price,3),
                                                      trade.value,
                                                      round(trade.pnl,2),
                                                      round(trade.pnlcomm,2)))
      
      #Create an instance of cerebro
      cerebro = bt.Cerebro()
                   
      #Add our strategy
      cerebro.addstrategy(maCross, oneplot=False)
                  
                  
                  
      start = dt.datetime(2017, 10, 1)
      end =  dt.datetime(2018,2, 28)
                  
      # chagne the path for your own data:
      datapath = 'F:\\Michael\\Python\\backtrader\\' 
      skiprows = 0
      header = 0 
       # data symbol used for this example:
      s = "IH_CFE"
                  
      datafile = datapath + s + '.csv'
      dataframe = pd.read_csv(datafile,
                                  skiprows=skiprows,
                                  header=header,
                                  encoding = 'gbk',
                                  parse_dates=True,
                                  index_col=0)
                  
      dataframe.columns =  ( ' WINDCODE', 'open', 'high', 'low', 'close', 'volume')
      dataframe = dataframe.loc[start: end]
      dataframe = dataframe.fillna(method = 'backfill')
      data = bt.feeds.PandasData(dataname= dataframe)
      cerebro.adddata(data, name = s)    # Give the data to cerebro
                        
       #Variable for our starting cash
      startcash = 1000000
                  
       # Set our desired cash start
      cerebro.broker.setcash(startcash)
                  
      cerebro.addobserver(bt.observers.BuySell)
      cerebro.addobserver(bt.observers.Trades)
                  
      #add executed file:
      cerebro.addwriter(bt.WriterFile, csv=True, out = "trade_history.csv" )
      # cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
      # cerebro.addanalyzer(trade_list, _name='trade_list')
                   
      # Run over everything
      result = cerebro.run(stdstats=False, tradehistory=True)
                              
      

      Ticker I am using in this example is "IH_CFE". The output of the first trade re as follows. I included many print statements in an attempt to resovle the issue. The first two trades executed as as expected. The stop order is sent out on the second day of each trade with 'valid=0', so the order is only good for that day. Then the stop price is updated based on the day's data then send out again the next day. This works well as show in this trade output initiated on 2018-01-02:

      ______________
      IH_CFE: time to buy on this date: 2018-01-02
      
       2018-01-03, Status Submitted: Ref: 3, Size: 143.7, Price: NA
      
       2018-01-03, Status Accepted: Ref: 3, Size: 143.7, Price: NA
      2018-01-03,  BUY EXECUTED, 2904.79
      2018-01-03,  Just completed BUY order with ref id: 3
      
       +++Openning Trade Notification: IH_CFE opened on bar 62  at price: 2904.786 trade duration: 0 at bar no.: 62
      
       $$$ New trade initiated for: IH_CFE on 2018-01-03 -- current positions: 143.7,opened at: 2904.786
      
       ### 2018-01-03 IH_CFE current positions: 143.7, trade length: 0, ATR: 41.765, trade high: 0, trade low: 10000000, close: 2906.986, longStop: 2863.022, shortStop: 2946.551
      
       ### 2018-01-04 IH_CFE current positions: 143.7, trade length: 1, ATR: 41.765, trade high: 2924.99, trade low: 2901.99, close: 2913.186, longStop: 2883.222, shortStop: 2946.551
      
       2018-01-05, Status Submitted: Ref: 4, Size: -143.7, Price: 2883.22178
      
       2018-01-05, Status Accepted: Ref: 4, Size: -143.7, Price: 2883.22178
      
       ### 2018-01-05 IH_CFE current positions: 143.7, trade length: 2, ATR: 41.765, trade high: 2930.99, trade low: 2901.99, close: 2926.786, longStop: 2889.222, shortStop: 2946.551
      
       2018-01-08, Status Submitted: Ref: 5, Size: -143.7, Price: 2889.22178
      
       2018-01-08, Status Accepted: Ref: 5, Size: -143.7, Price: 2889.22178
      
       ### 2018-01-08 IH_CFE current positions: 143.7, trade length: 3, ATR: 41.765, trade high: 2943.39, trade low: 2901.99, close: 2934.186, longStop: 2901.622, shortStop: 2946.551
      
       2018-01-09, Status Submitted: Ref: 6, Size: -143.7, Price: 2901.62178
      
       2018-01-09, Status Accepted: Ref: 6, Size: -143.7, Price: 2901.62178
      
       ### 2018-01-09 IH_CFE current positions: 143.7, trade length: 4, ATR: 41.765, trade high: 2963.79, trade low: 2901.99, close: 2963.786, longStop: 2922.022, shortStop: 2946.551
      
       2018-01-10, Status Submitted: Ref: 7, Size: -143.7, Price: 2922.02178
      
       2018-01-10, Status Accepted: Ref: 7, Size: -143.7, Price: 2922.02178
      
       ### 2018-01-10 IH_CFE current positions: 143.7, trade length: 5, ATR: 41.765, trade high: 2987.39, trade low: 2901.99, close: 2984.386, longStop: 2945.622, shortStop: 2946.551
      
       2018-01-11, Status Submitted: Ref: 8, Size: -143.7, Price: 2945.62178
      
       2018-01-11, Status Accepted: Ref: 8, Size: -143.7, Price: 2945.62178
      
       ### 2018-01-11 IH_CFE current positions: 143.7, trade length: 6, ATR: 41.765, trade high: 2995.19, trade low: 2901.99, close: 2982.986, longStop: 2945.622, shortStop: 2946.551
      
       2018-01-12, Status Submitted: Ref: 9, Size: -143.7, Price: 2945.62178
      
       2018-01-12, Status Accepted: Ref: 9, Size: -143.7, Price: 2945.62178
      
       ### 2018-01-12 IH_CFE current positions: 143.7, trade length: 7, ATR: 41.765, trade high: 3010.59, trade low: 2901.99, close: 3010.586, longStop: 2968.822, shortStop: 2946.551
      
       2018-01-15, Status Submitted: Ref: 10, Size: -143.7, Price: 2968.82178
      
       2018-01-15, Status Accepted: Ref: 10, Size: -143.7, Price: 2968.82178
      
       ### 2018-01-15 IH_CFE current positions: 143.7, trade length: 8, ATR: 41.765, trade high: 3055.59, trade low: 2901.99, close: 3033.186, longStop: 3013.822, shortStop: 2946.551
      
       2018-01-16, Status Submitted: Ref: 11, Size: -143.7, Price: 3013.82178
      
       2018-01-16, Status Accepted: Ref: 11, Size: -143.7, Price: 3013.82178
      
       ### 2018-01-16 IH_CFE current positions: 143.7, trade length: 9, ATR: 41.765, trade high: 3058.19, trade low: 2901.99, close: 3057.786, longStop: 3016.422, shortStop: 2946.551
      
       2018-01-17, Status Submitted: Ref: 12, Size: -143.7, Price: 3016.42178
      
       2018-01-17, Status Accepted: Ref: 12, Size: -143.7, Price: 3016.42178
      
       ### 2018-01-17 IH_CFE current positions: 143.7, trade length: 10, ATR: 41.765, trade high: 3117.39, trade low: 2901.99, close: 3062.986, longStop: 3075.622, shortStop: 2946.551
      
       2018-01-18, Status Submitted: Ref: 13, Size: -143.7, Price: 3075.62178
      
       2018-01-18, Status Accepted: Ref: 13, Size: -143.7, Price: 3075.62178
      2018-01-18,  SELL EXECUTED, 3075.62
      2018-01-18,  Just completed SELL order with ref id: 13
      
       ---Closing Trade Notification: 2018-01-18 IH_CFE Opened at 2904.786, Current Valuet 0.0: PnL Gross 24549.05, Net 24549.05
      

      As we can see, each day the stop order is send out with a new Ref no. (a new order). And on 2018-01-18, the stop order is executed based on the stop price and the trade is closed. However , on the next trade, things started to behave strangely.

      ______________
      IH_CFE: time to buy on this date: 2018-01-18
      
       2018-01-19, Status Submitted: Ref: 14, Size: 152.9, Price: NA
      
       2018-01-19, Status Accepted: Ref: 14, Size: 152.9, Price: NA
      2018-01-19,  BUY EXECUTED, 3124.98
      2018-01-19,  Just completed BUY order with ref id: 14
      
       +++Openning Trade Notification: IH_CFE opened on bar 74  at price: 3124.982 trade duration: 0 at bar no.: 74
      
       $$$ New trade initiated for: IH_CFE on 2018-01-19 -- current positions: 152.9,opened at: 3124.982
      
       ### 2018-01-19 IH_CFE current positions: 152.9, trade length: 0, ATR: 39.232, trade high: 0, trade low: 10000000, close: 3109.982, longStop: 3085.75, shortStop: 3164.214
      
       ### 2018-01-22 IH_CFE current positions: 152.9, trade length: 1, ATR: 39.232, trade high: 3129.58, trade low: 3099.18, close: 3121.782, longStop: 3085.75, shortStop: 3138.414
      
       2018-01-23, Status Submitted: Ref: 15, Size: -152.9, Price: 3085.74991
      
       2018-01-23, Status Accepted: Ref: 15, Size: -152.9, Price: 3085.74991
      
       ### 2018-01-23 IH_CFE current positions: 152.9, trade length: 2, ATR: 39.232, trade high: 3172.18, trade low: 3099.18, close: 3171.182, longStop: 3132.95, shortStop: 3138.414
      
       2018-01-24, Status Submitted: Ref: 16, Size: -152.9, Price: 3132.94991
      
       2018-01-24, Status Accepted: Ref: 16, Size: -152.9, Price: 3132.94991
      
       ### 2018-01-24 IH_CFE current positions: 152.9, trade length: 3, ATR: 39.232, trade high: 3189.18, trade low: 3099.18, close: 3164.182, longStop: 3132.95, shortStop: 3138.414
      
       2018-01-25, Status Submitted: Ref: 17, Size: -152.9, Price: 3132.94991
      
       2018-01-25, Status Accepted: Ref: 17, Size: -152.9, Price: 3132.94991
      2018-01-25,  SELL EXECUTED, 3132.95
      2018-01-25,  Just completed SELL order with ref id: 16
      2018-01-25,  SELL EXECUTED, 3132.95
      2018-01-25,  Just completed SELL order with ref id: 17
      
       ---Closing Trade Notification: 2018-01-25 IH_CFE Opened at 3124.982, Current Valuet 0.0: PnL Gross 1218.32, Net 1218.32
      
       +++Openning Trade Notification: IH_CFE opened on bar 78  at price: 3132.95 trade duration: 0 at bar no.: 78
      
       $$$ New trade initiated for: IH_CFE on 2018-01-25 -- current positions: -152.9,opened at: 3164.382
      
       ### 2018-01-25 IH_CFE current positions: -152.9, trade length: 0, ATR: 39.232, trade high: 3189.18, trade low: 3099.18, close: 3140.982, longStop: 3125.15, shortStop: 3203.614
      
       ### 2018-01-26 IH_CFE current positions: -152.9, trade length: 1, ATR: 39.232, trade high: 3189.18, trade low: 3099.18, close: 3165.182, longStop: 3149.95, shortStop: 3203.614
      
       2018-01-29, Status Submitted: Ref: 18, Size: 152.9, Price: 3203.61372
      
       2018-01-29, Status Accepted: Ref: 18, Size: 152.9, Price: 3203.61372
      
       ### 2018-01-29 IH_CFE current positions: -152.9, trade length: 2, ATR: 39.232, trade high: 3189.18, trade low: 3093.98, close: 3103.182, longStop: 3149.95, shortStop: 3133.214
      
       2018-01-30, Status Submitted: Ref: 19, Size: 152.9, Price: 3133.21372
      
       2018-01-30, Status Accepted: Ref: 19, Size: 152.9, Price: 3133.21372
      2018-01-30,  SELL EXECUTED, 3085.75
      2018-01-30,  Just completed SELL order with ref id: 15
      

      Everything was hehaving correctly, until 2018-01-25, both stop order Ref 16 and Ref 17 got executed. But order Ref 16 was from 2018-01-24 and should have been cancelled by the end of the day like many other orders before or did I misunderstand something? This happened again on 2018-01-30 when order ref 15 executed which was sent out on 2018-01-23. What am I missing? Thanks for any help from another pair of eyes. Sorry for the long post, but it was necessary to show the problem.

      I can include the data file if anyone is interested.. thanks.

      Here is the sample of the input data for the results shown above:

      2018/1/2	IH.CFE	2857.186363	2903.986363	2857.186363	2902.386363	9954
      2018/1/3	IH.CFE	2904.786363	2935.186363	2898.386363	2906.986363	11252
      2018/1/4	IH.CFE	2911.986363	2924.986363	2901.986363	2913.186363	9763
      2018/1/5	IH.CFE	2913.186363	2930.986363	2908.186363	2926.786363	8995
      2018/1/8	IH.CFE	2929.986363	2943.386363	2918.986363	2934.186363	9043
      2018/1/9	IH.CFE	2934.186363	2963.786363	2933.186363	2963.786363	8449
      2018/1/10	IH.CFE	2962.986363	2987.386363	2952.186363	2984.386363	10191
      2018/1/11	IH.CFE	2979.586363	2995.186363	2971.186363	2982.986363	9443
      2018/1/12	IH.CFE	2986.586363	3010.586363	2982.786363	3010.586363	9367
      2018/1/15	IH.CFE	3019.186363	3055.586363	3009.186363	3033.186363	11325
      2018/1/16	IH.CFE	3029.586363	3058.186363	3024.186363	3057.786363	10790
      2018/1/17	IH.CFE	3060.986363	3117.386363	3048.986363	3062.986363	12257
      2018/1/18	IH.CFE	3083.986363	3111.586363	3073.586363	3098.586363	8170
      2018/1/19	IH.CFE	3124.981818	3131.581818	3093.181818	3109.981818	12271
      2018/1/22	IH.CFE	3101.181818	3129.581818	3099.181818	3121.781818	11730
      2018/1/23	IH.CFE	3132.981818	3172.181818	3132.981818	3171.181818	12746
      2018/1/24	IH.CFE	3176.581818	3189.181818	3139.181818	3164.181818	14310
      2018/1/25	IH.CFE	3164.381818	3164.581818	3116.181818	3140.981818	13495
      2018/1/26	IH.CFE	3139.181818	3188.981818	3136.981818	3165.181818	12791
      2018/1/29	IH.CFE	3175.781818	3187.781818	3093.981818	3103.181818	14934
      2018/1/30	IH.CFE	3105.181818	3114.981818	3062.781818	3063.381818	12005
      2018/1/31	IH.CFE	3055.781818	3103.981818	3051.581818	3101.181818	13673
      

      thanks again!!!

      posted in General Code/Help
      M
      Michael172
    • RE: How to achieve more realistic stop behaviour

      Never mind, I did a little digging. We can achieve what I said in the previous post by using "stop orders". So, case is closed for now .. for me at least. :)

      posted in General Discussion
      M
      Michael172
    • RE: How to achieve more realistic stop behaviour

      You are both correct. The problem is data resolution. In reality and in Backtrader, trailing stop orders are evaluated on a tick(bar) by tick(bar) basis. So, at each iteration, the trailing limits and/or executions if conditions are met, are updated based on the lastest tick or bar-closing price. The problem a lot of us have is a data resolution since we use daily bars in the backtest. So, we don't have the data resultion to see how each tick affects our trailing-stop-orders during each day in the backtest. So, we use daily-highs or daily-lows to approximate this behavior. In other words, if the low is below your trailing-stop-limit for a long position, we assume that this order was executed at the specified stop price sometimes during that day. It's an approximation but models real-trading more accurately when we are using daily data. Is there a way in Backtrader to specify an execution price if and when a condition is met?? That may make this approximiation easier to achieve in Backtrader .. thanks.

      posted in General Discussion
      M
      Michael172
    • RE: Extending Datafeeds GenericCSV Attribute Error

      @backtrader

      Ha! Finally figured out two things! One: why my own data feeder wasn't getting accepted and Two: who the bigger idiot is... hopefully was. Thanks for helping out.. saved a lot of my time.

      posted in Indicators/Strategies/Analyzers
      M
      Michael172
    • RE: Extending Datafeeds GenericCSV Attribute Error

      thanks.. I noticed that and made the correction. I was hoping that he ran into a problem that has puzzled me for a bit. Here is the code that reproduces the problem for me. I simply modified the above code to keep it clean. The customized datafeeder is not recognized. It's not a typo, but must be something else I am missing???

      thanks again as always,

       from __future__ import (absolute_import, division, print_function,
                               unicode_literals)
       import backtrader as bt
       import pandas as pd
       from backtrader.feeds import GenericCSVData
       import backtrader.feeds as btfeeds
       import datetime as datetime
       import backtrader.indicators as btind
       import numpy as np
       
       from backtrader.feeds import GenericCSVData
       
       class GenericCSV_PE(GenericCSVData):
       
           # Add a 'pe' line to the inherited ones from the base class
           lines = ('pe_ttm',)
       
           # openinterest in GenericCSVData has index 7 ... add 1
           # add the parameter to the parameters inherited from the base class
           params = (('pe_ttm', 8),)
       
       class MyStrategy(bt.Strategy):
       
       
           def log(self, txt, dt=None):
               ''' Logging function for this strategy'''
               dt = self.datas[0].datetime.date(0)
               dt_time = self.datas[0].datetime.time(0)
               dt_weekday = datetime.datetime.weekday(dt)
               print('%s, %s' % (dt.isoformat(), txt))
       
       
           def __init__(self):
               # Keep a reference to the "close" line in the data[0] dataseries
               # init stop loss and take profit order variables
               self.sl_order, self.tp_order = None, None
               self.datavolume = self.datas[0].volume
               self.pe = self.datas[0].pe_ttm
       
       
           def next(self):
               if self.datavolume[0] / np.mean(self.datavolume.get(size=10, ago=-1)) >= 1.25:
                   self.buy()
                   print(self.pe[0])
       
       
       
       if __name__ == '__main__':
           # Create a cerebro entity
           cerebro = bt.Cerebro()
       
       
           data = btfeeds.GenericCSV_PE(
       #    data = btfeeds.GenericCSVData(    
               dataname='E:\\Michael\\R\\Stocks\\300Index_New_Combined_Corrected\\000001.csv',
       
               nullvalue=0.0,
       
               dtformat=('%Y-%m-%d'),
       
               datetime=0,
               time=-1,
               high=2,
               low=3,
               open=1,
               close=4,
               volume=5,
               openinterest=-1,
               pe_ttm = 6
           )
       
           # Add the Data Feed to Cerebro
           cerebro.adddata(data)
       
           # Set our desired cash start
           cerebro.broker.setcash(100000.0)
       
           # Add a strategy
           cerebro.addstrategy(MyStrategy)
       
           # Print out the starting conditions
           print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
       
           # Run over everything
           cerebro.run()
       
           # Print out the final result
           print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
       
           cerebro.plot(style='bar')
      

      error output:

           AttributeError                            Traceback (most recent call last)
           <ipython-input-21-26c81b63c6dc> in <module>()
                51 
                52 
           ---> 53     data = btfeeds.GenericCSV_PE(
                54 #    data = btfeeds.GenericCSVData(
                55         dataname='E:\\Michael\\R\\Stocks\\300Index_New_Combined_Corrected\\000001.csv',
           
           AttributeError: module 'backtrader.feeds' has no attribute 'GenericCSV_PE'
      
      posted in Indicators/Strategies/Analyzers
      M
      Michael172
    • RE: Extending Datafeeds GenericCSV Attribute Error

      @samk

      Hi,

      What was your mistake that you corrected. You just said you got it to work. I am getting the same error.

      valueError: time data '"2016-12-31' does not match format '%m/%d/%Y'

      thanks..

      posted in Indicators/Strategies/Analyzers
      M
      Michael172
    • RE: StopTrail(Limit)

      @backtrader Thanks for the quick reply. I understand what you are saying. It would be nice if I had intrady data when I do my backtest, then this wold work perfectly with data playback. Unfortunatly, I only have access to Open, High, Low, Close data, so I'll have to dig around to see if there is a sample code that does what I need or god forbid... have to write my own... :)

      posted in Blog
      M
      Michael172
    • RE: StopTrail(Limit)

      Hi, thanks for the post. I realize this is an old post, but I like to clarify something. In an "ideal" back test, my traillig stop orders are based off high for each trading day for a buy (long) position, and off the low of the day for sell (short) postion. So, the trailing stop orders are updated each day after the close based on the highs and lows reached. If the next day, the low is below the trailing stop order, the long trade is closed for the day at the traling stop limit price, neglecting slippage. I see your example here all trail stops are based off the close, is there a way that I can impliment my way of testing? Can I choose the data set that the trailing stop orders are adjusted and executed based on? thanks.

      posted in Blog
      M
      Michael172
    • RE: Real Time data processing and storage:

      @backtrader Thanks for the summary. As I suspected, there is much more to it, I'll have to think about it. There are just too many "unknow unknows".

      posted in General Code/Help
      M
      Michael172