Hello!
I am experiencing an issue and which despite reading other posts related to timing of positions, can't solve by myself. I implement my strategy to open a mean reversion position, so if the price of the current bar is lower than the previous bar, then open a long position. It seems like I receive correct signals, however instead of executing orders immediately at the beginning of a new bar after receiving the signal, the strategy waits until the end of a new bar,
Just to clarify what I mean by an example: if Tuesday's bar is lower than Monday's, then order should be executed immediately at the beginning Wednesday's bar. Instead, the position is opened at the end of Wednesday's bar.
I attached screenshots of the problem. “Pair1 0D” is the price of the FX pair, which is printed at the end of the bar,
As you can see, despite receiving signal at 19:00:00 on 2021-3-10 with the closing price of the bar at 8.48112, the order was executed next day, at 19:00 on 2021-3-11 at the price of 8.4545. I compared historical prices and indeed, the price on the 11th of March declined, which could cause such divergence in opening prices. However why did the strategy wait until the end of the next day to execute the order?
I would be grateful for any tips/advices.
from AlgorithmImports import *
class CustomIndexStrategy(QCAlgorithm):
def Initialize(self):
self.Pair_1_Multiplier = 9.5
self.Pair_1 = "USDSEK"
self.holdingDays = 1
self.SetStartDate (2021, 3, 3)
self.SetEndDate(2022,5,24)
self.SetCash(1000000)
self.SetBrokerageModel(BrokerageName.OandaBrokerage)
self.EURSEK = self.AddForex(self.Pair_1, Resolution.Daily, Market.Oanda)
self.symbols = [self.Pair_1]
self.prevPrices = { symbol : RollingWindow[QuoteBar](7) for symbol in self.symbols }
self.ticketPair1 = None
def OnData(self,data):
for symbol in self.symbols:
if data.ContainsKey(symbol):
self.prevPrices[symbol].Add( data[symbol] )
if not all([ window.IsReady for window in self.prevPrices.values() ]):
return
Pair1_window = self.prevPrices[self.Pair_1]
Pair1_3D = Pair1_window[3].Close
Pair1_2D = Pair1_window[2].Close
Pair1_1D = Pair1_window[1].Close
Pair1_0D = Pair1_window[0].Close
if self.ticketPair1 is not None and self.UtcTime < self.ticketPair1.Time + timedelta(days=(self.holdingDays)):
return
if self.ticketPair1 is None and Pair1_0D > Pair1_1D :
self.Log("Pair1 0D: " + str(Pair1_0D) +" Pair1 1D: " + str(Pair1_1D) + " Pair1 2D " + str(Pair1_2D) +" Pair1 3D " + str(Pair1_3D))
self.ticketPair1 = self.StopMarketOrder(self.Pair_1, -100000 * self.Pair_1_Multiplier, 1.03 * self.Securities[self.Pair_1].Close)
if self.ticketPair1 is None and Pair1_0D < Pair1_1D:
self.Log("Pair1 0D: " + str(Pair1_0D) +" Pair1 1D: " + str(Pair1_1D) + " Pair1 2D " + str(Pair1_2D) +" Pair1 3D " + str(Pair1_3D))
self.ticketPair1 = self.StopMarketOrder(self.Pair_1, 100000 * self.Pair_1_Multiplier, 0.97 * self.Securities[self.Pair_1].Close)
if self.ticketPair1 is not None and self.UtcTime >= self.ticketPair1.Time + timedelta(days = self.holdingDays):
self.Liquidate()
self.ticketPair1 = None
Nico Xenox
Hey sebul
So it took me a while but I found out that the stop market orders execute every time after the next bar. Which means that you have to either adjust your resolution or using other order types.
Sebul
Hey Nico Xenox,
thank you for your reply! I changed the order type into “marketOrder” and now the strategy opens orders immediately after receiving signals.
In the meantime I realised that a strange error occurs. When the strategy receives a signal at the end of Friday's bar, although it should execute the order as soon as the market opens on Monday, this erros is printed:
I've been looking for answers among older posts, and found advice to call the IsMarketOpen method.
https://www.quantconnect.com/forum/discussion/8537/the-oandabrokeragemodel-does-not-support-marketonopen-order-type-cfd-simple-framework/p1
https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-errors
Although I implemented the method to only execute trades or liquidiate positions when market is open (line 37 and 40), the problem still occurs.
I've attached screenshot of orders which present this error. As you can see, on 23.04 Long position was opened. The positions was supposed to be closed next day on 24th, but as it was Saturday, so I received the MarketOnOpen order type error again, despite implementing the method, which should prevent such error. The strategy skipped closing existing positions and opened another long trade a few days later.
By any chance, do you have any idea how to fix this issue? Or should I post this question as a separate post?
Nico Xenox
sebul
I also found a solution for that. Looking at the invalid orders I saw that it is always at fridays. One explanatino might be that it is closed at that time. So adding an if statement to check if it is friday is enough.
Sebul
Nico Xenox
Thank you for helping me out with this issue, I appreciate your help. I have one more question which I would like to ask. Although the strategy works correctly most of the time, a few days per year still exist, when the issue occurs. These days are bank holidays like Christmas and New Year Eve. They dont occur on Fridays but in the middle of a week. To solve this problem I added a simple rule in “OnData” event:
If I understand correctly, this rule should restrict the strategy to not trade on 25th of December. Despite that, I receive this error:
What could be the reason of such error?
Nico Xenox
sebul
You're using c# commands in Python. see here. When you write the code a little window always pops up. On there you can see the right values for python. In this case Day is day an Month is month.
Nico Xenox
Hey sebul
I foud a way better solution! You can check if the Exchange of the Security is Open or not.
Sebul
Nico Xenox great, thank you very much for you advices!
I've implemented you suggestions and there is one last thing I dont quite understand. Its anomaly in “strategy equity” chart in backtesting.
I extended the rule, so the price has to decline 4 days in a row to open a long position. Despite the fact, that during some periods of time no position is opened, “Strategy Equity” chart still slightly moves every day. The magnitude of changes is not large, is around 0.05-0.1% per day but I am still wondering where it comes from.
1st screenshot presents the chart. As you can see around 11th of June 2015 my strategy closed a position. Then, no positions are opened for next few weeks. Despite that, as you can see, small fluctuations occur every day. Second screenshot presents Orders History which confirms that no positions were opened after 12th of June 2015 and that the quantity of opened positions equals 0.
Of course I understand that this anomaly is not directly linked to the topic of this post, so please let me know if you think I would be better off by posting a separate question about this. I very much appreciate your help and advices which you have given me so far :)
Nico Xenox
Hey sebul I really have no idea but it might be the way how daily performance is calculated. Sorry about that, you can close this and open another one or ask on discord. There they might be able to answer the question without the need of opening a new conversation. Either way, good luck with your code ;)
Sebul
No need to apologise, thank you very much for your help Nico Xenox !
Sebul
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!