Created
September 19, 2016 23:45
-
-
Save GaZ3ll3/80f0de11e9f780e08249376f79853cc4 to your computer and use it in GitHub Desktop.
Pricercode for RGM advisors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <fstream> | |
| #include "Pricer.h" | |
| using namespace std; | |
| int main(int argc, const char* argv[]){ | |
| const char* default_file = "pricer.in"; | |
| if (argc != 2) { | |
| cerr << "Command: Pricer [target-size]" << endl; | |
| return 0; | |
| } | |
| int target_size = (atoi(argv[1])); | |
| Pricer pricer(target_size); | |
| ifstream order_book; | |
| string data; | |
| order_book.open(default_file); | |
| if (!order_book.is_open()) {cout << "input file cannot be opened." << endl; exit(1);} | |
| else { | |
| while(!order_book.eof()) { | |
| getline(order_book, data); | |
| pricer.process(data); | |
| } | |
| order_book.close(); | |
| } | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // Created by lurker on 3/27/16. | |
| // | |
| #ifndef PRICER_PRICER_H | |
| #define PRICER_PRICER_H | |
| #include <iostream> | |
| #include <algorithm> | |
| #include <map> | |
| #include <unordered_map> | |
| #include <cstdint> | |
| #include <string> | |
| #include <boost/algorithm/string/classification.hpp> | |
| #include <boost/algorithm/string/split.hpp> | |
| extern "C" { | |
| #include <stdio.h> | |
| }; | |
| #define PRNT 1 | |
| using namespace std; | |
| class Order { | |
| public: | |
| Order() : | |
| timestamp(0), | |
| id(""), | |
| side(false), | |
| price(0), | |
| qty(0) {} | |
| uint32_t timestamp; | |
| string id; | |
| bool side; | |
| uint32_t price; | |
| uint32_t qty; | |
| }; | |
| class OrderTable { | |
| public: | |
| OrderTable() : | |
| qty(0) {} | |
| ~OrderTable() { | |
| while(!table.empty()) { | |
| auto it = table.begin(); | |
| delete it->second; | |
| table.erase(it); | |
| } | |
| } | |
| uint32_t qty; | |
| unordered_map<string, Order*> table; | |
| void add(Order *o) { | |
| table[o->id] = o; | |
| qty += o->qty; | |
| } | |
| bool reduce(Order *o, uint32_t q) { | |
| if (o->qty < q) { | |
| qty -= o->qty; | |
| table.erase(o->id); | |
| return true; | |
| } | |
| else { | |
| o->qty -= q; | |
| qty -= q; | |
| return false; | |
| } | |
| } | |
| }; | |
| typedef map<uint32_t, OrderTable*> orderMap; | |
| class Pricer { | |
| public: | |
| Pricer(uint32_t ts) { | |
| target_size = ts; | |
| bidSum = 0; | |
| askSum = 0; | |
| } | |
| ~Pricer() { | |
| for (auto it : bid ) { | |
| delete it.second; | |
| } | |
| for (auto it : ask) { | |
| delete it.second; | |
| } | |
| while(!orders.empty()) { | |
| auto it = orders.begin(); | |
| orders.erase(it); | |
| } | |
| } | |
| uint32_t target_size; | |
| float last_ask = 0.; | |
| float last_bid = 0.; | |
| uint32_t bidSum; | |
| uint32_t askSum; | |
| map<uint32_t, OrderTable*> bid; | |
| map<uint32_t, OrderTable*> ask; | |
| unordered_map<string, Order*> orders; | |
| void add(Order* o) { | |
| auto it = orders.find(o->id); | |
| if (it != orders.end()) {return;} | |
| orders[o->id] = o; | |
| orderMap& ot = o->side ? bid : ask; | |
| uint32_t& sum = o->side ? bidSum : askSum; | |
| sum += o->qty; | |
| auto ret = ot.insert({o->price, new OrderTable()}); | |
| ret.first->second->add(o); | |
| } | |
| void reduce(Order* o, uint32_t amount) { | |
| auto it = orders.find(o->id); | |
| if (it == orders.end()) {return;} | |
| orderMap& ot = o->side ? bid : ask; | |
| uint32_t& sum = o->side ? bidSum : askSum; | |
| orders[o->id]->timestamp = o->timestamp; | |
| bool to_del = ot[o->price]->reduce(o, amount); | |
| if (to_del) { | |
| orders.erase(o->id); | |
| if (ot[o->price]->qty == 0) { | |
| ot.erase(o->price); | |
| sum -= o->qty; | |
| } | |
| } | |
| else { | |
| sum -= amount; | |
| } | |
| } | |
| void execute(Order *o) { | |
| float total = 0.; | |
| uint32_t completed = 0; | |
| if (o->side) { | |
| // sell it | |
| if (target_size > bidSum) { | |
| if (total != last_bid) { | |
| #if PRNT | |
| printf("%d S NA\n", o->timestamp); | |
| #endif | |
| last_bid = 0; | |
| } | |
| } | |
| else { | |
| for (auto it = bid.rbegin(); it != bid.rend(); it++) { | |
| float cur_price = static_cast<float>(it->first)/100; | |
| uint32_t sz = min(it->second->qty, target_size - completed); | |
| completed += sz; | |
| total += sz * cur_price; | |
| if (completed == target_size) { | |
| if (total != last_bid) { | |
| #if PRNT | |
| printf("%d S %.2f\n", o->timestamp, total); | |
| #endif | |
| last_bid = total; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| } | |
| else { | |
| if (target_size > askSum) { | |
| if (total != last_ask) { | |
| #if PRNT | |
| printf("%d B NA\n", o->timestamp); | |
| #endif | |
| last_ask = 0; | |
| } | |
| } | |
| else { | |
| for (auto it = ask.begin(); it != ask.end(); it++) { | |
| float cur_price = static_cast<float>(it->first)/100; | |
| uint32_t sz = min(it->second->qty, target_size- completed); | |
| completed += sz; | |
| total += sz * cur_price; | |
| if (completed == target_size) { | |
| if (total != last_ask) { | |
| #if PRNT | |
| printf("%d B %.2f\n", o->timestamp, total); | |
| #endif | |
| last_ask = total; | |
| } | |
| return; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void process(string data) { | |
| vector<string> tokens; | |
| boost::split(tokens, data, boost::is_any_of(" ")); | |
| if (tokens.size() >= 3) | |
| { | |
| uint32_t timestamp = atoi(tokens[0].c_str()); | |
| string message = tokens[1]; | |
| string orderId = tokens[2]; | |
| if (message == "A") | |
| { | |
| bool side = tokens[3] == "B"; | |
| uint32_t price = int(atof(tokens[4].c_str()) * 100); | |
| int qty = atoi(tokens[5].c_str()); | |
| auto o = new Order(); | |
| o->side = side; | |
| o->qty = qty; | |
| o->timestamp = timestamp; | |
| o->price = price; | |
| o->id = orderId; | |
| add(o); | |
| execute(o); | |
| } | |
| else if (message == "R") | |
| { | |
| int qty = atoi(tokens[3].c_str()); | |
| Order *o = orders[orderId]; | |
| o->timestamp = timestamp; | |
| reduce(o, qty); | |
| execute(o); | |
| } | |
| } | |
| } | |
| }; | |
| #endif //PRICER_PRICER_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment