Overall Statistics
Total Trades
771
Average Win
0.08%
Average Loss
-0.10%
Compounding Annual Return
10.186%
Drawdown
17.900%
Expectancy
0.361
Net Profit
14.018%
Sharpe Ratio
0.813
Probabilistic Sharpe Ratio
39.679%
Loss Rate
26%
Win Rate
74%
Profit-Loss Ratio
0.85
Alpha
0.023
Beta
0.47
Annual Standard Deviation
0.138
Annual Variance
0.019
Information Ratio
-0.503
Tracking Error
0.155
Treynor Ratio
0.239
Total Fees
$1924.95
import numpy as np
import pandas as pd

def GetUncorrelatedAssets(returns, num_assets):
    # Get correlation
    correlation = returns.corr()
    
    # Find assets with lowest mean correlation, scaled by STD
    selected = []
    for index, row in correlation.iteritems():
        corr_rank = row.abs().mean()/row.abs().std()
        selected.append((index, corr_rank))

    # Sort and take the top num_assets
    selected = sorted(selected, key = lambda x: x[1])[:num_assets]
    
    return selected
import pandas as pd
from GetUncorrelatedAssets import GetUncorrelatedAssets

class ModulatedOptimizedEngine(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)  # Set Start Date

        self.SetCash(1000000)  # Set Strategy Cash
        
        self.AddEquity("SPY", Resolution.Minute)
        self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.AfterMarketOpen("SPY", 5), self.Recalibrate) 
        
        self.UniverseSettings.Resolution = Resolution.Minute 
        self.tickers = ["SPY", "FXI", "EWI", "VGK", "GLD", "SHY"]
        self.symbols = [Symbol.Create(t, SecurityType.Equity, Market.USA) for t in self.tickers]
        self.AddUniverseSelection( ManualUniverseSelectionModel(self.symbols) )
 
        self.Settings.RebalancePortfolioOnInsightChanges = False
        self.Settings.RebalancePortfolioOnSecurityChanges = False
        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
        
        self.SetExecution(ImmediateExecutionModel()) 

    def Recalibrate(self):
          
        history = self.History(self.symbols, 122, Resolution.Daily)
        
        returns = history.unstack(level = 1).close.transpose().pct_change().dropna()
        
        rolling=10
        tickers=self.tickers
        corr_history = []
        for i in range(rolling, len(returns), 1):
            
            correlations = {}
            correlations['time'] = returns.index[i]
            spy = returns["SPY R735QTJ8XC9X"][i-rolling:i]
            
            for j in range(0, len(tickers)): 
                asset = returns[returns.columns[j]][i-rolling:i] 
                correlations[returns.columns[j]] = spy.corr(asset) 
                
            corr_history.append(correlations)
        
        latest = pd.DataFrame(corr_history[len(corr_history)-1], index=[corr_history[len(corr_history)-1]['time']] )
        
        # Get the minimum of the most recent row.
        asset = ""
        minimum = 2
        for c in latest.columns:
            if c == "time":
                continue
                
            if latest[c][0] < minimum:
                asset = c
                minimum = latest[c][0]
        
        #most uncorrelated
        uncor = asset
        
        correlation = abs(minimum)
        spyweight = 1 - correlation
        
        insights = [Insight.Price("SPY", timedelta(5), InsightDirection.Up, None, None, None, spyweight),
            Insight.Price(self.Symbol(uncor), timedelta(5), InsightDirection.Up, None, None, None, correlation)]

        self.EmitInsights(insights)