Overall Statistics
Total Orders
2693
Average Win
0.11%
Average Loss
-0.09%
Compounding Annual Return
-7.685%
Drawdown
29.000%
Expectancy
-0.102
Start Equity
100000
End Equity
80632.79
Net Profit
-19.367%
Sharpe Ratio
-0.317
Sortino Ratio
-0.414
Probabilistic Sharpe Ratio
1.249%
Loss Rate
59%
Win Rate
41%
Profit-Loss Ratio
1.19
Alpha
-0.067
Beta
-0.169
Annual Standard Deviation
0.222
Annual Variance
0.049
Information Ratio
-0.314
Tracking Error
0.282
Treynor Ratio
0.417
Total Fees
$2785.08
Estimated Strategy Capacity
$510000000.00
Lowest Capacity Asset
COG R735QTJ8XC9X
Portfolio Turnover
10.39%
# region imports
from AlgorithmImports import *
# endregion

class FatRedMosquito(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2022, 1, 1)
        self.set_cash(100000)
        self.universe_settings.resolution = Resolution.DAILY

        # Gold miners ETF constituents
        symbol = Symbol.create("XLE", SecurityType.EQUITY, Market.USA)
        universe = WeightETFConstituentsUniverseSelectionModel(symbol, self.universe_settings)
        self.add_universe_selection(universe)
        # Alpha specifically for gold miners
        gold = self.add_equity("GLD", Resolution.DAILY).symbol
        self.add_alpha(GoldMinerAlphaModel(gold, universe))

        self.set_portfolio_construction(InsightWeightingPortfolioConstructionModel(Expiry.END_OF_DAY))


class WeightETFConstituentsUniverseSelectionModel(ETFConstituentsUniverseSelectionModel):
    def __init__(self, symbol, settings):
        super().__init__(symbol, settings, self.etf_constituents_filter)

    def etf_constituents_filter(self, constituents):
        self.weights = {x.symbol: x.weight for x in constituents if x.weight}
        return list(self.weights.keys())

    
class GoldMinerAlphaModel(AlphaModel):
    def __init__(self, gold, universe):
        '''Instantiate a new instance of GoldMinerAlphaModel
        Parameter
        ---------
        - gold: Symbol
            Symbol of gold asset
        - universe: Universe
            A gold miner security universe reference that adapt GoldMinerAlphaModel
        '''
        self.gold = gold
        self.universe = universe

    def update(self, algorithm, data):
        insights = []

        if data.bars.contains_key(self.gold):
            gold = algorithm.securities[self.gold]
            gold_ema50 = gold.ema50.current.value

            if data.bars[self.gold].close > gold_ema50:
                insights.extend([
                    Insight.Price(symbol, timedelta(1), InsightDirection.UP, weight=weight) for symbol, weight in self.universe.weights.items()
                ])
            else:
                insights.extend([
                    Insight.Price(symbol, timedelta(1), InsightDirection.DOWN, weight=weight) for symbol, weight in self.universe.weights.items()
                ])

        return insights

    def on_securities_changed(self, algorithm, changes):
        for added in changes.added_securities:
            if added.symbol == self.gold:
                added.ema50 = algorithm.EMA(added.symbol, 50, Resolution.DAILY)
                algorithm.warm_up_indicator(added.symbol, added.ema50)