Hello all, someone on my YouTube channel requested I make a video like this.

What the code does is every month it rebalances the stocks it owns based on the Federal Funds Rate. The way I do this is, that when we have 0% rates, we buy 50 equities, taking on more risk in the low-rate environment. Then when rates go up we only buy 10.

The code has some logical flaws like I simply use self.liquidate before buying the equities for the month. Well if AAPL was already in my portfolio, and it is still in the good equities I sell it and rebuy it. I also added SPY to the account to make sure we rebalance on the first of a new month. It does include SPY in the selected equities and will purchase it. I figured why not have some Beta? Something to know if you would rather it not.

Check out the back-test if you notice a large drawdown, in my YouTube video I went over ways to increase profitability. Enjoy!

My YouTube channel: 

 

from AlgorithmImports import *
from datetime import datetime, timedelta


class FocusedYellowLemur(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash

        self.add_equity("SPY")

        # Set the risk-free interest rate model
        self.set_risk_free_interest_rate_model(InterestRateProvider())

        # Now that the model is set, get the interest rate
        self.interest_rate = self.risk_free_interest_rate_model.get_interest_rate(self.time)
        
        self.universe_settings.asynchronous = True
        self.add_universe_selection(FundamentalUniverseSelectionModel(self.fundamental_filter_function))

        self.schedule.on(self.date_rules.month_start("SPY"),
                 self.time_rules.after_market_open("SPY"),
                 self.rebalancing_code)

        #self.add_risk_management(MaximumDrawdownPercentPerSecurity(0.05))
        #self.add_risk_management(MaximumUnrealizedProfitPercentPerSecurity(0.15))
        

    def fundamental_filter_function(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        if self.interest_rate < 0.0025:
            amount = 50
        else:
            amount = 10
        
        selected = [c for c in coarse if c.has_fundamental_data]
        sorted_by_dollar_volume = sorted(selected, key=lambda c: c.dollar_volume, reverse=True)
        filtered = [f for f in sorted_by_dollar_volume if f.has_fundamental_data and f.price > 10 and not np.isnan(f.valuation_ratios.pe_ratio)]
        sorted_by_pe_ratio = sorted(filtered, key=lambda f: f.valuation_ratios.pe_ratio)
        fundamental_symbols = [f.symbol for f in sorted_by_pe_ratio[:amount]]
        return fundamental_symbols


    def rebalancing_code(self):
        self.interest_rate = self.risk_free_interest_rate_model.get_interest_rate(self.time)

        self.liquidate()

        for security in self.ActiveSecurities.Values:
            self.SetHoldings(security.Symbol, 1 / len(self.ActiveSecurities))

        self.Plot("interest rate", "value", self.interest_rate)