Overall Statistics
Total Trades
619
Average Win
0.01%
Average Loss
0.00%
Compounding Annual Return
3.820%
Drawdown
5.400%
Expectancy
13.419
Net Profit
7.817%
Sharpe Ratio
0.545
Probabilistic Sharpe Ratio
22.953%
Loss Rate
1%
Win Rate
99%
Profit-Loss Ratio
13.51
Alpha
0.034
Beta
-0.027
Annual Standard Deviation
0.059
Annual Variance
0.004
Information Ratio
-0.167
Tracking Error
0.233
Treynor Ratio
-1.221
Total Fees
$0.00
class WarmupHistoryAlgorithm(QCAlgorithm):

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2018,5,2)   #Set Start Date
        self.SetEndDate(2020,5,2)     #Set End Date
        self.SetCash(100000)          #Set Strategy Cash
        # Find more symbols here: http://quantconnect.com/data
        forex = self.AddForex("EURUSD", Resolution.Daily)
        forex = self.AddForex("NZDUSD", Resolution.Daily)
        
        
        self.SetAlpha(MOMAlphaModel())
        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
        self.SetExecution(ImmediateExecutionModel())
        

    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
        pass
            


class MOMAlphaModel(AlphaModel):
    
    def __init__(self):
        self.fast_period = 20
        self.slow_period = 60
        self.fast = ExponentialMovingAverage("EURUSD", self.fast_period)
        self.slow = ExponentialMovingAverage("EURUSD", self.slow_period)
        self.period = timedelta(hours=2)  
        
    def Update(self, algorithm, data):
        #3. Return a group of insights, emitting InsightDirection.Up for the first item of ordered, and InsightDirection.Flat for the second
        if self.fast.Current.Value > self.slow.Current.Value:
            return Insight.Group(
                [
                    Insight.Price("EURUSD", self.period, InsightDirection.Up)
                ])
        
        if self.fast.Current.Value < self.slow.Current.Value:
            return Insight.Group(
                [
                    Insight.Price("EURUSD", self.period, InsightDirection.Down)
                ])
            
        return []
        
    def OnSecuritiesChanged(self, algorithm, changes):
        # "slow_period + 1" because rolling window waits for one to fall off the back to be considered ready
        # History method returns a dict with a pandas.DataFrame
        history = algorithm.History(["EURUSD", "NZDUSD"], self.slow_period + 1)

        # prints out the tail of the dataframe
        #self.Log(str(history.loc["EURUSD"].tail()))
        #self.Log(str(history.loc["NZDUSD"].tail()))

        for index, row in history.loc["EURUSD"].iterrows():
            self.fast.Update(index, row["close"])
            self.slow.Update(index, row["close"])

        #self.Debug("FAST {0} READY. Samples: {1}".format("IS" if self.fast.IsReady else "IS NOT", self.fast.Samples))
        #self.Debug("SLOW {0} READY. Samples: {1}".format("IS" if self.slow.IsReady else "IS NOT", self.slow.Samples))

#TODO: Create Alpha - use code from the example - Done
#TODO: Create Universe
#TODO: Create Execution- DONE
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel

class TechnologyUniverseModule(FundamentalUniverseSelectionModel):
    '''
    This module selects the most liquid stocks listed on the Nasdaq Stock Exchange.
    '''
    def __init__(self, filterFineData = True, universeSettings = None, securityInitializer = None):
        '''Initializes a new default instance of the TechnologyUniverseModule'''
        super().__init__(filterFineData, universeSettings, securityInitializer)
        self.numberOfSymbolsCoarse = 100
        self.numberOfSymbolsFine = 10
        self.dollarVolumeBySymbol = {}
        self.lastMonth = -1

    def SelectCoarse(self, algorithm, coarse):
        '''
        Performs a coarse selection:
        
        -The stock must have fundamental data
        -The stock must have positive previous-day close price
        -The stock must have positive volume on the previous trading day
        '''
        if algorithm.Time.month == self.lastMonth: 
            return Universe.Unchanged

        sortedByDollarVolume = sorted([x for x in coarse if x.HasFundamentalData and x.Volume > 0 and x.Price > 0],
            key = lambda x: x.DollarVolume, reverse=True)[:self.numberOfSymbolsCoarse]

        self.dollarVolumeBySymbol = {x.Symbol:x.DollarVolume for x in sortedByDollarVolume}
        
        # If no security has met the QC500 criteria, the universe is unchanged.
        if len(self.dollarVolumeBySymbol) == 0:
            return Universe.Unchanged

        return list(self.dollarVolumeBySymbol.keys())

    def SelectFine(self, algorithm, fine):
        '''
        Performs a fine selection:
        
        -The company's headquarter must in the U.S.
        -The stock must be traded on the NASDAQ stock exchange
        -The stock must be in the Industry Template Code catagory N
        -At least half a year since its initial public offering
        '''
        # Filter stocks and sort on dollar volume
        sortedByDollarVolume = sorted([x for x in fine if x.CompanyReference.CountryId == "USA"
                                        and x.CompanyReference.PrimaryExchangeID == "NAS"
                                        and x.CompanyReference.IndustryTemplateCode == "N"
                                        and (algorithm.Time - x.SecurityReference.IPODate).days > 180],
            key = lambda x: self.dollarVolumeBySymbol[x.Symbol], reverse=True)

        if len(sortedByDollarVolume) == 0:
            return Universe.Unchanged
            
        self.lastMonth = algorithm.Time.month

        return [x.Symbol for x in sortedByDollarVolume[:self.numberOfSymbolsFine]]
from datetime import timedelta, datetime

class WarmupHistoryAlgorithm(QCAlgorithm):

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2014,5,2)   #Set Start Date
        self.SetEndDate(2020,5,2)     #Set End Date
        self.SetCash(100000)          #Set Strategy Cash
        # Find more symbols here: http://quantconnect.com/data
        forex = self.AddForex("EURUSD", Resolution.Daily)
        forex = self.AddForex("NZDUSD", Resolution.Daily)

        fast_period = 60
        slow_period = 3600
        self.fast = self.EMA("EURUSD", fast_period)
        self.slow = self.EMA("EURUSD", slow_period)

        # "slow_period + 1" because rolling window waits for one to fall off the back to be considered ready
        # History method returns a dict with a pandas.DataFrame
        history = self.History(["EURUSD", "NZDUSD"], slow_period + 1)

        # prints out the tail of the dataframe
        self.Log(str(history.loc["EURUSD"].tail()))
        self.Log(str(history.loc["NZDUSD"].tail()))

        for index, row in history.loc["EURUSD"].iterrows():
            self.fast.Update(index, row["close"])
            self.slow.Update(index, row["close"])

        self.Log("FAST {0} READY. Samples: {1}".format("IS" if self.fast.IsReady else "IS NOT", self.fast.Samples))
        self.Log("SLOW {0} READY. Samples: {1}".format("IS" if self.slow.IsReady else "IS NOT", self.slow.Samples))


    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''

        if self.fast.Current.Value > self.slow.Current.Value:
            self.SetHoldings("EURUSD", 1)
        else:
            self.SetHoldings("EURUSD", -1)
            


#TODO: Create Alpha - use code from the example
#TODO: Create Universe
#TODO: Create Execution