Overall Statistics
Total Trades
3212
Average Win
4.54%
Average Loss
-0.02%
Compounding Annual Return
13.522%
Drawdown
18.500%
Expectancy
1.500
Net Profit
36.129%
Sharpe Ratio
0.691
Probabilistic Sharpe Ratio
26.403%
Loss Rate
99%
Win Rate
1%
Profit-Loss Ratio
266.68
Alpha
0
Beta
0
Annual Standard Deviation
0.151
Annual Variance
0.023
Information Ratio
0.691
Tracking Error
0.151
Treynor Ratio
0
Total Fees
$6404.65
Estimated Strategy Capacity
$6700000.00
Lowest Capacity Asset
BIL TT1EBZ21QWKL
class VerticalNadionShield(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        self.leverage = 1
        
  
        self.equities = ["QQQ", "SPY"]
        self.equityCombinedMomentum = {}
        
        self.bonds = ["GLD", "SLV", "TLT", "BIL"]
        self.bondCombinedMomentum = {}

            
        for equity in self.equities:
            self.AddEquity(equity, Resolution.Hour)
            self.Securities[equity].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)
            self.equityCombinedMomentum[equity] = CombinedMomentum(self, equity)

        for bond in self.bonds:
            self.AddEquity(bond, Resolution.Hour)
            self.Securities[bond].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)
            self.bondCombinedMomentum[bond] = CombinedMomentum(self, bond)
            
        self.SetWarmUp(125)

    def shiftAssets(self, target):
        if not (self.Portfolio[target].Invested):
            for symbol in self.Portfolio.Keys:
                self.Liquidate(symbol)
            if not self.Portfolio.Invested:
                self.MarketOnCloseOrder(target, self.CalculateOrderQuantity(target, 1 * self.leverage))                

    def getMonthLastTradingDay(self):
        month_last_day = DateTime(self.Time.year, self.Time.month, DateTime.DaysInMonth(self.Time.year, self.Time.month))
        tradingDays = self.TradingCalendar.GetDaysByType(TradingDayType.BusinessDay, DateTime(self.Time.year, self.Time.month, 1), month_last_day)
        tradingDays = [day.Date.date() for day in tradingDays]
        return tradingDays[-1]
        

    def OnData(self, data):
        if self.IsWarmingUp:
            return

        if (self.Time.date() == self.getMonthLastTradingDay()) and (self.Time.hour == 15):
            topEquities = sorted(self.equityCombinedMomentum.items(), key=lambda x: x[1].getValue(), reverse=True)
            topBonds = sorted(self.bondCombinedMomentum.items(), key=lambda x: x[1].getValue(), reverse=True)
            if (topEquities[0][1].getValue() > 0):
                self.shiftAssets(topEquities[0][0])
            else:
                self.Liquidate()
            
        invested = [x.Key for x in self.Portfolio if x.Value.Invested]
            
        for symbol in invested:
            self.security_holding = self.Portfolio[symbol]
            self.quantity = self.security_holding.Quantity
            self.price = round(self.security_holding.AveragePrice, 2)
        #    self.stop_price = float(self.price, 2)
        #    self.Log("something:" + str(self.security_holding) + str(self.quantity))
            self.Log(round(self.price, 2))
        #    quantity = self.Portfolio[current_holding].Quantity
       #     quantityToString = str(quantity)
         #  averageprice = self.Portfolio[str(current_holding)].AveragePrice
        #    self.Log("Current Holding:" + str(current_holding))
        #    self.Log("Current Holding:" + str(quantityToString))
          #  self.Log("Current Holding:" + str(averageprice))
         #   stop_loss = self.StopMarketOrder(self.security_holding, -1 * self.quantity, )

    def OnOrderEvent(self, orderEvent):
        order = self.Transactions.GetOrderById(orderEvent.OrderId)
#        current_holding = [ x.Value for x in self.Portfolio.Values if x.Invested ]

        invested = [x.Key for x in self.Portfolio if x.Value.Invested]

        for symbol in invested:
            self.security_holding = self.Portfolio[symbol]
            self.quantity = self.security_holding.Quantity
            self.price = self.security_holding.AveragePrice
        #    self.Log("something:" + str(self.security_holding) + str(self.quantity))
            
        for kvp in self.Portfolio:
            security_holdings = kvp.Value
            symbol = security_holdings.Symbol.Value

        self.Log("symbol" + symbol)
      #  self.Log("quantity" + str(self.quantity))
      #  self.Log("price" + str(self.price))


        # Log average holding price
        if order.Status == OrderStatus.Filled:
                filled = orderEvent.FillPrice
                floatnum = float(filled)
                self.Log("filled price: " + str(filled))
                stop_loss = self.StopMarketOrder(symbol, -1 * self.quantity, self.price * .95)

class CombinedMomentum():
    def __init__(self, algo, symbol):
        self.sprfst = algo.MOMP(symbol,  10, Resolution.Daily)
        self.fst = algo.MOMP(symbol,  30, Resolution.Daily)
        self.med = algo.MOMP(symbol,  60, Resolution.Daily)
        self.slw = algo.MOMP(symbol,  120, Resolution.Daily)
        
    def getValue(self):
        value = (self.sprfst.Current.Value + self.fst.Current.Value + self.med.Current.Value + self.slw.Current.Value) / 3
        return value