← source index

src/OrderEntryItem.h

108 lines  ·  3.6 K  ·  cpp
#pragma once
#include "../Include.h"

#include <nlohmann/json.hpp>

enum class EntrySide
{
    BID,
    ASK,

    __NONE__,
    __LAST__
};

class OrderEntryItem
{
public:
    OrderEntryItem() {}
    OrderEntryItem(const nlohmann::json& json)
    {
        if(json.empty()) return;

        if(json.contains("type")) mOrderEntryData.type = json["type"];
        if(json.contains("symbol")) mOrderEntryData.symbol = json["symbol"];

        //I am reversing here so when i emplace_back into order array it will be in the exact order it arrives from the venue
        if(json.contains("changes"))
        {
            for (auto it = json["changes"].rbegin(); it != json["changes"].rend(); ++it)
            {
                const auto& entry = *it;
                L2Changes changes;

                std::string s = entry[0].get<std::string>();
                std::string p = entry[1].get<std::string>();
                std::string q = entry[2].get<std::string>();

                changes.side     = (s == "buy" ? EntrySide::BID : s == "sell" ? EntrySide::ASK : EntrySide::__NONE__);
                changes.price    = std::stod(p);
                changes.quantity = std::stod(q);

                mOrderEntryData.changes.emplace_back(changes);
            }
        }

        if(json.contains("trades"))
        {
            const auto& jsonTrades = json["trades"];

            for (auto it = jsonTrades.rbegin(); it != jsonTrades.rend(); ++it)
            {
                const auto& entryTd = *it;
                TradesData td;

                if(entryTd.contains("type"))         td.type = entryTd["type"].get<std::string>();
                if(entryTd.contains("symbol"))       td.symbol = entryTd["symbol"].get<std::string>();
                if(entryTd.contains("eventid"))      td.eventid = entryTd["eventid"].get<unsigned long>();
                if(entryTd.contains("timestamp"))    td.timestamp = entryTd["timestamp"].get<unsigned long>();
                if(entryTd.contains("price"))        td.price = std::stod(entryTd["price"].get<std::string>());
                if(entryTd.contains("quantity"))     td.quantity = std::stod(entryTd["quantity"].get<std::string>());
                if(entryTd.contains("side"))         td.side = (entryTd["side"].get<std::string>() == "buy" ? EntrySide::BID : 
                                                                entryTd["side"].get<std::string>() == "sell" ? EntrySide::ASK :
                                                                EntrySide::__NONE__);
                if(entryTd.contains("tid"))          td.tid = entryTd["tid"].get<unsigned long>();

                mTradesEntries.emplace_back(td);
            }
        }
    }

    struct TradesData
    {
        std::string type;
        std::string symbol;
        unsigned long eventid;
        unsigned long timestamp;
        double price;
        double quantity;
        EntrySide side;
        unsigned long tid;
    };

    struct L2Changes
    {
        EntrySide side;
        double price;
        double quantity;
    };

    struct L2Data
    {
        std::string type;
        std::string symbol;
        std::vector<L2Changes> changes;
    };

    const L2Data& getL2Data() const { return mOrderEntryData; };
    const std::vector<TradesData>& getTradesEntries() const { return mTradesEntries; };

    OrderEntryItem(const OrderEntryItem&) = delete;
    OrderEntryItem& operator=(const OrderEntryItem&) = delete;
    OrderEntryItem(OrderEntryItem&& other) = default;
    OrderEntryItem& operator=(OrderEntryItem&& other) = default;

private:
    std::vector<TradesData> mTradesEntries;
    L2Data mOrderEntryData;
};