Hi,

Can anyone help me understand why the marketorder to buy or sell the defaultQuantity is triggering thrice on some occasions?
Through debugging, I find that the defaultQuantity never changes i.e. 100,000. Also when I step through the code with a breakpoint at the marketorder lines with a watch on my holdings variable, i see that the holdings immediately jumps from 0 to 300,000 or -300,000 depending on a long or short.

 

import decimal as d

class MovingAverageBasic(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2019,1,1) # Set Start Date
self.SetEndDate(2019,2,1)
self.SetCash(1000000) # Set Strategy Cash
self.defaultQuantity = 100000

#self.AddForex("AUDUSD", Resolution.Hour, Market.Oanda) #AddForex merely adds the security, but you cant refer to it later.
self.audusd = self.AddForex("AUDUSD", Resolution.Hour, Market.Oanda).Symbol #But doing this you now can refer to self.symbol
# Symbols are a way to identify an asset uniquely. They are objects which contain all the information required
# to identify a security, without needing external references, or proprietary database look-ups.

self.SetBrokerageModel(BrokerageName.OandaBrokerage)

self.fastEMA = self.EMA("AUDUSD", 5, Resolution.Hour)
self.slowEMA = self.EMA("AUDUSD", 20, Resolution.Hour)
self.fastEMAWin = RollingWindow[float](5)
self.slowEMAWin = RollingWindow[float](20)
self.ATRindy = self.ATR("AUDUSD",20,MovingAverageType.Simple, Resolution.Hour)
self.SetWarmUp(30)

def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''

# Creates an indicator and adds to a rolling window when it is updated

self.fastEMAWin.Add(self.fastEMA.Current.Value)
self.slowEMAWin.Add(self.slowEMA.Current.Value)
self.ATR_Now = self.ATRindy.Current.Value

if not self.slowEMA.IsReady or not self.fastEMA.IsReady:
return

#Logging-------------------------------------------------------------------------------
Cutup = self.CrossAbove(self.fastEMAWin, self.slowEMAWin)
Cutdown = self.CrossBelow(self.fastEMAWin, self.slowEMAWin)
time_now = self.Time
holdings = self.Securities["AUDUSD"].Holdings.Quantity

if self.Portfolio[self.audusd].IsLong:

if self.Falling(self.slowEMAWin, self.slowEMAWin):
self.Liquidate(self.audusd)
self.Log("Closing Long | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))

elif self.Portfolio[self.audusd].IsShort:
if self.Rising(self.slowEMAWin, self.slowEMAWin):
self.Liquidate(self.audusd)
self.Log("Closing Short | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))
else:

if self.CrossAbove(self.fastEMAWin, self.slowEMAWin) and not self.Falling(self.slowEMAWin, self.slowEMAWin):

self.MarketOrder(self.audusd, self.defaultQuantity)
self.Log("New Long | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))
self.Log("Market long order fill price is {}".format(self.MarketOrder(self.audusd, self.defaultQuantity).AverageFillPrice))
self.StopMarketOrder(self.audusd, -self.defaultQuantity, self.MarketOrder(self.audusd, self.defaultQuantity).AverageFillPrice - 2*self.ATR_Now )
holdings = self.Securities["AUDUSD"].Holdings.Quantity
if self.CrossBelow(self.fastEMAWin, self.slowEMAWin) and not self.Rising(self.slowEMAWin, self.slowEMAWin):

self.MarketOrder(self.audusd, -self.defaultQuantity)
self.Log("New Short | Cutup is {} | Cutdown is {}".format(Cutup, Cutdown))
self.Log("Market short order fill price is {}".format(self.MarketOrder(self.audusd, self.defaultQuantity).AverageFillPrice))
holdings = self.Securities["AUDUSD"].Holdings.Quantity





#below are event handlers, as well as functions to determine the status of the EMA
#-------------------------------------------------------------------------------

def CrossAbove(self, fast, slow, tolerance=0):
return fast[0] > slow[0] * (1 + tolerance) and fast[2] < slow[2] * (1 - tolerance)

def CrossBelow(self, fast, slow, tolerance = 0):
return fast[0] < slow[0] * (1 - tolerance) and fast[2] > slow[2] * (1 + tolerance)

def Rising(self, current, lookback, tolerance = 0):
return current[0] > lookback[2] * (1 + tolerance)

def Falling(self, current, lookback, tolerance = 0):
return current[0] < lookback[2] * (1 - tolerance)