Issues with limit entry orders (v8.8 build 8593)
Posted: May 10 2014
I have spent the past few days testing the use of limit entry orders for TF futures in my IB simulated account. I have gotten some very unexpected results.
Brief notes on how my signal works: all my entries are currently on stops, but my setups do not include trading breakouts. My main code implements entries by firing off a market order when price hits a trigger level defined by a trend line. After entry, the main code and a trailing stop signal manage the trade (setting and executing targets, setting and moving stops, etc.).
In six months I have never had an entry failure using market orders. Not one. In the past few weeks, however, for some reason slippage issues have gotten worse. For months I averaged 2.2 ticks per contract (entry + exit). I trade two contracts and take the 1st off at 1.3 - 2.0 points depending upon market structure. The 2nd is a runner. Lately average slippage has increased to > 3.0 with one instance of 8 ticks of slippage on the first contract this week (1 on entry / 7 on exit!).
Asynchronous mode test results:
Here's a stripped down version of the main code. This test code still contains the sections for handling the trendlines because it's easier to do repeated tests by simply starting and stopping automation without having to enter entry prices using Format Objects>Signal>Format.
Brief notes on how my signal works: all my entries are currently on stops, but my setups do not include trading breakouts. My main code implements entries by firing off a market order when price hits a trigger level defined by a trend line. After entry, the main code and a trailing stop signal manage the trade (setting and executing targets, setting and moving stops, etc.).
In six months I have never had an entry failure using market orders. Not one. In the past few weeks, however, for some reason slippage issues have gotten worse. For months I averaged 2.2 ticks per contract (entry + exit). I trade two contracts and take the 1st off at 1.3 - 2.0 points depending upon market structure. The 2nd is a runner. Lately average slippage has increased to > 3.0 with one instance of 8 ticks of slippage on the first contract this week (1 on entry / 7 on exit!).
Asynchronous mode test results:
- 1. High percentage of failed entries (15%-20%). The MC position shows as entered but no actual entry occurs at IB.
2. Occasional (5%-10%) entries of > specified position size (i.e., multiple orders executed)
- 1. High percentage of failed entries (15%-20%). The MC position shows as entered but no actual entry occurs at IB.
2. Frequent (50%+) entries of > specified position size (i.e., multiple orders executed).
Here's a stripped down version of the main code. This test code still contains the sections for handling the trendlines because it's easier to do repeated tests by simply starting and stopping automation without having to enter entry prices using Format Objects>Signal>Format.
Code: Select all
{*******************************************************************************************************************************************************************
Name : $Limit_Entry_Order_Test
Description : Execution using limit orders for entry
Last Modified Date : 05/08/2014 --
*******************************************************************************************************************************************************************}
{ system parameter section }
[IntrabarOrderGeneration = true];
[RecoverDrawings = false];
[LegacyColorValue = true];
{*******************************************************************************************************************************************************************
inputs and variable initialization section
*******************************************************************************************************************************************************************}
inputs:
StartTime (0930), { time after which trades can be executed }
EODCloseTime (1600), { close positions eod }
Target_1_Contracts (1), { contracts taken off at target 1 }
PlannedSlippage (0.0), { a positive value here will result in positive slippage }
Use_Limit_Orders (true); { true = use limit entry orders / false = use market entry orders }
variables:
LinePlotLength (40), { length of trend line plotted to right of last price bar }
LongEntryColor (darkgreen), { match trendline colors and line style to order type }
ShortEntryColor (red), { match trendline colors and line style to order type }
EntryStyle (tool_solid),
LineEndTime (0),
LineStartTime (0),
ID (0),
intrabarpersist FirstTrade (true), { used to limit execution to a single trade }
intrabarpersist LE_Initial_Price (0), { initial long entry at the top of the page }
intrabarpersist SE_Initial_Price (0), { initial short entry at the bottom of the page }
intrabarpersist int ID_LE (0), { trendline ID for long entry }
intrabarpersist int ID_SE (0), { trendline ID for short entry }
intrabarpersist TradePeriod (false), { period during which trades are permitted }
intrabarpersist LE_Trigger (0), { trigger level for long entry }
intrabarpersist SE_Trigger (0), { trigger level for short entry }
intrabarpersist myShortEntry (0), { intialize short entry }
intrabarpersist myLongEntry (9999), { intialize long entry }
intrabarpersist PositionSize (0), { calculated position size }
Line_Entry_Long (-1),
Line_Entry_Short (-1);
arrays:
intrabarpersist int BDate[2] (0), { BDate[n] = beginning date for TL number n }
intrabarpersist int BTime[2] (0), { BTime[n] = beginning time for TL number n }
intrabarpersist int TL_Value[2] (0); { TL_Value[n] = TL value at BDate + BTime n }
{*******************************************************************************************************************************************************************
perform one-time intializations
*******************************************************************************************************************************************************************}
once begin
PositionSize = Target_1_Contracts;
end;
{*******************************************************************************************************************************************************************
initialize entry trend lines
*******************************************************************************************************************************************************************}
if date = currentdate and LastBarOnChart then once begin { this loop is only entered once per automation }
{ initially place entry trigger trend lines above and below current price }
LE_Initial_Price = round(GetAppInfo(aiHighestDispValue) - 3.0, 1); { gets the top of the chart screen }
SE_Initial_Price = round(GetAppInfo(aiLowestDispValue) + 3.0, 1); { gets the bottom of the chart screen }
{ set trend line plot start and end values for entry lines }
LineStartTime = (Calctime(time,+15));
LineEndTime = (Calctime(LineStartTime,+LinePlotLength));
{ plot trendlines }
Line_Entry_Long = TL_New(date,LineStartTime,LE_Initial_Price,date,LineEndTime,LE_Initial_Price);
TL_setstyle(Line_Entry_Long,EntryStyle);
TL_setcolor(Line_Entry_Long,LongEntryColor);
Line_Entry_Short = TL_New(date,LineStartTime,SE_Initial_Price,date,LineEndTime,SE_Initial_Price);
TL_setstyle(Line_Entry_Short,EntryStyle);
TL_setcolor(Line_Entry_Short,ShortEntryColor);
end;
{*******************************************************************************************************************************************************************
find trendlines and and their associated parameters
*******************************************************************************************************************************************************************}
if LastBarOnChart then begin
RecalcLastBarAfter(1);
{ trendlines: get ID, begin date, begin time, and value for the long and short entry trendlines }
begin
ID = TL_GetFirst(1); { get signal-created TLs only }
while ID > 0 begin
if TL_GetColor(ID) = LongEntryColor and TL_GetStyle(ID) = EntryStyle then begin { long entry trend line }
ID_LE = ID;
BDate[1] = TL_GetBeginDate(ID);
BTime[1] = TL_GetBeginTime(ID);
TL_Value[1] = TL_GetValue(ID, Date, Time);
end;
if TL_GetColor(ID) = ShortEntryColor and TL_GetStyle(ID) = EntryStyle then begin { short entry trend line }
ID_SE = ID;
BDate[2] = TL_GetBeginDate(ID);
BTime[2] = TL_GetBeginTime(ID);
TL_Value[2] = TL_GetValue(ID, Date, Time);
end;
ID = TL_GetNext(ID, 1); { only signal-created tls}
end;
end;
end;
{*******************************************************************************************************************************************************************
perform these calculations for each tick
*******************************************************************************************************************************************************************}
if marketposition <> 0 then FirstTrade = false; { upon entry set FirstTrade to false so there is only one trade per automation cycle }
LE_Trigger = round(TL_Value[1],1); { set long entry trigger price to TL value }
SE_Trigger = round(TL_Value[2],1); { set short entry trigger price to TL value }
myLongEntry = LE_Trigger - PlannedSlippage; { adjust entry level with desired slippage }
myShortEntry = SE_Trigger + PlannedSlippage; { adjust entry level with desired slippage }
{*******************************************************************************************************************************************************************
entries execution section
*******************************************************************************************************************************************************************}
TradePeriod = date = currentdate and time > StartTime and time <= EODCloseTime; { define trading period }
if LastBarOnChart and FirstTrade and TradePeriod and marketposition = 0 then begin
if Use_Limit_Orders then begin { use limit orders }
if close >= LE_Trigger then { price break above entry level triggers limit order }
buy ("LE") PositionSize shares next bar at myLongEntry limit;
if close <= SE_Trigger then
sellshort ("SE") PositionSize shares next bar at myShortEntry limit; { price break below entry level triggers limit order }
end
else begin { use market orders }
if close >= LE_Trigger then { price break above entry level triggers limit order }
buy ("LE") PositionSize shares next bar at market;
if close <= SE_Trigger then
sellshort ("SE") PositionSize shares next bar at market; { price break below entry level triggers limit order }
end;
end;