12 files modified
1 files deleted
| | |
| | | --- |
| | | BasedOnStyle: LLVM |
| | | IndentWidth: 4 |
| | | TabWidth: 4 |
| | | UseTab: AlignWithSpaces |
| | | AllowShortIfStatementsOnASingleLine: true |
| | | BreakBeforeBraces: Linux |
| | | IndentCaseLabels: false |
| | | PointerAlignment: Left |
| | | AllowShortIfStatementsOnASingleLine: true |
| | | IndentCaseBlocks: true |
| | | IndentCaseLabels: false |
| | | SortUsingDeclarations: true |
| | | SortUsingDeclarations: true |
| | |
| | | { |
| | | Order::Order(double price, OrderSideEnum side, int volume, double timestamp, |
| | | std::string id) |
| | | : price{price}, side{side}, remaining_volume{volume}, |
| | | filled_volume(0), timestamp{timestamp}, id{id} |
| | | : price{price}, side{side}, remaining_volume{volume}, |
| | | filled_volume(0), timestamp{timestamp}, id{id} |
| | | { |
| | | } |
| | | |
| | | Level::Level(Order& order) |
| | | : price{order.price}, volume(order.remaining_volume), side{order.side}, |
| | | timestamp{order.timestamp}, id{order.id} |
| | | : price{order.price}, volume(order.remaining_volume), side{order.side}, |
| | | timestamp{order.timestamp}, id{order.id} |
| | | { |
| | | } |
| | | |
| | | bool operator<(const Level& a, const Level& b) |
| | | { |
| | | if (a.price < b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp > b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | if (a.price < b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp > b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | } |
| | | |
| | | bool operator>(const Level& a, const Level& b) |
| | | { |
| | | if (a.price > b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp > b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | if (a.price > b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp > b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | } |
| | | |
| | | bool operator<=(const Level& a, const Level& b) |
| | | { |
| | | if (a.price <= b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp >= b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | if (a.price <= b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp >= b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | } |
| | | |
| | | bool operator>=(const Level& a, const Level& b) |
| | | { |
| | | if (a.price >= b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp >= b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | if (a.price >= b.price) |
| | | return true; |
| | | else if (a.price == b.price && (a.timestamp >= b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | } |
| | | |
| | | bool operator==(const Level& a, const Level& b) |
| | | { |
| | | if (a.price == b.price && (a.timestamp == b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | if (a.price == b.price && (a.timestamp == b.timestamp)) |
| | | return true; |
| | | else |
| | | return false; |
| | | } |
| | | |
| | | std::ostream& operator<<(std::ostream& out, const Level& a) |
| | | { |
| | | return out << "Price: " << a.price << ", volume: " << a.volume |
| | | << ", time: " << a.timestamp << ", id: " << a.id; |
| | | return out << "Price: " << a.price << ", volume: " << a.volume |
| | | << ", time: " << a.timestamp << ", id: " << a.id; |
| | | } |
| | | |
| | | Book::Book() |
| | | : bidSide(), askSide(), productType(TEST), product("a"), stationId(7), |
| | | unit("c"), expiry(std::chrono::nanoseconds(0)), aggFee(1), pasFee(-1), |
| | | broFee(2) |
| | | : bidSide(), askSide(), productType(TEST), product("a"), stationId(7), |
| | | unit("c"), expiry(std::chrono::nanoseconds(0)), aggFee(1), pasFee(-1), |
| | | broFee(2) |
| | | { |
| | | } |
| | | |
| | | Book::Book(ProductTypeEnum productType, std::string product, |
| | | int stationId, std::string unit, |
| | | std::chrono::nanoseconds expiry, double aggFee, double pasFee, |
| | | double broFee) |
| | | : bidSide{}, askSide{}, productType{productType}, product(product), |
| | | stationId(stationId), unit(unit), expiry(expiry), aggFee(aggFee), |
| | | pasFee(pasFee), broFee(broFee) |
| | | Book::Book(ProductTypeEnum productType, std::string product, int stationId, |
| | | std::string unit, std::chrono::nanoseconds expiry, double aggFee, |
| | | double pasFee, double broFee) |
| | | : bidSide{}, askSide{}, productType{productType}, product(product), |
| | | stationId(stationId), unit(unit), expiry(expiry), aggFee(aggFee), |
| | | pasFee(pasFee), broFee(broFee) |
| | | { |
| | | } |
| | | |
| | | void Book::ask(Order& order) |
| | | { |
| | | while (this->bidSide.size() && this->bidSide[0].price >= order.price) { |
| | | if (this->bidSide[0].volume > order.remaining_volume) { |
| | | int temp = this->bidSide[0].volume; |
| | | order.filled_volume += temp; |
| | | this->bidSide.front().volume -= order.remaining_volume; |
| | | order.remaining_volume -= temp; |
| | | break; |
| | | } else { |
| | | order.remaining_volume -= this->bidSide[0].volume; |
| | | order.filled_volume += this->bidSide[0].volume; |
| | | this->bidSide.erase(this->bidSide.begin()); |
| | | std::make_heap(this->bidSide.begin(), this->bidSide.end(), |
| | | std::less<Level>()); |
| | | while (this->bidSide.size() && this->bidSide[0].price >= order.price) { |
| | | if (this->bidSide[0].volume > order.remaining_volume) { |
| | | int temp = this->bidSide[0].volume; |
| | | order.filled_volume += temp; |
| | | this->bidSide.front().volume -= order.remaining_volume; |
| | | order.remaining_volume -= temp; |
| | | break; |
| | | } else { |
| | | order.remaining_volume -= this->bidSide[0].volume; |
| | | order.filled_volume += this->bidSide[0].volume; |
| | | this->bidSide.erase(this->bidSide.begin()); |
| | | std::make_heap(this->bidSide.begin(), this->bidSide.end(), |
| | | std::less<Level>()); |
| | | } |
| | | } |
| | | } |
| | | if (order.remaining_volume > 0) { |
| | | this->askSide.emplace(this->askSide.begin(), order); |
| | | std::make_heap(this->askSide.begin(), this->askSide.end(), |
| | | std::greater<Level>()); |
| | | } |
| | | if (order.remaining_volume > 0) { |
| | | this->askSide.emplace_back(order); |
| | | std::make_heap(this->askSide.begin(), this->askSide.end(), |
| | | std::greater<Level>()); |
| | | } |
| | | } |
| | | |
| | | void Book::bid(Order& order) |
| | | { |
| | | while (this->askSide.size() && this->askSide[0].price <= order.price) { |
| | | if (this->askSide[0].volume > order.remaining_volume) { |
| | | int temp = this->askSide.front().volume; |
| | | order.filled_volume += temp; |
| | | this->askSide.front().volume -= order.remaining_volume; |
| | | order.remaining_volume -= temp; |
| | | break; |
| | | } else { |
| | | order.remaining_volume -= this->askSide[0].volume; |
| | | order.filled_volume += this->askSide[0].volume; |
| | | this->askSide.erase(this->askSide.begin()); |
| | | std::make_heap(this->askSide.begin(), this->askSide.end(), |
| | | std::greater<Level>()); |
| | | while (this->askSide.size() && this->askSide[0].price <= order.price) { |
| | | if (this->askSide[0].volume > order.remaining_volume) { |
| | | int temp = this->askSide.front().volume; |
| | | order.filled_volume += temp; |
| | | this->askSide.front().volume -= order.remaining_volume; |
| | | order.remaining_volume -= temp; |
| | | break; |
| | | } else { |
| | | order.remaining_volume -= this->askSide[0].volume; |
| | | order.filled_volume += this->askSide[0].volume; |
| | | this->askSide.erase(this->askSide.begin()); |
| | | std::make_heap(this->askSide.begin(), this->askSide.end(), |
| | | std::greater<Level>()); |
| | | } |
| | | } |
| | | } |
| | | if (order.remaining_volume > 0) { |
| | | this->bidSide.emplace(this->bidSide.begin(), order); |
| | | std::make_heap(this->bidSide.begin(), this->bidSide.end(), |
| | | std::less<Level>()); |
| | | } |
| | | if (order.remaining_volume > 0) { |
| | | this->bidSide.emplace_back(order); |
| | | std::make_heap(this->bidSide.begin(), this->bidSide.end(), |
| | | std::less<Level>()); |
| | | } |
| | | } |
| | | |
| | | void Book::printBook(std::size_t numOrders) |
| | | { |
| | | std::cout << "Sell side: " << this->askSide.size() << std::endl; |
| | | std::vector<Level> askCopy(this->askSide); |
| | | std::size_t count = 0; |
| | | std::sort(askCopy.begin(), askCopy.end()); |
| | | for (auto i = askCopy.rbegin(); i != askCopy.rend() && count < numOrders; i++, count++) { |
| | | std::cout << *i << std::endl; |
| | | } |
| | | std::cout << "Buy side: " << this->bidSide.size() << std::endl; |
| | | std::vector<Level> bidCopy(this->bidSide); |
| | | count = 0; |
| | | std::sort(bidCopy.begin(), bidCopy.end()); |
| | | for (auto i = bidCopy.rbegin(); i != bidCopy.rend() && count < numOrders; i++, count++) { |
| | | std::cout << *i << std::endl; |
| | | } |
| | | } |
| | | std::cout << "Sell side: " << this->askSide.size() << std::endl; |
| | | std::vector<Level> askCopy(this->askSide); |
| | | std::size_t count = 0; |
| | | std::sort(askCopy.begin(), askCopy.end()); |
| | | std::reverse(askCopy.begin(), askCopy.end()); |
| | | uint64_t volume = 0; |
| | | double price = askCopy.front().price; |
| | | for (auto i : askCopy) { |
| | | std::cout << i << std::endl; |
| | | count++; |
| | | if (count > numOrders) break; |
| | | } |
| | | std::cout << "Buy side: " << this->bidSide.size() << std::endl; |
| | | std::vector<Level> bidCopy(this->bidSide); |
| | | count = 0; |
| | | std::sort(bidCopy.begin(), bidCopy.end()); |
| | | std::reverse(bidCopy.begin(), bidCopy.end()); |
| | | price = bidCopy.front().price; |
| | | for (auto i : bidCopy) { |
| | | std::cout << i << std::endl; |
| | | count++; |
| | | if (count > numOrders) break; |
| | | } |
| | | } |
| | | |
| | | Book testBook(int orders, bool printBook) |
| | | { |
| | | Book b = Book(); |
| | | double time(1); |
| | | for (int i = 1; i < orders; i++) { |
| | | Order t(i, Buy, 10, time++, "a"); |
| | | b.bid(t); |
| | | } |
| | | for (int i = orders + 1; i < 2 * orders; i++) { |
| | | Order t(i, Sell, 10, time++, "b"); |
| | | b.ask(t); |
| | | } |
| | | if (printBook) b.printBook(orders - 1); |
| | | return b; |
| | | Book b = Book(); |
| | | double time(1); |
| | | for (int i = 1; i < orders; i++) { |
| | | Order t(i, Buy, 10, time++, "a"); |
| | | b.bid(t); |
| | | } |
| | | for (int i = orders + 1; i < 2 * orders; i++) { |
| | | Order t(i, Sell, 10, time++, "b"); |
| | | b.ask(t); |
| | | } |
| | | if (printBook) b.printBook(orders - 1); |
| | | return b; |
| | | } |
| | | } // namespace book |
| | |
| | | enum ProductTypeEnum { TEST, FUTURE, SPREAD, CALL, PUT }; |
| | | |
| | | struct Order { |
| | | double price; |
| | | OrderSideEnum side; |
| | | int remaining_volume; |
| | | int filled_volume; |
| | | double timestamp; |
| | | std::string id; |
| | | Order(double price, OrderSideEnum side, int volume, double timestamp, |
| | | std::string id); |
| | | double price; |
| | | OrderSideEnum side; |
| | | int remaining_volume; |
| | | int filled_volume; |
| | | double timestamp; |
| | | std::string id; |
| | | Order(double price, OrderSideEnum side, int volume, double timestamp, |
| | | std::string id); |
| | | }; |
| | | |
| | | struct Level { |
| | | double price; |
| | | int volume; |
| | | OrderSideEnum side; |
| | | double timestamp; |
| | | std::string id; |
| | | double price; |
| | | int volume; |
| | | OrderSideEnum side; |
| | | double timestamp; |
| | | std::string id; |
| | | |
| | | Level(Order& order); |
| | | Level(Order& order); |
| | | }; |
| | | |
| | | bool operator>(const Level& a, const Level& b); |
| | |
| | | std::ostream& operator<<(std::ostream& out, const Level& a); |
| | | |
| | | struct Book { |
| | | std::vector<Level> bidSide; |
| | | std::vector<Level> askSide; |
| | | ProductTypeEnum productType; |
| | | std::string product; |
| | | int stationId; |
| | | std::string unit; |
| | | std::chrono::nanoseconds expiry; |
| | | double aggFee; |
| | | double pasFee; |
| | | double broFee; |
| | | std::vector<Level> bidSide; |
| | | std::vector<Level> askSide; |
| | | ProductTypeEnum productType; |
| | | std::string product; |
| | | int stationId; |
| | | std::string unit; |
| | | std::chrono::nanoseconds expiry; |
| | | double aggFee; |
| | | double pasFee; |
| | | double broFee; |
| | | |
| | | Book(); |
| | | Book(ProductTypeEnum productType, std::string product, |
| | | int stationId, std::string unit, |
| | | std::chrono::nanoseconds expiry, double aggFee, double pasFee, |
| | | double broFee); |
| | | void ask(Order& order); |
| | | void bid(Order& order); |
| | | void printBook(std::size_t numOrders = 10); |
| | | Book(); |
| | | Book(ProductTypeEnum productType, std::string product, int stationId, |
| | | std::string unit, std::chrono::nanoseconds expiry, double aggFee, |
| | | double pasFee, double broFee); |
| | | void ask(Order& order); |
| | | void bid(Order& order); |
| | | void printBook(std::size_t numOrders = 10); |
| | | }; |
| | | |
| | | Book testBook(int orders = 10, bool printBook = true); |
| | |
| | | #include "strat.hpp" |
| | | |
| | | int main(void) |
| | | { |
| | | |
| | | } |
| | | int main(void) {} |
| | |
| | | |
| | | void initialise() |
| | | { |
| | | mapClick = {{"BUY", Buy}, {"SELL", Sell}, {"FLASH", Flash}, |
| | | {"b", Buy}, {"s", Sell}, {"f", Flash}, |
| | | {"B", Buy}, {"S", Sell}, {"F", Flash}}; |
| | | mapClick = {{"BUY", Buy}, {"SELL", Sell}, {"FLASH", Flash}, |
| | | {"b", Buy}, {"s", Sell}, {"f", Flash}, |
| | | {"B", Buy}, {"S", Sell}, {"F", Flash}}; |
| | | } |
| | | |
| | | void usage() |
| | | { |
| | | std::cout << "DESCRIPTION" << std::endl |
| | | << "Click trader using same algs" << std::endl |
| | | << std::endl |
| | | << "USAGE" << std::endl |
| | | << "\t-a product" << std::endl |
| | | << "\t-t click type (buy, sell, flash)" << std::endl |
| | | << "\t-p price" << std::endl |
| | | << "\t-v volume" << std::endl |
| | | << "\t-i id" << std::endl |
| | | << "Always need product, need side, price and volume for " |
| | | "adding/flash, need id for deleting" |
| | | << std::endl; |
| | | std::cout << "DESCRIPTION" << std::endl |
| | | << "Click trader using same algs" << std::endl |
| | | << std::endl |
| | | << "USAGE" << std::endl |
| | | << "\t-a product" << std::endl |
| | | << "\t-t click type (buy, sell, flash)" << std::endl |
| | | << "\t-p price" << std::endl |
| | | << "\t-v volume" << std::endl |
| | | << "\t-i id" << std::endl |
| | | << "Always need product, need side, price and volume for " |
| | | "adding/flash, need id for deleting" |
| | | << std::endl; |
| | | } |
| | | |
| | | int main(int argc, char** argv) |
| | | { |
| | | int c; |
| | | std::string product, id; |
| | | double price; |
| | | clickType click; |
| | | uint64_t volume; |
| | | initialise(); |
| | | if (argc == 1) { |
| | | usage(), exit(0); |
| | | } |
| | | while ((c = getopt(argc, argv, "a::t::p::v::i::")) != -1) { |
| | | switch (c) { |
| | | case 'a': |
| | | product = std::string(optarg); |
| | | break; |
| | | case 's': |
| | | click = mapClick[optarg]; |
| | | break; |
| | | case 'p': |
| | | price = std::stod(optarg); |
| | | break; |
| | | case 'v': |
| | | volume = std::stoll(optarg); |
| | | break; |
| | | case 'i': |
| | | id = std::string(optarg); |
| | | break; |
| | | case '?': |
| | | default: |
| | | usage(); |
| | | exit(0); |
| | | int c; |
| | | std::string product, id; |
| | | double price; |
| | | clickType click; |
| | | uint64_t volume; |
| | | initialise(); |
| | | if (argc == 1) { |
| | | usage(), exit(0); |
| | | } |
| | | } |
| | | switch (click) { |
| | | case Buy: |
| | | case Sell: |
| | | case Flash:; |
| | | } |
| | | while ((c = getopt(argc, argv, "a::t::p::v::i::")) != -1) { |
| | | switch (c) { |
| | | case 'a': |
| | | product = std::string(optarg); |
| | | break; |
| | | case 's': |
| | | click = mapClick[optarg]; |
| | | break; |
| | | case 'p': |
| | | price = std::stod(optarg); |
| | | break; |
| | | case 'v': |
| | | volume = std::stoll(optarg); |
| | | break; |
| | | case 'i': |
| | | id = std::string(optarg); |
| | | break; |
| | | case '?': |
| | | default: |
| | | usage(); |
| | | exit(0); |
| | | } |
| | | } |
| | | switch (click) { |
| | | case Buy: |
| | | case Sell: |
| | | case Flash:; |
| | | } |
| | | } |
| | |
| | | |
| | | void initialise() |
| | | { |
| | | mapTypes = {{"FUTURE", FUTURE_TYPE}, |
| | | {"SPREAD", SPREAD_TYPE}, |
| | | {"CALL", CALL_TYPE}, |
| | | {"PUT", PUT_TYPE}, |
| | | {"SETTLEMENT", SETTLEMENT}, |
| | | {"ADDED", ADDED}, |
| | | {"DELETED", DELETED}, |
| | | {"TRADE", TRADE}, |
| | | {"BROKER_REQUEST", BROKER_REQUEST}, |
| | | {"BROKER_ACK", BROKER_ACK}, |
| | | {"BROKER_CONFIRM", BROKER_CONFIRM}}; |
| | | mapTypes = {{"FUTURE", FUTURE_TYPE}, |
| | | {"SPREAD", SPREAD_TYPE}, |
| | | {"CALL", CALL_TYPE}, |
| | | {"PUT", PUT_TYPE}, |
| | | {"SETTLEMENT", SETTLEMENT}, |
| | | {"ADDED", ADDED}, |
| | | {"DELETED", DELETED}, |
| | | {"TRADE", TRADE}, |
| | | {"BROKER_REQUEST", BROKER_REQUEST}, |
| | | {"BROKER_ACK", BROKER_ACK}, |
| | | {"BROKER_CONFIRM", BROKER_CONFIRM}}; |
| | | |
| | | mapAnnounce = {{FUTURE_TYPE, book::FUTURE}, |
| | | {SPREAD_TYPE, book::SPREAD}, |
| | | {CALL_TYPE, book::CALL}, |
| | | {PUT_TYPE, book::PUT}}; |
| | | mapAnnounce = {{FUTURE_TYPE, book::FUTURE}, |
| | | {SPREAD_TYPE, book::SPREAD}, |
| | | {CALL_TYPE, book::CALL}, |
| | | {PUT_TYPE, book::PUT}}; |
| | | |
| | | mapOrder = {{"BUY", book::Buy}, {"SELL", book::Sell}}; |
| | | mapOrder = {{"BUY", book::Buy}, {"SELL", book::Sell}}; |
| | | |
| | | mapTrade = {{"BUY_AGGRESSOR", BUY_AGGRESSOR}, |
| | | {"SELL_AGGRESSOR", SELL_AGGRESSOR}}; |
| | | mapTrade = {{"BUY_AGGRESSOR", BUY_AGGRESSOR}, |
| | | {"SELL_AGGRESSOR", SELL_AGGRESSOR}}; |
| | | |
| | | mapOrderSide = {{book::Buy, "BUY"}, {book::Sell, "SELL"}}; |
| | | mapOrderSide = {{book::Buy, "BUY"}, {book::Sell, "SELL"}}; |
| | | } |
| | | |
| | | Message* parseSingle(rapidjson::Value& d); |
| | |
| | | |
| | | std::queue<Message*> parse(std::string& str) |
| | | { |
| | | std::queue<Message*> out; |
| | | rapidjson::Document d; |
| | | d.Parse(str.c_str()); |
| | | if (d.IsArray()) { |
| | | for (rapidjson::SizeType i = 0; i < d.Size(); i++) { |
| | | out.push(parseSingle(d[i])); |
| | | std::queue<Message*> out; |
| | | rapidjson::Document d; |
| | | d.Parse(str.c_str()); |
| | | if (d.IsArray()) { |
| | | for (rapidjson::SizeType i = 0; i < d.Size(); i++) { |
| | | out.push(parseSingle(d[i])); |
| | | } |
| | | } else { |
| | | out.push(parseSingle(d)); |
| | | } |
| | | } else { |
| | | out.push(parseSingle(d)); |
| | | } |
| | | return out; |
| | | return out; |
| | | } |
| | | |
| | | Message* parseSingle(rapidjson::Value& d) |
| | | { |
| | | if (mapTypes.empty()) { |
| | | initialise(); |
| | | } |
| | | Message* out; |
| | | switch (mapTypes[d["type"].GetString()]) { |
| | | case FUTURE_TYPE: |
| | | case SPREAD_TYPE: |
| | | case CALL_TYPE: |
| | | case PUT_TYPE: |
| | | out = announce(d); |
| | | break; |
| | | case SETTLEMENT: |
| | | out = settle(d); |
| | | break; |
| | | case ADDED: |
| | | out = added(d); |
| | | break; |
| | | case DELETED: |
| | | out = deleted(d); |
| | | break; |
| | | case TRADE: |
| | | out = trade(d); |
| | | break; |
| | | case BROKER_REQUEST: |
| | | out = brokerReq(d); |
| | | break; |
| | | case BROKER_ACK: |
| | | out = brokerAck(d); |
| | | break; |
| | | case BROKER_CONFIRM: |
| | | out = brokerCon(d); |
| | | break; |
| | | default: |
| | | out = new Message(NONE, ""); |
| | | break; |
| | | } |
| | | return out; |
| | | if (mapTypes.empty()) { |
| | | initialise(); |
| | | } |
| | | Message* out; |
| | | switch (mapTypes[d["type"].GetString()]) { |
| | | case FUTURE_TYPE: |
| | | case SPREAD_TYPE: |
| | | case CALL_TYPE: |
| | | case PUT_TYPE: |
| | | out = announce(d); |
| | | break; |
| | | case SETTLEMENT: |
| | | out = settle(d); |
| | | break; |
| | | case ADDED: |
| | | out = added(d); |
| | | break; |
| | | case DELETED: |
| | | out = deleted(d); |
| | | break; |
| | | case TRADE: |
| | | out = trade(d); |
| | | break; |
| | | case BROKER_REQUEST: |
| | | out = brokerReq(d); |
| | | break; |
| | | case BROKER_ACK: |
| | | out = brokerAck(d); |
| | | break; |
| | | case BROKER_CONFIRM: |
| | | out = brokerCon(d); |
| | | break; |
| | | default: |
| | | out = new Message(NONE, ""); |
| | | break; |
| | | } |
| | | return out; |
| | | } |
| | | |
| | | AnnounceMessage* announce(rapidjson::Value& d) |
| | | { |
| | | // std::stringstream expiryStream(d["expiry"].GetString()); |
| | | std::chrono::nanoseconds exp_time(0); |
| | | // expiryStream >> |
| | | // date::parse("%Y-%m-%f %H:%M%z", exp_time); // Parsing is broken |
| | | return new AnnounceMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["stationId"].GetInt(), d["stationName"].GetString(), |
| | | d["unit"].GetString(), exp_time, d["aggressiveFee"].GetDouble(), |
| | | d["passiveFee"].GetDouble(), d["brokerFee"].GetDouble(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | // std::stringstream expiryStream(d["expiry"].GetString()); |
| | | std::chrono::nanoseconds exp_time(0); |
| | | // expiryStream >> |
| | | // date::parse("%Y-%m-%f %H:%M%z", exp_time); // Parsing is broken |
| | | return new AnnounceMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["stationId"].GetInt(), d["stationName"].GetString(), |
| | | d["unit"].GetString(), exp_time, d["aggressiveFee"].GetDouble(), |
| | | d["passiveFee"].GetDouble(), d["brokerFee"].GetDouble(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | } |
| | | |
| | | SettleMessage* settle(rapidjson::Value& d) |
| | | { |
| | | // std::stringstream expiryStream(d["expiry"].GetString()); |
| | | std::chrono::nanoseconds exp_time(0); |
| | | // expiryStream >> date::parse("%Y-%m-%d %H:%M%z", exp_time); |
| | | return new SettleMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["stationName"].GetString(), exp_time, d["price"].GetDouble(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | // std::stringstream expiryStream(d["expiry"].GetString()); |
| | | std::chrono::nanoseconds exp_time(0); |
| | | // expiryStream >> date::parse("%Y-%m-%d %H:%M%z", exp_time); |
| | | return new SettleMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["stationName"].GetString(), exp_time, d["price"].GetDouble(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | } |
| | | |
| | | AddedMessage* added(rapidjson::Value& d) |
| | | { |
| | | return new AddedMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["id"].GetString(), mapOrder[d["side"].GetString()], |
| | | d["price"].GetDouble(), d["filled"].GetInt(), d["resting"].GetInt(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | return new AddedMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["id"].GetString(), mapOrder[d["side"].GetString()], |
| | | d["price"].GetDouble(), d["filled"].GetInt(), d["resting"].GetInt(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | } |
| | | |
| | | DeletedMessage* deleted(rapidjson::Value& d) |
| | | { |
| | | return new DeletedMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["id"].GetString(), mapOrder[d["side"].GetString()], |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | return new DeletedMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["id"].GetString(), mapOrder[d["side"].GetString()], |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | } |
| | | |
| | | TradeMessage* trade(rapidjson::Value& d) |
| | | { |
| | | return new TradeMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["price"].GetDouble(), d["volume"].GetInt(), d["buyer"].GetString(), |
| | | d["seller"].GetString(), mapTrade[d["tradeType"].GetString()], |
| | | d["passiveOrder"].GetString(), d["passiveOrderRemaining"].GetInt(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | return new TradeMessage( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["price"].GetDouble(), d["volume"].GetInt(), d["buyer"].GetString(), |
| | | d["seller"].GetString(), mapTrade[d["tradeType"].GetString()], |
| | | d["passiveOrder"].GetString(), d["passiveOrderRemaining"].GetInt(), |
| | | d["sequence"].GetInt(), d["timestamp"].GetDouble()); |
| | | } |
| | | |
| | | BrokerRequest* brokerReq(rapidjson::Value& d) |
| | | { |
| | | return new BrokerRequest( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["price"].GetDouble(), mapOrder[d["side"].GetString()], |
| | | d["volume"].GetInt(), d["counterparty"].GetString()); |
| | | return new BrokerRequest( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["price"].GetDouble(), mapOrder[d["side"].GetString()], |
| | | d["volume"].GetInt(), d["counterparty"].GetString()); |
| | | } |
| | | |
| | | BrokerAck* brokerAck(rapidjson::Value& d) |
| | | { |
| | | return new BrokerAck(mapTypes[d["type"].GetString()], |
| | | d["product"].GetString(), d["price"].GetDouble(), |
| | | mapOrder[d["side"].GetString()], d["volume"].GetInt(), |
| | | d["counterparty"].GetString(), d["id"].GetString(), |
| | | d["brokerTradeStatus"].GetString(), |
| | | d["owner"].GetString()); |
| | | return new BrokerAck(mapTypes[d["type"].GetString()], |
| | | d["product"].GetString(), d["price"].GetDouble(), |
| | | mapOrder[d["side"].GetString()], d["volume"].GetInt(), |
| | | d["counterparty"].GetString(), d["id"].GetString(), |
| | | d["brokerTradeStatus"].GetString(), |
| | | d["owner"].GetString()); |
| | | } |
| | | BrokerConfirm* brokerCon(rapidjson::Value& d) |
| | | { |
| | | return new BrokerConfirm( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["price"].GetDouble(), mapOrder[d["side"].GetString()], |
| | | d["volume"].GetInt(), d["counterparty"].GetString(), |
| | | d["id"].GetString()); |
| | | return new BrokerConfirm( |
| | | mapTypes[d["type"].GetString()], d["product"].GetString(), |
| | | d["price"].GetDouble(), mapOrder[d["side"].GetString()], |
| | | d["volume"].GetInt(), d["counterparty"].GetString(), |
| | | d["id"].GetString()); |
| | | } |
| | | |
| | | Message::Message() : type(NONE), product("error") {} |
| | | |
| | | Message::Message(MessageTypes types, std::string product) |
| | | : type(types), product(product) |
| | | : type(types), product(product) |
| | | { |
| | | } |
| | | |
| | | FromExchange::FromExchange(MessageTypes type, std::string product, |
| | | uint64_t sequence, double timestamp) |
| | | : Message(type, product), sequence(sequence), timestamp(timestamp) |
| | | : Message(type, product), sequence(sequence), timestamp(timestamp) |
| | | { |
| | | } |
| | | |
| | | ToExchange::ToExchange(MessageTypes type, std::string product) |
| | | : Message(type, product){}; |
| | | : Message(type, product){}; |
| | | |
| | | Broker::Broker(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty) |
| | | : Message(type, product), price(price), side(side), volume(volume), |
| | | counterparty(counterparty) |
| | | : Message(type, product), price(price), side(side), volume(volume), |
| | | counterparty(counterparty) |
| | | { |
| | | } |
| | | |
| | |
| | | std::chrono::nanoseconds expiry, double aggFee, |
| | | double pasFee, double broFee, |
| | | uint64_t sequence, double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), stationId(stationId), |
| | | stationName(stationName), unit(unit), expiry(expiry), aggFee(aggFee), |
| | | pasFee(pasFee), broFee(broFee) |
| | | : FromExchange(type, product, sequence, timestamp), stationId(stationId), |
| | | stationName(stationName), unit(unit), expiry(expiry), aggFee(aggFee), |
| | | pasFee(pasFee), broFee(broFee) |
| | | { |
| | | } |
| | | |
| | |
| | | std::string stationName, |
| | | std::chrono::nanoseconds expiry, double price, |
| | | uint64_t sequence, double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), |
| | | stationName(stationName), expiry(expiry), price(price) |
| | | : FromExchange(type, product, sequence, timestamp), |
| | | stationName(stationName), expiry(expiry), price(price) |
| | | { |
| | | } |
| | | |
| | | AddMessage::AddMessage(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume) |
| | | : ToExchange(type, product), price(price), side(side), volume(volume) |
| | | : ToExchange(type, product), price(price), side(side), volume(volume) |
| | | { |
| | | } |
| | | |
| | | std::string AddMessage::as_string() |
| | | { |
| | | if (mapOrderSide.empty()) initialise(); |
| | | return "{\"type\": \"ADD\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | "\", \"volume\": " + std::to_string(this->volume) + "}"; |
| | | if (mapOrderSide.empty()) initialise(); |
| | | return "{\"type\": \"ADD\", \"product\": \"" + this->product + |
| | | "\", \"price\": " + std::to_string(this->price) + ", \"side\": \"" + |
| | | mapOrderSide[this->side] + |
| | | "\", \"volume\": " + std::to_string(this->volume) + "}"; |
| | | } |
| | | |
| | | AddedMessage::AddedMessage(MessageTypes type, std::string product, |
| | | std::string id, book::OrderSideEnum side, |
| | | double price, uint64_t filled, uint64_t resting, |
| | | uint64_t sequence, double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), id(id), side(side), |
| | | price(price), filled(filled), resting(resting) |
| | | : FromExchange(type, product, sequence, timestamp), id(id), side(side), |
| | | price(price), filled(filled), resting(resting) |
| | | { |
| | | } |
| | | |
| | | DeleteMessage::DeleteMessage(MessageTypes type, std::string product, |
| | | std::string id) |
| | | : ToExchange(type, product), id(id) |
| | | : ToExchange(type, product), id(id) |
| | | { |
| | | } |
| | | |
| | | std::string DeleteMessage::as_string() |
| | | { |
| | | if (mapOrderSide.empty()) initialise(); |
| | | return "{\"type\": \"DELETE\", \"product\": \"" + this->product + |
| | | "\", \"id\": \"" + this->id + "\"}"; |
| | | if (mapOrderSide.empty()) initialise(); |
| | | return "{\"type\": \"DELETE\", \"product\": \"" + this->product + |
| | | "\", \"id\": \"" + this->id + "\"}"; |
| | | } |
| | | |
| | | DeletedMessage::DeletedMessage(MessageTypes type, std::string product, |
| | | std::string id, book::OrderSideEnum side, |
| | | uint64_t sequence, double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), id(id), side(side) |
| | | : FromExchange(type, product, sequence, timestamp), id(id), side(side) |
| | | { |
| | | } |
| | | |
| | | RejectMessage::RejectMessage(MessageTypes type, std::string product, |
| | | std::string error, uint64_t sequence, |
| | | double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), error(error) |
| | | : FromExchange(type, product, sequence, timestamp), error(error) |
| | | { |
| | | } |
| | | |
| | |
| | | std::string passiveOrder, |
| | | uint64_t passiveOrderRemaining, uint64_t sequence, |
| | | double timestamp) |
| | | : FromExchange(type, product, sequence, timestamp), price(price), |
| | | volume(volume), buyer(buyer), seller(seller), tradeType(tradeType), |
| | | passiveOrder(passiveOrder), passiveOrderRemaining(passiveOrderRemaining) |
| | | : FromExchange(type, product, sequence, timestamp), price(price), |
| | | volume(volume), buyer(buyer), seller(seller), tradeType(tradeType), |
| | | passiveOrder(passiveOrder), passiveOrderRemaining(passiveOrderRemaining) |
| | | { |
| | | } |
| | | |
| | | BrokerRequest::BrokerRequest(MessageTypes type, std::string product, |
| | | double price, book::OrderSideEnum side, |
| | | uint64_t volume, std::string counterparty) |
| | | : Broker(type, product, price, side, volume, counterparty) |
| | | : Broker(type, product, price, side, volume, counterparty) |
| | | { |
| | | } |
| | | |
| | |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty, std::string id, |
| | | std::string brokerTradeStatus, std::string owner) |
| | | : Broker(type, product, price, side, volume, counterparty), id(id), |
| | | brokerTradeStatus(brokerTradeStatus), owner(owner) |
| | | : Broker(type, product, price, side, volume, counterparty), id(id), |
| | | brokerTradeStatus(brokerTradeStatus), owner(owner) |
| | | { |
| | | } |
| | | |
| | |
| | | double price, book::OrderSideEnum side, |
| | | uint64_t volume, std::string counterparty, |
| | | std::string id) |
| | | : Broker(type, product, price, side, volume, counterparty), id(id) |
| | | : Broker(type, product, price, side, volume, counterparty), id(id) |
| | | { |
| | | } |
| | | } // namespace json |
| | |
| | | namespace json |
| | | { |
| | | enum MessageTypes { |
| | | FUTURE_TYPE, |
| | | SPREAD_TYPE, |
| | | CALL_TYPE, |
| | | PUT_TYPE, |
| | | SETTLEMENT, |
| | | ADD, |
| | | ADDED, |
| | | DELETE, |
| | | DELETED, |
| | | REJECT, |
| | | TRADE, |
| | | BROKER_REQUEST, |
| | | BROKER_ACK, |
| | | BROKER_CONFIRM, |
| | | NONE |
| | | FUTURE_TYPE, |
| | | SPREAD_TYPE, |
| | | CALL_TYPE, |
| | | PUT_TYPE, |
| | | SETTLEMENT, |
| | | ADD, |
| | | ADDED, |
| | | DELETE, |
| | | DELETED, |
| | | REJECT, |
| | | TRADE, |
| | | BROKER_REQUEST, |
| | | BROKER_ACK, |
| | | BROKER_CONFIRM, |
| | | NONE |
| | | }; |
| | | |
| | | enum TradeTypeEnum { BUY_AGGRESSOR, SELL_AGGRESSOR }; |
| | | |
| | | struct Message { |
| | | MessageTypes type; |
| | | std::string product; |
| | | Message(MessageTypes type, std::string product); |
| | | Message(); |
| | | virtual ~Message() = default; |
| | | MessageTypes type; |
| | | std::string product; |
| | | Message(MessageTypes type, std::string product); |
| | | Message(); |
| | | virtual ~Message() = default; |
| | | }; |
| | | |
| | | struct FromExchange : public Message { |
| | | uint64_t sequence; |
| | | double timestamp; |
| | | FromExchange(MessageTypes type, std::string product, uint64_t sequence, |
| | | double timestamp); |
| | | virtual ~FromExchange() = default; |
| | | uint64_t sequence; |
| | | double timestamp; |
| | | FromExchange(MessageTypes type, std::string product, uint64_t sequence, |
| | | double timestamp); |
| | | virtual ~FromExchange() = default; |
| | | }; |
| | | |
| | | struct ToExchange : public Message { |
| | | ToExchange(MessageTypes type, std::string product); |
| | | virtual ~ToExchange() = default; |
| | | ToExchange(MessageTypes type, std::string product); |
| | | virtual ~ToExchange() = default; |
| | | }; |
| | | |
| | | struct Broker : public Message { |
| | | double price; |
| | | book::OrderSideEnum side; |
| | | uint64_t volume; |
| | | std::string counterparty; |
| | | Broker(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, std::string counterparty); |
| | | virtual ~Broker() = default; |
| | | double price; |
| | | book::OrderSideEnum side; |
| | | uint64_t volume; |
| | | std::string counterparty; |
| | | Broker(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, std::string counterparty); |
| | | virtual ~Broker() = default; |
| | | }; |
| | | |
| | | struct AnnounceMessage : public FromExchange { |
| | | int stationId; |
| | | std::string stationName; |
| | | std::string unit; |
| | | std::chrono::nanoseconds expiry; |
| | | double aggFee; |
| | | double pasFee; |
| | | double broFee; |
| | | int stationId; |
| | | std::string stationName; |
| | | std::string unit; |
| | | std::chrono::nanoseconds expiry; |
| | | double aggFee; |
| | | double pasFee; |
| | | double broFee; |
| | | |
| | | AnnounceMessage(MessageTypes type, std::string product, |
| | | int stationId, std::string stationName, |
| | | std::string unit, std::chrono::nanoseconds expiry, |
| | | double aggFee, double pasFee, double broFee, |
| | | uint64_t sequence, double timestamp); |
| | | AnnounceMessage(MessageTypes type, std::string product, int stationId, |
| | | std::string stationName, std::string unit, |
| | | std::chrono::nanoseconds expiry, double aggFee, |
| | | double pasFee, double broFee, uint64_t sequence, |
| | | double timestamp); |
| | | }; |
| | | |
| | | struct SettleMessage : public FromExchange { |
| | | std::string stationName; |
| | | std::chrono::nanoseconds expiry; |
| | | double price; |
| | | SettleMessage(MessageTypes type, std::string product, |
| | | std::string stationName, std::chrono::nanoseconds expiry, |
| | | double price, uint64_t sequence, double timestamp); |
| | | std::string stationName; |
| | | std::chrono::nanoseconds expiry; |
| | | double price; |
| | | SettleMessage(MessageTypes type, std::string product, |
| | | std::string stationName, std::chrono::nanoseconds expiry, |
| | | double price, uint64_t sequence, double timestamp); |
| | | }; |
| | | |
| | | struct AddMessage : public ToExchange { |
| | | double price; |
| | | book::OrderSideEnum side; |
| | | uint64_t volume; |
| | | AddMessage(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume); |
| | | std::string as_string(); |
| | | double price; |
| | | book::OrderSideEnum side; |
| | | uint64_t volume; |
| | | AddMessage(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume); |
| | | std::string as_string(); |
| | | }; |
| | | |
| | | struct AddedMessage : public FromExchange { |
| | | std::string id; |
| | | book::OrderSideEnum side; |
| | | double price; |
| | | uint64_t filled; |
| | | uint64_t resting; |
| | | AddedMessage(MessageTypes type, std::string product, std::string id, |
| | | book::OrderSideEnum side, double price, uint64_t filled, |
| | | uint64_t resting, uint64_t sequence, double timestamp); |
| | | std::string id; |
| | | book::OrderSideEnum side; |
| | | double price; |
| | | uint64_t filled; |
| | | uint64_t resting; |
| | | AddedMessage(MessageTypes type, std::string product, std::string id, |
| | | book::OrderSideEnum side, double price, uint64_t filled, |
| | | uint64_t resting, uint64_t sequence, double timestamp); |
| | | }; |
| | | |
| | | struct DeleteMessage : public ToExchange { |
| | | std::string id; |
| | | DeleteMessage(MessageTypes type, std::string product, std::string id); |
| | | std::string as_string(); |
| | | std::string id; |
| | | DeleteMessage(MessageTypes type, std::string product, std::string id); |
| | | std::string as_string(); |
| | | }; |
| | | |
| | | struct DeletedMessage : public FromExchange { |
| | | std::string id; |
| | | book::OrderSideEnum side; |
| | | DeletedMessage(MessageTypes type, std::string product, std::string id, |
| | | book::OrderSideEnum side, uint64_t sequence, |
| | | double timestamp); |
| | | std::string id; |
| | | book::OrderSideEnum side; |
| | | DeletedMessage(MessageTypes type, std::string product, std::string id, |
| | | book::OrderSideEnum side, uint64_t sequence, |
| | | double timestamp); |
| | | }; |
| | | |
| | | struct RejectMessage : public FromExchange { |
| | | std::string error; |
| | | RejectMessage(MessageTypes type, std::string product, std::string error, |
| | | uint64_t sequence, double timestamp); |
| | | std::string error; |
| | | RejectMessage(MessageTypes type, std::string product, std::string error, |
| | | uint64_t sequence, double timestamp); |
| | | }; |
| | | |
| | | struct TradeMessage : public FromExchange { |
| | | double price; |
| | | uint64_t volume; |
| | | std::string buyer; |
| | | std::string seller; |
| | | TradeTypeEnum tradeType; |
| | | std::string passiveOrder; |
| | | uint64_t passiveOrderRemaining; |
| | | TradeMessage(MessageTypes type, std::string product, double price, |
| | | uint64_t volume, std::string buyer, std::string seller, |
| | | TradeTypeEnum tradeType, std::string passiveOrder, |
| | | uint64_t passiveOrderRemaining, uint64_t sequence, |
| | | double timestamp); |
| | | double price; |
| | | uint64_t volume; |
| | | std::string buyer; |
| | | std::string seller; |
| | | TradeTypeEnum tradeType; |
| | | std::string passiveOrder; |
| | | uint64_t passiveOrderRemaining; |
| | | TradeMessage(MessageTypes type, std::string product, double price, |
| | | uint64_t volume, std::string buyer, std::string seller, |
| | | TradeTypeEnum tradeType, std::string passiveOrder, |
| | | uint64_t passiveOrderRemaining, uint64_t sequence, |
| | | double timestamp); |
| | | }; |
| | | |
| | | struct BrokerRequest : public Broker { |
| | | BrokerRequest(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty); |
| | | BrokerRequest(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty); |
| | | }; |
| | | |
| | | struct BrokerAck : public Broker { |
| | | std::string id; |
| | | std::string brokerTradeStatus; |
| | | std::string owner; |
| | | BrokerAck(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty, std::string id, |
| | | std::string brokerTradeStatus, std::string owner); |
| | | std::string id; |
| | | std::string brokerTradeStatus; |
| | | std::string owner; |
| | | BrokerAck(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty, std::string id, |
| | | std::string brokerTradeStatus, std::string owner); |
| | | }; |
| | | |
| | | struct BrokerConfirm : public Broker { |
| | | std::string id; |
| | | BrokerConfirm(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty, std::string id); |
| | | std::string id; |
| | | BrokerConfirm(MessageTypes type, std::string product, double price, |
| | | book::OrderSideEnum side, uint64_t volume, |
| | | std::string counterparty, std::string id); |
| | | }; |
| | | |
| | | std::queue<Message*> parse(std::string& str); |
| | |
| | | namespace protocol |
| | | { |
| | | static std::unordered_map<json::MessageTypes, book::ProductTypeEnum> |
| | | mapAnnounce; |
| | | mapAnnounce; |
| | | std::string server = std::string(HOST) + ":" + std::string(PORT); |
| | | httplib::Client cli("http://" + server); |
| | | |
| | | void initialise() |
| | | { |
| | | mapAnnounce = {{json::FUTURE_TYPE, book::FUTURE}, |
| | | {json::SPREAD_TYPE, book::SPREAD}, |
| | | {json::CALL_TYPE, book::CALL}, |
| | | {json::PUT_TYPE, book::PUT}}; |
| | | mapAnnounce = {{json::FUTURE_TYPE, book::FUTURE}, |
| | | {json::SPREAD_TYPE, book::SPREAD}, |
| | | {json::CALL_TYPE, book::CALL}, |
| | | {json::PUT_TYPE, book::PUT}}; |
| | | } |
| | | |
| | | std::unordered_map<std::string, book::Book> recoverBook() |
| | | { |
| | | std::unordered_map<std::string, book::Book> bs; |
| | | std::ifstream sampleFile("../data.test"); |
| | | std::stringstream ss; |
| | | ss << sampleFile.rdbuf(); |
| | | // httplib::Client cli("http://" + server); |
| | | // auto res = cli.Get("/recover"); |
| | | std::string l; |
| | | l = ss.str(); |
| | | std::queue<json::Message*> a(json::parse(l)); |
| | | while (!a.empty()) { |
| | | protocol::handleMessage(bs, a.front()); |
| | | delete a.front(); |
| | | a.pop(); |
| | | } |
| | | return bs; |
| | | std::unordered_map<std::string, book::Book> bs; |
| | | // std::ifstream sampleFile("../data.test"); |
| | | // std::stringstream ss; |
| | | // ss << sampleFile.rdbuf(); |
| | | httplib::Client cli("http://" + server); |
| | | auto res = cli.Get("/recover"); |
| | | std::string l; |
| | | // l = ss.str(); |
| | | l = res->body; |
| | | std::queue<json::Message*> a(json::parse(l)); |
| | | while (!a.empty()) { |
| | | protocol::handleMessage(bs, a.front()); |
| | | delete a.front(); |
| | | a.pop(); |
| | | } |
| | | return bs; |
| | | } |
| | | |
| | | json::Message* addOrder(json::AddMessage& order) |
| | | { |
| | | std::string message = "{\"message\": " + order.as_string() + ", " + |
| | | "\"username\": \"" + std::string(USER) + |
| | | "\", \"password\": \"" + std::string(PASS) + "\"}"; |
| | | return send(message); |
| | | std::string message = "{\"message\": " + order.as_string() + ", " + |
| | | "\"username\": \"" + std::string(USER) + |
| | | "\", \"password\": \"" + std::string(PASS) + "\"}"; |
| | | return send(message); |
| | | } |
| | | |
| | | json::Message* deleteOrder(json::DeleteMessage& order) |
| | | { |
| | | std::string message = "{\"message\": " + order.as_string() + |
| | | ", \"username\": \"" + std::string(USER) + |
| | | "\", \"password\": \"" + std::string(PASS) + "\"}"; |
| | | return send(message); |
| | | std::string message = "{\"message\": " + order.as_string() + |
| | | ", \"username\": \"" + std::string(USER) + |
| | | "\", \"password\": \"" + std::string(PASS) + "\"}"; |
| | | return send(message); |
| | | } |
| | | |
| | | void handleMessage(std::unordered_map<std::string, book::Book>& bs, |
| | | json::Message* message) |
| | | { |
| | | if (mapAnnounce.empty()) initialise(); |
| | | switch (message->type) { |
| | | case json::FUTURE_TYPE: |
| | | case json::SPREAD_TYPE: |
| | | case json::CALL_TYPE: |
| | | case json::PUT_TYPE: |
| | | announce(bs, dynamic_cast<json::AnnounceMessage*>(message)); |
| | | break; |
| | | case json::SETTLEMENT: |
| | | settle(bs, dynamic_cast<json::SettleMessage*>(message)); |
| | | break; |
| | | case json::ADDED: |
| | | addedOrder(bs, dynamic_cast<json::AddedMessage*>(message)); |
| | | break; |
| | | case json::DELETED: |
| | | deletedOrder(bs, dynamic_cast<json::DeletedMessage*>(message)); |
| | | break; |
| | | case json::TRADE: |
| | | tradeOrder(bs, dynamic_cast<json::TradeMessage*>(message)); |
| | | break; |
| | | case json::BROKER_REQUEST: |
| | | case json::BROKER_ACK: |
| | | case json::BROKER_CONFIRM: |
| | | broker(bs, dynamic_cast<json::Broker*>(message)); |
| | | break; |
| | | default:; |
| | | } |
| | | if (mapAnnounce.empty()) initialise(); |
| | | switch (message->type) { |
| | | case json::FUTURE_TYPE: |
| | | case json::SPREAD_TYPE: |
| | | case json::CALL_TYPE: |
| | | case json::PUT_TYPE: |
| | | announce(bs, dynamic_cast<json::AnnounceMessage*>(message)); |
| | | break; |
| | | case json::SETTLEMENT: |
| | | settle(bs, dynamic_cast<json::SettleMessage*>(message)); |
| | | break; |
| | | case json::ADDED: |
| | | addedOrder(bs, dynamic_cast<json::AddedMessage*>(message)); |
| | | break; |
| | | case json::DELETED: |
| | | deletedOrder(bs, dynamic_cast<json::DeletedMessage*>(message)); |
| | | break; |
| | | case json::TRADE: |
| | | tradeOrder(bs, dynamic_cast<json::TradeMessage*>(message)); |
| | | break; |
| | | case json::BROKER_REQUEST: |
| | | case json::BROKER_ACK: |
| | | case json::BROKER_CONFIRM: |
| | | broker(bs, dynamic_cast<json::Broker*>(message)); |
| | | break; |
| | | default:; |
| | | } |
| | | } |
| | | |
| | | void announce(std::unordered_map<std::string, book::Book>& bs, |
| | | json::AnnounceMessage* message) |
| | | { |
| | | bs[message->product] = |
| | | book::Book(mapAnnounce[message->type], message->product, |
| | | message->stationId, message->unit, message->expiry, |
| | | message->aggFee, message->pasFee, message->broFee); |
| | | bs[message->product] = |
| | | book::Book(mapAnnounce[message->type], message->product, |
| | | message->stationId, message->unit, message->expiry, |
| | | message->aggFee, message->pasFee, message->broFee); |
| | | } |
| | | void settle(std::unordered_map<std::string, book::Book>& bs, |
| | | json::SettleMessage* message) |
| | | { |
| | | bs.erase(message->product); |
| | | bs.erase(message->product); |
| | | } |
| | | void addedOrder(std::unordered_map<std::string, book::Book>& bs, |
| | | json::AddedMessage* message) |
| | | { |
| | | if (message->side == book::Buy) { |
| | | book::Order t(message->price, book::Buy, message->resting, |
| | | message->timestamp, message->id); |
| | | bs[message->product].bid(t); |
| | | } else { |
| | | book::Order t(message->price, book::Sell, message->resting, |
| | | message->timestamp, message->id); |
| | | bs[message->product].ask(t); |
| | | } |
| | | if (message->side == book::Buy) { |
| | | book::Order t(message->price, book::Buy, message->resting, |
| | | message->timestamp, message->id); |
| | | bs[message->product].bid(t); |
| | | } else { |
| | | book::Order t(message->price, book::Sell, message->resting, |
| | | message->timestamp, message->id); |
| | | bs[message->product].ask(t); |
| | | } |
| | | } |
| | | void deletedOrder(std::unordered_map<std::string, book::Book>& bs, |
| | | json::DeletedMessage* message) |
| | | { |
| | | if (message->side == book::Buy) { |
| | | for (std::size_t i = 0; i < bs[message->product].bidSide.size(); i++) { |
| | | if (bs[message->product].bidSide[i].id == message->id) { |
| | | bs[message->product].bidSide[i] = bs[message->product].bidSide.back(); |
| | | bs[message->product].bidSide.erase(bs[message->product].bidSide.end()); |
| | | std::make_heap(bs[message->product].bidSide.begin(), |
| | | bs[message->product].bidSide.end(), |
| | | std::less<book::Level>()); |
| | | } |
| | | if (message->side == book::Buy) { |
| | | for (std::size_t i = 0; i < bs[message->product].bidSide.size(); i++) { |
| | | if (bs[message->product].bidSide[i].id == message->id) { |
| | | bs[message->product].bidSide[i] = |
| | | bs[message->product].bidSide.back(); |
| | | bs[message->product].bidSide.pop_back(); |
| | | std::make_heap(bs[message->product].bidSide.begin(), |
| | | bs[message->product].bidSide.end(), |
| | | std::less<book::Level>()); |
| | | } |
| | | } |
| | | } else { |
| | | for (std::size_t i = 0; i < bs[message->product].askSide.size(); i++) { |
| | | if (bs[message->product].askSide[i].id == message->id) { |
| | | bs[message->product].askSide[i] = |
| | | bs[message->product].askSide.back(); |
| | | bs[message->product].askSide.pop_back(); |
| | | std::make_heap(bs[message->product].askSide.begin(), |
| | | bs[message->product].askSide.end(), |
| | | std::greater<book::Level>()); |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | for (std::size_t i = 0; i < bs[message->product].askSide.size(); i++) { |
| | | if (bs[message->product].askSide[i].id == message->id) { |
| | | bs[message->product].askSide[i] = bs[message->product].askSide.back(); |
| | | bs[message->product].askSide.erase(bs[message->product].askSide.end()); |
| | | std::make_heap(bs[message->product].askSide.begin(), |
| | | bs[message->product].askSide.end(), |
| | | std::greater<book::Level>()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | void tradeOrder(std::unordered_map<std::string, book::Book>& bs, |
| | | json::TradeMessage* message) |
| | | { |
| | | if (message->tradeType == json::BUY_AGGRESSOR) { |
| | | book::Order t(message->price, book::Buy, message->volume, |
| | | message->timestamp, message->passiveOrder); |
| | | bs[message->product].bid(t); |
| | | } else { |
| | | book::Order t(message->price, book::Sell, message->volume, |
| | | message->timestamp, message->passiveOrder); |
| | | bs[message->product].ask(t); |
| | | } |
| | | if (message->tradeType == json::BUY_AGGRESSOR) { |
| | | book::Order t(message->price, book::Buy, message->volume, |
| | | message->timestamp, message->passiveOrder); |
| | | bs[message->product].bid(t); |
| | | } else { |
| | | book::Order t(message->price, book::Sell, message->volume, |
| | | message->timestamp, message->passiveOrder); |
| | | bs[message->product].ask(t); |
| | | } |
| | | } |
| | | void broker(std::unordered_map<std::string, book::Book>& bs, |
| | | json::Broker* message) |
| | |
| | | |
| | | json::Message* send(std::string& message) |
| | | { |
| | | auto res = cli.Post("/execution", message, "text/plain"); |
| | | std::queue<json::Message*> a = json::parse(res->body); |
| | | return a.front(); |
| | | auto res = cli.Post("/execution", message, "text/plain"); |
| | | std::queue<json::Message*> a = json::parse(res->body); |
| | | return a.front(); |
| | | } |
| | | |
| | | } // namespace protocol |
| | |
| | | |
| | | #include <string> |
| | | |
| | | #define TEST |
| | | // #define TEST |
| | | |
| | | constexpr const char* HOST="sytev070"; |
| | | constexpr const char* HOST = "sytev070"; |
| | | #ifdef TEST |
| | | constexpr const char* PORT="9005"; |
| | | constexpr const char* PORT = "9005"; |
| | | #else |
| | | constexpr const char* PORT="9000"; |
| | | constexpr const char* PORT = "9000"; |
| | | #endif |
| | | |
| | | constexpr const char* USER="jgrunbau"; |
| | | constexpr const char* PASS="b7d630945a0854581d9f86ba147f34a5"; |
| | | constexpr const char* USER = "jgrunbau"; |
| | | constexpr const char* PASS = "b7d630945a0854581d9f86ba147f34a5"; |
| | |
| | | #include "strat.hpp" |
| | | |
| | | namespace strat { |
| | | namespace strat |
| | | { |
| | | |
| | | } |
| | |
| | | #pragma once |
| | | |
| | | #include "book.hpp" |
| | | #include <unordered_map> |
| | | #include <string> |
| | | #include <unordered_map> |
| | | |
| | | namespace strat { |
| | | namespace strat |
| | | { |
| | | } |
| | |
| | | |
| | | int main(void) |
| | | { |
| | | book::Book b = book::testBook(10, true); |
| | | auto bs = protocol::recoverBook(); |
| | | std::cout << bs.size() << std::endl; |
| | | for (auto i : bs) { |
| | | std::cout << i.first << std::endl; |
| | | i.second.printBook(); |
| | | } |
| | | // book::Book b = book::testBook(10, true); |
| | | auto bs = protocol::recoverBook(); |
| | | std::cout << bs.size() << std::endl; |
| | | for (auto i : bs) { |
| | | std::cout << i.first << std::endl; |
| | | i.second.printBook(); |
| | | } |
| | | } |