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)
Ben Wong
Added backtest
Ben Wong
Found the problem: Marketorders, even in logs or elsewhere, actually trigger an actual market order. I shouldve been using order tickets.
https://www.quantconnect.com/forum/discussion/1521/order-tickets/p1For anyone chancing upon this in future, you can refer to :
Lordy Mike
Do you have the revised backtest with the changes you made?
Ben Wong
Hi Mike,
Unfortunately at the moment no, im getting errors from the OnOrderEvent function that say my market order has no fill price. All I want is to get my market order fill price, but I still havent figured out a way to do it. Will post when I find something.
Ben Wong
did it!
Ben Wong
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!