Overall Statistics |
Total Trades 1893 Average Win 0.00% Average Loss 0.00% Compounding Annual Return 157.114% Drawdown 1.700% Expectancy 8.493 Net Profit 12.651% Sharpe Ratio 6.693 Probabilistic Sharpe Ratio 95.729% Loss Rate 5% Win Rate 95% Profit-Loss Ratio 9.01 Alpha 1.496 Beta -0.29 Annual Standard Deviation 0.172 Annual Variance 0.029 Information Ratio -0.218 Tracking Error 0.237 Treynor Ratio -3.956 Total Fees $1917.95 Estimated Strategy Capacity $54000000.00 |
from io import StringIO import pandas as pd import datetime class PensiveTanAnguilline(QCAlgorithm): ################################################################## ### Run the algo once to to store the objectStore ### ### Run the algo a second time to use it as a custom Benchmark ### ################################################################## ### START TO CUSTOM BENCHMARK ### portfolio_ObjectStore_Key_test = "test_v1.0.10" string_object = "" ### END - RELATED TO CUSTOM BENCHMARK ### START_DATE = datetime.datetime(2020,11,1) END_DATE = datetime.datetime(2020,12,15) def Initialize(self): self.SetStartDate(self.START_DATE.year, self.START_DATE.month, self.START_DATE.day) self.SetEndDate(self.END_DATE.year, self.END_DATE.month, self.END_DATE.day) self.SetCash(2000000) self.symbols = ['A','AAL','AAP','AAPL','ABBV','ABC','ABMD','ABT','ACN','ADBE','ADI','ADM','ADP','ADSK','AEE','AEP','AES','AFL','AIG','AIZ','AJG','AKAM','ALB','ALGN','ALK','ALL','ALLE','ALXN','AMAT','AMCR','AMD','AME','AMGN','AMP','AMT','AMZN','ANET','ANSS','ANTM','AON','AOS','APA','APD','APH','APTV','ARE','ATO','ATVI','AVB','AVGO','AVY','AWK','AXP','AZO','BA','BAC','BAX','BBY','BDX','BEN','BFb','BIIB','BIO','BK','BKNG','BKR','BLK','BLL','BMY','BR','BRKb','BSX','BWA','BXP','C','CAG','CAH','CARR','CAT','CB','CBOE','CBRE','CCI','CCL','CDNS','CDW','CE','CERN','CF','CFG','CHD','CHRW','CHTR','CI','CINF','CL','CLX','CMA','CMCSA','CME','CMG','CMI','CMS','CNC','CNP','COF','COG','COO','COP','COST','CPB','CPRT','CRM','CSCO','CSX','CTAS','CTLT','CTSH','CTVA','CTXS','CVS','CVX','D','DAL','DD','DE','DFS','DG','DGX','DHI','DHR','DIS','DISCA','DISCK','DISH','DLR','DLTR','DOV','DOW','DPZ','DRE','DRI','DTE','DUK','DVA','DVN','DXC','DXCM','EA','EBAY','ECL','ED','EFX','EIX','EL','EMN','EMR','ENPH','EOG','EQIX','EQR','ES','ESS','ETN','ETR','ETSY','EVRG','EW','EXC','EXPD','EXPE','EXR','F','FANG','FAST','FB','FBHS','FCX','FDX','FE','FFIV','FIS','FISV','FITB','FLIR','FLS','FLT','FMC','FOXA','FRC','FRT','FTNT','FTV','GD','GE','GILD','GIS','GL','GLW','GM','GOOG','GOOGL','GPC','GPN','GPS','GRMN','GS','GWW','HAL','HAS','HBAN','HBI','HCA','HD','HES','HFC','HIG','HII','HLT','HOLX','HON','HPE','HPQ','HRL','HSIC','HST','HSY','HUM','HWM','IBM','ICE','IDXX','IEX','IFF','ILMN','INCY','INFO','INTC','INTU','IP','IPG','IPGP','IQV','IR','IRM','ISRG','IT','ITW','IVZ','JBHT','JCI','JEC','JKHY','JNJ','JNPR','JPM','K','KEY','KEYS','KHC','KIM','KLAC','KMB','KMI','KMX','KO','KR','KSU','L','LB','LDOS','LEG','LEN','LH','LHX','LIN','LKQ','LLY','LMT','LNC','LNT','LOW','LRCX','LUMN','LUV','LVS','LW','LYB','LYV','MA','MAA','MAR','MAS','MCD','MCHP','MCK','MCO','MDLZ','MDT','MET','MGM','MHK','MKC','MKTX','MLM','MMC','MMM','MNST','MO','MOS','MPC','MPWR','MRK','MRO','MS','MSCI','MSFT','MSI','MTB','MTD','MU','MXIM','NCLH','NDAQ','NEE','NEM','NFLX','NI','NKE','NLOK','NLSN','NOC','NOV','NOW','NRG','NSC','NTAP','NTRS','NUE','NVDA','NVR','NWL','NWSA','O','ODFL','OKE','OMC','ORCL','ORLY','OTIS','OXY','PAYC','PAYX','PBCT','PCAR','PEAK','PEG','PEP','PFE','PFG','PG','PGR','PH','PHM','PKG','PKI','PLD','PM','PNC','PNR','PNW','POOL','PPG','PPL','PRGO','PRU','PSA','PSX','PVH','PWR','PXD','PYPL','QCOM','QRVO','RCL','RE','REG','REGN','RF','RHI','RJF','RL','RMD','ROK','ROL','ROP','ROST','RSG','RTX','SBAC','SBUX','SCHW','SEE','SHW','SIVB','SJM','SLB','SLG','SNA','SNPS','SO','SPG','SPGI','SRE','STE','STT','STX','STZ','SWK','SWKS','SYF','SYK','SYY','T','TAP','TDG','TDY','TEL','TER','TFC','TFX','TGT','TJX','TMO','TMUS','TPR','TRMB','TROW','TRV','TSCO','TSLA','TSN','TT','TTWO','TWTR','TXN','TXT','TYL','UA','UAA','UAL','UDR','UHS','ULTA','UNH','UNM','UNP','UPS','URI','USB','V','VAR','VFC','VIAC','VLO','VMC','VNO','VNT','VRSK','VRSN','VRTX','VTR','VTRS','VZ','WAB','WAT','WBA','WDC','WEC','WELL','WFC','WHR','WLTW','WM','WMB','WMT','WRB','WRK','WST','WU','WY','WYNN','XEL','XLNX','XOM','XRAY','XRX','XYL','YUM','ZBH','ZBRA','ZION','ZTS'] self.allSecurities = [] for symbol in self.symbols: security = self.AddEquity(symbol, Resolution.Daily).Symbol self.allSecurities.append(security) self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol self.tradableSecurities = [] self.SetWarmUp(timedelta(days = 30)) self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.BeforeMarketClose("SPY", 0), self.rebalance ) self.investedCount = 0 ### START - RELATED TO CUSTOM BENCHMARK ### # ObjectStore for custom Benchmark if self.ObjectStore.ContainsKey(self.portfolio_ObjectStore_Key_test): values = self.ObjectStore.Read(self.portfolio_ObjectStore_Key_test) self.Debug(f'{self.portfolio_ObjectStore_Key_test} key exists in object store.') self.Debug("str(values)" + "\n") self.Debug(str(values)) history = pd.read_csv(StringIO(values), header=None, index_col=0, squeeze=True) history.index = pd.to_datetime(history.index) """ Here comes the problems I tried two ways: 1) benchmark = [history.index.values,history.values] self.SetBenchmark(benchmark) 2) self.SetBenchmark(self.custom_function) # function definition below Both doesn't work """ # Doesn't work : #benchmark = [history.index.values,history.values] #self.SetBenchmark(benchmark) # Doesn't work neither: #self.SetBenchmark(self.custom_function) ### END - RELATED TO CUSTOM BENCHMARK ### def OnData(self, data): ### START - RELATED TO CUSTOM BENCHMARK ### #self.Debug("self.Time : " + str(self.Time) + " - FIN" + "\n" ) # output : self.Time : 2021-02-01 00:00:00 - FIN #self.Debug("self.Portfolio.TotalPortfolioValue : " + str(self.Portfolio.TotalPortfolioValue) + " - FIN" + "\n") # output : self.Portfolio.TotalPortfolioValue : 2000000.0 - FIN ### Add only portfolio value since the start_date ### We don't store the portfolio value during the warmup period if(self.Time >= self.START_DATE): self.string_object += ('\n' + str(self.Time) + "," + str(self.Portfolio.TotalPortfolioValue) ) #Save the object at the last day of the algorithm if( (self.END_DATE.year == self.Time.year) and (self.END_DATE.month == self.Time.month) and (self.END_DATE.day == self.Time.day) ): self.Debug(str(self.Time)) self.ObjectStore.Save(self.portfolio_ObjectStore_Key_test, self.string_object) # self.Debug("string_object : " + self.string_object) ### END - RELATED TO CUSTOM BENCHMARK ### self.tradableSecurities = [] for security in self.allSecurities: if data.ContainsKey(security.Value): self.tradableSecurities.append(security) else: continue def rebalance(self): '''Include sell statement for removed securities''' # Faire if len < 100; return if len(self.tradableSecurities) == 0: return if (len(self.tradableSecurities) < 100): self.Debug("Number of tradableSecurities : " + str(len(self.tradableSecurities))) self.Debug("We don''t rebalance") return for security in self.tradableSecurities: if not self.Portfolio[security].Invested: self.investedCount += 1 INVESTED_FRACTION = 0.995 # Remove 0.5% for the fees ? weight_temp = INVESTED_FRACTION/len(self.tradableSecurities) WEIGHT_LIMIT = 0.03 weight = self.weightLimitation(weight_temp, WEIGHT_LIMIT) for security in self.tradableSecurities: if self.Portfolio[security].Invested: self.SetHoldings([PortfolioTarget(security.Value, weight)]) for security in self.tradableSecurities: if not self.Portfolio[security].Invested: self.SetHoldings([PortfolioTarget(security.Value, weight)]) ### START - RELATED TO CUSTOM BENCHMARK ### def custom_function(self): time = self.Time date = datetime.datetime(time.year, time.month, time.day) t = pd.Timestamp(date) value = history.loc[t] return t, value ### END - RELATED TO CUSTOM BENCHMARK ### def weightLimitation(self, weight_temp,WEIGHT_LIMIT): if(weight_temp > WEIGHT_LIMIT): return WEIGHT_LIMIT else: return weight_temp