Overall Statistics
Total Trades
4428
Average Win
0.05%
Average Loss
-0.01%
Compounding Annual Return
0.018%
Drawdown
9.300%
Expectancy
0.010
Net Profit
0.091%
Sharpe Ratio
0.023
Probabilistic Sharpe Ratio
0.430%
Loss Rate
79%
Win Rate
21%
Profit-Loss Ratio
3.74
Alpha
0.007
Beta
-0.1
Annual Standard Deviation
0.04
Annual Variance
0.002
Information Ratio
-0.494
Tracking Error
0.127
Treynor Ratio
-0.009
Total Fees
$17169.88
Estimated Strategy Capacity
$290000.00
Lowest Capacity Asset
TLO TT1EBZ21QWKL
using Accord.Statistics;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Brokerages;

namespace QuantConnect.Algorithm.CSharp
{
	public class UncorrelatedAssetsDemo : QCAlgorithm
	{
		private List<string> _asset = new List<string>{"SHY", "TLT", "IEI", "SHV", "TLH", "EDV", "BIL",
	        "SPTL", "TBT", "TMF", "TMV", "TBF", "VGSH", "VGIT",
	        "VGLT", "SCHO", "SCHR", "SPTS", "GOVT"};
	        
		public override void Initialize()
		{
		    // 1. Required: Five years of backtest history
		    SetStartDate(2014, 1, 1);
		    SetEndDate(2019, 1, 1);
		
		    // 2. Required: Alpha Streams Models:
		    SetBrokerageModel(BrokerageName.AlphaStreams);
		
		    // 3. Required: Significant AUM Capacity
		    SetCash(1000000);
		
		    // 4. Required: Benchmark to SPY
		    SetBenchmark("SPY");
		
		    SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
		    SetExecution(new ImmediateExecutionModel());
		
		    // Add Equity ------------------------------------------------ 
		    foreach(var ticker in _asset)
		    {
		    AddEquity(ticker, Resolution.Minute);
		    }
		
		    // Set Scheduled Event Method For Our Model. In this example, we'll rebalance every month.
		    Schedule.On(DateRules.MonthStart(), 
		        TimeRules.BeforeMarketClose("SHY", 5),
		        EveryDayBeforeMarketClose);
		}
		
		private void EveryDayBeforeMarketClose()
		{
		    // Fetch history on our universe
		    var history = History(Securities.Keys, 252*2, Resolution.Daily);
		    if (history.Count() < 0) return;
		    
		    // Extract daily return of close prices for each Symbol from Slice data
		    var returns = new Dictionary<string, List<double>>();
		    var last = new Dictionary<string, double>();
		    foreach(var slice in history){
		        foreach(var symbol in slice.Bars.Keys){
		            if(!returns.ContainsKey(symbol)){
		                returns.Add(symbol, new List<double>());
		                last.Add(symbol, (double)slice.Bars[symbol].Close);
		            }
		            var change = (double) ((double)slice.Bars[symbol].Close - last[symbol])/last[symbol];
		            last[symbol] = (double)slice.Bars[symbol].Close;
		            returns[symbol].Add(change);
		        }    
		    }
		    
		    // Convert returns into 2-d array
		    double[,] ret = new double[returns.Values.ElementAt(0).Count - 1, _asset.Count];
		    int k = 0;
		    foreach(var kvp in returns)
		    {
		        var symbol = kvp.Key;
		        for(int i=0; i < returns[symbol].Count - 1; i++)
		        {
		            ret[i, k] = returns[symbol][i + 1];
		        }
		        k++;
		    }
		    
		    // Get correlation matrix
		    var corrMatrix = Measures.Correlation(ret);
		    
		    // Find 5 assets with the least absolute sum correlation
		    var correlations = new Dictionary<string, double>();
		    for(int i=0; i < corrMatrix.GetLength(0); i++)
		    {
		        var symbol = _asset[i];
		        if(!correlations.ContainsKey(symbol)){
		            correlations.Add(symbol, 0);
		        }
		        for (int j=0; j < corrMatrix.GetLength(1); j++)
		        {
		            var value_ = corrMatrix[i, j];
		            correlations[symbol] += value_ >= 0 ? value_ : -value_;
		        }
		    }
		    var selected = correlations.OrderBy(x => x.Value).Take(5).Select(x => x.Key).ToList();
		    
		    // Emit insights
		    foreach(var symbol in selected)
		    {
		        var insight = new Insight(symbol, Expiry.EndOfMonth, InsightType.Price, InsightDirection.Up);
		        EmitInsights(insight);
		    }
		}
	}
}