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 CreateOTO.

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);
  }

back