| 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- DONEfrom 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