Create OCO Orders

You can create two or more entry orders and then join them into OCO using just one call.

To create an OCO order:

1) Create an IO2GValueMap and specify only one parameter:

Parameter name

Datatype

Description

Command

const char *

The command. Must be CreateOCO.

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 value map to the main value map using the IO2GValueMap.appendChild method.

4) Pass the main IO2GValueMap to the IO2GRequestFactory.createOrderRequest method.

Limitations:

1) Only entry orders can be joined into OCO. However, entry orders with attached stops/limits, either regular or ELS, can be joined into OCO.

2) All entry orders must be created for the same account.

Returns:

The createOrderRequest method will return the list of request IDs for each entry order created. So, if 3 entry orders are created - 3 request IDs separated by commas (,) will be returned. Moreover, if any of the orders is an ELS order, 3 request IDs will be returned per each ELS order inside the OCO.

Example: Create an OCO order [hide]

  void CreateOrderSample::prepareParamsFromLoginRules(IO2GLoginRules *loginRules)
  {
      mParams = new OrderCreationParam();
 
      O2G2Ptr<IO2GResponseReaderFactory> factory = mSession->getResponseReaderFactory();
      // Gets 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;
          }
      }
 
  }
 
  void CreateOrderSample::prepareParamsAndCallOCOOrders(const char *offerID, const char *accountID, int amount, double pointSize, const char * buySell)
  {
      bool bBuy = strcmp(buySell, O2G2::Buy) == 0;
      double rate = bBuy ? mParams->mAsk : mParams->mBid;
      double amendment = 5 * pointSize;
      if (strcmp(buySell, O2G2::Buy) == 0)
          rate -= amendment;
      else
          rate += amendment;
      createOCO(offerID, accountID, amount, rate, buySell, 3);
  }
 
  void CreateOrderSample::createOCO(const char *offerID, const char *accountID, int amount, double rate, const char * buySell, int iOrdersCount)
  {
      using namespace O2G2;
      O2G2Ptr<IO2GRequestFactory> factory = mSession->getRequestFactory();
 
      O2G2Ptr<IO2GValueMap> mainValueMap = factory->createValueMap();
      mainValueMap->setString(Command, Commands::CreateOCO);
      for (int i = 0; i < iOrdersCount; i++)
      {
          O2G2Ptr<IO2GValueMap> valuemap = factory->createValueMap();
          valuemap->setString(Command, Commands::CreateOrder);
          valuemap->setString(OrderType, Orders::LimitEntry);
          valuemap->setString(AccountID, accountID);          // The identifier of the account the order should be placed for.
          valuemap->setString(OfferID, offerID);              // The identifier of the instrument the order should be placed for.
          valuemap->setString(BuySell, buySell);              // The order direction ("B" for buy, "S" for sell)
          valuemap->setDouble(Rate, rate);                    // The rate at which the order must be filled (below current rate for Buy, above current rate for Sell)
          valuemap->setInt(Amount, amount);                   // The quantity of the instrument to be bought or sold.
 
          char customID[32];
          sprintf_s(customID, 32, "OCO_LimitEntry_N%d", i + 1);
 
          valuemap->setString(CustomID, customID); // The custom identifier of the order.
          mainValueMap->appendChild(valuemap);
      }
 
      O2G2Ptr<IO2GRequest> request = factory->createOrderRequest(mainValueMap);
      for (int i = 0; i < request->getChildrenCount(); i++)
      {
          O2G2Ptr<IO2GRequest> childRequest = request->getChildRequest(i);
          mActions[childRequest->getRequestID()] = deleteOrderAction;
      }
      mSession->sendRequest(request);
  }

back