Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Trendwide Python Vedere Video Correlato Per Capire Come Lavora
- # (Long: Incrocio di 2 medie a rialzo ed un filtro per il long, con chiusura incrocio opposto senza filtro)
- # (Short: Incrocio di 2 medie a ribasso senza filtro per lo short, con chiusura incrocio opposto senza filtro)
- # (Buona per btc/usdt 30 Min medie sma 81 51 filtro 15)
- # Installazione librerie backtrade e matplotlib
- !pip install backtrader
- !pip install matplotlib==3.2.2
- !pip install pandas
- import backtrader as bt
- -------------------------------------------------------------------------------------------------------------
- # Definizione strategia
- ###############################################################################################################
- # @Author.....: Quantaste.com - Quant Trader Academy
- # @strategy...: TrendWide
- # @Type.......: Trend-follow
- # @long.......: Prezzo di chiusura > emaLenta e (media veloce - media lenta) > parametro min distanza
- # @long-exit..: Media veloce incrocia a ribasso media lenta
- # @short......: Prezzo di chiusura incrocia a ribasso media lenta
- # @short-exit.: Prezzo di chiusura incrocia a rialzo media veloce
- ###############################################################################################################
- class TrendWide(bt.Strategy):
- # parametri di input
- params = (
- ('periodoEmaLenta', 81),
- ('periodoEmaVeloce', 51),
- ('soloLong', False),
- ('distanzaMinMedie', 15),
- )
- # init: metodo che viene eseguito all'inizio
- def __init__(self):
- self.emaVeloce = bt.ind.EMA(period=self.params.periodoEmaVeloce)
- self.emaLenta = bt.ind.EMA(period=self.params.periodoEmaLenta)
- self.closePrice = self.datas[0].close
- self.distanzaMinMedie = self.params.distanzaMinMedie
- # long
- self.exitLong = bt.ind.CrossDown(self.emaVeloce, self.emaLenta)
- # short
- self.entryShort = bt.ind.CrossDown(self.closePrice, self.emaLenta)
- self.exitShort = bt.ind.CrossUp(self.closePrice, self.emaVeloce)
- # next: viene azionato barra per barra (o tick per tick)
- def next(self):
- if self.position.size == 0:
- if self.closePrice[0] > self.emaLenta[0] and (
- (self.emaVeloce[0] - self.emaLenta[0]) > self.distanzaMinMedie):
- self.buy(size=25)
- elif self.entryShort and (self.emaLenta[0] - self.emaVeloce[0]) > self.distanzaMinMedie and not self.params.soloLong:
- self.sell(size=25)
- else:
- if self.position.size > 0 and self.exitLong:
- self.close()
- elif self.position.size < 0 and self.exitShort and not self.params.soloLong:
- self.close()
- # metodo mio personale creato per scrive i log in maniera formattata :)
- def log(self, txt):
- print("[{} {}] {}".format(self.datas[0].datetime.date(), self.datas[0].datetime.time(), txt))
- # metodo che viene eseguito quando si inserisce un ordine
- def notify_order(self, order):
- if order.status == order.Completed:
- self.log("Inserito ordine {}@{} size@{}".format('BUY' if order.isbuy() else 'SELL', order.executed.price, order.size))
- # metodo che viene eseguito quando si inserisce un trade
- def notify_trade(self, trade):
- if trade.isclosed:
- self.log("Trade chiuso: PNL Lordo@{} PNL netto@{}".format(trade.pnl, trade.pnlcomm))
- -------------------------------------------------------------------------------------------------------------
- # Motore backtest (capitale, parametri, data feed...)
- import backtrader as bt
- from datetime import datetime
- from backtrader import CommInfoBase
- import yfinance as yf
- initCapital = 20000
- cerebro = bt.Cerebro()
- data = bt.feeds.GenericCSVData(
- dataname='STOCK_US_QQQ_30m_20180101_20210920.csv',
- timeframe=bt.TimeFrame.Minutes,
- compression=30,
- fromdate=datetime(2018, 1, 1),
- todate=datetime(2021, 9, 20),
- dtformat=('%Y%m%d'),
- tmformat=('%H%M'),
- date=0,
- time=1,
- open=2,
- high=3,
- low=4,
- close=5,
- volume=-1,
- openinterest=-1
- )
- cerebro.adddata(data)
- cerebro.addstrategy(TrendWide, periodoEmaLenta=18, periodoEmaVeloce=7, soloLong=True, distanzaMinMedie=0.001)
- cerebro.broker.setcommission(commission=0.05, commtype=CommInfoBase.COMM_FIXED)
- cerebro.broker.setcash(initCapital)
- cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
- cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trade")
- cerebro.addanalyzer(bt.analyzers.TimeReturn, _name="timereturn")
- cerebro.addobserver(bt.observers.Value)
- result = cerebro.run()
- -------------------------------------------------------------------------------------------------------------
- # Plotting
- cerebro.plot(style="candlestick", volume=False)
- -------------------------------------------------------------------------------------------------------------
- # Statistiche
- finalCapital = initCapital + result[0].analyzers.trade.get_analysis()['pnl']['net']['total']
- print("+++++++++++++++++++++++++++++++++++++++++++++++++++++")
- print("+++++++++++++++++++++ Backtest ++++++++++++++++++++++")
- print("+++++++++++++++++++++++++++++++++++++++++++++++++++++")
- print("")
- print("Ordini Totali..........: {}".format(result[0].analyzers.trade.get_analysis()['total']['total']))
- print("Ordini Streak vinti....: {}".format(result[0].analyzers.trade.get_analysis()['streak']['won']['current']))
- print("Ordini Streak persi....: {}".format(result[0].analyzers.trade.get_analysis()['streak']['lost']['current']))
- print("Profit Factor..........: {}".format(
- abs(result[0].analyzers.trade.get_analysis()['won']['pnl']['total']) / abs(
- result[0].analyzers.trade.get_analysis()['lost']['pnl']['total'])))
- print("Drawdown Max...........: {}".format(result[0].analyzers.drawdown.get_analysis()['max']['drawdown']))
- print("Capitale finale........: {}".format(finalCapital))
- print("Profitto %.............: {}".format(((finalCapital - initCapital) / initCapital) * 100))
- print("PNL lorda..............: {}".format(result[0].analyzers.trade.get_analysis()['pnl']['gross']['total']))
- print("PNL netta..............: {}".format(result[0].analyzers.trade.get_analysis()['pnl']['net']['total']))
- print("---------------- Vincite -------------")
- print("Trade totali...........: {}".format(result[0].analyzers.trade.get_analysis()['won']['total']))
- print("Trade PNL totale.......: {}".format(result[0].analyzers.trade.get_analysis()['won']['pnl']['total']))
- print("Trade PNL medio........: {}".format(result[0].analyzers.trade.get_analysis()['won']['pnl']['average']))
- print("Trade PNL massimo......: {}".format(result[0].analyzers.trade.get_analysis()['won']['pnl']['max']))
- print("---------------- Perdite -------------")
- print("Trade totali...........: {}".format(result[0].analyzers.trade.get_analysis()['lost']['total']))
- print("Trade PNL totale.......: {}".format(result[0].analyzers.trade.get_analysis()['lost']['pnl']['total']))
- print("Trade PNL medio........: {}".format(result[0].analyzers.trade.get_analysis()['lost']['pnl']['average']))
- print("Trade PNL massimo......: {}".format(result[0].analyzers.trade.get_analysis()['lost']['pnl']['max']))
- print("----------------- Long ---------------")
- print("Win/Loss Ratio.........: {}".format(
- result[0].analyzers.trade.get_analysis()['long']['won'] / result[0].analyzers.trade.get_analysis()['long'][
- 'total']))
- -------------------------------------------------------------------------------------------------------------
- # change to optimizate
- import backtrader as bt
- from datetime import datetime
- from backtrader import CommInfoBase
- import pandas as pd
- initCapital = 20000
- cerebro = bt.Cerebro()
- data = bt.feeds.GenericCSVData(
- dataname='STOCK_US_QQQ_30m_20180101_20210920.csv',
- timeframe=bt.TimeFrame.Minutes,
- compression=30,
- fromdate=datetime(2018, 1, 1),
- todate=datetime(2021, 12, 31),
- dtformat=('%Y%m%d'),
- tmformat=('%H%M'),
- date=0,
- time=1,
- open=2,
- high=3,
- low=4,
- close=5,
- volume=-1,
- openinterest=-1
- )
- cerebro.adddata(data)
- cerebro.broker.setcommission(commission=0.05, commtype=CommInfoBase.COMM_FIXED)
- cerebro.broker.setcash(initCapital)
- cerebro.optstrategy(TrendWide, periodoEmaLenta=range(30, 40), periodoEmaVeloce=7, soloLong=True, distanzaMinMedie=0.001)
- cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
- cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trade")
- result = cerebro.run()
- res_list = [[x[0].params.periodoEmaVeloce,
- x[0].params.periodoEmaLenta,
- x[0].params.distanzaMinMedie,
- x[0].analyzers.trade.get_analysis()['total']['total'],
- abs(x[0].analyzers.trade.get_analysis()['won']['pnl']['total']) / abs(x[0].analyzers.trade.get_analysis()['lost']['pnl']['total']),
- x[0].analyzers.drawdown.get_analysis()['max']['drawdown'],
- x[0].analyzers.trade.get_analysis()['long']['won']/x[0].analyzers.trade.get_analysis()['long']['total'],
- ] for x in result]
- pd.set_option("max_columns", None)
- pd.set_option('display.max_rows', None)
- pd.set_option('display.width', 300)
- dfOpt = pd.DataFrame(res_list, columns=['EmaVeloce', 'EmaLenta', 'distanzaMinMedie', 'tot_trade', 'ProfitFactor', 'DDMax', 'Win%Long'])
- dfOpt = dfOpt.sort_values(['ProfitFactor', 'DDMax', 'Win%Long','tot_trade'], ascending=[False, True, False, False])
- -------------------------------------------------------------------------------------------------------------
- dfOpt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement