Overall Statistics
Total Orders
208
Average Win
1.96%
Average Loss
-2.02%
Compounding Annual Return
12.918%
Drawdown
11.000%
Expectancy
0.269
Start Equity
100000
End Equity
170442.60
Net Profit
70.443%
Sharpe Ratio
0.609
Sortino Ratio
0.698
Probabilistic Sharpe Ratio
27.612%
Loss Rate
36%
Win Rate
64%
Profit-Loss Ratio
0.97
Alpha
0.073
Beta
-0.007
Annual Standard Deviation
0.119
Annual Variance
0.014
Information Ratio
-0.074
Tracking Error
0.218
Treynor Ratio
-10.163
Total Fees
$1265.75
Estimated Strategy Capacity
$52000000.00
Lowest Capacity Asset
TLT SGNKIKYGE9NP
Portfolio Turnover
12.92%
from AlgorithmImports import *

class BondTradingAlgorithm(QCAlgorithm):
    def Initialize(self):
        # Set the start and end date for the backtest
        self.SetStartDate(2020, 1, 1)
        #self.SetEndDate(2024, 1, 1)
        
        # Set the initial cash balance
        self.SetCash(100000)
        
        # Add Treasury bond data
        self.bond = self.AddEquity("TLT", Resolution.Daily).Symbol
        
        # Schedule the trading events
        self.Schedule.On(self.DateRules.MonthEnd(self.bond), self.TimeRules.BeforeMarketClose(self.bond, 0), self.SellAtMonthEnd)
        self.Schedule.On(self.DateRules.MonthEnd(self.bond), self.TimeRules.BeforeMarketClose(self.bond, 0), self.SellShortAtMonthEnd)
        
        # Schedule the Buy and Cover events dynamically
        self.Schedule.On(self.DateRules.EveryDay(self.bond), self.TimeRules.BeforeMarketClose(self.bond, 0), self.CheckSeventhLastTradingDay)
        
    def CheckSeventhLastTradingDay(self):
        # Get the current date
        current_date = self.Time.date()
        
        # Get the last trading day of the current month
        last_trading_day = self.GetLastTradingDayOfMonth(current_date)
        
        # Calculate the seventh last trading day of the month
        seventh_last_trading_day = self.GetNthLastTradingDayOfMonth(current_date, 7)
        
        # Check if today is the seventh last trading day of the month
        if current_date == seventh_last_trading_day:
            self.BuyAtSeventhLastTradingDay()
        elif current_date == self.GetNthTradingDayOfMonth(current_date, 7):
            self.CoverAtSeventhLastTradingDay()
        
    def GetLastTradingDayOfMonth(self, date):
        # Get the last day of the month
        last_day = date.replace(day=1) + timedelta(days=32)
        last_day = last_day.replace(day=1) - timedelta(days=1)
        
        # Find the last trading day of the month
        while not self.Securities[self.bond].Exchange.DateIsOpen(last_day):
            last_day -= timedelta(days=1)
        
        return last_day
    
    def GetNthLastTradingDayOfMonth(self, date, n):
        # Get the last trading day of the month
        last_trading_day = self.GetLastTradingDayOfMonth(date)
        
        # Find the nth last trading day of the month
        count = 0
        while count < n:
            last_trading_day -= timedelta(days=1)
            if self.Securities[self.bond].Exchange.DateIsOpen(last_trading_day):
                count += 1
        
        return last_trading_day
    
    def GetNthTradingDayOfMonth(self, date, n):
        # Get the first day of the month
        first_day = date.replace(day=1)
        
        # Find the nth trading day of the month
        count = 0
        while count < n:
            if self.Securities[self.bond].Exchange.DateIsOpen(first_day):
                count += 1
            first_day += timedelta(days=1)
        
        return first_day - timedelta(days=1)
    
    def BuyAtSeventhLastTradingDay(self):
        # Buy at the close of the seventh last trading day of the month
        self.SetHoldings(self.bond, 1)
        self.Debug(f"Bought {self.bond} at {self.Time}")
        
    def SellAtMonthEnd(self):
        # Sell at the close of the last trading day of the month
        self.Liquidate(self.bond)
        self.Debug(f"Sold {self.bond} at {self.Time}")
        
    def SellShortAtMonthEnd(self):
        # Sell short at the close of the month
        self.SetHoldings(self.bond, -1)
        self.Debug(f"Sold short {self.bond} at {self.Time}")
        
    def CoverAtSeventhLastTradingDay(self):
        # Cover at the close of the seventh trading day of the month
        self.Liquidate(self.bond)
        self.Debug(f"Covered short {self.bond} at {self.Time}")