checking status of limit orders
- Dave Masalov
- Posts: 1712
- Joined: 16 Apr 2010
- Has thanked: 51 times
- Been thanked: 489 times
Re: checking status of limit orders
Dear janus,
It is the only way to check if the limit order was filled from the code.
It is the only way to check if the limit order was filled from the code.
Re: checking status of limit orders
Not the news I was hoping for. I find it impossible to be sure in a study all the time that a limit order is completely filled when cover orders are also submitted in the same direction as the limit order. Oh well, can't have everything.
- Dave Masalov
- Posts: 1712
- Joined: 16 Apr 2010
- Has thanked: 51 times
- Been thanked: 489 times
Re: checking status of limit orders
Dear janus,
If you have a suggestion on how it can be realized, please post a feature request in Project Management.
If you have a suggestion on how it can be realized, please post a feature request in Project Management.
Re: checking status of limit orders
It is allready there, posted by me (MC-99 " Order execution control").Dear janus,
If you have a suggestion on how it can be realized, please post a feature request in Project Management.
I think it is minimal that traders need. Of cource it will be better to have orderstatus function
like OrderStatus(OrderName) and it returns string -filled,placed,paritally filled,canceled,pending or if no such order returns 0).
Re: checking status of limit orders
Yes, something like that would be ideal, if not essential for any serious trader.Of cource it will be better to have orderstatus function
like OrderStatus(OrderName) and it returns string -filled,placed,paritally filled,canceled,pending or if no such order returns 0).
Re: checking status of limit orders
Meanwhile I've stitched up this code to workaround the issue. I haven't tested it enough to be confident it works all the time - so far it's good. I'm going to test it with a pyramid strategy. I would be surprised if it does work all the time. Of course, more work has to be programmed when this workaround is to be used in a strategy. The more complex the strategy the harder it will be. Clearly, the only real solution is for MC to add the feature discussed earlier.
Code: Select all
[IntrabarOrderGeneration = True]
// Note: In Format Signal -> Intra-Bar Order Generation - set to "Allow unlimited entries and exits per bar", and
// Strategy Properties -> Properties - Allow up to a sufficiently large number of entry orders in the same
// direction as the currently held position, regardless of the entry that generated the order,
// with a suitable maximum shares/contracts per position
variables:
n(0), n1(0), n2(0), profit(0), max.lots(10), num.covered(0),
intrabarpersist posi(0), intrabarpersist qty(0), intrabarpersist num.to.fill(0),
intrabarpersist nlot(0), intrabarpersist delay(-1), intrabarpersist init.posi(0),
num.total(10), num.inc(2), intrabarpersist num.left(0), intrabarpersist exec.order(0),
intrabarpersist prev.posi(0);
arrays:
intrabarpersist entry.price[10](0), intrabarpersist entry.num[10](0), intrabarpersist sell.limit[10](False),
intrabarpersist sell.limit.sent[10](False), intrabarpersist exit.price[10](0), intrabarpersist buy.limit[10](False),
intrabarpersist buy.limit.sent[10](False);
once begin
cleardebug;
print ("Started simulation");
profit = 5; // number of points profit for each entry
num.left = 5; // number of contracts total to process
exec.order = 1; // test buy order(s) with corresponding sell limit order(s)
end;
if LastBarOnChart_s and getappinfo(aiStrategyAuto) = 1 and GetAppInfo(airealtimecalc) = 1 then begin // last bar and real-time
posi = MarketPosition_at_Broker; // current position
if ((posi >= 0 and prev.posi > 0) or (posi <= 0 and prev.posi < 0))
and absvalue(posi) < absvalue(prev.posi) then begin // contracts were reduced so a limit order must have been hit
num.covered = absvalue(prev.posi)-absvalue(posi); // number covered
print (num.covered:0:0, " contracts covered");
// look for the most likely limit order(s) that was(were) filled - lowest entry price for sell limits, highest for buy limits
while num.covered > 0 begin // loop until exact number covered are accounted for
n1 = 0;
n2 = 0;
for n = 1 to max.lots begin
if entry.num[n] > 0 then begin
if n1 = 0 or (prev.posi > 0 and entry.price[n] < n1) or (prev.posi < 0 and entry.price[n] > n1) then begin
n1 = entry.price[n];
n2 = n;
end;
end;
end;
if entry.num[n2] >= num.covered then begin // sufficient number in lot #n2 so terminate loop
entry.num[n2] = entry.num[n2] - num.covered; // reduce number for this lot
num.covered = 0; // terminate loop since all are now accounted for
end else begin // insufficient in lot #n2 so keep looping
num.covered = num.covered - entry.num[n2]; // adjust for remaining number covered
entry.num[n2] = 0; // clear this lot
end;
end;
end;
if nlot > 0 and num.to.fill > 0 and absvalue(posi) - absvalue(init.posi) >= num.to.fill then begin // requested number of contracts are filled
print ("Order filled for lot #",nlot:0:0);
if nlot = 1 then begin // 1st lot so store entry price
entry.price[1] = avgentryprice;
end else begin // 2nd or more lot so compute entry price of additional entries
n1 = 0;
n2 = 0;
for n = 1 to nlot-1 begin
n1 = n1 + entry.num[n] * entry.price[n];
n2 = n2 + entry.num[n];
end;
n2 = n2 + num.to.fill;
entry.price[nlot] = (avgentryprice*n2 - n1)/num.to.fill;
end;
entry.num[nlot] = num.to.fill; // number of contracts filled for this lot
if posi > 0 then exit.price[nlot] = entry.price[nlot] + profit; // sell limit to take profit on longs
if posi < 0 then exit.price[nlot] = entry.price[nlot] - profit; // buy limit to take profit on shorts
num.to.fill = 0; // all entries filled for this lot - prepare for the next lot to fill, if any
if posi > 0 then sell.limit[nlot] = True; // now long so set flag to send sell limit order for this lot
if posi < 0 then buy.limit[nlot] = True; // now short so set flag to send buy limit order for this lot
end;
if posi > 0 then begin // currently long so set or continue any sell limit order(s)
if sell.limit[1] then sell ("CL#1") from entry ("BL#1") next bar at exit.price[1] limit;
if sell.limit[2] then sell ("CL#2") from entry ("BL#2") next bar at exit.price[2] limit;
if sell.limit[3] then sell ("CL#3") from entry ("BL#3") next bar at exit.price[3] limit;
if sell.limit[4] then sell ("CL#4") from entry ("BL#4") next bar at exit.price[4] limit;
if sell.limit[5] then sell ("CL#5") from entry ("BL#5") next bar at exit.price[5] limit;
if sell.limit[6] then sell ("CL#6") from entry ("BL#6") next bar at exit.price[6] limit;
if sell.limit[7] then sell ("CL#7") from entry ("BL#7") next bar at exit.price[7] limit;
if sell.limit[8] then sell ("CL#8") from entry ("BL#8") next bar at exit.price[8] limit;
if sell.limit[9] then sell ("CL#9") from entry ("BL#9") next bar at exit.price[9] limit;
if sell.limit[10] then sell ("CL#10") from entry ("BL#10") next bar at exit.price[10] limit;
end else if posi < 0 then begin// currently short so set or continue any buy limit order(s)
if buy.limit[1] then buytocover ("CS#1") from entry ("SS#1") next bar at exit.price[1] limit;
if buy.limit[2] then buytocover ("CS#2") from entry ("SS#2") next bar at exit.price[2] limit;
if buy.limit[3] then buytocover ("CS#3") from entry ("SS#3") next bar at exit.price[3] limit;
if buy.limit[4] then buytocover ("CS#4") from entry ("SS#4") next bar at exit.price[4] limit;
if buy.limit[5] then buytocover ("CS#5") from entry ("SS#5") next bar at exit.price[5] limit;
if buy.limit[6] then buytocover ("CS#6") from entry ("SS#6") next bar at exit.price[6] limit;
if buy.limit[7] then buytocover ("CS#7") from entry ("SS#7") next bar at exit.price[7] limit;
if buy.limit[8] then buytocover ("CS#8") from entry ("SS#8") next bar at exit.price[8] limit;
if buy.limit[9] then buytocover ("CS#9") from entry ("SS#9") next bar at exit.price[9] limit;
if buy.limit[10] then buytocover ("CS#10") from entry ("SS#10") next bar at exit.price[10] limit;
end;
// check status of limit orders
for n = 1 to max.lots begin
// ?? if posi = 0 then sell.limit[n] = False; // reset if flat
// ?? if posi = 0 then sell.limit.sent[n] = False; // as above
if sell.limit[n] and not sell.limit.sent[n] then begin
print ("Sent new sell limit for lot #",n:0:0, " with price limit = ",exit.price[n]);
sell.limit.sent[n] = True; // avoids repeating the message
end;
end;
// start with one buy order, wait for it to be filled then send a sell limit order attached to it,
// then send another buy order, and again wait for it to be filled and also send another sell limit order attached to it. Keep doing this until all
// required contracts are bought.
qty = 0;
if num.to.fill = 0 and num.left > 0 and delay <= 0 then begin // outstanding contracts to process
if delay = 0 and delay[1] > 0 then print ("delay has expired");
nlot = nlot + 1; // lot number
if nlot > max.lots then begin // too many lots
print ("WARMING: reached maximum number of allowed lots; ",num.left:0:0, " contracts remaining - ignored");
num.left = 0; // ignore the remaining contracts
end else begin
print ("buying lot #", nlot:0:0);
if num.left >= num.inc then begin
qty = num.inc; // qty to process for this lot
num.left = num.left - num.inc; // reduce the number of contracts left to process; could be the last
end else begin // less than a lot size left to process so adjust
qty = num.left; // qty to process for this lot
num.left = 0; // this is the last lot; no more left to process after this one
end;
if exec.order = 1 then begin // buy long order
if nlot = 1 then buy ("BL#1") qty contracts next bar at market;
if nlot = 2 then buy ("BL#2") qty contracts next bar at market;
if nlot = 3 then buy ("BL#3") qty contracts next bar at market;
if nlot = 4 then buy ("BL#4") qty contracts next bar at market;
if nlot = 5 then buy ("BL#5") qty contracts next bar at market;
if nlot = 6 then buy ("BL#6") qty contracts next bar at market;
if nlot = 7 then buy ("BL#7") qty contracts next bar at market;
if nlot = 8 then buy ("BL#8") qty contracts next bar at market;
if nlot = 9 then buy ("BL#9") qty contracts next bar at market;
if nlot = 10 then buy ("BL#10") qty contracts next bar at market;
sell.limit[nlot] = False; // reset flag
sell.limit.sent[nlot] = False; // reset flag
end else if exec.order = 2 then begin // sell short order
if nlot = 1 then sellshort ("SS#1") qty contracts next bar at market;
if nlot = 2 then sellshort ("SS#2") qty contracts next bar at market;
if nlot = 3 then sellshort ("SS#3") qty contracts next bar at market;
if nlot = 4 then sellshort ("SS#4") qty contracts next bar at market;
if nlot = 5 then sellshort ("SS#5") qty contracts next bar at market;
if nlot = 6 then sellshort ("SS#6") qty contracts next bar at market;
if nlot = 7 then sellshort ("SS#7") qty contracts next bar at market;
if nlot = 8 then sellshort ("SS#8") qty contracts next bar at market;
if nlot = 9 then sellshort ("SS#9") qty contracts next bar at market;
if nlot = 10 then sellshort ("SS#10") qty contracts next bar at market;
buy.limit[nlot] = False; // reset flag
buy.limit.sent[nlot] = False; // reset flag
end;
num.to.fill = qty; // number of contracts expecting to be filled for this lot
init.posi = posi; // current position size; will wait when position size >= this + number to fill for this lot
end;
delay = 0; // introduce a delay (# ticks) between successive lots; 0 = no delay
end;
if delay > 0 then delay = delay - 1;
prev.posi = posi;
end;