Overall Statistics
Total Orders
1073
Average Win
0.15%
Average Loss
-0.14%
Compounding Annual Return
-6.638%
Drawdown
24.500%
Expectancy
-0.184
Start Equity
100000
End Equity
86402.83
Net Profit
-13.597%
Sharpe Ratio
-0.489
Sortino Ratio
-0.386
Probabilistic Sharpe Ratio
1.414%
Loss Rate
62%
Win Rate
38%
Profit-Loss Ratio
1.12
Alpha
-0.073
Beta
0.122
Annual Standard Deviation
0.148
Annual Variance
0.022
Information Ratio
-0.374
Tracking Error
0.202
Treynor Ratio
-0.593
Total Fees
$1671.14
Estimated Strategy Capacity
$920000.00
Lowest Capacity Asset
TLH TP8J6Z7L419H
Portfolio Turnover
12.12%
# region imports
from AlgorithmImports import *
# endregion

class AdaptableBlueSnake(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2022, 1, 1)
        self.set_cash(100000)
        self.set_benchmark("SPY")
        
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
        self.set_execution(ImmediateExecutionModel())
        
        self.assets = ["IEF", "SHY", "TLT", "IEI", "SHV", "TLH", "EDV", "BIL",
                    "SPTL", "TBT", "TMF", "TMV", "TBF", "VGSH", "VGIT",
                    "VGLT", "SCHO", "SCHR", "SPTS", "GOVT"]
        
        self.symbols = {}
        
        # Add Equity ------------------------------------------------ 
        for i in range(len(self.assets)):
            self.symbols[self.assets[i]] = self.add_equity(self.assets[i], Resolution.MINUTE).symbol 
            
        # Set the Scheduled Event method
        self.schedule.on(self.date_rules.every(DayOfWeek.MONDAY), self.time_rules.after_market_open("IEF", 1), self.every_day_after_market_open)

        for i, symbol in enumerate(self.symbols.values()):
            chart = Chart(symbol)
            chart.add_series(CandlestickSeries(symbol, 0, "$"))
            self.add_chart(chart)

    def OnData(self, data: Slice):
        return
    
    def on_end_of_day(self, symbol: Symbol) -> None:
        self.Plot(symbol, symbol, self.securities[symbol].get_last_data())

    def every_day_after_market_open(self):
        # Fetch history on our universe
        df = self.history(self.securities.keys(), 5, Resolution.DAILY)

        
        # Make all of them into a single time index.
        df = df.close.unstack(level=0)
        
        # Calculate the truth value of the most recent price being less than 1 std away from the mean
        classifier = df.le(df.mean().subtract(df.std())).tail(1)
        
        # Get indexes of the True values
        classifier_indexes = np.where(classifier)[1]
        
        # Get the Symbols for the True values
        classifier = classifier.transpose().iloc[classifier_indexes].index.values
        
        # Get the std values for the True values (used for magnitude)
        magnitude = df.std().transpose()[classifier_indexes].values
        
        # Zip together to iterate over later
        selected = zip(classifier, magnitude)
        
        # ==============================
        
        insights = []
        
        for symbol, magnitude in selected:
            insights.append(Insight.price(symbol, timedelta(days=5), InsightDirection.UP, magnitude))
        
        self.emit_insights(insights)