Overall Statistics
Total Trades
18
Average Win
2.46%
Average Loss
-9.72%
Compounding Annual Return
-3.124%
Drawdown
38.100%
Expectancy
-0.060
Net Profit
-14.694%
Sharpe Ratio
-0.116
Probabilistic Sharpe Ratio
0.128%
Loss Rate
25%
Win Rate
75%
Profit-Loss Ratio
0.25
Alpha
-0.019
Beta
0.043
Annual Standard Deviation
0.123
Annual Variance
0.015
Information Ratio
-0.723
Tracking Error
0.176
Treynor Ratio
-0.33
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
WGC/GOLD_DAILY_USD.NasdaqDataLink 2S
# region imports
from AlgorithmImports import *
# endregion

class GoldMarketTimingAlgorithm(QCAlgorithm):

    def Initialize(self):

        self.SetStartDate(2010, 1, 1) 
        self.SetEndDate(2015, 1, 1)  
        self.SetCash(100000)
        # United States Government 10-Year Bond Yield   
        self.bond_yield = self.AddData(NasdaqDataLinkRate, "YC/USA10Y", Resolution.Daily, TimeZones.Utc, True).Symbol
        # S&P 500 Earnings Yield. Earnings Yield = trailing 12 month earnings divided by index price 
        self.earnings_yield = self.AddData(NasdaqDataLink, "MULTPL/SP500_EARNINGS_YIELD_MONTH", Resolution.Daily, TimeZones.Utc, True).Symbol
        # Gold Prices (Daily) - Currency USD (All values are national currency units per troy ounce)
        self.gold = self.AddData(NasdaqDataLink, "WGC/GOLD_DAILY_USD", Resolution.Daily, TimeZones.Utc, True).Symbol
        self.AddEquity("SPY", Resolution.Daily)
        # Monthly rebalance
        self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.At(0, 0), self.Rebalance)
        # Chart
        yieldPlot = Chart("Yield Plot")
        yieldPlot.AddSeries(Series("BondYield", SeriesType.Line, 0))
        yieldPlot.AddSeries(Series("EarningsYield", SeriesType.Line, 0))
        self.AddChart(yieldPlot)

    def OnData(self, data):
        if data.ContainsKey(self.bond_yield) and data.ContainsKey(self.earnings_yield):
            self.Plot("Yield Plot", "BondYield", data[self.bond_yield].Price)
            self.Plot("Yield Plot", "EarningsYield", data[self.earnings_yield].Price)

    def Rebalance(self):
        if self.Securities[self.earnings_yield].Price == 0 or self.Securities[self.bond_yield].Price == 0: return
        # Buy gold if E/P is higher than the bond yield and their ratio is at least 2
        if self.Securities[self.earnings_yield].Price > self.Securities[self.bond_yield].Price * 2:
            self.SetHoldings(self.gold, 0.9)
        else:
            self.Liquidate()


class NasdaqDataLinkRate(NasdaqDataLink):
    def __init__(self) -> None:
        # Select the column "rate".
        self.ValueColumnName = "rate"