Overall Statistics
Total Orders
117902
Average Win
0.04%
Average Loss
-0.05%
Compounding Annual Return
0.531%
Drawdown
11.600%
Expectancy
0.033
Start Equity
1000000
End Equity
1056130.89
Net Profit
5.613%
Sharpe Ratio
-0.656
Sortino Ratio
-0.811
Probabilistic Sharpe Ratio
0.074%
Loss Rate
42%
Win Rate
58%
Profit-Loss Ratio
0.78
Alpha
-0.012
Beta
-0.031
Annual Standard Deviation
0.022
Annual Variance
0
Information Ratio
-0.592
Tracking Error
0.15
Treynor Ratio
0.46
Total Fees
$9565.91
Estimated Strategy Capacity
$1200000.00
Lowest Capacity Asset
TBF UF9WRZG9YA1X
Portfolio Turnover
1.31%
#region imports
from AlgorithmImports import *
from sklearn.ensemble import RandomForestRegressor
#endregion

class RandomForestRegressionDemo(QCAlgorithm):

    def initialize(self):
        #1. Required: Five years of backtest history
        self.set_start_date(2014, 1, 1)
    
        #2. Required: Alpha Streams Models:
        self.set_brokerage_model(BrokerageName.ALPHA_STREAMS)
    
        #3. Required: Significant AUM Capacity
        self.set_cash(1000000)
    
        #4. Required: Benchmark to SPY
        self.set_benchmark("SPY")
        
        self.set_portfolio_construction(MeanVarianceOptimizationPortfolioConstructionModel(Resolution.DAILY, PortfolioBias.LONG,
                                                                                        period=5))
        self.set_execution(ImmediateExecutionModel())
    
        self.assets = ["SHY", "TLT", "IEI", "SHV", "TLH", "EDV", "BIL",
                        "SPTL", "TBT", "TMF", "TMV", "TBF", "VGSH", "VGIT",
                        "VGLT", "SCHO", "SCHR", "SPTS", "GOVT"]
        
        # Add Equity ------------------------------------------------ 
        for i in range(len(self.assets)):
            self.add_equity(self.assets[i], Resolution.MINUTE).symbol
            
        # Initialize the timer to train the Machine Learning model
        self.last_time = datetime.min
        
        # Set Scheduled Event Method For Our Model
        self.schedule.on(self.date_rules.every_day(), self.time_rules.before_market_close("SHY", 5), self.every_day_before_market_close)
        
        
    def build_model(self):
        # Initialize the Random Forest Regressor
        self.regressor = RandomForestRegressor(n_estimators=100, min_samples_split=5, random_state = 1990)
        
        # Get historical data
        history = self.history(self.securities.Keys, 360, Resolution.DAILY)
        
        # Select the close column and then call the unstack method.
        df = history['close'].unstack(level=0)
        
        # Feature engineer the data for input.
        input_ = df.diff() * 0.5 + df * 0.5
        input_ = input_.iloc[1:].ffill().fillna(0)
        
        # Shift the data for 1-step backward as training output result.
        output = df.shift(-1).iloc[:-1].ffill().fillna(0)
        
        # Fit the regressor
        self.regressor.fit(input_, output)
        
        
    def every_day_before_market_close(self):
        # Retrain the regressor every week
        if self.last_time < self.time:
            self.build_model()
            self.last_time = Expiry.end_of_week(self.last_time)
        
        qb = self
        # Fetch history on our universe
        df = qb.history(qb.securities.Keys, 2, Resolution.DAILY)
        if df.empty: return
    
        # Make all of them into a single time index.
        df = df.close.unstack(level=0)
    
        # Feature engineer the data for input
        input_ = df.diff() * 0.5 + df * 0.5
        input_ = input_.iloc[-1].fillna(0).values.reshape(1, -1)
        
        # Predict the expected price
        predictions = self.regressor.predict(input_)
        
        # Get the expected return
        predictions = (predictions - df.iloc[-1].values) / df.iloc[-1].values
        predictions = predictions.flatten()
    
        # ==============================
        
        insights = []
        
        for i in range(len(predictions)):
            insights.append( Insight.price(self.assets[i], timedelta(days=1), InsightDirection.UP, predictions[i]) )
    
        self.emit_insights(insights)