Create OTO Orders
You can create two or more entry orders and then join them into OTO (one-triggers-others) using just one call.
The first of the orders specified is a root order of the OTO group. This is the only order which becomes active immediately. All other orders are inactive until the root order is executed.
To create an OTO order group:
1) Create an IO2GValueMap
and fill only one field:
Valuemap field |
Datatype |
Description |
Command |
const char * |
The command. Must be The field is obligatory. |
2) Create an IO2GValueMap
for each entry order you want to create and
fill it as for a regular entry order.
3) Append each entry order valuemap to the main valuemap using the IO2GValueMap.appendChild
method. Always append the root order first. Instead of any of dependent orders you can also create another "CreateOTO"
command. In this case the root order of this additional OTO will become a dependent order of the root OTO, so, you can
create a tree of OTO orders of any level of hierarchy.
4) Pass the main valuemap
table to the createOrderRequest method.
Limitations:
1) Only entry orders or other OTO groups can be joined into OTO. However, entry orders with attached stops/limits, either regular or ELS, can be joined into OTO.
2) All entry orders must be created for the same account.
Returns:
The createOrderRequest method will return an IO2GRequest (the main request) containing child requests. If 3 entry orders are created, 3 child requests will be returned. Note that you will receive responses to the child requests and will not receive a response to the main request.
Example: Create an OTO order [hide]
void CExample::prepareParamsFromLoginRules(IO2GLoginRules *loginRules) { mParams = new OrderCreationParam(); O2G2Ptr<IO2GResponseReaderFactory> factory = mSession->getResponseReaderFactory(); // Get first account from login O2G2Ptr<IO2GResponse> accountsResponse = loginRules->getTableRefreshResponse(Accounts); O2G2Ptr<IO2GAccountsTableResponseReader> accountsReader = factory->createAccountsTableReader(accountsResponse); O2G2Ptr<IO2GAccountRow> account = accountsReader->getRow(0); // Store account id mParams->mAccountID = account->getAccountID(); // Store base amount mParams->mBaseAmount = account->getBaseUnitSize(); // Get offers for eur/usd O2G2Ptr<IO2GResponse> offerResponse = loginRules->getTableRefreshResponse(Offers); O2G2Ptr<IO2GOffersTableResponseReader> offersReader = factory->createOffersTableReader(offerResponse); for (int i = 0; i < offersReader->size(); i++) { O2G2Ptr<IO2GOfferRow> offer = offersReader->getRow(i); if (_stricmp(offer->getInstrument(), "EUR/USD") == 0) { mParams->mOfferID = offer->getOfferID(); mParams->mAsk = offer->getAsk(); mParams->mBid = offer->getBid(); mParams->mPointSize = offer->getPointSize(); break; } } } struct sOrderParams { std::string offerID; int amount; double rate; std::string buySell; std::string orderType; }; // Helper method for creating valueMap for one order IO2GValueMap* CExample::createOrder(const char* accountID, const char* offerID, double rate, int amount, const char* buySell, const char* orderType) { using namespace O2G2; O2G2Ptr<IO2GRequestFactory> factory = getRequestFactory(); IO2GValueMap* valuemap = factory->createValueMap(); valuemap->setString(Command, Commands::CreateOrder); // for OTO orders this field is not mandatory valuemap->setString(OrderType, orderType); valuemap->setString(AccountID, accountID); valuemap->setString(OfferID, offerID); valuemap->setString(BuySell, buySell); valuemap->setDouble(Rate, rate); valuemap->setInt(Amount, amount); return valuemap; } // Helper method for creating valueMap for one order IO2GValueMap* CExample::createOrder(const char* accountID, sOrderParams& params) { return createOrder(accountID, params.offerID.c_str(), params.rate, params.amount, params.buySell.c_str(), params.orderType.c_str()); } void CreateOrderSample::prepareAndCreateOTO(const char* accountID, const char* offerID, int baseAmount, double pointSize) { double rate = mParams->mAsk; sOrderParams orders[3]; orders[0].amount = orders[1].amount = orders[2].amount = 10 * baseAmount; orders[0].offerID = orders[1].offerID = orders[2].offerID = offerID; orders[0].buySell = O2G2::Buy; orders[0].orderType = O2G2::Orders::LimitEntry; orders[0].rate = rate + 50 * pointSize; orders[1].buySell = O2G2::Sell; orders[1].orderType = O2G2::Orders::StopEntry; orders[1].rate = orders[0].rate - 10 * pointSize; orders[2].buySell = O2G2::Buy; orders[2].orderType = O2G2::Orders::StopEntry; orders[2].rate = orders[0].rate + 20 * pointSize; IO2GValueMap* primary = createOrder(accountID, orders[0]); IO2GValueMap* secondary1 = createOrder(accountID, orders[1]); IO2GValueMap* secondary2 = createOrder(accountID, orders[2]); createOTO(primary, secondary1, secondary2); } void CreateOrderSample::createOTO(IO2GValueMap* primary, IO2GValueMap* secondary1, IO2GValueMap* secondary2) { using namespace O2G2; O2G2Ptr<IO2GRequestFactory> factory = mSession->getRequestFactory(); // create OTO command O2G2Ptr<IO2GValueMap> valuemap = factory->createValueMap(); valuemap->setString(Command, Commands::CreateOTO); // create primary order valuemap->appendChild(primary); // create two secondary orders valuemap->appendChild(secondary1); valuemap->appendChild(secondary2); // create request from valueMap O2G2Ptr<IO2GRequest> request = factory->createOrderRequest(valuemap); for (int i = 0; i < request->getChildrenCount(); i++) { O2G2Ptr<IO2GRequest> childRequest = request->getChildRequest(i); mActions[childRequest->getRequestID()] = deleteOrderAction; } mSession->sendRequest(request); }