Skip to content

Instantly share code, notes, and snippets.

@GaZ3ll3
Created September 19, 2016 23:45
Show Gist options
  • Save GaZ3ll3/80f0de11e9f780e08249376f79853cc4 to your computer and use it in GitHub Desktop.
Save GaZ3ll3/80f0de11e9f780e08249376f79853cc4 to your computer and use it in GitHub Desktop.
Pricercode for RGM advisors
#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;
}
//
// 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