Advertisement
Maurizio-Ciullo

Strategia Completa Python Trend Wide Dotto

Sep 24th, 2021 (edited)
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.06 KB | None | 0 0
  1.                #              Trendwide Python Vedere Video Correlato Per Capire Come Lavora
  2.                #      (Long: Incrocio di 2 medie a rialzo ed un filtro per il long, con chiusura incrocio opposto senza filtro)
  3.                #      (Short: Incrocio di 2 medie a ribasso senza filtro per lo short, con chiusura incrocio opposto senza filtro)
  4.                #      (Buona per btc/usdt 30 Min medie sma 81 51 filtro 15)
  5.  
  6.                                              # Installazione librerie backtrade e matplotlib
  7.  
  8. !pip install backtrader
  9. !pip install matplotlib==3.2.2
  10. !pip install pandas
  11.  
  12.  
  13. import backtrader as bt
  14.  
  15. -------------------------------------------------------------------------------------------------------------
  16.  
  17.                                                        # Definizione strategia
  18.  
  19. ###############################################################################################################
  20. # @Author.....: Quantaste.com - Quant Trader Academy
  21. # @strategy...: TrendWide
  22. # @Type.......: Trend-follow
  23. # @long.......: Prezzo di chiusura > emaLenta e (media veloce - media lenta) > parametro min distanza
  24. # @long-exit..: Media veloce incrocia a ribasso media lenta
  25. # @short......: Prezzo di chiusura incrocia a ribasso media lenta
  26. # @short-exit.: Prezzo di chiusura incrocia a rialzo media veloce
  27. ###############################################################################################################
  28.  
  29. class TrendWide(bt.Strategy):
  30.     # parametri  di input
  31.     params = (
  32.         ('periodoEmaLenta', 81),
  33.         ('periodoEmaVeloce', 51),
  34.         ('soloLong', False),
  35.         ('distanzaMinMedie', 15),
  36.     )
  37.     # init: metodo che viene eseguito all'inizio
  38.     def __init__(self):
  39.         self.emaVeloce = bt.ind.EMA(period=self.params.periodoEmaVeloce)
  40.         self.emaLenta = bt.ind.EMA(period=self.params.periodoEmaLenta)
  41.  
  42.         self.closePrice = self.datas[0].close
  43.         self.distanzaMinMedie = self.params.distanzaMinMedie
  44.  
  45.         # long
  46.         self.exitLong = bt.ind.CrossDown(self.emaVeloce, self.emaLenta)
  47.  
  48.         # short
  49.         self.entryShort = bt.ind.CrossDown(self.closePrice, self.emaLenta)
  50.         self.exitShort = bt.ind.CrossUp(self.closePrice, self.emaVeloce)
  51.    
  52.     # next: viene azionato barra per barra (o tick per tick)
  53.     def next(self):
  54.         if self.position.size == 0:
  55.             if self.closePrice[0] > self.emaLenta[0] and (
  56.                     (self.emaVeloce[0] - self.emaLenta[0]) > self.distanzaMinMedie):
  57.                
  58.                 self.buy(size=25)
  59.  
  60.             elif self.entryShort and (self.emaLenta[0] - self.emaVeloce[0]) > self.distanzaMinMedie and not self.params.soloLong:
  61.                 self.sell(size=25)
  62.  
  63.         else:
  64.             if self.position.size > 0 and self.exitLong:
  65.                 self.close()
  66.             elif self.position.size < 0 and self.exitShort  and not self.params.soloLong:
  67.                 self.close()
  68.                
  69.     # metodo mio personale creato per scrive i log in maniera formattata :)
  70.     def log(self, txt):
  71.         print("[{} {}] {}".format(self.datas[0].datetime.date(), self.datas[0].datetime.time(), txt))
  72.    
  73.     # metodo che viene eseguito quando si inserisce un ordine
  74.     def notify_order(self, order):
  75.         if order.status == order.Completed:
  76.             self.log("Inserito ordine {}@{} size@{}".format('BUY' if order.isbuy() else 'SELL', order.executed.price, order.size))
  77.    
  78.     # metodo che viene eseguito quando si inserisce un trade
  79.     def notify_trade(self, trade):
  80.         if trade.isclosed:
  81.             self.log("Trade chiuso: PNL Lordo@{} PNL netto@{}".format(trade.pnl, trade.pnlcomm))
  82.  
  83. -------------------------------------------------------------------------------------------------------------
  84.  
  85.                                    # Motore backtest (capitale, parametri, data feed...)
  86.  
  87. import backtrader as bt
  88. from datetime import datetime
  89. from backtrader import CommInfoBase
  90. import yfinance as yf
  91.  
  92. initCapital = 20000
  93. cerebro = bt.Cerebro()
  94.  
  95. data = bt.feeds.GenericCSVData(
  96.     dataname='STOCK_US_QQQ_30m_20180101_20210920.csv',
  97.     timeframe=bt.TimeFrame.Minutes,
  98.     compression=30,
  99.     fromdate=datetime(2018, 1, 1),
  100.     todate=datetime(2021, 9, 20),
  101.     dtformat=('%Y%m%d'),
  102.     tmformat=('%H%M'),
  103.     date=0,
  104.     time=1,
  105.     open=2,
  106.     high=3,
  107.     low=4,
  108.     close=5,
  109.     volume=-1,
  110.     openinterest=-1
  111. )
  112.  
  113. cerebro.adddata(data)
  114.  
  115. cerebro.addstrategy(TrendWide, periodoEmaLenta=18, periodoEmaVeloce=7, soloLong=True, distanzaMinMedie=0.001)
  116. cerebro.broker.setcommission(commission=0.05, commtype=CommInfoBase.COMM_FIXED)
  117.  
  118. cerebro.broker.setcash(initCapital)
  119.  
  120. cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
  121. cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trade")
  122. cerebro.addanalyzer(bt.analyzers.TimeReturn, _name="timereturn")
  123. cerebro.addobserver(bt.observers.Value)
  124. result = cerebro.run()
  125.  
  126. -------------------------------------------------------------------------------------------------------------
  127.  
  128.                                                         #  Plotting
  129.  
  130. cerebro.plot(style="candlestick", volume=False)
  131.  
  132. -------------------------------------------------------------------------------------------------------------
  133.  
  134.                                                          # Statistiche
  135.  
  136. finalCapital = initCapital + result[0].analyzers.trade.get_analysis()['pnl']['net']['total']
  137.  
  138.     print("+++++++++++++++++++++++++++++++++++++++++++++++++++++")
  139.     print("+++++++++++++++++++++ Backtest ++++++++++++++++++++++")
  140.     print("+++++++++++++++++++++++++++++++++++++++++++++++++++++")
  141.     print("")
  142.     print("Ordini Totali..........: {}".format(result[0].analyzers.trade.get_analysis()['total']['total']))
  143.     print("Ordini Streak vinti....: {}".format(result[0].analyzers.trade.get_analysis()['streak']['won']['current']))
  144.     print("Ordini Streak persi....: {}".format(result[0].analyzers.trade.get_analysis()['streak']['lost']['current']))
  145.     print("Profit Factor..........: {}".format(
  146.         abs(result[0].analyzers.trade.get_analysis()['won']['pnl']['total']) / abs(
  147.             result[0].analyzers.trade.get_analysis()['lost']['pnl']['total'])))
  148.     print("Drawdown Max...........: {}".format(result[0].analyzers.drawdown.get_analysis()['max']['drawdown']))
  149.     print("Capitale finale........: {}".format(finalCapital))
  150.     print("Profitto %.............: {}".format(((finalCapital - initCapital) / initCapital) * 100))
  151.     print("PNL lorda..............: {}".format(result[0].analyzers.trade.get_analysis()['pnl']['gross']['total']))
  152.     print("PNL netta..............: {}".format(result[0].analyzers.trade.get_analysis()['pnl']['net']['total']))
  153.     print("---------------- Vincite -------------")
  154.     print("Trade totali...........: {}".format(result[0].analyzers.trade.get_analysis()['won']['total']))
  155.     print("Trade PNL totale.......: {}".format(result[0].analyzers.trade.get_analysis()['won']['pnl']['total']))
  156.     print("Trade PNL medio........: {}".format(result[0].analyzers.trade.get_analysis()['won']['pnl']['average']))
  157.     print("Trade PNL massimo......: {}".format(result[0].analyzers.trade.get_analysis()['won']['pnl']['max']))
  158.     print("---------------- Perdite -------------")
  159.     print("Trade totali...........: {}".format(result[0].analyzers.trade.get_analysis()['lost']['total']))
  160.     print("Trade PNL totale.......: {}".format(result[0].analyzers.trade.get_analysis()['lost']['pnl']['total']))
  161.     print("Trade PNL medio........: {}".format(result[0].analyzers.trade.get_analysis()['lost']['pnl']['average']))
  162.     print("Trade PNL massimo......: {}".format(result[0].analyzers.trade.get_analysis()['lost']['pnl']['max']))
  163.     print("----------------- Long ---------------")
  164.     print("Win/Loss Ratio.........: {}".format(
  165.         result[0].analyzers.trade.get_analysis()['long']['won'] / result[0].analyzers.trade.get_analysis()['long'][
  166.             'total']))
  167.  
  168. -------------------------------------------------------------------------------------------------------------
  169.  
  170.                                                         # change to optimizate
  171.  
  172. import backtrader as bt
  173. from datetime import datetime
  174. from backtrader import CommInfoBase
  175. import pandas as pd
  176.  
  177. initCapital = 20000
  178. cerebro = bt.Cerebro()
  179.  
  180. data = bt.feeds.GenericCSVData(
  181.     dataname='STOCK_US_QQQ_30m_20180101_20210920.csv',
  182.     timeframe=bt.TimeFrame.Minutes,
  183.     compression=30,
  184.     fromdate=datetime(2018, 1, 1),
  185.     todate=datetime(2021, 12, 31),
  186.     dtformat=('%Y%m%d'),
  187.     tmformat=('%H%M'),
  188.     date=0,
  189.     time=1,
  190.     open=2,
  191.     high=3,
  192.     low=4,
  193.     close=5,
  194.     volume=-1,
  195.     openinterest=-1
  196. )
  197.  
  198. cerebro.adddata(data)
  199. cerebro.broker.setcommission(commission=0.05, commtype=CommInfoBase.COMM_FIXED)
  200. cerebro.broker.setcash(initCapital)
  201.  
  202. cerebro.optstrategy(TrendWide, periodoEmaLenta=range(30, 40), periodoEmaVeloce=7, soloLong=True, distanzaMinMedie=0.001)
  203.  
  204. cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
  205. cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trade")
  206.  
  207. result = cerebro.run()
  208.  
  209. res_list = [[x[0].params.periodoEmaVeloce,
  210.              x[0].params.periodoEmaLenta,
  211.              x[0].params.distanzaMinMedie,
  212.              x[0].analyzers.trade.get_analysis()['total']['total'],
  213.              abs(x[0].analyzers.trade.get_analysis()['won']['pnl']['total']) / abs(x[0].analyzers.trade.get_analysis()['lost']['pnl']['total']),
  214.              x[0].analyzers.drawdown.get_analysis()['max']['drawdown'],
  215.              x[0].analyzers.trade.get_analysis()['long']['won']/x[0].analyzers.trade.get_analysis()['long']['total'],
  216.              ] for x in result]
  217.  
  218. pd.set_option("max_columns", None)
  219. pd.set_option('display.max_rows', None)
  220. pd.set_option('display.width', 300)
  221.  
  222. dfOpt = pd.DataFrame(res_list, columns=['EmaVeloce', 'EmaLenta', 'distanzaMinMedie', 'tot_trade', 'ProfitFactor', 'DDMax', 'Win%Long'])
  223.  
  224. dfOpt = dfOpt.sort_values(['ProfitFactor', 'DDMax', 'Win%Long','tot_trade'], ascending=[False, True, False, False])
  225.  
  226. -------------------------------------------------------------------------------------------------------------
  227.  
  228. dfOpt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement