Overall Statistics
Total Trades
208
Average Win
0.91%
Average Loss
-0.65%
Compounding Annual Return
0.885%
Drawdown
16.400%
Expectancy
-0.001
Net Profit
4.425%
Sharpe Ratio
0.13
Probabilistic Sharpe Ratio
1.737%
Loss Rate
58%
Win Rate
42%
Profit-Loss Ratio
1.40
Alpha
0.012
Beta
-0.01
Annual Standard Deviation
0.082
Annual Variance
0.007
Information Ratio
-0.595
Tracking Error
0.148
Treynor Ratio
-1.106
Total Fees
$693.44
class UncoupledModulatedPrism(QCAlgorithm):
    stopMarketTicket = None
    stopMarketOrderFillTime = datetime.min
    highestSPYPrice = -1
    highestBNDPrice = -1
    
    def Initialize(self):
        self.SetStartDate(2015, 1, 1)
        self.SetEndDate(2019, 12, 1)
        self.SetCash(100000) 
        self.spy = self.AddEquity("SPY", Resolution.Daily)
        self.bnd = self.AddEquity("BND", Resolution. Daily)
        self.spyMomentum = self.MOMP("SPY", 50, Resolution.Daily) 
        self.bondMomentum = self.MOMP("BND", 50, Resolution.Daily)
        self.SetBenchmark(self.spy.Symbol)  
        self.SetWarmUp(50) 
        
    def OnData(self, data):
        self.Plot("SPY Data Chart", "Asset Price", self.Securities["SPY"].Price)
        self.Plot("BND Data Chart", "Asset Price", self.Securities["BND"].Price)

        if self.IsWarmingUp:
            return
        
        if (self.Time - self.stopMarketOrderFillTime).days < 1:
            return
        
        if self.spyMomentum.Current.Value > self.bondMomentum.Current.Value:
            self.Liquidate("BND")
            self.SetHoldings("SPY", 1)
            self.stopMarketTicket = self.StopMarketOrder("SPY", -100, 0.9 * self.Securities["SPY"].Close)

        elif self.spyMomentum.Current.Value < self.bondMomentum.Current.Value:  
            self.Liquidate("SPY")
            self.SetHoldings("BND", 1)
            self.stopMarketTicket = self.StopMarketOrder("BND", -100, 0.9 * self.Securities["BND"].Close)
        else:
            self.Plot("SPY Data Chart", "Stop Price", self.Securities["SPY"].Price * 0.90)
            self.Plot("BND Data Chart", "Stop Price", self.Securities["BND"].Price * 0.90)

            if self.Portfolio["SPY"].Invested and self.Securities["SPY"].Close > self.highestSPYPrice:
                self.highestSPYPrice = self.Securities["SPY"].Close
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.highestSPYPrice * 0.9
                self.stopMarketTicket.Update(updateFields) 
                
            elif self.Portfolio["BND"].Invested and self.Securities["BND"].Close > self.highestBNDPrice:
                self.highestBNDPrice = self.Securities["BND"].Close
                updateFields = UpdateOrderFields()
                updateFields.StopPrice = self.highestBNDPrice * 0.9
                self.stopMarketTicket.Update(updateFields) 
        
    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status != OrderStatus.Filled:
            return
        
        if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId: 
            self.stopMarketOrderFillTime = self.Time