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)