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 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
from clr import AddReference AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm.Framework") AddReference("QuantConnect.Indicators") from System import * from QuantConnect import * from QuantConnect.Indicators import * from QuantConnect.Algorithm.Framework.Alphas import * class MacdMomentumAlphaModel(AlphaModel): '''Defines a custom alpha model that uses MACD crossovers. The MACD signal line is used to generate up/down insights if it's stronger than the bounce threshold. If the MACD signal is within the bounce threshold then a flat price insight is returned.''' def __init__(self, fastPeriod = 12, slowPeriod = 26, signalPeriod = 9, movingAverageType = MovingAverageType.Exponential, resolution = Resolution.Minute): ''' Initializes a new instance of the MacdAlphaModel class Args: fastPeriod: The MACD fast period slowPeriod: The MACD slow period</param> signalPeriod: The smoothing period for the MACD signal movingAverageType: The type of moving average to use in the MACD''' self.fastPeriod = fastPeriod self.slowPeriod = slowPeriod self.signalPeriod = signalPeriod self.movingAverageType = movingAverageType self.resolution = resolution self.insightPeriod = Time.Multiply(Extensions.ToTimeSpan(resolution), fastPeriod) self.bounceThresholdPercent = 0.01 self.symbolData = {}; resolutionString = Extensions.GetEnumString(resolution, Resolution) movingAverageTypeString = Extensions.GetEnumString(movingAverageType, MovingAverageType) self.Name = '{}({},{},{},{},{})'.format(self.__class__.__name__, fastPeriod, slowPeriod, signalPeriod, movingAverageTypeString, resolutionString) def Update(self, algorithm, data): ''' Determines an insight for each security based on it's current MACD signal Args: algorithm: The algorithm instance data: The new data available Returns: The new insights generated''' insights = [] if algorithm.IsWarmingUp: return for key, sd in self.symbolData.items(): if sd.Security.Price == 0: continue algorithm.Debug("Inside Update For loop...") direction = InsightDirection.Flat holdings = algorithm.Portfolio[sd.Security.Symbol.Value].Quantity algorithm.Debug(sd.Security.Symbol.Value+" holdings ="+str(holdings)) if(sd.MACDTrend_Previous == None): return normalized_signal = sd.macd.Signal.Current.Value / sd.Security.Price if normalized_signal > self.bounceThresholdPercent: direction = InsightDirection.Up elif normalized_signal < -self.bounceThresholdPercent: direction = InsightDirection.Down # ignore signal for same direction as previous signal if direction == sd.PreviousDirection: continue; insight = Insight.Price(sd.Security.Symbol, self.insightPeriod, direction) sd.PreviousDirection = insight.Direction insights.append(insight) return insights def OnSecuritiesChanged(self, algorithm, changes): '''Event fired each time the we add/remove securities from the data feed. This initializes the MACD for each added security and cleans up the indicator for each removed security. Args: algorithm: The algorithm instance that experienced the change in securities changes: The security additions and removals from the algorithm''' for added in changes.AddedSecurities: self.symbolData[added.Symbol] = SymbolData(algorithm, added, self.fastPeriod, self.slowPeriod, self.signalPeriod, self.movingAverageType, self.resolution) data = self.symbolData.pop(added.Symbol, None) # Do we need the following two lines ? algorithm.SubscriptionManager.AddConsolidator(added.Symbol, data.Consolidator_15) algorithm.SubscriptionManager.AddConsolidator(added.Symbol, data.Consolidator_240) #Creating the RollingWindow here and updating the 240 mins MACDTrend data.MACDWindow = RollingWindow[IndicatorDataPoint](3) data.MACDTrend.Updated += data.MacdUpdated for removed in changes.RemovedSecurities: data = self.symbolData.pop(removed.Symbol, None) if data is not None: # clean up our consolidator algorithm.SubscriptionManager.RemoveConsolidator(removed.Symbol, data.Consolidator_15); algorithm.SubscriptionManager.RemoveConsolidator(removed.Symbol, data.Consolidator_240); # How to Reset() ??? class SymbolData: ''' Not sure which indicator and/or rolling window should be created here, or OnSecuritiesChanged Here, I am trying to translate what I saw in your C# sample into python. ''' def __init__(self, algorithm, security, fastPeriod, slowPeriod, signalPeriod, movingAverageType, resolution): self.Security = security self.macd = MovingAverageConvergenceDivergence(fastPeriod, slowPeriod, signalPeriod, movingAverageType) self.MACDTrend = MovingAverageConvergenceDivergence(fastPeriod, slowPeriod, signalPeriod, movingAverageType) #self.Consolidator = algorithm.ResolveConsolidator(security.Symbol, resolution) self.Consolidator_15 = QuoteBarConsolidator(15) algorithm.RegisterIndicator(security.Symbol, self.macd, self.Consolidator_15) self.Consolidator_240 = QuoteBarConsolidator(240) algorithm.RegisterIndicator(security.Symbol, self.MACDTrend, self.Consolidator_240) self.MACDWindow = None self.MACDTrend_Previous = None self.kamaFast = KaufmanAdaptiveMovingAverage(security.Symbol.Value,5) algorithm.RegisterIndicator(security.Symbol, self.kamaFast, self.Consolidator_15) self.kamaSlow = KaufmanAdaptiveMovingAverage(security.Symbol.Value,30) algorithm.RegisterIndicator(security.Symbol, self.kamaSlow, self.Consolidator_15) self.adx = AverageDirectionalIndex(security.Symbol.Value,14) self.adxr = AverageDirectionalMovementIndexRating(security.Symbol.Value,14) algorithm.RegisterIndicator(security.Symbol, self.adx, self.Consolidator_15) algorithm.RegisterIndicator(security.Symbol, self.adxr, self.Consolidator_15) self.PreviousDirection = None ''' Wait for our macd to fully initialize May not look right to have this check in this method here, but if I put it elsewhere, there will be object instance error. i.e. seems macd is called before it is instantiated. ''' if not (self.macd.IsReady and self.MACDTrend.IsReady and self.kamaFast.IsReady and self.kamaSlow.IsReady and self.MACDWindow.IsReady): return algorithm.Debug(self.macd.Current.Value) ''' I need to wait at least 4 QuoteBars (15m) or 240 mins to get a 4 hour QuoteBars,so self.MACDWindow.IsReady check is essential ''' self.MACDTrend_Previous = self.MACDWindow[1] algorithm.Debug(self.MACDTrend_Previous.Value) algorithm.Debug(self.MACDTrend) def MacdUpdated(self, sender, updated): # if not self._macdWindow.IsReady : return self.MACDWindow.Add(updated)
from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Orders import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from QuantConnect.Algorithm.Framework.Alphas import * from QuantConnect.Algorithm.Framework.Portfolio import * from QuantConnect.Algorithm.Framework.Selection import * from Alphas.ConstantAlphaModel import ConstantAlphaModel from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Risk.MaximumDrawdownPercentPerSecurity import MaximumDrawdownPercentPerSecurity from datetime import timedelta import numpy as np from MACDMomentumAlphaModel import MacdMomentumAlphaModel ### <summary> ### Basic template framework algorithm uses framework components to define the algorithm. ### </summary> ### <meta name="tag" content="using data" /> ### <meta name="tag" content="using quantconnect" /> ### <meta name="tag" content="trading and orders" /> class MACDMomentumFramework(QCAlgorithmFramework): '''Basic template framework algorithm uses framework components to define the algorithm.''' def Initialize(self): ''' A function to define things to do at the start of the strategy Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. ''' # universe selection #self.failedSecurities = ["USDCAD"] #self.symbols = ["EURUSD","EURAUD","GBPUSD","AUDUSD"] #self.forex = self.AddForex(self.symbols[0], Resolution.Minute, Market.FXCM) self.params = {'start_yr':2016, 'start_mth':1, 'start_day':1, 'end_yr':2018, 'end_mth':6, 'end_day':1, 'principal':25000, 'warmup':100, 'max_weight_per_pos':0.02, 'leverage':200, 'tp_atr_factor':2.5, 'sl_atr_factor':3.0, 'main_timeframe':15, 'trend_timeframe':240, 'kama_fast_period':5, 'kama_slow_period':30, 'adx_period':14, 'adxr_period':14, 'atr_period':14, 'macd_fast_period':12, 'macd_slow_period':26, 'macd_signal_period':9, 'lookback_win':5 } self.SetStartDate(self.params['start_yr'], self.params['start_mth'], self.params['start_day']) #Set Start Date self.SetEndDate(self.params['end_yr'], self.params['end_mth'], self.params['end_day']) #Set End Date self.SetCash(self.params['principal']) #Set Strategy Cash # Set requested data resolution self.UniverseSettings.Resolution = Resolution.Minute self.SetBrokerageModel(BrokerageName.FxcmBrokerage) # Find more symbols here: http://quantconnect.com/data # Forex, CFD, Equities Resolutions: Tick, Second, Minute, Hour, Daily. # Futures Resolution: Tick, Second, Minute # Options Resolution: Minute Only. self.symbols = [] #curr = Currencies.CurrencyPairs curr = ["EURUSD","GBPUSD","EURAUD","GBPNZD"] for i in range(len(curr)): self.Debug(curr[i]) self.symbols.append(Symbol.Create(curr[i], SecurityType.Forex, Market.FXCM)) # set algorithm framework models self.SetUniverseSelection(ManualUniverseSelectionModel(self.symbols)) self.Debug("Before!!!") self.SetAlpha(MacdMomentumAlphaModel(fastPeriod = 12, slowPeriod = 26, signalPeriod = 9, movingAverageType = MovingAverageType.Exponential, resolution = Resolution.Minute)) self.Debug("After...") #self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(minutes = 20), 0.025, None)) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) #self.SetExecution(ImmediateExecutionModel()) #self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.01)) self.Debug("numpy test >>> print numpy.pi: " + str(np.pi)) def OnOrderEvent(self, orderEvent): if orderEvent.Status == OrderStatus.Filled: self.Debug("Purchased Stock: {0}".format(orderEvent.Symbol))