Skip to content

Instantly share code, notes, and snippets.

@cdfpaz
Last active February 17, 2016 13:51
Show Gist options
  • Save cdfpaz/7d1c7ad16b21fa64650d to your computer and use it in GitHub Desktop.
Save cdfpaz/7d1c7ad16b21fa64650d to your computer and use it in GitHub Desktop.
#include <set>
#include <iostream>
#include <complex>
#include <algorithm>
#include <stdexcept>
template <typename T> int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
class ProfitLoss {
public:
typedef std::set<std::pair<int, double> > Type;
ProfitLoss():m_net(0), m_realized(0), m_avgOpenPrice(0) {
}
ProfitLoss(const Type& initial) {
int buyQuantity = 0, sellQuantity = 0;
double averageBuyPrice = 0, averageSellPrice = 0;
Type::const_iterator fill = initial.begin();
for(; fill != initial.end(); ++fill) {
if (fill->first > 0) {
buyQuantity += fill->first;
averageBuyPrice += fill->first * fill->second;
}
else if(fill->first < 0) {
int absQuantity = std::abs(fill->first);
sellQuantity += absQuantity;
averageSellPrice += absQuantity * fill->second;
}
}
if (buyQuantity > 0)
averageBuyPrice /= buyQuantity;
if (sellQuantity > 0)
averageSellPrice /= sellQuantity;
set_Net(buyQuantity - sellQuantity);
set_AverageOpenPrice(get_Net() > 0 ? averageBuyPrice : averageSellPrice);
set_Realized((averageSellPrice - averageBuyPrice) * std::min(buyQuantity, sellQuantity));
}
double get_Realized() {
return m_realized;
}
void set_Realized(double v) {
m_realized = v;
}
double get_Net() {
return m_net;
}
void set_Net(double v) {
m_net = v;
}
double get_AverageOpenPrice() {
return m_avgOpenPrice;
}
void set_AverageOpenPrice(double v) {
m_avgOpenPrice = v;
}
void AddFill(int fillQty, double fillPrice) {
if (fillQty == 0)
throw std::logic_error("Quantity must be non-zero.");
if ((sgn(get_Net()) != sgn(fillQty))) {
int absNet = std::abs(get_Net());
int absQuantity = std::abs(fillQty);
if (absNet == absQuantity) { // flat
set_Realized(get_Realized() + (fillPrice - get_AverageOpenPrice()) * get_Net());
set_AverageOpenPrice(0);
}
else if (absNet > absQuantity) { // decrease
set_Realized(get_Realized() + (fillPrice - get_AverageOpenPrice()) * -fillQty);
}
else { // reverse
set_Realized(get_Realized() + (fillPrice - get_AverageOpenPrice()) * get_Net());
set_AverageOpenPrice(fillPrice);
}
}
else {
set_AverageOpenPrice((get_Net() * get_AverageOpenPrice() + fillQty * fillPrice) / (get_Net() + fillQty));
}
set_Net(get_Net() + fillQty);
}
double FloatingForTheoriticalExit(double exitPrice) {
return (exitPrice - get_AverageOpenPrice()) * get_Net();
}
void Dump() {
std::cout << std::endl << "\tRealized " << get_Realized() << std::endl;
std::cout << "\tNet " << get_Net() << std::endl;
std::cout << "\tAverageOpenPrice " << get_AverageOpenPrice() << std::endl;
}
private:
int m_net;
double m_realized;
double m_avgOpenPrice;
};
int main(void) {
std::cout << std::endl;
std::cout << "*** calling constructor PL" << std::endl;
ProfitLoss::Type t;
t.insert(std::pair<int, double>(12, 100.0));
t.insert(std::pair<int, double>(17, 99.0));
t.insert(std::pair<int, double>(-9, 101.0));
t.insert(std::pair<int, double>(-4, 105.0));
t.insert(std::pair<int, double>(3, 103.0));
ProfitLoss pa(t);
pa.Dump();
try {
//pa.AddFill(10, 100.0);
//pa.AddFill(-12, 101.0);
//pa.AddFill(-19, 101.0);
//pa.AddFill(-22, 101.0);
}
catch(std::exception& ex) {
std::cout << "error: " << ex.what() << std::endl;
}
//pa.Dump();
std::cout << std::endl << "*** calling add fill PL" << std::endl;
ProfitLoss pb;
try {
pb.AddFill(12, 100.0);
pb.AddFill(17, 99.0);
pb.AddFill(-9, 101.0);
pb.AddFill(-4, 105.0);
pb.AddFill(3, 103.0);
}
catch(std::exception& ex) {
std::cout << "error: " << ex.what() << std::endl;
}
pb.Dump();
std::cout << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment