TT CORE SDK

Processing External Algo Requests

Processing External Algo Requests

OnStartRequest()

There are several ways to design a mechanism to launch algos within your process. One such approach is to first create a pure virtual base class that defines the semantics for managing the algo. For example:


#pragma once
#include <sdkalgo.h>
class BaseStrategy
{
  public:
    BaseStrategy() {};
    virtual ~BaseStrategy() {};

    // handle the requests from the TT SDK
    virtual bool Start(ttsdk::SDKAlgoPtr algoOrder, ttsdk::SDKAlgoRequestPtr req) = 0;
    virtual void Update(ttsdk::SDKAlgoRequestPtr req) = 0;
    virtual void Stop(ttsdk::SDKAlgoRequestPtr req) = 0;
    virtual void Pause(ttsdk::SDKAlgoRequestPtr req) = 0;
    virtual void Resume(ttsdk::SDKAlgoRequestPtr req) = 0;
};

Each algo would then be defined by a class which derives from and provides implementation for:

  • BaseStrategy
    • virtual bool Start(ttsdk::SDKAlgoPtr algoOrder, ttsdk::SDKAlgoRequestPtr req) = 0;
    • virtual void Update(ttsdk::SDKAlgoRequestPtr req) = 0;
    • virtual void Stop(ttsdk::SDKAlgoRequestPtr req) = 0;
    • virtual void Pause(ttsdk::SDKAlgoRequestPtr req) = 0;
    • virtual void Resume(ttsdk::SDKAlgoRequestPtr req) = 0;
  • ttsdk::IPriceEventHandler
    • virtual void OnUnsubscribed(const uint64_t subId);
    • virtual void OnDisconnect(const uint64_t subId, const ttsdk::InstrumentPtr&, const ttsdk::PriceEventType);
    • virtual void OnPriceUpdate(const uint64_t, const ttsdk::InstrumentPtr&, const ttsdk::PriceSnap& snap);
    • virtual void OnError(const uint64_t subId, const ttsdk::InstrumentPtr& instrument, const ttsdk::SubscriptionError code, const char* error);
  • ttsdk::IOrderEventHandler
    • virtual void OnUnsubscribed(const char*);
    • virtual void OnExecutionReport(ttsdk::OrderPtr order, ttsdk::ExecutionReportPtr execRpt);
    • virtual void OnReject(ttsdk::OrderPtr order, ttsdk::RejectResponsePtr rejResp);
    • virtual void OnSendFailed(ttsdk::OrderPtr order, const ttsdk::OrderProfile& profile, const ttsdk::IOrderEventHandler::SendCode code);

For Example:


class TrailingCrossStrategy : public BaseStrategy, 
    public ttsdk::IOrderEventHandler,
    public ttsdk::IPriceEventHandler
    {
    public:
    TrailingCrossStrategy(SDKAlgoManager& mgr)
        {   //  …  }
    virtual ~TrailingCrossStrategy()
        {   //  …  }

    //  from BaseStrategy
    virtual bool Start(ttsdk::SDKAlgoPtr algoOrder, ttsdk::SDKAlgoRequestPtr req)
        {   //  …  }
    virtual void Update(ttsdk::SDKAlgoRequestPtr req)
        {   //  …  }
    virtual void Stop(ttsdk::SDKAlgoRequestPtr req)
        {   //  …  }
    virtual void Pause(ttsdk::SDKAlgoRequestPtr req)
        {   //  …  }
    virtual void Resume(ttsdk::SDKAlgoRequestPtr req)
        {   //  …  }

    // from ttsdk::IPriceEventHandler
    virtual void OnUnsubscribed(const uint64_t subId)
        {   //  …  }
    virtual void OnDisconnect(const uint64_t subId, const ttsdk::InstrumentPtr&, const ttsdk::PriceEventType)
        {   //  …  }
    virtual void OnPriceUpdate(const uint64_t, const ttsdk::InstrumentPtr&, const ttsdk::PriceSnap& snap)
        {   //  …  }
    virtual void OnError(const uint64_t subId, const ttsdk::InstrumentPtr& instrument, const ttsdk::SubscriptionError code, const char* error)
        {   //  …  }

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

We can then add a collection to store instances of the algos being launched to the SDKAlgoManager class.


class SDKAlgoManager : public ttsdk::ISDKAlgoManager
    {
    //  …

    protected:
    mutable std::mutex mutexStrategies_;
    std::map< std::string, std::shared_ptr > strategies_;
    };

The SDKAlgoManager::OnStartRequest() method would then be written as follows.

void SDKAlgoManager::OnStartRequest(ttsdk::SDKAlgoPtr algoOrder, 
ttsdk::SDKAlgoRequestPtr req)
    {
    auto algo = algoOrder->GetAlgoDefinition();

    if (strncmp(algo->GetName(), "TrailingXSDKAlgo", sizeof(algo->GetName())) == 0)
        {
        std::shared_ptr strategy(new TrailingCrossStrategy(*this));
        if (strategy->Start(algoOrder, req))
            {
            std::unique_lock lock(mutexStrategies_);
            strategies_.insert(std::make_pair(req->GetOrderId(), strategy));
            }
        }
    else if (strncmp(algo->GetName(), "StrikerAlgo", sizeof(algo->GetName())) == 0)
        {
        std::shared_ptr strategy(new StrikerAlgo(*this));
        if (strategy>Start(algoOrder, req))
            {
            std::unique_lock lock(mutexStrategies_);
            strategies_.insert(std::make_pair(req->GetOrderId(), strategy));
            }
        }
    else
        {
        //  …
        }
    }

OnUpdateRequest()

Once an algo has been started, external update messages are forwarded to it from the TT UI as follows:


void SDKAlgoManager::OnUpdateRequest(ttsdk::SDKAlgoPtr algoOrder, 
ttsdk::SDKAlgoRequestPtr req)
{
    std::shared_ptr strategy(nullptr);
    {
        std::unique_lock lock(this->mutexStrategies_);
        auto iter = strategies_.find(algoOrder->GetOrderId());
        if (iter != strategies_.end())
        {
            strategy = iter->second;
        }
    }
    if (strategy)
    {
        return strategy->Update(req);
    }
}

OnStopRequest()

Once an algo has been started, external stop messages are forwarded to it from the TT UI as follows:


void SDKAlgoManager::OnStopRequest(ttsdk::SDKAlgoPtr algoOrder, 
ttsdk::SDKAlgoRequestPtr req)
{
    std::shared_ptr strategy(nullptr);
    {
        std::unique_lock lock(this->mutexStrategies_);
        auto iter = strategies_.find(algoOrder->GetOrderId());
        if (iter != strategies_.end())
        {
            strategy = iter->second;
        }
    }
    if (strategy)
    {
        return strategy->Stop(req);
    }
}
 

OnPauseRequest()

Once an algo has been started, external pause messages are forwarded to it from the TT UI as follows:


void SDKAlgoManager::OnPauseRequest(ttsdk::SDKAlgoPtr algoOrder, 
ttsdk::SDKAlgoRequestPtr req)
{
    std::shared_ptr strategy(nullptr);
    {
        std::unique_lock lock(this->mutexStrategies_);
        auto iter = strategies_.find(algoOrder->GetOrderId());
        if (iter != strategies_.end())
        {
            strategy = iter->second;
        }
    }
    if (strategy)
    {
        return strategy->Pause(req);
    }
}

OnResumeRequest()

Once an algo has been started, external resume messages are forwarded to it from the TT UI as follows:


void SDKAlgoManager::OnResumeRequest(ttsdk::SDKAlgoPtr algoOrder, 
ttsdk::SDKAlgoRequestPtr req)
{
    std::shared_ptr strategy(nullptr);
    {
        std::unique_lock lock(this->mutexStrategies_);
        auto iter = strategies_.find(algoOrder->GetOrderId());
        if (iter != strategies_.end())
        {
            strategy = iter->second;
        }
    }
    if (strategy)
    {
        return strategy->Resume(req);
    }
}