Overall Statistics
Total Trades
47
Average Win
5.40%
Average Loss
-2.36%
Compounding Annual Return
2.259%
Drawdown
17.600%
Expectancy
0.573
Net Profit
31.696%
Sharpe Ratio
0.279
Loss Rate
52%
Win Rate
48%
Profit-Loss Ratio
2.29
Alpha
-0.04
Beta
3.7
Annual Standard Deviation
0.076
Annual Variance
0.006
Information Ratio
0.064
Tracking Error
0.076
Treynor Ratio
0.006
Total Fees
$143.63
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel

class HorizontalMultidimensionalReplicator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2007, 1, 1)  # Set Start Date
        self.SetCash(100000)           # Set Strategy Cash
        
        # Set WarmUp period of 252 days
        self.SetWarmUp(252)
        
        # Add the Alpha Model
        self.AddAlpha(PanicToExcuberanceAlphaModel(self))
        
        # Use EqualWeightingPortfolioConstructionModel() to maintain equal weights
        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
        
        # Use ImmediateExecutionModel() for instant execution using market orders
        self.SetExecution(ImmediateExecutionModel())
        
        # Add SPY to the security universe
        symbols = [ Symbol.Create("SPY", SecurityType.Equity, Market.USA) ]
        self.SetUniverseSelection( ManualUniverseSelectionModel(symbols) )
 
class PanicToExcuberanceAlphaModel(AlphaModel):
    
    def __init__(self, algorithm): 
        
        # Set resolution for EMA Indicator
        self.resolution = Resolution.Daily 
        
        self.algorithm = algorithm
        
        # Add custom data from Quandl
        self.yearlyHighs = algorithm.AddData(QuandlData, 'URC/NASDAQ_52W_HI', Resolution.Daily).Symbol 
        
        # Add indicators using custom data
        self.ema = algorithm.EMA(self.yearlyHighs, 5, self.resolution)
        self.max = algorithm.MAX(self.yearlyHighs, 252, self.resolution)
        self.min = algorithm.MIN(self.yearlyHighs, 252, self.resolution) 
        
        # Set the prediction period
        self.period = timedelta(days=30)
 
    def Update(self, algorithm, data):
        insights = []
        
        # Return if no data
        if not data.ContainsKey(self.yearlyHighs): return insights
        
        # Return if indicators are not ready
        if not (self.min.IsReady or self.max.IsReady): return insights
        
        # Calculate the numerator of the custom indicator
        delta = self.max.Current.Value - self.min.Current.Value
        
        # Calculate the denominator of the custom indicator
        scaled = self.ema.Current.Value - self.min.Current.Value 
        
        # Calculate the value of the custom indicator
        rank = scaled / delta
        
        # Plot the custom indicator
        self.algorithm.Plot("Rank", "High Rank", rank)
         
        # Emit insight on SPY if the indicator value exceeds 0.5
        if rank > 0.50:
            insights.append(Insight.Price("SPY", self.period, InsightDirection.Up, 0.001))
             
        return insights
           
class QuandlData(PythonQuandl):
    
    def __init__(self):
        ## Retrieve the data from the the Quandl object, specifying the data field used on Quandl
        self.ValueColumnName = "NUMBERS OF STOCKS"