| Overall Statistics |
|
Total Orders 609 Average Win 17.11% Average Loss -2.26% Compounding Annual Return 47.498% Drawdown 27.100% Expectancy 5.543 Start Equity 10000 End Equity 86474.13 Net Profit 764.741% Sharpe Ratio 1.334 Sortino Ratio 1.538 Probabilistic Sharpe Ratio 77.013% Loss Rate 24% Win Rate 76% Profit-Loss Ratio 7.59 Alpha 0.232 Beta 0.794 Annual Standard Deviation 0.235 Annual Variance 0.055 Information Ratio 1.168 Tracking Error 0.18 Treynor Ratio 0.395 Total Fees $46.91 Estimated Strategy Capacity $250000000.00 Lowest Capacity Asset WMT R735QTJ8XC9X Portfolio Turnover 0.57% Drawdown Recovery 507 |
#region import
from AlgorithmImports import *
#endregion
from Alphas.MacdAlphaModel import MacdAlphaModel
class WellDressedYellowGreenFish(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 3, 11) # Set Start Date
self.SetCash(10000) # Set Strategy Cash
self.AddUniverse(self.CoarseSelectionFunction)
self.UniverseSettings.Resolution = Resolution.Daily
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Cash)
self.set_benchmark(SecurityType.Equity, "MTUM")
self.averages = { }
self.SetWarmUp(400)
self.n = 0
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][:89]
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, 189, 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 > self.averages[symbol].slow:
selected.append(symbol)
return selected[:4]
def OnData(self, data):
for symbol, symbol_data in self.averages.items():
tolerance = 0.003
tolerance5 = 48.87
tolerance6 = 57.87
tolerance7 = 67.02
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:
if self.n == 4:
return
elif symbol_data.macd.Histogram.Current.Value < tolerance:
if tolerance6 > symbol_data.mfi.Current.Value > tolerance5 and symbol_data.mfi.Current.Value > symbol_data.mfi.Previous.Value:
if symbol_data.rc.LowerChannel >= symbol_data.bb.UpperBand:
if symbol_data.rc.LowerChannel > symbol_data.bb.UpperBand > symbol_data.trading > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.55)
self.n += 1
elif symbol_data.rc.LinearRegression >= symbol_data.bb.UpperBand >= symbol_data.rc.LowerChannel:
if symbol_data.trading > symbol_data.rc.LowerChannel > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.15)
self.n += 1
elif symbol_data.rc.LowerChannel > symbol_data.trading > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.55)
self.n += 1
elif symbol_data.macd.Histogram.Current.Value > tolerance:
if symbol_data.mfi.Current.Value < tolerance5:
if symbol_data.trading >= symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.trading >= symbol_data.rc.LowerChannel and symbol_data.trading < symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.5)
self.n += 1
elif tolerance6 > symbol_data.mfi.Current.Value >= tolerance5 and symbol_data.mfi.Current.Value > symbol_data.mfi.Previous.Value:
if symbol_data.rc.LowerChannel > symbol_data.bb.UpperBand:
if symbol_data.rc.LowerChannel > symbol_data.trading > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.35)
self.n += 1
elif symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand >= symbol_data.rc.LowerChannel:
if symbol_data.rc.LowerChannel > symbol_data.trading > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.65)
self.n += 1
elif symbol_data.rc.LowerChannel > symbol_data.bb.MiddleBand > symbol_data.trading:
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.bb.UpperBand > symbol_data.trading >= symbol_data.rc.LowerChannel > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.75)
self.n += 1
elif symbol_data.bb.UpperBand > symbol_data.trading > symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.15)
self.n += 1
elif symbol_data.rc.UpperChannel > symbol_data.bb.UpperBand >= symbol_data.rc.LinearRegression:
if symbol_data.trading >= symbol_data.bb.MiddleBand > symbol_data.rc.LinearRegression:
self.SetHoldings(symbol, 0.2)
self.n += 1
elif symbol_data.trading > symbol_data.rc.LinearRegression >= symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.2)
self.n += 1
elif symbol_data.rc.LinearRegression > symbol_data.trading >= symbol_data.bb.UpperBand :
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.mfi.Current.Value >= tolerance6 and symbol_data.mfi.Current.Value > symbol_data.mfi.Previous.Value:
if symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand > symbol_data.rc.LowerChannel:
if symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand > symbol_data.trading:
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.rc.LinearRegression > symbol_data.trading > symbol_data.bb.UpperBand:
self.SetHoldings(symbol, 0.5)
self.n += 1
elif symbol_data.trading < symbol_data.rc.LowerChannel and symbol_data.bb.UpperBand.Current.Value > symbol_data.bb.UpperBand.Previous.Value:
if symbol_data.bb.UpperBand < symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.5)
self.n += 1
elif symbol_data.bb.UpperBand < symbol_data.rc.LinearRegression and symbol_data.bb.UpperBand >= symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.bb.UpperBand >= symbol_data.rc.LinearRegression and symbol_data.bb.UpperBand < symbol_data.rc.UpperChannel and symbol_data.trading < symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.2)
self.n += 1
elif symbol_data.bb.UpperBand >= symbol_data.trading >= symbol_data.rc.LowerChannel > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.45)
self.n += 1
elif symbol_data.bb.MiddleBand <= symbol_data.rc.LowerChannel <= symbol_data.trading < symbol_data.rc.LinearRegression:
if symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand > symbol_data.trading :
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.rc.LinearRegression > symbol_data.trading >= symbol_data.bb.UpperBand:
self.SetHoldings(symbol, 0.25)
self.n += 1
elif symbol_data.mfi.Current.Value >= tolerance6 and symbol_data.mfi.Current.Value < symbol_data.mfi.Previous.Value:
if symbol_data.rc.LowerChannel > symbol_data.bb.UpperBand:
self.SetHoldings(symbol, 0.5)
self.n += 1
elif holdings >= 0 and signalDeltaPercent >= tolerance:
if symbol_data.trading >= symbol_data.rc.UpperChannel >= symbol_data.rc.UpperChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.trading >= symbol_data.rc.UpperChannel:
if tolerance6 >= symbol_data.mfi.Current.Value >= tolerance5:
if symbol_data.rc.LinearRegression > symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
if symbol_data.mfi.Current.Value < symbol_data.mfi.Previous.Value:
self.Liquidate(symbol)
self.n -= 1
elif tolerance6 >= symbol_data.mfi.Current.Value >= tolerance5:
if symbol_data.rc.LinearRegression > symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
if symbol_data.mfi.Current.Value > symbol_data.mfi.Previous.Value:
self.SetHoldings(symbol, 0.5)
elif symbol_data.mfi.Current.Value < symbol_data.mfi.Previous.Value:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.rc.UpperChannel >= symbol_data.trading and symbol_data.mfi.Current.Value < symbol_data.mfi.Previous.Value:
if tolerance7 >= symbol_data.mfi.Current.Value >= tolerance6:
if symbol_data.trading >= symbol_data.rc.LinearRegression >= symbol_data.bb.MiddleBand:
if symbol_data.MiddleBand < symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.95)
elif symbol_data.MiddleBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression >= symbol_data.trading:
self.Liquidate(symbol)
self.n -= 1
elif tolerance6 >= symbol_data.mfi.Current.Value >= tolerance5:
if symbol_data.trading > symbol_data.rc.LinearRegression:
if symbol_data.bb.MiddleBand < symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.95)
elif symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.mfi.Current.Value < tolerance5:
if symbol_data.trading >= symbol_data.bb.MiddleBand > symbol_data.rc.LinearRegression > symbol_data.bb.LowerBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.trading >= symbol_data.rc.LinearRegression > symbol_data.bb.LowerBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.MiddleBand >= symbol_data.trading >= symbol_data.rc.LinearRegression > symbol_data.bb.LowerBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.UpperChannel > symbol_data.bb.UpperBand >= symbol_data.rc.LinearRegression :
if symbol_data.mfi.Current.Value >= tolerance7:
if symbol_data.trading >= symbol_data.bb.UpperBand:
self.SetHoldings(symbol, 0.45)
elif symbol_data.bb.UpperBand > symbol_data.trading > symbol_data.rc.LinearRegression:
self.SetHoldings(symbol, 0.2)
elif symbol_data.mfi.Current.Value < tolerance7 and symbol_data.mfi.Current.Value >= tolerance6:
if symbol_data.trading >= symbol_data.bb.UpperBand and symbol_data.rc.LowerChannel > symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.25)
elif symbol_data.trading >= symbol_data.bb.UpperBand and symbol_data.rc.LowerChannel < symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand > symbol_data.trading > symbol_data.bb.MiddleBand >= symbol_data.rc.LinearRegression:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression >= symbol_data.trading >= symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression >= symbol_data.bb.MiddleBand >= symbol_data.trading >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.mfi.Current.Value < tolerance6:
if symbol_data.trading > symbol_data.bb.MiddleBand > symbol_data.rc.LinearRegression:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.trading > symbol_data.rc.LinearRegression > symbol_data.bb.MiddleBand:
if symbol_data.bb.MiddleBand < symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.15)
elif symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.MiddleBand > symbol_data.rc.LinearRegression > symbol_data.trading:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression > symbol_data.trading > symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression > symbol_data.bb.MiddleBand > symbol_data.trading:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand >= symbol_data.rc.LowerChannel:
if symbol_data.mfi.Current.Value >= tolerance7:
if symbol_data.trading >= symbol_data.rc.LowerChannel and symbol_data.trading < symbol_data.rc.LinearRegression:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.trading >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.mfi.Current.Value < tolerance7 and symbol_data.mfi.Current.Value >= tolerance6:
if symbol_data.trading >= symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.trading >= symbol_data.rc.LowerChannel > symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LowerChannel > symbol_data.trading >= symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.mfi.Current.Value < tolerance6 and symbol_data.mfi.Current.Value >= tolerance5:
if symbol_data.rc.LinearRegression > symbol_data.bb.UpperBand >= symbol_data.trading:
if symbol_data.bb.MiddleBand > symbol_data.rc.LowerChannel:
self.SetHoldings(symbol, 0.4)
elif symbol_data.bb.rc.LowerChannel > symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LowerChannel > symbol_data.trading > symbol_data.bb.MiddleBand and symbol_data.bb.MiddleBand.Current.Value < symbol_data.bb.MiddleBand.Previous.Value:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.mfi.Current.Value < tolerance5:
if symbol_data.trading < symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif holdings >= 0 and signalDeltaPercent < 0.0001:
if symbol_data.rc.Current.Value >= symbol_data.rc.Previous.Value:
if symbol_data.trading >= symbol_data.bb.UpperBand >= symbol_data.rc.UpperChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.trading >= symbol_data.rc.UpperChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.rc.UpperChannel >= symbol_data.trading:
if tolerance7 >= symbol_data.mfi.Current.Value >= tolerance6:
if symbol_data.trading > symbol_data.rc.LinearRegression:
self.Liquidate(symbol)
self.n -= 1
if tolerance6 >= symbol_data.mfi.Current.Value >= tolerance5:
if symbol_data.trading > symbol_data.rc.LinearRegression and symbol_data.bb.MiddleBand > symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.UpperChannel > symbol_data.bb.UpperBand > symbol_data.rc.LinearRegression:
if tolerance7 >= symbol_data.mfi.Current.Value >= tolerance6:
if symbol_data.bb.UpperBand > symbol_data.trading >= symbol_data.rc.LinearRegression:
if symbol_data.rc.LowerChannel >= symbol_data.bb.MiddleBand:
self.SetHoldings(symbol, 0.55)
elif symbol_data.rc.LowerChannel < symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif tolerance6 >= symbol_data.mfi.Current.Value >= tolerance5:
if symbol_data.bb.UpperBand > symbol_data.trading >= symbol_data.rc.LinearRegression:
if symbol_data.bb.MiddleBand >= symbol_data.rc.LinearRegression and symbol_data.bb.MiddleBand < symbol_data.trading:
self.SetHoldings(symbol, 0.55)
elif symbol_data.rc.LinearRegression > symbol_data.bb.MiddleBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.MiddleBand >= symbol_data.trading:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.mfi.Current.Value < tolerance5:
if symbol_data.bb.MiddleBand >= symbol_data.trading >= symbol_data.bb.LowerBand:
self.SetHoldings(symbol, 0.25)
elif symbol_data.rc.LinearRegression >= symbol_data.bb.MiddleBand >= symbol_data.trading >= symbol_data.bb.LowerBand >= symbol_data.rc.LowerChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression >= symbol_data.bb.UpperBand and tolerance6 > symbol_data.mfi.Current.Value >= tolerance5:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.Current.Value < symbol_data.rc.Previous.Value:
if symbol_data.trading >= symbol_data.bb.UpperBand >= symbol_data.rc.UpperChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.trading >= symbol_data.rc.UpperChannel:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.bb.UpperBand >= symbol_data.rc.UpperChannel >= symbol_data.trading:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.UpperChannel > symbol_data.bb.UpperBand >= symbol_data.rc.LinearRegression:
if symbol_data.trading >= symbol_data.bb.MiddleBand >= symbol_data.rc.LinearRegression:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression < symbol_data.trading <= symbol_data.bb.MiddleBand:
self.Liquidate(symbol)
self.n -= 1
elif symbol_data.rc.LinearRegression >= symbol_data.bb.UpperBand and tolerance6 > symbol_data.mfi.Current.Value > tolerance5:
self.Liquidate(symbol)
self.n -= 1
elif holdings > 0 and symbol_data.sma5.IsReady:
stop_level = symbol_data.sma5.Current.Value * 0.9
if data[symbol].Price < stop_level:
self.Liquidate(symbol)
self.n -= 1
class SelectionData():
#3. Update the constructor to accept a history array
def __init__(self, history):
self.slow = ExponentialMovingAverage(335)#optimised Fib
self.mid = ExponentialMovingAverage(233)#optimised Fib
self.fast = ExponentialMovingAverage(136)
self.trading = WilderMovingAverage(20)
self.macd = MovingAverageConvergenceDivergence(145, 377, 233, MovingAverageType.Simple)
self.mfi = RelativeStrengthIndex(50, MovingAverageType.Simple)
self.bb = BollingerBands(50, 1.25, MovingAverageType.EXPONENTIAL)
self.rc = RegressionChannel(100, 1)
self.sma5 = SimpleMovingAverage(20)
#4. Loop over the history data and update the indicators
for bar in history.itertuples():
self.slow.Update(bar.Index[1], bar.close)
self.mid.Update(bar.Index[1], bar.close)
self.fast.Update(bar.Index[1], bar.close)
self.trading.Update(bar.Index[1], bar.close)
self.macd.Update(bar.Index[1], bar.close)
self.mfi.Update(bar.Index[1], bar.close)
self.bb.Update(bar.Index[1], bar.close)
self.rc.Update(bar.Index[1], bar.close)
self.sma5.Update(bar.Index[1], bar.close)
def is_ready(self):
return (self.slow.IsReady and self.mid.IsReady and self.fast.IsReady and self.trading.IsReady and
self.bb.UpperBand.IsReady and self.bb.MiddleBand.IsReady and self.bb.LowerBand.IsReady and
self.rc.UpperChannel.IsReady and self.rc.LowerChannel.IsReady and self.rc.LinearRegression.IsReady)
def update(self, time, price):
self.fast.Update(time, price)
self.trading.Update(time, price)
self.mid.Update(time, price)
self.slow.Update(time, price)
self.macd.Update(time, price)
self.rc.Update(time, price)
self.mfi.Update(time, price)
self.sma5.Update(time, price)