Backtrader Community

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

    Topics created by Jens Halsberghe

    • Jens Halsberghe

      Entering and taking profit on the same bar
      General Code/Help • • Jens Halsberghe

      9
      0
      Votes
      9
      Posts
      902
      Views

      Jens Halsberghe

      I agree and I understand the logic. I can't replay but also, it's useful to use target.activate() and it can be used to do only in certain scenarios where it looks most likely the target would have been hit. for example if the price never even reached the stoploss but got to the entry and then the target, it's perfectly fine to use it. in case of a big outside bar which would hit all three entry, target and stoploss there would be doubt but it's more an exceptional case.

      thanks again for your help Dasch

    • Jens Halsberghe

      resampling - first resampled bar is sampled incorrectly
      General Code/Help • • Jens Halsberghe

      7
      1
      Votes
      7
      Posts
      347
      Views

      ?

      I am still using backtrader. For simple stuff I write stuff directly using the oanda api.

    • Jens Halsberghe

      Filtering trading sessions
      General Code/Help • • Jens Halsberghe

      10
      0
      Votes
      10
      Posts
      562
      Views

      run-out

      In next you have assigend your entry order object to the variable self.order. When in notify_order, you access the current order object using the variable order. These are both order objects.

      In an order object you can access the status of that object which is stores as in next self.order.status or in notify_order as order.status.

      For completed orders this status variable will equal 4.

      In your code, in next, you can use:

      if self.order.status != self.order.Completed etc.

      or

      if self.order.status != 4 etc.

      The cancel is normal. It is cancelling the other side of the bracket, so if you fill on the take profit, the stop gets cancelled and vice versa. If you want a bit more information in your log you can show the order reference numbers.

      Also as another side note, I notice you are assigning the size using order.size. Size is acutally tracked in order.created.size.

    • Jens Halsberghe

      Trying to execute on the open, although the order executes the next day
      General Code/Help • • Jens Halsberghe

      8
      0
      Votes
      8
      Posts
      1659
      Views

      Jens Halsberghe

      A further update. I've simplified it further. the order is now being cancelled as it should. The execution is also fine bar one last problem. If the bar where the trade gets entered also hits the target, it doesn't execute the buy and sell on the same bar. I don't see how this can be achieved.

      class Order_testing(bt.Strategy): params = dict( pfast=10, # period for the fast moving average pslow=30 # period for the slow moving average ) def log(self, txt, dt=None): ''' Logging function for this strategy''' dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.strftime("%Y-%m-%d %H:%M"), txt)) def __init__(self): sma1 = bt.ind.SMA(period=self.p.pfast) # fast moving average sma2 = bt.ind.SMA(period=self.p.pslow) # slow moving average self.crossover = bt.ind.CrossOver(sma1, sma2) # crossover signal # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None 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 enough cash if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.5f, Cost: %.f, 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: %.5f, Cost: %.f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.5f, NET %.5f' % (trade.pnl, trade.pnlcomm)) def next(self): # Check if an order is pending ... if yes, we cannot send a 2nd one if self.order: if self.order.status == 2 and len(self) == self.bar_order_submitted + 1: self.broker.cancel(self.order) self.log("order was cancelled") # Check if we are in the market if not self.position: # Not yet ... we MIGHT BUY if ... if self.crossover > 0: # if fast crosses slow to the upside self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high[0], transmit=False) self.StopLoss = self.sell(price=self.data.low[0],exectype=bt.Order.Stop, transmit=False, size=self.order.size,parent=self.order) self.target = self.sell(price=(self.data.high[0]-self.data.low[0])*1.1+self.data.high[0], exectype=bt.Order.Limit, transmit=True, size=self.order.size, parent=self.order) self.bar_order_submitted = len(self) self.log('BUY CREATE, %.5f' % self.order.price) self.log('SL: %.5f, T: %.5f' %(self.StopLoss.price,self.target.price)) if __name__ == '__main__': cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(Order_testing) # Create a Data Feed data = bt.feeds.PandasData(dataname=df2020) one_minute = cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=1) # cerebro.adddata(data) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.PercentSizer, percents=5000) #Add Analyzer cerebro.addanalyzer(bt.analyzers.PyFolio) cerebro.broker.setcommission(commission=0.0,leverage=500) # Set our desired cash start cerebro.broker.setcash(1000000.0) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) HG = cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

      below is a copy of the log again. It should sell at 06:29.

      2020-08-12 06:28, BUY CREATE, 1.17185 2020-08-12 06:28, SL: 1.17171, T: 1.17200 2020-08-12 06:29, BUY EXECUTED, Price: 1.17185, Cost: 49324578, Comm 0.00 2020-08-12 06:30, SELL EXECUTED, Price: 1.17203, Cost: 49324578, Comm 0.00 2020-08-12 06:30, Order Canceled/Margin/Rejected 2020-08-12 06:30, OPERATION PROFIT, GROSS 7576.41679, NET 7576.41679
    • Jens Halsberghe

      trailing stoploss
      General Code/Help • • Jens Halsberghe

      2
      0
      Votes
      2
      Posts
      551
      Views

      run-out

      Have a look at my post here.

    • Jens Halsberghe

      SQN indicator for regime shifts
      Indicators/Strategies/Analyzers • • Jens Halsberghe

      8
      0
      Votes
      8
      Posts
      577
      Views

      S

      @Jens-Halsberghe But in next(), you get a single OHLC bar which is a plain Python object, you can use math.log in def next()

    • Jens Halsberghe

      Resampling issues + adding multiple timeframes
      General Code/Help • • Jens Halsberghe

      34
      0
      Votes
      34
      Posts
      1982
      Views

      A

      @dasch said in Resampling issues + adding multiple timeframes:

      there are a lot of shortcuts to different lines, which are not used that much in examples, so it would only make sense to use them, when you know what you are doing.

      I totally agree.

    • Jens Halsberghe

      ATR difference with Metatrader? + original welles wilder version
      Indicators/Strategies/Analyzers • • Jens Halsberghe

      7
      1
      Votes
      7
      Posts
      537
      Views

      G

      I found a better way:
      just add a movav parameter when you use the ATR indicator like this:
      bt.indicators.AverageTrueRange(self.data0, period=20, movav=MovAv.Simple)

    • Jens Halsberghe

      custom indicator - error in strategy
      General Code/Help • • Jens Halsberghe

      5
      0
      Votes
      5
      Posts
      493
      Views

      Jens Halsberghe

      I meant of course 1 for uptrend, -1 for downtrend but I can't edit my post

    • Jens Halsberghe

      storing the candle data which touched a bollinger band
      General Code/Help • • Jens Halsberghe

      10
      0
      Votes
      10
      Posts
      522
      Views

      vladisld

      You may take a look at the _Bar class as an example (it is an internal class in Backtrader) and create something similar for your needs.

    • Jens Halsberghe

      Interactive brokers - can't retrieve historical data
      General Code/Help • • Jens Halsberghe

      5
      0
      Votes
      5
      Posts
      676
      Views

      A

      IB is the brokerage company, not data provider. This is not their business. Common approach is to get data from the data providers for backtests.

    • Jens Halsberghe

      retrieve backtraders information as a dataframe
      General Discussion • • Jens Halsberghe

      4
      1
      Votes
      4
      Posts
      1246
      Views

      Bard Tim

      @run-out that is smart,thanks

    • 1 / 1