Overall Statistics
Total Trades
2
Average Win
0%
Average Loss
-21.09%
Compounding Annual Return
-19.110%
Drawdown
85.100%
Expectancy
-1
Net Profit
-70.823%
Sharpe Ratio
0.068
Probabilistic Sharpe Ratio
0.664%
Loss Rate
100%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.038
Beta
0.075
Annual Standard Deviation
0.66
Annual Variance
0.435
Information Ratio
-0.071
Tracking Error
0.669
Treynor Ratio
0.601
Total Fees
$5.88
class AlphaFivePreciousMetalsUniverse(QCAlgorithm):

    def Initialize(self):
        #1. Required: Five years of backtest history
        self.SetStartDate(2014, 1, 1) 
        
        #2. Required: Alpha Streams Models:
        self.SetBrokerageModel(BrokerageName.AlphaStreams)
        
        #3. Required: Significant AUM Capacity
        self.SetCash(1000000)
        
        tickers = ["GLD", "IAU", "SLV", "GDX", "AGQ", "GDXJ", "PPLT", "NUGT",
                              "DUST", "USLV", "UGLD", "JNUG", "JDST"]
    
        # Add Equity ------------------------------------------------
        for ticker in tickers:
            self.AddEquity(ticker, Resolution.Hour)
        
        self.universe = { }
        history = self.History(tickers, 30, Resolution.Hour)
        for symbol in self.Securities.Keys:
            self.universe[symbol] = AssetData(symbol, history.loc[str(symbol.ID)])
        
        #5. Set Relevent Benchmark
        self.reference = "GLD"
        self.SetBenchmark("SPY")

        # Demonstration: Consolidation
        # See more: https://www.quantconnect.com/docs/algorithm-reference/consolidating-data
        self.Consolidate(self.reference, CalendarType.Weekly, self.ConsolidationDemo);
        
        # Demonstration: Scheduled Events
        # See more: https://www.quantconnect.com/docs/algorithm-reference/scheduled-events
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.AfterMarketOpen(self.reference, 30), self.ScheduleDemo)
        
    def OnData(self, data):
        # Manually update the Indicators
        for symbol in self.universe.keys():
            if data.Bars.ContainsKey(symbol):
                self.universe[symbol].update(data[symbol].EndTime, data[symbol].Close)
    
    def ScheduleDemo(self):
        insights = []
        for symbol, assetData in self.universe.items():
            price = self.ActiveSecurities[symbol].Price
            if assetData.is_ready() and assetData.deviating(price):
                # Demonstration: Ensure to emit Insights to clearly signal intent to fund.
                insights.append(Insight.Price(symbol, timedelta(3), InsightDirection.Up))
        
        for insight in insights:
            self.SetHoldings(insight.Symbol, 1/len(insights))
                
        self.EmitInsights(insights)


    def ConsolidationDemo(self, bar):
        self.Debug(f'{self.Time} :: {bar.Time} {bar.Close}')

# Indicators+Universe Demonstration
class AssetData(object):
    def __init__(self, symbol, history):
        self.std = StandardDeviation(30)
        self.mean = SimpleMovingAverage(7)
        self.symbol = symbol
        
        for bar in history.itertuples():
            self.update(bar.Index, bar.close)
        
    def is_ready(self):
        return self.std.IsReady
        
    def update(self, time, price):
        self.std.Update(time, price)
        self.mean.Update(time, price)
        
    def deviating(self, price):
        if self.std.Current.Value == 0:
            return False
        return ( (price - self.mean.Current.Value) / self.std.Current.Value ) < -3