Posted 9/26/2010 21:37:01
|
|
|
|
When I was running backtesting, I noticed some weird behavior. Following are the data file:
datetime open high low close volume 08/24/2010 02:20:00,1061.75,1063.0,1061.75,1062.75,1340 08/24/2010 02:25:00,1063.0,1063.0,1062.5,1063.0,254 08/24/2010 02:30:00,1062.75,1062.75,1062.0,1062.5,1153 (note the order is different from the bar editor)
the strategy is very simple:
public override void NewBar() { OutputMessage("onBar: "+ Bars.Current.BarStartTime);
//if(Bars.Current.BarStartTime == new DateTime(2010, 8, 24, 2, 25, 0)){ OutputMessage("shorting. "); OpenPosition( PositionType.Short, OrderType.Limit, 1063, 1); //} return; }
public override void OrderFilled(Position position, Trade trade) { OutputMessage("order filled: "+ "Pos ID = "+position.ID + " "+ "Size = " +position.CurrentSize + " "+position.Type+", trade: "+ trade.TransactionType+" tradesize: "+trade.Size+ " at price: "+ trade.Price.AccountPrice +" time "+trade.FilledTime); }
public override void OrderCancelled(Position position, Order order, string information) { OutputMessage("order cancelled: "+ "Pos ID = "+position.ID + " "+ "Size = " +position.CurrentSize + " "+position.Type +", order: "+order.TransactionType+" "+order.OrderType+" "+order.LimitPrice);
}
The order was supposed to be filled at the 2:30:00 bar, but it's not. I can see that the limit short order was placed, because "shorting" was printed, and but it was cancelled at next bar, and not filled.
if I change the code a little bit, to take out the if statement:
public override void NewBar() { OutputMessage("onBar: "+ Bars.Current.BarStartTime);
//if(Bars.Current.BarStartTime == new DateTime(2010, 8, 24, 2, 25, 0)){ OutputMessage("shorting. "); OpenPosition( PositionType.Short, OrderType.Limit, 1063, 1); //} return; }
or change the limit price to 1062.75
public override void NewBar() { OutputMessage("onBar: "+ Bars.Current.BarStartTime);
if(Bars.Current.BarStartTime == new DateTime(2010, 8, 24, 2, 25, 0)){ OutputMessage("shorting. "); OpenPosition( PositionType.Short, OrderType.Limit, 1062.75, 1); } return; }
They all works.
Can you help me out? Thanks.
|
|
Posted 9/26/2010 21:58:10
|
|
|
|
Shorting is in the opposite direction of a long order. So while a limit buy order means "fill at the limit price or less", a limit short order means "fill at the limit price or greater."
If you actually do want a fill price of 1063 or less on a limit short order, then use a stop order.
Thanks,
Daniel
|
|
Posted 9/27/2010 18:00:50
|
|
|
|
Daniel,
Thanks for your reply.
I understand sellLimit is "fill at the limit price or greater".
From simulation point of view, if I placed sellLimit at 1063, and the high of that bar was 1063, volume is none-zero, then there is no reason that the order would not be filled, excluding the possibility of total position limit or capital limit.
I'm raising this issue because I implemented my strategy in both RightEdge and OpenQuant, and I found out that RightEdge matched OpenQuant on all other trades, but missed this one. I reproduced the issue in the test case.
Please, do a simple experiment on the data that I posted. Thanks.
|
|
Posted 9/27/2010 21:14:37
|
|
|
|
You are placing an order at the end of the 02:25:00 bar, so it is only eligible to be filled on the 02:30:00 bar, which has a high of 1062.75. The price of 1063 on the 02:25:00 bar has already passed when you submit the order.
I think the timing for OpenQuant's "New Bar" may be a bit different than RightEdge's, I think maybe it happens when a new bar opens, not after a bar has closed.
Daniel
|
|
Posted 9/28/2010 14:23:02
|
|
|
|
Daniel, you are absolutely right. It seems that I didn't create the test case correctly. I'll double check it this evening. Thanks.
dplaisted (9/27/2010) You are placing an order at the end of the 02:25:00 bar, so it is only eligible to be filled on the 02:30:00 bar, which has a high of 1062.75. The price of 1063 on the 02:25:00 bar has already passed when you submit the order.
I think the timing for OpenQuant's "New Bar" may be a bit different than RightEdge's, I think maybe it happens when a new bar opens, not after a bar has closed.
Daniel
|
|
Posted 9/29/2010 22:33:30
|
|
|
|
Daniel, the above test case was not correct.
But, There really is an issue. Still use the data I posted in the original post.
public override void NewBar()
{
OutputMessage("onBar: "+ Bars.Current.BarStartTime);
if(Bars.Current.BarStartTime == new DateTime(2010, 8, 24, 2, 20, 0)){
OutputMessage("shorting. ");
OpenPosition( PositionType.Short, OrderType.Limit, 1062.75, 1);
}
return;
}
public override void OrderFilled(Position position, Trade trade)
{
OutputMessage("order filled: "+ "Pos ID = "+position.ID + " "+ "Size = " +position.CurrentSize + " "+position.Type+", trade: "+ trade.TransactionType+" tradesize: "+trade.Size+ " at price: "+trade.Price.AccountPrice +" time "+trade.FilledTime);
}
Here I placed an order to sell limit at 1062.75 at the 2:25, which is the tailing edge of 2:20 bar. and the next bar has and open of 1063.
In this case, the order should be filled at 1063, but it's actually filled at 1062.75.
|
|
Posted 9/29/2010 23:52:50
|
|
|
|
For intraday bars we don't fill a gap up like that. The close of one bar should be close to the open of the next (on a liquid stock), and we assume that if the price moved through your limit/stop price that the order would be filled at that price, not the "gap up/down" price.
Here's another post which talks a bit about this: http://www.rightedgesystems.com/forums/Topic12266-9-1.aspx#bm12270
Thanks,
Daniel
|
|
Posted 9/30/2010 20:41:40
|
|
|
|
Daniel, probably you want to improve this a little bit for the following reasons:
1. The data I'm showing is e-mini ES, 0.25 is the minimum tick size. so 1063 and 1062.75 are adjacent.
2. Different from the other post you are referring, this is a limit order, a limit order of 1062.75 was placed at the end of one bar, and next bar starts at 1063, then filling the order at 1063 is closer to reality.
|
|
|
|