I am brand new with QA and is backtesting a system using limit orders. To make sure that the order will fill in real trading, I have attempted to create a MM script to check (in case of buy orders) if the low of the day was lower than the limit price and not just equal. That way I can be sure that the fill price is more legit.
The outline of my QS strategy is below:
----------- start -------------
SetSimTiming(_Buy, _Limit, 0);
Rule1 = "My buy rules"
Rule2 = "My Sell Rules")
buy = (Rule1);
BuyPrice(close * 0.95, 1);
Sell = Close > MA(Close,8, _MaSma);
--------------end-------------------
Then to filter out the trades where the low of the is equal to the BuyPrice, I created the MM Script below.
The problem is that instead of filtering out and reducing the number of trades, the total number of trades actually increased significantly, so obviously my MM Script is not working as intended.
I am still learning C# and just cannot figure out what I am doing wrong and was hoping that someone can take a look and let me know what I am doing wrong.
OnStartSimulation
-----------------------
Functions.SetNumericInput("Limit%", (double)5.0, "Set limit x% below/above close price");
OnNewPosition Event
-----------------------------
double EntryPrice = NewPosition.Price;
TimeSeries h = Data.GetPriceSeries(Data.GetSymbolInfo(NewPosition.Symbol).Name, "high");
TimeSeries l = Data.GetPriceSeries(Data.GetSymbolInfo(NewPosition.Symbol).Name, "low");
TimeSeries c = Data.GetPriceSeries(Data.GetSymbolInfo(NewPosition.Symbol).Name, "close");
double limit = (double)Variables.GetVariable("Limit%");
double BuyLimitPrice = c[1] * (1 - (limit/100)); //Limit is 5% below yesterday's close
double SellLimitPrice = c[1] * (1 + (limit/100)); //Limit is 5% above yesterday's close
bool TradeBelowLimit = l[0] < BuyLimitPrice; //See if low was lower than limit price
bool TradeAboveLimit = h[0] > SellLimitPrice; //See if high was higher than limitproce
Thank you for replying so quickly. I have just ran it again and got similar results before. Here are the steps that I have followed:
Remove MM Script from my strategy and execute the strategy as is.
Number of trades: 1643
Then I add the MM script to the strategy without making any other changes and execute.
Number of trades: 2711.
What could be causing the increase in trades? Does adding code to the OnNewPosition even override other internal settings like checking if there is enough equity, or something like that?
Without MM, a LimitOrder is executed only if the CLOSE price is below the limit. In your script, you are using the High and thus it is normal that more traders are generated.
Note that you can instruct QS to execute orders exactly at the limit price (within the high/low range) by updating the trading system then selecting "Settings -> Capital -> Activate stop immediately"
My MM Script only uses the high for short orders. For Buy orders, it check that the low is lower than the limit with this line: if(NewPosition.IsLong && TradeBelowLimit). (I realize there is an error in the if statement checking of this is a short trade in the code above, but since this system is long only, this is not really relevant.)
I just ran it again with and without the MM script and "Activate Stop immediately" selected. Without the MM script, trades are 731. This raises another issue. Based on your explanation that without "Activate Stop Immediately" trades are only executed if the close is below the limit and when this option is selected, that the exact limit price (within High/Low) is used. Since the low of the bar will almost always be lower than the close, this means then that with it checked that there should be more trades with "Activate Stop Immediately" checked. But there is much less. Why is that?
Then when I ran it with the MM script and "Activate Stop Immediately" selected, there is 1106 trades which is again more than without the MM script instead of less.
As a reference, the same system on the exact same data and timeframe in Amibroker produces 1828 trades. I expected some differences due to how available cash is calculated and position sizing, but even if I use fixed dollar trades (i.e. $2000 per trade), there are still big differences. I really don't want this to be an argument between Amibroker and QS as I think the features and options of QS looks to be vastly superior. I just uses Amibroker as a comparison as this is where I do my current development and understand how it works.
I think I might understand what is happening. From what I can see, the OnNewPosition event is raised when the signal become true and not when the order is executed. My assumption was that the even is raised on the bar that the trade is executed, which is a day after the signal become true, but it is not.
In short what I am testing is that is a signal is true tonight based on EOD data, I place a limit order for tomorrow and want to make sure that tomorrow the low is lower than the limit order before placing the order. Let's say my signal bar is Today, the entry bar is Tomorrow and yesterday's price is Yesterday.
So, these lines in my MM Script is executed on Today (signal bar), instead of Tomorrow (Entry bar):
Which means the BuyLimitPrice calculation is using the Closing price of Yesterday and I am filtering trades based on the bar of Today and not Tomorrow when the order is actually placed for.
So, the question then is, how do I accomplish what I am trying to do? I want to make sure that the low of tomorrow is below the limit price before accepting the order. I was thinking to use the OnEndPeriod and see if the EntryDate is the same as Today's date and then check if the fill was legit, but that means the order is already open and I cannot remove/cancel an already opened order?
I also would appreciate if you can help me understand as I mentioned in my previous post why there are even less trades when I select the "Activate Stop Immediately"?
Yes, the "OnNewPosition" is executed on each entry signal (not when an order is executed).
I think the "Activate Stop Immediately" option is what your are looking for. For a buy order, it makes sure the order is executed at the exact limit.
At the end of the period, it check if the order would have been executed based on current bar's high/low and if it is the case then the limit order is executed at that exact price.
Note also that you can remove/update an already opened order. You can do that by getting orders first using: Orders.GetPendingBuyOrders() or Orders.GetPendingSellOrders()...
Thank you for being patient with me. I have two concerns with "Activate Stop Immediately".
1. I want to make sure that the low of the day is lower than the limit order to ensure that this will result in a fill in real trading. I have backtested too many system that doesn't require that and produce excellent backtesting results, but fail in real trading because the orders do not get filled by just touching the limit price.
2. When I turn Activate Stop Immediately" on, I am getting less trades instead of more. That doesn't seem right to me, because in the case of buy orders, without it turned on, the close price is compare with the limit price and with it turned on, the low is use. Since the low is almost always lower than the close, there should be more filled trades and not less.
1/ No need to worry about that. You can check some positions on a chart to confirm that "Activate Stop Immediately" is working correctly.
2/ Several reasons could explain this. The systems would generate different trades. For example, the first system may ended up having an average "bars held" higher than the second one and that could explain why there are few trades with the first system. I suggest you plot entries and exists on a chart and manually check some trades.
Trading financial instruments, including foreign exchange on margin, carries a high level of risk and is not suitable for all investors. The high degree of leverage can work against you as well as for you. Before deciding to invest in financial instruments or foreign exchange you should carefully consider your investment objectives, level of experience, and risk appetite. The possibility exists that you could sustain a loss of some or all of your initial investment and therefore you should not invest money that you cannot afford to lose. You should be aware of all the risks associated with trading and seek advice from an independent financial advisor if you have any doubts.