Overall Statistics |
Total Trades 6231 Average Win 0.11% Average Loss -0.03% Compounding Annual Return 10.874% Drawdown 16.800% Expectancy 1.114 Net Profit 180.898% Sharpe Ratio 0.835 Probabilistic Sharpe Ratio 24.135% Loss Rate 55% Win Rate 45% Profit-Loss Ratio 3.69 Alpha 0.1 Beta -0.035 Annual Standard Deviation 0.115 Annual Variance 0.013 Information Ratio -0.13 Tracking Error 0.18 Treynor Ratio -2.723 Total Fees $6875.14 |
from datetime import timedelta import numpy as np from scipy import stats from collections import deque class FrameworkAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2010, 1, 1) self.SetEndDate(2019, 12, 31) self.SetCash(100000) self.tickers = ["QQQ","PQSC","IYC","IYK","IGV","IHI","ITA","ITB","SMH","GLD","SBUG","TLH","TLT","EDV","CWB"] self.UniverseSettings.Resolution = Resolution.Daily self.sym=[] for x in self.tickers: self.sym.append(Symbol.Create(x, SecurityType.Equity, Market.USA)) self.SetUniverseSelection( ManualUniverseSelectionModel(self.sym) ) # Alpha Model self.SetAlpha(MOMAlphaModel()) # PortfolioConstruction Model self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) # RiskManagement Model self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(1)) # Execution Model self.SetExecution(ImmediateExecutionModel()) class MOMAlphaModel(AlphaModel): def __init__(self): self.mom = [] self.slopy={} def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: symbol = security.Symbol self.slopy[symbol] = custom_slope(symbol, 100) history = algorithm.History(symbol, 100, Resolution.Daily) self.slopy[symbol].Warmup(history) algorithm.RegisterIndicator(symbol, self.slopy[symbol], Resolution.Daily) self.mom.append({"symbol":symbol, "indicator": self.slopy[symbol]}) def Update(self, algorithm, data): insights = [] ordered = sorted(self.mom, key=lambda kv: kv["indicator"].Current.Value, reverse=True)[:4] for x in ordered: symbol = x['symbol'] #if self.slopy[symbol].IsReady : insights.append( Insight.Price(symbol, timedelta(1), InsightDirection.Up) ) return insights class custom_slope(PythonIndicator): def __init__(self,symbol, periods): self.symbol=symbol self.queue = deque(maxlen=periods) self.Value = 0 self.Time=None #self.IsReady=False def Update(self,input): self.queue.appendleft(input.Close) count = len(self.queue) if count == self.queue.maxlen: y = np.log(self.queue) x = [range(len(y))] slope, intercept, r_value, p_value, std_err = stats.linregress(x, y) self.Value=slope * 10000 #self.IsReady=True def Warmup(self,history): if self.symbol not in history: return for index, row in history.loc[self.symbol].iterrows(): self.queue.Add(row["close"]) self.Time=index