| Overall Statistics |
|
Total Trades 298 Average Win 1.71% Average Loss -0.50% Compounding Annual Return 56.107% Drawdown 46.200% Expectancy 1.716 Net Profit 494.599% Sharpe Ratio 1.118 Sortino Ratio 0.96 Probabilistic Sharpe Ratio 45.188% Loss Rate 39% Win Rate 61% Profit-Loss Ratio 3.44 Alpha 0.315 Beta 1.415 Annual Standard Deviation 0.414 Annual Variance 0.171 Information Ratio 1.033 Tracking Error 0.347 Treynor Ratio 0.327 Total Fees $298.00 Estimated Strategy Capacity $36000000.00 Lowest Capacity Asset DOCU WU16SJRONF51 Portfolio Turnover 1.00% |
# region imports
from AlgorithmImports import *
# endregion
class AlertMagentaParrot(QCAlgorithm):
def Initialize(self) -> None:
self.SetStartDate(2017, 1, 1)
self.SetEndDate(2020, 12, 31)
self.SetCash(50000)
# Add symbols
self.docu_symbol = self.AddEquity("DOCU", Resolution.Daily).Symbol
self.amd_symbol = self.AddEquity("AMD", Resolution.Daily).Symbol
self.nflx_symbol = self.AddEquity("NFLX", Resolution.Daily).Symbol
self.tsla_symbol = self.AddEquity("TSLA", Resolution.Daily).Symbol
self.goog_symbol = self.AddEquity("GOOG", Resolution.Daily).Symbol
# RSI for DOCU
self.docu_rsi = self.RSI(self.docu_symbol, 3)
self.docu_periods_above_70 = 0
self.docu_periods_below_30 = 0
# RSI for AMD
self.amd_rsi = self.RSI(self.amd_symbol, 3)
self.amd_periods_above_70 = 0
self.amd_periods_below_30 = 0
# RSI for nflx
self.nflx_rsi = self.RSI(self.nflx_symbol, 3)
self.nflx_periods_above_70 = 0
self.nflx_periods_below_30 = 0
# RSI for tsla
self.tsla_rsi = self.RSI(self.tsla_symbol, 3)
self.tsla_periods_above_70 = 0
self.tsla_periods_below_30 = 0
# RSI for GOOG
self.goog_rsi = self.RSI(self.goog_symbol, 3)
self.goog_periods_above_70 = 0
self.goog_periods_below_30 = 0
self.sma_period = 21
self.docu_sma_symbol = self.docu_symbol # SMA based on DOCU, you can change this if needed
self.amd_sma_symbol = self.amd_symbol # SMA based on amd
self.nflx_sma_symbol = self.nflx_symbol # SMA based on nflx
self.tsla_sma_symbol = self.tsla_symbol # sma based on tsla
self.goog_sma_symbol = self.goog_symbol # sma based on goog
# SMA runs every day after market open
self.Schedule.On(self.DateRules.EveryDay(self.docu_sma_symbol),
self.TimeRules.AfterMarketOpen(self.docu_sma_symbol, 1),
self.Rebalance)
self.Schedule.On(self.DateRules.EveryDay(self.amd_sma_symbol),
self.TimeRules.AfterMarketOpen(self.amd_sma_symbol, 1),
self.Rebalance)
self.Schedule.On(self.DateRules.EveryDay(self.nflx_sma_symbol),
self.TimeRules.AfterMarketOpen(self.nflx_sma_symbol, 1),
self.Rebalance)
self.Schedule.On(self.DateRules.EveryDay(self.tsla_sma_symbol),
self.TimeRules.AfterMarketOpen(self.tsla_sma_symbol, 1),
self.Rebalance)
self.Schedule.On(self.DateRules.EveryDay(self.goog_sma_symbol),
self.TimeRules.AfterMarketOpen(self.goog_sma_symbol, 1),
self.Rebalance)
def OnData(self, slice: Slice) -> None:
# Check if there is enough data to compute SMA
if self.IsWarmingUp:
return
# Check if the symbols are in the slice
if self.docu_sma_symbol not in slice.Keys or self.docu_symbol not in slice.Keys:
return
if self.amd_sma_symbol not in slice.Keys or self.amd_symbol not in slice.Keys:
return
if self.nflx_sma_symbol not in slice.Keys or self.nflx_symbol not in slice.Keys:
return
if self.tsla_sma_symbol not in slice.Keys or self.tsla_symbol not in slice.Keys:
return
if self.goog_sma_symbol not in slice.Keys or self.goog_symbol not in slice.Keys:
return
# Access historical data for SMA calculation
docu_history = self.History(self.docu_symbol, self.sma_period, Resolution.Daily)
amd_history = self.History(self.amd_symbol, self.sma_period, Resolution.Daily)
nflx_history = self.History(self.nflx_symbol, self.sma_period, Resolution.Daily)
tsla_history = self.History(self.tsla_symbol, self.sma_period, Resolution.Daily)
goog_history = self.History(self.goog_symbol, self.sma_period, Resolution.Daily)
# Calculate SMA for DOCU
if not docu_history.empty:
docu_sma = docu_history["close"].mean()
docu_current_price = slice.Bars[self.docu_symbol].Close
# Buying and Selling Logic for DOCU (similar logic can be applied to amd)
if self.docu_rsi.Current.Value > 70:
self.docu_periods_above_70 += 1
if self.docu_periods_above_70 == 2 and docu_current_price > docu_sma:
self.LimitOrder("DOCU", 100, docu_current_price)
else:
self.docu_periods_above_70 = 0
if self.docu_rsi.Current.Value < 30:
self.docu_periods_below_30 += 1
if self.docu_periods_below_30 == 2 and docu_current_price < docu_sma:
if self.Portfolio[self.docu_symbol].Quantity >= 100:
self.LimitOrder("DOCU", -100, docu_current_price)
else:
self.docu_periods_below_30 = 0
# Calculate SMA for amd (similar logic can be applied to DOCU)
if not amd_history.empty:
amd_sma = amd_history["close"].mean()
amd_current_price = slice.Bars[self.amd_symbol].Close
# Buying and Selling Logic for amd
if self.amd_rsi.Current.Value > 70:
self.amd_periods_above_70 += 1
if self.amd_periods_above_70 == 2 and amd_current_price > amd_sma:
self.LimitOrder("AMD", 40, amd_current_price)
else:
self.amd_periods_above_70 = 0
if self.amd_rsi.Current.Value < 30:
self.amd_periods_below_30 += 1
if self.amd_periods_below_30 == 2 and amd_current_price < amd_sma:
if self.Portfolio[self.amd_symbol].Quantity >= 40:
self.LimitOrder("AMD", -40, amd_current_price)
else:
self.amd_periods_below_30 = 0
# Calculate SMA for nflx(similar logic can be applied to nflx)
if not nflx_history.empty:
nflx_sma = nflx_history["close"].mean()
nflx_current_price = slice.Bars[self.nflx_symbol].Close
# Buying and Selling Logic for amd
if self.nflx_rsi.Current.Value > 70:
self.nflx_periods_above_70 += 1
if self.nflx_periods_above_70 == 2 and nflx_current_price > nflx_sma:
self.LimitOrder("nflx", 10, nflx_current_price)
else:
self.nflx_periods_above_70 = 0
if self.nflx_rsi.Current.Value < 30:
self.nflx_periods_below_30 += 1
if self.nflx_periods_below_30 == 2 and nflx_current_price < nflx_sma:
if self.Portfolio[self.nflx_symbol].Quantity >= 10:
self.LimitOrder("nflx", -10, nflx_current_price)
else:
self.nflx_periods_below_30 = 0
# Calculate SMA for tsla
if not tsla_history.empty:
tsla_sma = tsla_history["close"].mean()
tsla_current_price = slice.Bars[self.tsla_symbol].Close
# Buying and Selling Logic for tsla (similar logic can be applied to amd)
if self.tsla_rsi.Current.Value > 70:
self.tsla_periods_above_70 += 1
if self.tsla_periods_above_70 == 2 and tsla_current_price > tsla_sma:
self.LimitOrder("tsla", 21, tsla_current_price)
else:
self.tsla_periods_above_70 = 0
if self.tsla_rsi.Current.Value < 30:
self.tsla_periods_below_30 += 1
if self.tsla_periods_below_30 == 2 and tsla_current_price < tsla_sma:
if self.Portfolio[self.tsla_symbol].Quantity >= 21:
self.LimitOrder("tsla", -21, tsla_current_price)
else:
self.tsla_periods_below_30 = 0
# Calculate SMA for GOOG
if not goog_history.empty:
goog_sma = goog_history["close"].mean()
goog_current_price = slice.Bars[self.goog_symbol].Close
# Buying and Selling Logic for goog (similar logic can be applied to amd)
if self.goog_rsi.Current.Value > 70:
self.goog_periods_above_70 += 1
if self.goog_periods_above_70 == 2 and goog_current_price > goog_sma:
self.LimitOrder("GOOG", 65, goog_current_price)
else:
self.goog_periods_above_70 = 0
if self.goog_rsi.Current.Value < 30:
self.goog_periods_below_30 += 1
if self.goog_periods_below_30 == 2 and goog_current_price < goog_sma:
if self.Portfolio[self.goog_symbol].Quantity >= 65:
self.LimitOrder("GOOG", -65, goog_current_price)
else:
self.goog_periods_below_30 = 0
def Rebalance(self):
# Rebalance logic goes here
pass
if self.docu_rsi.IsReady:
# The current value of self.rsi is represented by self.rsi.Current.Value
self.Plot("RelativeStrengthIndex", "rsi", self.docu_rsi.Current.Value)
# Plot all attributes of self.rsi
self.Plot("RelativeStrengthIndex", "averagegain", self.docu_rsi.AverageGain.Current.Value)
self.Plot("RelativeStrengthIndex", "averageloss", self.docu_rsi.AverageLoss.Current.Value)
if self.amd_rsi.IsReady:
# The current value of self.rsi is represented by self.rsi.Current.Value
self.Plot("RelativeStrengthIndex", "rsi", self.amd_rsi.Current.Value)
# Plot all attributes of self.rsi
self.Plot("RelativeStrengthIndex", "averagegain", self.amd_rsi.AverageGain.Current.Value)
self.Plot("RelativeStrengthIndex", "averageloss", self.amd_rsi.AverageLoss.Current.Value)
if self.nflx_rsi.IsReady:
# The current value of self.rsi is represented by self.rsi.Current.Value
self.Plot("RelativeStrengthIndex", "rsi", self.nflx_rsi.Current.Value)
# Plot all attributes of self.rsi
self.Plot("RelativeStrengthIndex", "averagegain", self.nflx_rsi.AverageGain.Current.Value)
self.Plot("RelativeStrengthIndex", "averageloss", self.nflx_rsi.AverageLoss.Current.Value)
if self.tsla_rsi.IsReady:
# The current value of self.rsi is represented by self.rsi.Current.Value
self.Plot("RelativeStrengthIndex", "rsi", self.tsla_rsi.Current.Value)
# Plot all attributes of self.rsi
self.Plot("RelativeStrengthIndex", "averagegain", self.tsla_rsi.AverageGain.Current.Value)
self.Plot("RelativeStrengthIndex", "averageloss", self.tsla_rsi.AverageLoss.Current.Value)
if self.goog_rsi.IsReady:
# The current value of self.rsi is represented by self.rsi.Current.Value
self.Plot("RelativeStrengthIndex", "rsi", self.goog_rsi.Current.Value)
# Plot all attributes of self.rsi
self.Plot("RelativeStrengthIndex", "averagegain", self.goog_rsi.AverageGain.Current.Value)
self.Plot("RelativeStrengthIndex", "averageloss", self.goog_rsi.AverageLoss.Current.Value)