TT CORE SDK

Receiving Solicited and Unsolicited Order / Fill Events

Receiving Solicited and Unsolicited Order / Fill Events

To receive solicited and unsolicited order / fill events, you need to:

  • Create a class that is derived from ttsdk::IOrderBookEventHandler and defines your Order Book event handler.
    • You must provide implementations for the following methods:
      • virtual void OnExecutionReport(OrderPtr order, ExecutionReportPtr execRpt) = 0;
        • Callback fired when delivering execution report messages
      • virtual void OnReject(OrderPtr order, RejectResponsePtr rejResp) = 0;
        • Callback fired when delivering order reject messages
      • virtual void OnSendFailed(OrderPtr order, const OrderProfile& profile, const SendCode code) = 0;
        • Callback fired when a request delivery surpasses the timeout threshold
      • virtual void OnUnsubscribed(const char* orderId) = 0;
        • Callback fired when the unsubscribe request is complete and it is safe to destroy the handler object
    • You can also optionally provide implementations for the following methods:
      • virtual void OnPositionUpdate(const Position& updatedPosition) {};
        • Callback delivering position updates
      • virtual void OnAccountDownloadEnd(const uint64_t accountId) {};
        • Callback indicating that the given account has been synchronized with the real time streams, and orders and positions have been downloaded.
      • virtual void OnAccountDownloadFailed(const uint64_t accountId, const char* message) {};
        • Callback indicating that the given account’s orders and positions downloads have failed and the account is not usable.
      • virtual void OnOrderBookDownloadEnd() {};
        • Callback indicating that all orders and positions for all accounts are downloaded and synchronized with the real time stream.
    • Initialize the TT Core SDK passing your TTSDKOptions instance variable, your SDK event handler instance variable, and your Order Book event handler instance variable.
      • Note that both the SDK and Order Book event handlers must have a lifespan that is valid for the life of the SDK (until shutdown is completed).

An OnAccountDownloadEnd event is fired when an account is ready to be used for trading. And an OnOrderBookDownloadEnd event is fired when all accounts are ready.

The following code snippet demonstrates an example of this process.



#include 
#include 
#include 
#include 
#include 
#include 
#include 

std::mutex mutex;
std::condition_variable sdkReadyCondition;

//
//  SDK event handler class
//

class SDKEventHandler : public ttsdk::IEventHandler
{
  public:
      SDKEventHandler() : IEventHandler() {}
      virtual ~SDKEventHandler() {}

      // received on an SDK managed thread that can be used for processing.
      // beware that time consuming tasks can delay the delivery of another status event.

      virtual void OnStatus(const ttsdk::IEventHandler::Status status) override
      {
          std::cout << "SDKEventHandler::OnStatus (" << (uint32_t)status << ")" << std::endl;
      }
};

//
//  Order Book event handler class
//

class MyOrderBookHandler : public ttsdk::IOrderBookEventHandler
{
  public:
    MyOrderBookHandler() : IOrderBookEventHandler() {};
    virtual ~MyOrderBookHandler() {};

    virtual void OnExecutionReport(ttsdk::OrderPtr order, 
              ttsdk::ExecutionReportPtr execRpt) override
    {
      // ...
    }
    virtual void OnReject(ttsdk::OrderPtr order, ttsdk::RejectResponsePtr rejResp) override
    {
      // ...
    }
    virtual void OnSendFailed(ttsdk::OrderPtr order, const ttsdk::OrderProfile& profile, 
const SendCode code) override
    {
      // ...
    }
    virtual void OnUnsubscribed(const char* orderId) override
    {
      // ...
    }

    // account and book sync events are sent on the position thread so they are sequenced
    // properly with the position update events

    virtual void OnOrderBookDownloadEnd() override
    {
      std::cout << "---All assigned accounts are ready to use." << std::endl;
      std::lock_guard lock(mutex);
      sdkReadyCondition.notify_one();
    }
    
    // the SDK synchronizes the order book and positions by account.  as such, 
    // any given account can be able to trade without needing to wait 
    // for all accounts to be ready

    virtual void OnAccountDownloadEnd(const uint64_t accountId) override
    {
      std::cout << "---Account accountId:" << accountId 
              << " is synchronized and ready to use." << std::endl;
    }
    virtual void OnAccountDownloadFailed(const uint64_t accountId, const char* msg) override
    {
      std::cout << "---Account accountId:" << accountId <<" download failed details: " 
              << msg << std::endl;
    }

    // all position events are received on the SDK position processing thread. 
    // holding up processing for a given position event will impact all 
    // subsequent position updates

    virtual void OnPositionUpdate(const ttsdk::Position& updatedPosition) override
    {
      std::cout << "---OnPositionUpdate for AccountId:" << updatedPosition.account_id 
              << " Instrument:" << updatedPosition.instrument->GetAlias() << std::endl;
      std::cout << " SOD:" << updatedPosition.sod_quantity << "@" 
              << updatedPosition.sod_price 
              << " Buys:" <<  updatedPosition.buy_quantity << "@" 
              << updatedPosition.buy_average_price 
              << " Sells:" << updatedPosition.sell_quantity << "@" 
              << updatedPosition.sell_average_price
              << " Net:" << updatedPosition.net_position 
              << " P/L:" << updatedPosition.native_currency_pnl 
              << " AvgPrc:" << updatedPosition.open_average_price 
              << std::endl;
    }
};

//
//  Main
//

int main(int argc, char* argv[])
{
  //Set the environment the app needs to run in here
  ttsdk::Environment env = ttsdk::Environment::ProdLive;

  // Add your app secret Key here. It looks like:
00000000-0000-0000-0000-000000000000:00000000-0000-0000-0000-000000000000
  std::string app_key = “Your App Key”;

  ttsdk::TTSDKOptions options;
  options.environment = env;
  options.app_key_secret = app_key.c_str();

  SDKEventHandler myObserver;
  MyOrderBookHandler myOrderBookObserver;
    
  if (!ttsdk::Initialize(options, &myObserver, &myOrderBookObserver))
  {
    std::cout << "Unable to initialize SDK!" << std::endl;
    return -1;
  }  

  std::unique_lock lock(mutex);
  if (sdkReadyCondition.wait_for(lock, std::chrono::seconds(300)) == std::cv_status::timeout)
  {
    std::cout << "Timeout waiting for SDK to initialize!" << std::endl;
    return -1;
  }

  std::cout << std::endl;
  std::cout << "<<<<< TT CORE SDK is initialized. >>>>>" << std::endl;

  std::cout << std::endl << "Press q to exit....." << std::endl;
  std::string command;
  while (std::cin >> command)
  {
    if (command == "q")
    {
      std::cout << "Quitting...\n";
      break;
    }
  }
  std::cout << "Exiting..." << std::endl;
  ttsdk::Shutdown();
}