Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Optimize Stop-Trail order values

    Indicators/Strategies/Analyzers
    2
    3
    809
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      j45p41 last edited by

      Hi,

      after posting "Create orders from CSV file" and getting quick and helpful feedabck. I have started using backtrader again and thanks to the great documentation I have now gotten to the stage where I can push in my own orders. I am now trying to:

      Optimize against stop order entry price and trailing stop distance.

      I have :

      1. declared parameters to be optimized
      2. referenced them under self.params.x
      3. added the “Strategy” hook stop method
      4. called the cerebro.optstategy function

      However I keep getting the same value back from the broker for all variances of the optimization parameters.

      Here is my code:

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import datetime  # For datetime objects
      import os.path  # To manage paths
      import sys  # To find out the script name (in argv[0])
      
      # Import the backtrader platform
      import backtrader as bt
      import backtrader.feeds as btfeed
      import pandas as pd
      
      class PlotScheme(object):
          def __init__(self):
      
              # Default plotstyle for the OHLC bars which (line -> line on close)
              # Other options: 'bar' and 'candle'
              self.style = 'line'
      
      
      class dataFeed(btfeed.GenericCSVData):
          params = (
              ('dtformat', '%Y-%m-%d %H:%M:%S'),
              ('datetime', 0),
              ('open', 1),
              ('high', 2),
              ('low', 3),
              ('close', 4),
              ('volume', 5),
              ('openinterest', -1)
          )
      
      # Create a Stratey
      class TestStrategy(bt.Strategy):
          params = (
              ('trail', 10),
              ('distance', 3),)
      
          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 __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataopen = self.datas[0].open
              self.datahigh = self.datas[0].high
              self.datalow = self.datas[0].low
              self.dataclose = self.datas[0].close
              self.datavolume = self.datas[0].volume
      
              # 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
                  # print('Submitted/Accepted: ', str(self.data.datetime.time(0)))
      
                  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: %.2f, Cost: %.2f, Comm %.2f' %
                          (order.executed.price,
                           order.executed.value,
                           order.executed.comm))
                      print(str(self.data.datetime.time(0)))
      
                      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))
                      print(str(self.data.datetime.time(0)))
      
                  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 %.2f, NET %.2f' %
                       (trade.pnl, trade.pnlcomm))
      
          def next(self):
              global i,dt
      
              # Get datetime
              dt = self.datas[0].datetime.datetime()
      
              # Check if we are in the market
              try:
                  # if not self.position:
                  if orders['DATE'][i] == dt.strftime('%Y-%m-%d %H:%M:%S'):
                      if orders['DIRECTION'][i] == 'BUY':
                          self.log('OPEN BUY ORDER, %.2f' % self.dataclose[0])
                          self.order = self.buy(exectype=bt.Order.StopTrail, price=float(self.dataclose[0] + self.params.distance), trailamount=self.params.trail, valid=bt.Order.DAY)
                      elif orders['DIRECTION'][i] == 'SELL':
                          self.log('OPEN SELL ORDER, %.2f' % self.dataclose[0])
                          self.order = self.sell(exectype=bt.Order.StopTrail, price=float(self.dataclose[0] - self.params.distance), trailamount=self.params.trail, valid=bt.Order.DAY)
                      i = i + 1
      
                  if dt.strftime('%H:%M') == '21:00': self.close()
      
              except:
                  pass
      
          def stop(self):
              self.log('(Start distance %2d, Trail distance %2d) Ending Value %.2f' %
                       (self.params.distance, self.params.trail, self.broker.getvalue()))
      
      
      if __name__ == '__main__':
          # Create a cerebro entity
          cerebro = bt.Cerebro()
          i = 0
          state = False
      
          # Add a strategy
          # cerebro.addstrategy(TestStrategy)
      
          strats = cerebro.optstrategy(TestStrategy,distance=range(3,8), trail=range(3,8))
      
          datapath = os.path.join('backtrader/deepanalysis/US500/US50015m_bid_chart_data_with_vol.csv')
      
          # Create a Data Feed
          data = dataFeed(dataname=datapath, timeframe=bt.TimeFrame.Minutes, compression=15)
      
          # Read Orders
      
          orders = pd.read_csv('backtrader/deepanalysis/US500/US500_orders_20180601_to_20180815_Norm_priority.csv')
      
          # Add the Data Feed to Cerebro
          cerebro.adddata(data)
      
          # Set our desired cash start
          cerebro.broker.setcash(5000.0)
      
          # Add a FixedSize sizer according to the stake
          cerebro.addsizer(bt.sizers.FixedSize, stake=1)
      
          # Set the commission
          cerebro.broker.setcommission(commission=0.0)
      
          # 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())
      
      

      Here is the output that i get:

      C:\Users\jaspa\AppData\Local\conda\conda\envs\backtrader\python.exe C:/Users/jaspa/PycharmProjects/backtrader/US500_backtest_1.py
      Starting Portfolio Value: 5000.00
      2018-08-15, (Start distance  3, Trail distance  6) Ending Value 5000.00
      2018-08-15, (Start distance  3, Trail distance  7) Ending Value 5000.00
      2018-08-15, (Start distance  6, Trail distance  7) Ending Value 5000.00
      2018-08-15, (Start distance  4, Trail distance  6) Ending Value 5000.00
      2018-08-15, (Start distance  3, Trail distance  3) Ending Value 5000.00
      2018-08-15, (Start distance  3, Trail distance  4) Ending Value 5000.00
      2018-08-15, (Start distance  4, Trail distance  3) Ending Value 5000.00
      2018-08-15, (Start distance  5, Trail distance  5) Ending Value 5000.00
      2018-08-15, (Start distance  4, Trail distance  5) Ending Value 5000.00
      2018-08-15, (Start distance  5, Trail distance  6) Ending Value 5000.00
      2018-08-15, (Start distance  4, Trail distance  4) Ending Value 5000.00
      2018-08-15, (Start distance  3, Trail distance  5) Ending Value 5000.00
      2018-08-15, (Start distance  6, Trail distance  4) Ending Value 5000.00
      2018-08-15, (Start distance  7, Trail distance  4) Ending Value 5000.00
      2018-08-15, (Start distance  5, Trail distance  4) Ending Value 5000.00
      2018-08-15, (Start distance  5, Trail distance  3) Ending Value 5000.00
      2018-08-15, (Start distance  7, Trail distance  6) Ending Value 5000.00
      2018-08-15, (Start distance  6, Trail distance  6) Ending Value 5000.00
      2018-08-15, (Start distance  4, Trail distance  7) Ending Value 5000.00
      2018-08-15, (Start distance  5, Trail distance  7) Ending Value 5000.00
      2018-08-15, (Start distance  6, Trail distance  3) Ending Value 5000.00
      2018-08-15, (Start distance  7, Trail distance  5) Ending Value 5000.00
      2018-08-15, (Start distance  7, Trail distance  7) Ending Value 5000.00
      2018-08-15, (Start distance  6, Trail distance  5) Ending Value 5000.00
      2018-08-15, (Start distance  7, Trail distance  3) Ending Value 5000.00
      Final Portfolio Value: 5000.00
      
      Process finished with exit code 0
      
      
      

      Here is the output I get when I run the strategy with the default parameter values:

      C:\Users\jaspa\AppData\Local\conda\conda\envs\backtrader\python.exe C:/Users/jaspa/PycharmProjects/backtrader/US500_backtest_1.py
      Starting Portfolio Value: 5000.00
      2018-06-05, OPEN BUY ORDER, 2748.13
      2018-06-05, BUY EXECUTED, Price: 2749.75, Cost: 2749.75, Comm 0.00
      19:45:00
      2018-06-05, SELL EXECUTED, Price: 2751.51, Cost: 2749.75, Comm 0.00
      21:15:00
      2018-06-05, OPERATION PROFIT, GROSS 1.76, NET 1.76
      2018-06-06, OPEN SELL ORDER, 2755.69
      2018-06-07, OPEN BUY ORDER, 2775.99
      2018-06-07, BUY EXECUTED, Price: 2771.76, Cost: 2771.76, Comm 0.00
      20:30:00
      2018-06-07, SELL EXECUTED, Price: 2771.60, Cost: 2771.76, Comm 0.00
      21:15:00
      2018-06-07, OPERATION PROFIT, GROSS -0.16, NET -0.16
      2018-06-08, OPEN SELL ORDER, 2765.90
      2018-06-12, OPEN SELL ORDER, 2784.50
      2018-06-13, OPEN SELL ORDER, 2788.59
      2018-06-13, SELL EXECUTED, Price: 2780.88, Cost: -2780.88, Comm 0.00
      19:00:00
      2018-06-13, BUY EXECUTED, Price: 2773.30, Cost: -2780.88, Comm 0.00
      21:15:00
      2018-06-13, OPERATION PROFIT, GROSS 7.58, NET 7.58
      2018-06-14, OPEN BUY ORDER, 2783.62
      2018-06-15, OPEN BUY ORDER, 2769.40
      2018-06-15, BUY EXECUTED, Price: 2776.40, Cost: 2776.40, Comm 0.00
      19:15:00
      2018-06-15, SELL EXECUTED, Price: 2779.87, Cost: 2776.40, Comm 0.00
      21:15:00
      2018-06-15, OPERATION PROFIT, GROSS 3.47, NET 3.47
      2018-06-18, OPEN SELL ORDER, 2761.90
      2018-06-19, OPEN SELL ORDER, 2752.10
      2018-06-20, OPEN BUY ORDER, 2770.13
      2018-06-21, OPEN BUY ORDER, 2762.47
      2018-06-21, BUY EXECUTED, Price: 2760.22, Cost: 2760.22, Comm 0.00
      16:45:00
      2018-06-21, SELL EXECUTED, Price: 2749.00, Cost: 2760.22, Comm 0.00
      21:15:00
      2018-06-21, OPERATION PROFIT, GROSS -11.22, NET -11.22
      2018-06-25, OPEN SELL ORDER, 2733.98
      2018-06-25, SELL EXECUTED, Price: 2720.98, Cost: -2720.98, Comm 0.00
      15:00:00
      2018-06-25, BUY EXECUTED, Price: 2719.10, Cost: -2720.98, Comm 0.00
      21:15:00
      2018-06-25, OPERATION PROFIT, GROSS 1.88, NET 1.88
      2018-06-26, OPEN BUY ORDER, 2724.19
      2018-06-26, BUY EXECUTED, Price: 2730.26, Cost: 2730.26, Comm 0.00
      18:00:00
      2018-06-26, SELL EXECUTED, Price: 2725.91, Cost: 2730.26, Comm 0.00
      21:15:00
      2018-06-26, OPERATION PROFIT, GROSS -4.35, NET -4.35
      2018-06-27, OPEN SELL ORDER, 2730.00
      2018-06-27, SELL EXECUTED, Price: 2734.02, Cost: -2734.02, Comm 0.00
      16:00:00
      2018-06-27, BUY EXECUTED, Price: 2702.05, Cost: -2734.02, Comm 0.00
      21:15:00
      2018-06-27, OPERATION PROFIT, GROSS 31.97, NET 31.97
      2018-06-28, OPEN BUY ORDER, 2699.73
      2018-06-28, BUY EXECUTED, Price: 2707.06, Cost: 2707.06, Comm 0.00
      16:00:00
      2018-06-28, SELL EXECUTED, Price: 2717.05, Cost: 2707.06, Comm 0.00
      21:15:00
      2018-06-28, OPERATION PROFIT, GROSS 9.99, NET 9.99
      2018-06-29, OPEN BUY ORDER, 2735.20
      2018-06-29, BUY EXECUTED, Price: 2743.16, Cost: 2743.16, Comm 0.00
      16:00:00
      2018-06-29, SELL EXECUTED, Price: 2720.23, Cost: 2743.16, Comm 0.00
      21:15:00
      2018-06-29, OPERATION PROFIT, GROSS -22.93, NET -22.93
      2018-07-30, OPEN BUY ORDER, 2812.63
      2018-07-31, OPEN BUY ORDER, 2813.06
      2018-07-31, BUY EXECUTED, Price: 2819.25, Cost: 2819.25, Comm 0.00
      16:45:00
      2018-07-31, SELL EXECUTED, Price: 2822.88, Cost: 2819.25, Comm 0.00
      21:15:00
      2018-07-31, OPERATION PROFIT, GROSS 3.63, NET 3.63
      2018-08-01, OPEN SELL ORDER, 2819.48
      2018-08-01, SELL EXECUTED, Price: 2814.76, Cost: -2814.76, Comm 0.00
      16:45:00
      2018-08-01, BUY EXECUTED, Price: 2809.82, Cost: -2814.76, Comm 0.00
      21:15:00
      2018-08-01, OPERATION PROFIT, GROSS 4.94, NET 4.94
      2018-08-02, OPEN SELL ORDER, 2799.40
      2018-08-03, OPEN BUY ORDER, 2830.09
      2018-08-03, BUY EXECUTED, Price: 2838.84, Cost: 2838.84, Comm 0.00
      20:00:00
      2018-08-03, SELL EXECUTED, Price: 2838.85, Cost: 2838.84, Comm 0.00
      21:15:00
      2018-08-03, OPERATION PROFIT, GROSS 0.01, NET 0.01
      2018-08-06, OPEN SELL ORDER, 2837.96
      2018-08-07, OPEN SELL ORDER, 2858.17
      2018-08-08, OPEN BUY ORDER, 2855.45
      2018-08-09, OPEN SELL ORDER, 2856.91
      2018-08-09, SELL EXECUTED, Price: 2851.92, Cost: -2851.92, Comm 0.00
      20:45:00
      2018-08-09, BUY EXECUTED, Price: 2851.81, Cost: -2851.92, Comm 0.00
      21:15:00
      2018-08-09, OPERATION PROFIT, GROSS 0.11, NET 0.11
      2018-08-10, OPEN SELL ORDER, 2838.98
      2018-08-10, SELL EXECUTED, Price: 2829.47, Cost: -2829.47, Comm 0.00
      18:45:00
      2018-08-10, BUY EXECUTED, Price: 2835.86, Cost: -2829.47, Comm 0.00
      21:15:00
      2018-08-10, OPERATION PROFIT, GROSS -6.39, NET -6.39
      2018-08-13, OPEN BUY ORDER, 2837.68
      2018-08-13, BUY EXECUTED, Price: 2831.50, Cost: 2831.50, Comm 0.00
      19:15:00
      2018-08-13, SELL EXECUTED, Price: 2824.10, Cost: 2831.50, Comm 0.00
      21:15:00
      2018-08-13, OPERATION PROFIT, GROSS -7.40, NET -7.40
      2018-08-14, OPEN BUY ORDER, 2831.96
      2018-08-14, BUY EXECUTED, Price: 2840.96, Cost: 2840.96, Comm 0.00
      15:45:00
      2018-08-14, SELL EXECUTED, Price: 2839.56, Cost: 2840.96, Comm 0.00
      21:15:00
      2018-08-14, OPERATION PROFIT, GROSS -1.40, NET -1.40
      2018-08-15, OPEN SELL ORDER, 2822.43
      2018-08-15, SELL EXECUTED, Price: 2809.43, Cost: -2809.43, Comm 0.00
      15:00:00
      2018-08-15, (Start distance  3, Trail distance 10) Ending Value 5010.83
      Final Portfolio Value: 5010.83
      
      Process finished with exit code 0
      
      

      I'm sure it is probably something obvious but we all have to start somewhere :) All help greatly appreciated!

      1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators last edited by backtrader

        You have a try ... except that catches all exceptions (you won't even know an error happened) and plays with global variables: doomed to fail.

        J 1 Reply Last reply Reply Quote 1
        • J
          j45p41 @backtrader last edited by

          @backtrader So obvious (when you know how) got it. Removed the globals and try except and got it to work! Thank you sir!

          1 Reply Last reply Reply Quote 0
          • 1 / 1
          • First post
            Last post
          Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors