Overall Statistics |
Total Trades 149 Average Win 15.05% Average Loss -4.70% Compounding Annual Return 38.856% Drawdown 51.700% Expectancy 0.728 Net Profit 447.784% Sharpe Ratio 0.872 Probabilistic Sharpe Ratio 23.380% Loss Rate 59% Win Rate 41% Profit-Loss Ratio 3.21 Alpha 0.32 Beta 0.59 Annual Standard Deviation 0.426 Annual Variance 0.181 Information Ratio 0.68 Tracking Error 0.419 Treynor Ratio 0.629 Total Fees $151.32 Estimated Strategy Capacity $33000000.00 Lowest Capacity Asset ORLY R735QTJ8XC9X |
#region imports from AlgorithmImports import * #endregion from Alphas.MacdAlphaModel import MacdAlphaModel class WellDressedYellowGreenFish(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) # Set Start Date self.SetCash(5000) # Set Strategy Cash #self.AddAlpha(MacdAlphaModel(12, 26, 9, MovingAverageType.Simple, Resolution.Daily)) self.SetBenchmark("SPY") self.AddUniverse(self.CoarseSelectionFunction) self.UniverseSettings.Resolution = Resolution.Daily self.averages = { } self.SetWarmUp(400) def CoarseSelectionFunction(self, universe): selected = [] universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True) universe = [c for c in universe if c.Price > 100][:100] for coarse in universe: symbol = coarse.Symbol if symbol not in self.averages: # 1. Call history to get an array of 200 days of history data history = self.History(symbol, 200, Resolution.Daily) #2. Adjust SelectionData to pass in the history result self.averages[symbol] = SelectionData(history) self.averages[symbol].update(self.Time, coarse.AdjustedPrice) if self.averages[symbol].is_ready() and self.averages[symbol].fast > self.averages[symbol].mid and self.averages[symbol].mid > self.averages[symbol].slow: selected.append(symbol) return selected[:2] def OnData(self, data): for symbol, symbol_data in self.averages.items(): tolerance = 0.0015 if not data.ContainsKey(symbol) or not data.Bars.ContainsKey(symbol): continue holdings = self.Portfolio[symbol].Quantity if self.Portfolio.ContainsKey(symbol) else 0 signalDeltaPercent = (symbol_data.macd.Current.Value - symbol_data.macd.Signal.Current.Value)/symbol_data.macd.Fast.Current.Value if holdings <= 0 and signalDeltaPercent > tolerance: # 0.01% # longterm says buy as well self.SetHoldings(symbol, 0.5) elif holdings >= 0 and signalDeltaPercent < -tolerance: self.Liquidate(symbol) class SelectionData(): #3. Update the constructor to accept a history array def __init__(self, history): self.slow = ExponentialMovingAverage(200) self.mid = ExponentialMovingAverage(13) self.fast = ExponentialMovingAverage(5) self.macd = MovingAverageConvergenceDivergence(50, 200, 9, MovingAverageType.Exponential) #4. Loop over the history data and update the indicators for bar in history.itertuples(): self.fast.Update(bar.Index[1], bar.close) self.slow.Update(bar.Index[1], bar.close) self.mid.Update(bar.Index[1], bar.close) self.macd.Update(bar.Index[1], bar.close) def is_ready(self): return self.slow.IsReady and self.fast.IsReady and self.mid.IsReady def update(self, time, price): self.fast.Update(time, price) self.mid.Update(time, price) self.slow.Update(time, price) self.macd.Update(time, price)