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]
-
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