Hi,
I have some problems with the order „sell this bar on close“ on a DayChart.
It tries to close the position after the market is close and it varies from 9 sec to 4 min after the market closed. Of course all the Market orders to sell are rejected.
Where do I enter the time to send the order prior the close eg. 5 min or 30 sec or any other time prior close? Sending the order AFTER the market is close has to fail.
Where is the timesetting for "this bar on close"?
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
„sell this bar on close“ is for backtest only.Hi,
I have some problems with the order „sell this bar on close“ on a DayChart.
It tries to close the position after the market is close and it varies from 9 sec to 4 min after the market closed. Of course all the Market orders to sell are rejected.
Where do I enter the time to send the order prior the close eg. 5 min or 30 sec or any other time prior close? Sending the order AFTER the market is close has to fail.
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
EasyLanguage Essentials
Programmers Guide
Strategy Order Syntax... pg. 80
Programmers Guide
Strategy Order Syntax... pg. 80
Order Actions
this bar on Close: Market order on the close of this bar, generally used for historical backtesting purposes only. This will not generate a market on close order.
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
Most brokers require the final order entered 3 minutes before close to guarantee a fill, but the required time can vary from broker to broker.
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
By default (ie no intrabarordergeneration), orders are calculated at the end of the bar and sent at the next tick.
If you want to exit by close, you have to:
1. wrap up the calculation. That has to happen before the start of last bar because the calculations are done at the end of the bar.
2. generate an order and post it to broker well in advance of the last call.
If you want to exit by close, you have to:
1. wrap up the calculation. That has to happen before the start of last bar because the calculations are done at the end of the bar.
2. generate an order and post it to broker well in advance of the last call.
Just to make sure with your 2 points... I have to enable IOG?
If I did understand your points then I have to enable IOG and if I want a order to be generated 10 min before close and hope there are 2 ticks coming before it closes I have to add this code
if time>1550 and marketposition=1 then
...
If I did understand your points then I have to enable IOG and if I want a order to be generated 10 min before close and hope there are 2 ticks coming before it closes I have to add this code
if time>1550 and marketposition=1 then
...
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
no, IOG is not my point.Just to make sure with your 2 points... I have to enable IOG?
If I did understand your points then I have to enable IOG and if I want a order to be generated 10 min before close and hope there are 2 ticks coming before it closes I have to add this code
if time>1550 and marketposition=1 then
...
whether you use IOG depends on the design of your strategy.
I can't give you suggestions without knowing your specifics.
what is the resolution of your chart?
what instrument you are trading? stock? future? forex?
ps. trading was never designed for thin markets that have no volume.
Just a simple strategy...
Market: US-Stocks
Exitstrategy as simple as:
condition1=c>o;
if condition1 and marketposition=1 then
sell this bar on close;
DayChart -> openprice (at 09:30) and closeprice (at 15:50 in my case or in your case 16:00).
In order to use the closeprice (or near to it) of the day I have to enable IOG and add the timefilter.
The entry is calculated on a D1 information with a average holdingtime of 4-5 days I just changed the code from "next bar at market" to "this bar on close" and it had better result in backtest.
Now after it rejected the marketorder after marketclosed - the position is still open after the market opend today. I had to close it manually.
Market: US-Stocks
Exitstrategy as simple as:
condition1=c>o;
if condition1 and marketposition=1 then
sell this bar on close;
DayChart -> openprice (at 09:30) and closeprice (at 15:50 in my case or in your case 16:00).
In order to use the closeprice (or near to it) of the day I have to enable IOG and add the timefilter.
The entry is calculated on a D1 information with a average holdingtime of 4-5 days I just changed the code from "next bar at market" to "this bar on close" and it had better result in backtest.
Now after it rejected the marketorder after marketclosed - the position is still open after the market opend today. I had to close it manually.
I am not sure what this has to do with it?ps. trading was never designed for thin markets that have no volume.
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
a few things to consider:
1. your perspective is on the daily chart, but your operation (the closing order) is actually intrabar. ie intraday trading.
2. to get an order executed during the day, there are 2 methods you can use:
a) use IOG on daily chart
b) use 2 data streams... a daily chart as data2, and a shorter resolution as data1. You can execute your orders anytime on the intraday data1.
for more information on multi-data strategies,
see post #4
viewtopic.php?f=16&t=6929
1. your perspective is on the daily chart, but your operation (the closing order) is actually intrabar. ie intraday trading.
2. to get an order executed during the day, there are 2 methods you can use:
a) use IOG on daily chart
b) use 2 data streams... a daily chart as data2, and a shorter resolution as data1. You can execute your orders anytime on the intraday data1.
for more information on multi-data strategies,
see post #4
viewtopic.php?f=16&t=6929
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
This is in reference to your comment "...hope there are 2 ticks coming before it closes..."....I am not sure what this has to do with it?ps. trading was never designed for thin markets that have no volume.
When there is no trade in the market,
even the best strategy cannot make any money.
- Stan Bokov
- Posts: 963
- Joined: Dec 18 2009
- Has thanked: 367 times
- Been thanked: 302 times
Siscop - this is a very valid question. TJ - thanks for your help on this.
I have encountered this before, and studied it at length - there are nuances that make this seemingly logical and simple thing rather difficult to accomplish.
First, a little background on backtesting vs. real-time. Backtesting is a simulation of what "would have" happened, which tried to approach real-time in accuracy, so that you can see if your strategies are any good. In any simulation there are assumptions, which do not work in real-time. "This bar on close" works well in backtesting, because fills are assumed to happen instantly, which does not happen in real-time. In real-time there are all sorts of delays - transmission time, broker response time, internet speed, local and server computer speed, possible interruptions along the way, etc.
In real-time, MultiCharts closes a bar on two conditions - 1) the first tick of the next bar arrives, or 2) there are no ticks received for a particular time period. So, "this bar on close" will always happen in backtesting, but it has no chance of happening in real-time - by the time the bar is considered closed, the order is no longer valid, since the new bar already opened. You should use "next bar open" for intraday trading, which is essentially the same as "this bar close".
Now, what it appears you are trying to do is to exit at the end of the day. That is a whole other task altogether. There are a couple of ways to do this.
Solution 1
If you insist on keeping "this bar close" expression for end of day, you need to close the last bar of the day early, so that the order has time to process. This can be accomplished by doing 2 things.
1. Set the Exchange or Symbol Session a few minutes earlier than the actual closing time, which will stop your chart from ticking. However there will still be time to process your order.
2. There is a timeout setting in MultiCharts which forces your bar to close after no ticks are received for a pre-defined amount of time. By default it's 5 min (300 seconds). You can shorten that timeout to let's say 60 seconds, and your this bar close orders will be generated.
The above solution is not optimal, but it was the only way to do that until certain keywords were introduced.
Solution 2
In MC6, your script only recalculated based on "events", i.e. upon receiving new ticks. There was no way to make the script calculate if the symbol was not ticking. We introduced a keyword called "RecalcLastBarAfter", which forces your script to recalculate after a certain number of seconds. With this keyword you are no longer required to wait for a tick, and instead of waiting for the timeout as in Solution 1, you can simply force a recalculation, which can send your order after your bar is closed early.
1. Set the Exchange or Symbol Session a few minutes earlier than the actual closing time, which will stop your chart from ticking. However there will still be time to process your order.
2. Use RecalcLastBarAfter, which will recalc your script and send the order if appropriate.
I have encountered this before, and studied it at length - there are nuances that make this seemingly logical and simple thing rather difficult to accomplish.
First, a little background on backtesting vs. real-time. Backtesting is a simulation of what "would have" happened, which tried to approach real-time in accuracy, so that you can see if your strategies are any good. In any simulation there are assumptions, which do not work in real-time. "This bar on close" works well in backtesting, because fills are assumed to happen instantly, which does not happen in real-time. In real-time there are all sorts of delays - transmission time, broker response time, internet speed, local and server computer speed, possible interruptions along the way, etc.
In real-time, MultiCharts closes a bar on two conditions - 1) the first tick of the next bar arrives, or 2) there are no ticks received for a particular time period. So, "this bar on close" will always happen in backtesting, but it has no chance of happening in real-time - by the time the bar is considered closed, the order is no longer valid, since the new bar already opened. You should use "next bar open" for intraday trading, which is essentially the same as "this bar close".
Now, what it appears you are trying to do is to exit at the end of the day. That is a whole other task altogether. There are a couple of ways to do this.
Solution 1
If you insist on keeping "this bar close" expression for end of day, you need to close the last bar of the day early, so that the order has time to process. This can be accomplished by doing 2 things.
1. Set the Exchange or Symbol Session a few minutes earlier than the actual closing time, which will stop your chart from ticking. However there will still be time to process your order.
2. There is a timeout setting in MultiCharts which forces your bar to close after no ticks are received for a pre-defined amount of time. By default it's 5 min (300 seconds). You can shorten that timeout to let's say 60 seconds, and your this bar close orders will be generated.
The above solution is not optimal, but it was the only way to do that until certain keywords were introduced.
Solution 2
In MC6, your script only recalculated based on "events", i.e. upon receiving new ticks. There was no way to make the script calculate if the symbol was not ticking. We introduced a keyword called "RecalcLastBarAfter", which forces your script to recalculate after a certain number of seconds. With this keyword you are no longer required to wait for a tick, and instead of waiting for the timeout as in Solution 1, you can simply force a recalculation, which can send your order after your bar is closed early.
1. Set the Exchange or Symbol Session a few minutes earlier than the actual closing time, which will stop your chart from ticking. However there will still be time to process your order.
2. Use RecalcLastBarAfter, which will recalc your script and send the order if appropriate.
Thank you TJ and Stan.
I still think it would be much easier just to implement an entrybox that covers syncs with QM.
if ticktime>QM Endtime (16:00) - PreExitTime(user defined in seconds) then
"execute the this bar on close order"
The PreExitTime is an input just as in the screenshot. Instead of 30 sec the user can enter 600 (10min.) just to make sure that there are ticks coming in before the market closes.
Regarding your solution of setting the Endtime early in QM and upcoming from there the solution 1 and 2.
That is a nice workaround. I will do this and hope your Team might think about implementing this feature into a future MC release.
EDIT 12:45
I do understand where the problem here was. Normally on an Intradaycharts there is no gap between the close an the open of a new bar (or a very small one) so this doesn't make a difference. I also understand you when you say that you can only work with ticks coming in to run threw the loop (that was before RecalcLastBarAfter) and in normal condition the last tick of a daychart is the marketclose.
My request was for the DayChart where gaps come up very often so my statement of requesting a live trading execution on this bar on close should have meant a close on the end of the day.
I still think it would be much easier just to implement an entrybox that covers syncs with QM.
if ticktime>QM Endtime (16:00) - PreExitTime(user defined in seconds) then
"execute the this bar on close order"
The PreExitTime is an input just as in the screenshot. Instead of 30 sec the user can enter 600 (10min.) just to make sure that there are ticks coming in before the market closes.
Regarding your solution of setting the Endtime early in QM and upcoming from there the solution 1 and 2.
That is a nice workaround. I will do this and hope your Team might think about implementing this feature into a future MC release.
EDIT 12:45
I do understand where the problem here was. Normally on an Intradaycharts there is no gap between the close an the open of a new bar (or a very small one) so this doesn't make a difference. I also understand you when you say that you can only work with ticks coming in to run threw the loop (that was before RecalcLastBarAfter) and in normal condition the last tick of a daychart is the marketclose.
My request was for the DayChart where gaps come up very often so my statement of requesting a live trading execution on this bar on close should have meant a close on the end of the day.
- Attachments
-
- ExitOnClose.png
- (3.08 KiB) Downloaded 5148 times
- TJ
- Posts: 7775
- Joined: Aug 29 2006
- Location: Global Citizen
- Has thanked: 1036 times
- Been thanked: 2233 times
There is a keyword called SetExitOnClose.
It will flatten ALL positions at the end of the day.
Unfortunately it works in the same fashion as "Sell this Bar on Close".
It would be good to enhance the keyword with the following options:
SetExitOnClose( SessionNumber, PreExitTime);
where:
SessionNumber is the session that you want to exit,
and
PreExitTime is the time offset you want to post your exit order.
It will flatten ALL positions at the end of the day.
Unfortunately it works in the same fashion as "Sell this Bar on Close".
It would be good to enhance the keyword with the following options:
SetExitOnClose( SessionNumber, PreExitTime);
where:
SessionNumber is the session that you want to exit,
and
PreExitTime is the time offset you want to post your exit order.
- furytrader
- Posts: 354
- Joined: Jul 30 2010
- Location: Chicago, IL
- Has thanked: 155 times
- Been thanked: 217 times
Agreed, TJ's suggested enhancements to that function would be great.
- Stan Bokov
- Posts: 963
- Joined: Dec 18 2009
- Has thanked: 367 times
- Been thanked: 302 times
I see your points. Please add this as a feature request to PM.
Hi All,
I am struggling with the same problem. I trade in a market where continuous trading is between 09:00 and 16:50, then there is a 10 minute auction between 16:50 and 17:00 and then a final close price. Between 16:50 and 17:00 there will be no ticks as no trades go through.
Reading the information above, i see i am not alone in needing to close my position slightly before the end of the day. I am using RecalcLastbarAfter(5); in my code which will recalculate every 5 with or without new ticks coming in. Because no ticks are coming in, i have decided to use the system clock to see if the time is in the auction range. I am using the following code:
My question is that even if the code enters the if statement, when i place the trades at next bar, will that occur due to the RecalcLastbarAfter(5); or will it simply be at my session end 17:00 when it is too late, in which case do i still need to make my session end time a few minutes earlier?
I am struggling with the same problem. I trade in a market where continuous trading is between 09:00 and 16:50, then there is a 10 minute auction between 16:50 and 17:00 and then a final close price. Between 16:50 and 17:00 there will be no ticks as no trades go through.
Reading the information above, i see i am not alone in needing to close my position slightly before the end of the day. I am using RecalcLastbarAfter(5); in my code which will recalculate every 5 with or without new ticks coming in. Because no ticks are coming in, i have decided to use the system clock to see if the time is in the auction range. I am using the following code:
Code: Select all
RecalcLastbarAfter(5);
CurrTime = currenttime;
if(CurrTime > 1650 and StartFlag = False and EndFlag = True) then
begin
if (marketposition = -1) then
begin
buy absvalue(currentshares) shares next bar at market;
end
else if(marketposition = 1) then
begin
sell absvalue(currentshares) shares next bar at market;
end;
end;
- Dave Masalov
- Posts: 1712
- Joined: Apr 16 2010
- Has thanked: 51 times
- Been thanked: 490 times
dblend,
Please try to use PlaceMarketOrder keyword instead of buy next bar at market.
Try the following code:
Please try to use PlaceMarketOrder keyword instead of buy next bar at market.
Try the following code:
Code: Select all
RecalcLastbarAfter(5);
CurrTime = currenttime;
value1 = currentshares;
if(CurrTime > 1650 and StartFlag = False and EndFlag = True) then
begin
if (marketposition = -1) then
begin
if PlaceMarketOrder(True, True, value1) = True then
ChangeMarketPosition(value1, close, "Final Buy");
end
else if(marketposition = 1) then
begin
if PlaceMarketOrder(False, False, value1) = True then
ChangeMarketPosition(-value1, close, "Final Sell");
end;
end;
Some programs support the following built-in signal functions:
[1] SetStopEndofDay(time)
- This function closes the open positions at the specified time with the preset price.
- If time is 0, this feature is cancelled. Also if you do not provide time at all,
it will close positions on the today's close as usual.
- For this feature to work, IOG must be turned on.
- ex) SetStopEndofday(150130) will close the open positioins at 15:01:30.
[2] SetStopInactivity([minprice], [period], [method])
- ex) SetStopInactivity(2, 5, PercentStop) will close open positions if the price
does not move more than 2% after the positon entry
during the next 5 bars
Other users in this forum can add up all the other useful modifications for general usage.
[1] SetStopEndofDay(time)
- This function closes the open positions at the specified time with the preset price.
- If time is 0, this feature is cancelled. Also if you do not provide time at all,
it will close positions on the today's close as usual.
- For this feature to work, IOG must be turned on.
- ex) SetStopEndofday(150130) will close the open positioins at 15:01:30.
[2] SetStopInactivity([minprice], [period], [method])
- ex) SetStopInactivity(2, 5, PercentStop) will close open positions if the price
does not move more than 2% after the positon entry
during the next 5 bars
Other users in this forum can add up all the other useful modifications for general usage.
Hi 2haerim,
Thanks for the comments.
The functions SetStopEndofDay and SetStopInactivity do not seem to be supported by Multicharts.
Are you able to use them or are they 3rd party functions? These functions would be very useful and would solve my problem shown above.
I am finding using
gives me errors as for some reason. The use of currtime doesnt close my positions during that time and also makes backtesting impossible. Does anyone have any other alternatives to close all my days positions at a specified time when there is no tick data during that time period (auction period)
Thanks for the comments.
The functions SetStopEndofDay and SetStopInactivity do not seem to be supported by Multicharts.
Are you able to use them or are they 3rd party functions? These functions would be very useful and would solve my problem shown above.
I am finding using
Code: Select all
RecalcLastbarAfter(5);
CurrTime = currenttime;
value1 = currentshares;
if(CurrTime > 1650 and StartFlag = False and EndFlag = True) then
begin
if (marketposition = -1) then
begin
if PlaceMarketOrder(True, True, value1) = True then
ChangeMarketPosition(value1, close, "Final Buy");
end
else if(marketposition = 1) then
begin
if PlaceMarketOrder(False, False, value1) = True then
ChangeMarketPosition(-value1, close, "Final Sell");
end;
end;
- JoshM
- Posts: 2196
- Joined: May 20 2011
- Location: The Netherlands
- Has thanked: 1544 times
- Been thanked: 1565 times
- Contact:
Can the Name parameter of the ChangeMarketPosition keyword be changed programmatically depending on the type of ChangeMarketPosition() order is needed?dblend,
Please try to use PlaceMarketOrder keyword instead of buy next bar at market.
Try the following code:
Code: Select all
RecalcLastbarAfter(5);
CurrTime = currenttime;
value1 = currentshares;
if(CurrTime > 1650 and StartFlag = False and EndFlag = True) then
begin
if (marketposition = -1) then
begin
if PlaceMarketOrder(True, True, value1) = True then
ChangeMarketPosition(value1, close, "Final Buy");
end
else if(marketposition = 1) then
begin
if PlaceMarketOrder(False, False, value1) = True then
ChangeMarketPosition(-value1, close, "Final Sell");
end;
end;
For example, something like this:
Code: Select all
test = IffString(MarketPosition_at_Broker > 0,
Text("Buy @ ", NumToStr(AvgEntryPrice_at_Broker, numDeci)),
Text("SellShort @ ", NumToStr(AvgEntryPrice_at_Broker, numDeci)));
ChangeMarketPosition(MarketPosition_at_Broker - (MarketPosition(0) * CurrentContracts),
IFF(AvgEntryPrice_at_Broker = 0, Close, AvgEntryPrice_at_Broker),
test);
It seems to me that the Name parameter of ChangeMarketPosition() only remembers the first instance (i.e., therefore the SellShort orders are still termed Buy orders in the image).
- Attachments
-
- scr.29-01-2013 18.43.47.png
- (2.62 KiB) Downloaded 5834 times
- Henry MultiСharts
- Posts: 9165
- Joined: Aug 25 2011
- Has thanked: 1264 times
- Been thanked: 2958 times
Hello Josh,
That is correct.It seems to me that the Name parameter of ChangeMarketPosition() only remembers the first instance (i.e., therefore the SellShort orders are still termed Buy orders in the image).
That is not possible with the current implementation of ChangeMarketPosition. We will extend the functionality in one of the future versions by adding possibility to change the name parameter.Can the Name parameter of the ChangeMarketPosition keyword be changed programmatically depending on the type of ChangeMarketPosition() order is needed?