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