Overall Statistics
Total Trades
404
Average Win
1.99%
Average Loss
-0.59%
Compounding Annual Return
14.666%
Drawdown
28.500%
Expectancy
0.333
Net Profit
45.687%
Sharpe Ratio
0.754
Probabilistic Sharpe Ratio
28.788%
Loss Rate
70%
Win Rate
30%
Profit-Loss Ratio
3.39
Alpha
0.028
Beta
0.356
Annual Standard Deviation
0.147
Annual Variance
0.022
Information Ratio
-0.743
Tracking Error
0.165
Treynor Ratio
0.312
Total Fees
₹117193.28
Estimated Strategy Capacity
₹0
Lowest Capacity Asset
GAIL QZKDT3XTVVWT
#region imports
from AlgorithmImports import *
#endregion


class MomentumExampleAlgorithm(QCAlgorithm):

   def Initialize(self):
       self.SetStartDate(2020, 4, 1)
       self.SetEndDate(2022, 12, 31)
       self.SetAccountCurrency("INR")
       self.SetCash(10000000)
       self.orderDict={}
       period = 3*21
       self.data = {}
       self.SetWarmUp(period)
       self.SetBrokerageModel(BrokerageName.Zerodha, AccountType.Margin)
       tickers = ["LIQUIDBEES", "ACC", "AUBANK", "AARTIIND", "ADANIENT", "ADANIGREEN", "ADANIPORTS", "ATGL", "ADANITRANS", "ABCAPITAL", "ABFRL", "AJANTPHARM", "APLLTD", "ALKEM", "AMARAJABAT", "AMBUJACEM", "APOLLOHOSP", "APOLLOTYRE", "ASHOKLEY", "ASIANPAINT", "ASTRAL", "AUROPHARMA", "DMART", "AXISBANK", "BAJAJ-AUTO", "BAJFINANCE", "BAJAJFINSV", "BAJAJHLDNG", "BALKRISIND", "BANDHANBNK", "BANKBARODA", "BANKINDIA", "BATAINDIA", "BERGEPAINT", "BEL", "BHARATFORG", "BHEL", "BPCL", "BHARTIARTL", "BIOCON", "BOSCHLTD", "BRITANNIA", "CANBK", "CASTROLIND", "CHOLAFIN", "CIPLA", "CUB", "COALINDIA", "COFORGE", "COLPAL", "CONCOR", "COROMANDEL", "CROMPTON", "CUMMINSIND", "DLF", "DABUR", "DALBHARAT", "DEEPAKNTR", "DHANI", "DIVISLAB", "DIXON", "LALPATHLAB", "DRREDDY", "EICHERMOT", "EMAMILTD", "ENDURANCE", "ESCORTS", "EXIDEIND", "FEDERALBNK", "FORTIS", "GAIL", "GLAND", "GLENMARK", "GODREJCP", "GODREJIND", "GODREJPROP", "GRASIM", "GUJGASLTD", "GSPL", "HCLTECH", "HDFCAMC", "HDFCBANK", "HDFCLIFE", "HAVELLS", "HEROMOTOCO", "HINDALCO", "HAL", "HINDCOPPER", "HINDPETRO", "HINDUNILVR", "HINDZINC", "HDFC", "ICICIBANK", "ICICIGI", "ICICIPRULI", "ISEC", "IDFCFIRSTB", "ITC", "INDIAMART", "INDIANB", "INDHOTEL", "IOC", "IRCTC", "IRFC", "IGL", "INDUSTOWER", "INDUSINDBK", "NAUKRI", "INFY", "INDIGO", "IPCALAB", "JSWENERGY", "JSWSTEEL", "JINDALSTEL", "JUBLFOOD", "KOTAKBANK", "L&TFH", "LTTS", "LICHSGFIN", "LTI", "LT", "LAURUSLABS", "LUPIN", "MRF", "MGL", "M&MFIN", "M&M", "MANAPPURAM", "MARICO", "MARUTI", "MFSL", "MINDTREE", "MPHASIS", "MUTHOOTFIN", "NATCOPHARM", "NMDC", "NTPC", "NATIONALUM", "NAVINFLUOR", "NESTLEIND", "NAM-INDIA", "OBEROIRLTY", "ONGC", "OIL", "PIIND", "PAGEIND", "PETRONET", "PFIZER", "PIDILITIND", "PEL", "POLYCAB", "PFC", "POWERGRID", "PRESTIGE", "PGHH", "PNB", "RBLBANK", "RECLTD", "RELIANCE", "SBICARD", "SBILIFE", "SRF", "SANOFI", "SHREECEM", "SRTRANSFIN", "SIEMENS", "SONACOMS", "SBIN", "SAIL", "SUNPHARMA", "SUNTV", "SYNGENE", "TVSMOTOR", "TATACHEM", "TATACOMM", "TCS", "TATACONSUM", "TATAELXSI", "TATAMOTORS", "TATAPOWER", "TATASTEEL", "TECHM", "RAMCOCEM", "TITAN", "TORNTPHARM", "TORNTPOWER", "TRENT", "UPL", "ULTRACEMCO", "UNIONBANK", "UBL", "MCDOWELL-N", "VBL", "VEDL", "IDEA", "VOLTAS", "WHIRLPOOL", "WIPRO", "YESBANK", "ZEEL", "ZYDUSLIFE"]
       for symbol in tickers:
           self.equity = self.AddEquity(symbol, Resolution.Daily, Market.India).Symbol
           #history = self.History(self.equity, period, Resolution.Daily)
           self.data[symbol] = self.SR(symbol, period, Resolution.Daily)
       self.SetBenchmark(SecurityType.Equity, "NIFTYBEES")
       self.Schedule.On(self.DateRules.MonthStart(), self.TimeRules.AfterMarketOpen(self.equity,10), self.Rebalance)
   
   def OnData(self, data):
        pass
        # keys=self.orderDict.keys()
        # for x in keys:
        #     if(x.Price*.95>self.orderDict[x].TriggerPrice):
        #     pass

   def Rebalance(self):
        if self.IsWarmingUp: return
        top3 = pd.Series(self.data).sort_values(ascending = False)[:10]
        #top3 = top3[top3>0]
        self.Liquidate()
        if len(top3) ==0 :
            return
        #top3 = top3[top3.values > 0]
        # for kvp in self.Portfolio:
        #     security_hold = kvp.Value
        #     # liquidate the security which is no longer in the top3 momentum list
        #     if security_hold.Invested and (security_hold.Symbol.Value not in top3.index):
        #         self.Liquidate(security_hold.Symbol)

        added_symbols = []
        for symbol in top3.index:
            if not self.Portfolio[symbol].Invested:
                added_symbols.append(symbol)
        for added in added_symbols:
            self.SetHoldings(added, 1/len(added_symbols))

   def OnOrderEvent(self, orderEvent):
        if(orderEvent.Status==OrderStatus.Filled and orderEvent.Quantity > 0):
            self.orderDict[orderEvent.Symbol]=self.StopMarketOrder(orderEvent.Symbol,- orderEvent.Quantity,  0.95 * orderEvent.FillPrice)