Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
5.818
Tracking Error
0.069
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
from datetime import timedelta

class RedGhost(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 12)
        self.SetEndDate(2021, 1, 15)
        self.SetCash(100000) 
        self.AddUniverseSelection(UniverseModule())
        self.UniverseSettings.Resolution = Resolution.Daily
        self.SetAlpha(RGAlphaModel())
        self.histories = {}
   
class UniverseModule(FundamentalUniverseSelectionModel):
    def __init__(self, filterFineData = True, universeSettings = None):
        super().__init__(filterFineData, universeSettings)
        self.averages = {}
        
    '''
    Filter by price
    '''
    def SelectCoarse(self, algorithm, coarse):
        return [
            x.Symbol for x in coarse if (
                x.Price > 10
                and x.HasFundamentalData
            )
        ]
        
    '''
    Filter by min market cap and share count
    '''
    def SelectFine(self, algorithm, fine):
        MIN_MKT_CAP = 1 * 10 ^ 9
        MIN_SHARE_COUNT = 1 * 10 ^ 9
        MAX_BARS_BACK = 200
        
        initialFilter = [
            x.Symbol for x in fine if (
                x.FinancialStatements.BalanceSheet.OrdinarySharesNumber.Value >= MIN_SHARE_COUNT
                and x.MarketCap >= MIN_MKT_CAP
            )
        ]
        
        historySlices = algorithm.History(initialFilter, MAX_BARS_BACK, Resolution.Daily)
        for symbol, history in historySlices.groupby(level=0):
            if symbol not in self.averages:
                self.averages[symbol] = SymbolData(symbol, history)

            avg = self.averages[symbol]
            latestTime = history.loc[symbol].index[-1]
            lastClose = history.loc[symbol].close.iloc[-1]
            avg.update(latestTime, lastClose)
            
            # algorithm.histories[symbol] = history # -> had to comment this line out, giving the error
        
        upTrending = list(filter(lambda x: x.isUptrend, self.averages.values()))
        
        finalSymbols = [x.symbol for x in upTrending]
        
        return finalSymbols

class RGAlphaModel(AlphaModel):
    
    def __init__(self):
        self.insightPeriod = timedelta(days = 30)
            
    def Update(self, algorithm, slice):
        insights = []
        # for symbol in slice.Bars:
        #     closingPrices = algorithm.histories[symbol]["close"].tolist()[:10]
            # append to insights
        return insights 
        
class SymbolData(object):
    def __init__(self, symbol, history):
        self.symbol = symbol
        self.longTerm = ExponentialMovingAverage(200)
        self.mediumTerm = ExponentialMovingAverage(100)
        self.isUptrend = False
        
        history.loc[self.symbol].apply(lambda row: self.update(row.name, row.close), axis=1)

    def update(self, time, value):
        self.longTerm.Update(time, value)
        self.mediumTerm.Update(time, value)
        
        longTerm = self.longTerm.Current.Value
        mediumTerm = self.mediumTerm.Current.Value
        
        self.isUptrend = (
            mediumTerm > longTerm
        )