| Overall Statistics |
|
Total Orders 19 Average Win 0.83% Average Loss -0.48% Compounding Annual Return 11.058% Drawdown 3.300% Expectancy 1.123 Start Equity 2000000 End Equity 2089665.73 Net Profit 4.483% Sharpe Ratio 0.392 Sortino Ratio 0.592 Probabilistic Sharpe Ratio 60.327% Loss Rate 22% Win Rate 78% Profit-Loss Ratio 1.73 Alpha -0.053 Beta 0.408 Annual Standard Deviation 0.056 Annual Variance 0.003 Information Ratio -2.358 Tracking Error 0.069 Treynor Ratio 0.054 Total Fees $181.98 Estimated Strategy Capacity $420000000.00 Lowest Capacity Asset MSFT R735QTJ8XC9X Portfolio Turnover 3.13% |
from AlgorithmImports import *
class CombinedTradingAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2023, 12, 20)
self.SetEndDate(2024, 5, 20)
self.SetCash(2_000_000)
# S1: AMZN (Momentum Strategy)
self.s1 = self.AddEquity("AMZN", Resolution.Daily).Symbol
self.sma_s1 = self.SMA(self.s1, 20, Resolution.Daily)
# S2: MSFT (Mean Reversion Strategy)
self.s2 = self.AddEquity("MSFT", Resolution.Daily).Symbol
self.sma_s2 = self.SMA(self.s2, 20, Resolution.Daily)
self.weight = 0.25 ## each stock gets 25% allocation
def OnData(self, data):
if not self.sma_s1.IsReady or not self.sma_s2.IsReady:
return
#get latest price & Simple Moving Average (SMA) values
if self.s1 in data and data[self.s1] is not None:
price_s1 = data[self.s1].Close
sma_value_s1 = self.sma_s1.Current.Value
# Momentum Strategy (AMZN)
if price_s1 > sma_value_s1 and not self.Portfolio[self.s1].Invested:
self.SetHoldings(self.s1, self.weight) # Buy 25% of portfolio
elif price_s1 <= sma_value_s1 and self.Portfolio[self.s1].Invested:
self.Liquidate(self.s1)
if self.s2 in data and data[self.s2] is not None:
price_s2 = data[self.s2].Close
sma_value_s2 = self.sma_s2.Current.Value
# Mean Reversion Strategy (MSFT)
if price_s2 < sma_value_s2 and not self.Portfolio[self.s2].Invested:
self.SetHoldings(self.s2, self.weight) # Buy 25% of portfolio
elif price_s2 >= sma_value_s2 and self.Portfolio[self.s2].Invested:
self.Liquidate(self.s2)