ascent wrote:1. Place an order to buy or sell at market, simultaneously with a stop and limit order attached that is OCO, such that execution of the stop or limit cancels the other.
I think, OCO is not the best solution for risk management on US (FIFO) accounts. I'd recommend you to use
ELS (Entry Limit Stop).
To create ELS order, use exactly the same way as for regular Stop/Limit orders (i.e. just attach Stops and Limits to Entry or Market order), but specify the EntryLimitStop flag.
Please see the example on how to open a position with Stop/Limit (ELS) below. This is a snippet from the standrad MA_Advisor.lua strategy.
- Code: Select all
function Update()
if not(init) then
CANCLOSE = core.host:execute("getTradingProperty", "canCreateMarketClose", TICKSRC:instrument(), ACCOUNT);
init = true;
...
end
...
end
-- the method enters to the market
function enter(side)
local valuemap;
valuemap = core.valuemap();
valuemap.OrderType = "OM";
valuemap.OfferID = OFFER;
valuemap.AcctID = ACCOUNT;
valuemap.Quantity = AMOUNT;
valuemap.CustomID = CID;
valuemap.BuySell = side;
if STOP >= 1 then
valuemap.PegTypeStop = "O";
if side == "B" then
valuemap.PegPriceOffsetPipsStop = -STOP;
else
valuemap.PegPriceOffsetPipsStop = STOP;
end
if USE_TRAILING_STOP then
valuemap.TrailStepStop = 1;
end
end
if LIMIT >= 1 then
valuemap.PegTypeLimit = "O";
if side == "B" then
valuemap.PegPriceOffsetPipsLimit = LIMIT;
else
valuemap.PegPriceOffsetPipsLimit = -LIMIT;
end
end
if (not CANCLOSE) and (STOP >= 1 or LIMIT >= 1) then
valuemap.EntryLimitStop = 'Y'
end
success, msg = terminal:execute(200, valuemap);
assert(success, msg);
end
ascent wrote:2. Over the course of the trade, modify the stop order, and possibly the limit order using code.
Please see the function below. To change Stop (from ELS group), specify "SE" in the OrderType parameter. To change Limit order, specify "LE".
Note that the it is supposed that you have only one Stop and Limit per instrument. If you have a few Stops/Limits, you should define which of them should be modified (need to introduce additional parameter in the function, e.g. CurrentOrderPrice).
- Code: Select all
function ChangeStopLimit(OrderType, Instrument, OrderPrice)
enum = core.host:findTable("orders"):enumerator();
while true do
row = enum:next();
if row == nil then
break;
end
if row.Type == OrderType and -- OrderType must be equal to SE or LE.
row.Instrument == Instrument and
row.ContingencyType == 3 then
-- order found
local valuemap;
valuemap = core.valuemap();
valuemap.Command = "EditOrder";
valuemap.OrderID = row.OrderID;
valuemap.AcctID= row.AccountID;
valuemap.Rate = OrderPrice;
success, msg = terminal:execute(200, valuemap);
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "Failed create limit " .. msg, instance.bid:date(NOW));
end
end
end
end
ascent wrote:3. Also, if the initial order is closed for whatever reason not related to the stop or limit, the limit and stop orders are also canceled.
ELS order (Stop/Limit on US account) will be automatically removed by the system in case the positions have been closed (that is, when there are no any positions on the instrument).