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/

    Evolutionary algorithm for newbies [Code]

    General Code/Help
    1
    1
    96
    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
      jmorales last edited by

      Hello,
      I recently made a basic strategy, using the optuna library, I leave you here the code to be a starting point for newbies.

      https://github.com/JavierMoralesEstevez/Backtrader-optuna.git

      below I attach the most important code:

      Objective function

      cash = 1
      datos = 1
      precioactual = 1.0
      def opt_objective(trial):
          global datos
          global cash
          global precioactual
      
          perprofitA = trial.suggest_float('perprofitA', 1.0, 2.0)
          perlostA = trial.suggest_float('perlostA', 0.0, 1.0)
          perprofitB = trial.suggest_float('perprofitB', 0.0, 1.0)
          perlostB = trial.suggest_float('perlostB', 1.0, 2.0)
      
          cerebro = bt.Cerebro()
          cerebro.broker.set_coc(True)
          cerebro.broker.set_coo(True)
          cerebro.broker.setcash(cash=cash)
          # cerebro.addwriter(bt.WriterFile, out='analisis.txt')
          # cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
          cerebro.addstrategy(Bits, perprofitA=perprofitA,
                              perlostA=perlostA, perprofitB=perprofitB, perlostB=perlostB)
          cerebro.adddata(datos)
          cerebro.run()
          return (float(cerebro.broker.get_value()))
      
      

      Strategy

      
      class Bits(bt.Strategy):
          params = (
              ('perprofitA', 1),
              ('perlostA', 1),
              ('perprofitB', 1),
              ('perlostB', 1),
          )
      
          def __init__(self):
              self.porcentajeBeneficioA = self.params.perprofitA
              self.porcentajePerdidaA = self.params.perlostA
              self.porcentajeBeneficioB = self.params.perprofitB
              self.porcentajePerdidaB = self.params.perlostB
              self.order = None
              # self.ma_fast = bt.ind.EMA(period=int(self.params.fast))
              # self.ma_slow = bt.ind.EMA(period=int(self.params.slow))
              # self.crossover = bt.ind.CrossOver(self.ma_fast, self.ma_slow)
              self.prevClose = 1.0
              # self.euros = 1.0
              # self.coins = self.euros
              self.precioBit = self.broker.get_value() / self.prevClose
              self.y = self.precioBit
              self.tendenciaBajista = False
              self.short = False
              self.long = False
              self.empieza = True
              self.price = 1.0
              self.longTakeprofit = 1.0
              self.longStoploss = 1.0
              self.shortTakeprofit = 1.0
              self.shortStoploss = 1.0
              # self.btc = 0.0 #self.coins
              self.eur = 0.0
              self.abierto = False
              global last_datetime_format
              global precioactual
      
          def next(self):
              self.prevClose = self.data.open[0]
              self.auxdatetime = dt.datetime.strptime(last_datetime_format, '%d-%m-%Y %H:%M:%S')
              self.nowdatetime = dt.datetime.strptime(self.data.datetime.datetime().strftime('%d-%m-%Y %H:%M:%S'), '%d-%m-%Y %H:%M:%S')
              
      if self.nowdatetime > self.auxdatetime:
      
                  if ((self.prevClose >= self.shortTakeprofit or self.prevClose <= self.shortStoploss) and self.abierto is False) or self.empieza is True:
                      self.longTakeprofit = self.prevClose * (self.porcentajeBeneficioA)
                      self.longStoploss = self.prevClose * (self.porcentajePerdidaA)
                      self.y = self.broker.get_cash() / self.data.open[0]
                      self.order = self.buy(size=self.y, price=self.data.open[0])
                      self.empieza = False
                      self.abierto = True
      
                  if ((self.prevClose >= self.longTakeprofit or self.prevClose <= self.longStoploss) and self.abierto is True) and self.empieza is False:
                      self.shortTakeprofit = self.prevClose * (self.porcentajeBeneficioB)
                      self.shortStoploss = self.prevClose * (self.porcentajePerdidaB)
                      self.y = self.broker.get_cash() / self.data.open[0]
                      self.order = self.sell(size=self.y, price=self.data.open[0])
                      self.abierto = False
      
          def stop(self):
              global precioactual
              self.order = self.close()
              precioactual = self.prevClose
              # calculate the actual returns
              # print('Ganancias :{:.2f}'.format(self.broker.get_value()))
              print('value: {}, cash: {}'.format(str(self.broker.get_value()), str(self.broker.get_cash())))
              print('pba: {}, ppa: {}, pbb: {}, ppb: {}\n'.format(self.porcentajeBeneficioA, self.porcentajePerdidaA, self.porcentajeBeneficioB, self.porcentajePerdidaB))
      
      

      Main

      # Pasando argumento
          # -s CAKE/BUSD -hora "02/01/2021 00:00:00" -cash 70.0 -t 4h -cycle 100
          args = parse_args()
          horadecomienzo = str(args.horadecomienzo)
          symbol = str(args.symbol)
          cash = float(args.cash)
          timeframe = str(args.timeframe)
          cycle = int(args.cycle)
          # horadecomienzo = str("02/01/2021 00:00:00")
          # symbol = str("CAKE/BUSD")
          # cash = float(70.0)
          # timeframe = str("4h")
          # cycle = 100
      
          exchange = str("binance")
          horadecomienzo = horadecomienzo.replace("/", "-")
          simbolos = symbol.split(sep='/')
          first_symbol = simbolos[0]
          second_symbol = simbolos[1]
          symbol_out = symbol.replace("/", "")
          filename = '{}-{}.csv'.format(symbol_out, timeframe)
      
          # Tiempo
          # last_date = dt.datetime(2021, 1, 10, 0, 0, 0)
          last_date = dt.datetime.strptime(horadecomienzo, '%d-%m-%Y %H:%M:%S') - dt.timedelta(days=1)
          last_datetime_ticker = dt.datetime.strptime(last_date.strftime('%d-%m-%Y %H:%M:%S'),
                                                      '%d-%m-%Y %H:%M:%S')  # (2021, 1, 13)
          last_datetime = dt.datetime.strptime(horadecomienzo, '%d-%m-%Y %H:%M:%S')
          last_datetime_format = last_datetime.strftime('%d-%m-%Y %H:%M:%S')
          time_actual_ticker = dt.datetime.now()  # dt.datetime(2021, 7, 23)
          time_actual = dt.datetime.now().date()  # dt.datetime(2021, 7, 23)
      
          # intervalos = ['1d', '12h', '3h', '2h', '1h', '30m', '15m', '5m', '3m', '1m']
          resultados = []
          resultadosOpt = []
          i = timeframe
          # for i in intervalos:
      
          # Recuperar los valores de la gráfica desde binance y guardarlos en el csv
          if not os.path.isfile(filename):
              df_list = []
              while True:
                  new_df = get_binance_bars(symbol_out, i, last_datetime_ticker, time_actual_ticker)  # timeframe
      
                  if new_df is None:
                      break
                  df_list.append(new_df)
                  last_datetime_ticker = max(new_df.index) + dt.timedelta(0, 1)
              df = pd.concat(df_list)
              df.columns
              # data = bt.feeds.PandasData(dataname=df)
              df.to_csv(filename)
              df = pd.read_csv(filename, sep=',', header=0,
                               names=['time', 'datetime', 'open', 'high', 'low', 'close', 'volume', 'adj_close'],
                               low_memory=False)
              df.to_csv(filename)
      
          # time.sleep(5)
          print('Intervalo: {}'.format(i))
          # print('Intervalo: {}'.format(timeframe))
      
          # timeframe y compresión
          compression_actual, timeframe_actual = timeFrame(i)  # (timeframe)
      
          # Cargar csv
          data = btfeed.GenericCSVData(
              dataname=filename,
              fromdate=last_datetime_ticker,
              todate=time_actual,
              nullvalue=0.0,
              dtformat='%Y-%m-%d %H:%M:%S',
              datetime=1,
              open=3,
              high=4,
              low=5,
              close=6,
              volume=7,
              adj_close=8,
              openinterest=-1,
              timeframe=timeframe_actual,
              compression=compression_actual,
          )
          datos = data
      
          # print('precio actual: {}'.format(precioactual))
          ######
      
          # optuna
          study = optuna.create_study(direction="maximize")
          study.optimize(opt_objective, n_trials=cycle)
      
          # print(study.best_params)
          parametros_optimos = study.best_params
          trial = study.best_trial
          print('Saldo máximo: {}'.format(trial.value))
          print(parametros_optimos)
          print()
      

      Strategy in TradingView

      //@version=4
      strategy(title="cryptos", shorttitle="cryptos",  default_qty_type=strategy.percent_of_equity, default_qty_value=100.0, initial_capital=100.0, precision=8, overlay=true) //default_qty_type=strategy.percent_of_equity, default_qty_value=10, overlay=true
      
      var price = open
      var begin = true
      var longTakeprofit = 1.0
      var longStoploss = 1.0
      var shortTakeprofit = 1.0
      var shortStoploss = 1.0
      var long = false
      var short = false
      var profitA = 1.0
      var lossA = 1.0
      var profitB = 1.0
      var lossB = 1.0
      var fin = false
      var y = 0.0
      var euros = 0.0
      var abierto = false
      
      
      profitA := 1.570173110761911
      lossA :=   0.6139438232090115
      profitB := 1.788102175824208 
      lossB :=  1.1373272588047958
      
      if (time > timestamp(2021, 04, 02, 00, 00)) 
      
          if ((open>=shortTakeprofit or open<=shortStoploss) and abierto==false) or begin==true
              price := open
              longTakeprofit := open * (profitA)
              longStoploss := open * (lossA)
              
              strategy.order("LONG", strategy.long)
              begin:=false
              abierto := true
      
          if ((open>=longTakeprofit or open<=longStoploss) and abierto ==true) and begin ==false
              price := open
              shortTakeprofit := open * (profitB)
              shortStoploss := open * (lossB)
              strategy.order("SHORT", strategy.short)
              abierto :=false
      
      

      I hope I can help you with something.
      Thank you

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