Compare commits

...
Author SHA1 Message Date
Taha Afzal b3dc0e9533 maker taker hedging logic added, not hooked 2019-05-14 19:17:30 -04:00
5 changed files with 80 additions and 4 deletions

No files matched your search

@@ -366,6 +366,22 @@ void SpreaderOrder::_send_hedge(size_t hedge_leg_index,
hedge_price,
hedge_qty);
}
void SpreaderOrder::_compute_nlegs_crossed_hedges(size_t filled_leg_index,
Price filled_price,
double filled_quantity){
SpreaderBookkeepingData& bk_data = _bookkeeping_data();
const LegPropertyData& q_leg_data =
bk_data.get_leg_data(filled_leg_index).leg_property_data();
const ISpreaderManager& spreader = *this;
SpreaderUtils::compute_nlegs_crossed_hedges(bk_data.side(),
bk_data.effective_price(),
bk_data.n_legs(),
q_leg_data,
filled_price,
filled_quantity,
spreader,
bk_data.nlegs_crossed_hedges());
}
void SpreaderOrder::_compute_hedge_price_quantity(size_t filled_leg_index,
Price fill_price,
double fill_quantity,
@@ -386,15 +402,13 @@ void SpreaderOrder::_compute_hedge_price_quantity(size_t filled_leg_index,
hedge_quantity);
else{
const QuoteLegDriver& driver_data = filled_leg_data.quoter().driver_data(quote_order_price, hedge_leg_index);
// QuoteLegDriver driver_data;
// driver_data.set(quote_order_price,Quantity(1),Quantity(1));
SpreaderUtils::compute_hedge_price_size_n_legs (filled_leg_data.leg_property_data(),
fill_price,
fill_quantity,
hedged_leg_data.leg_property_data(),
driver_data,
computed_hedge_price,
hedge_quantity);
hedge_quantity);
}
hedge_price = SpreaderUtils::apply_pre_hedge_parameters (hedged_leg_data.leg_property_data().leg_params().pre_hedge_params(),
hedged_leg_data.book(),
@@ -233,6 +233,13 @@ private:
void _send_hedge(size_t hedge_leg_index,
Price hedge_price,
Quantity hedge_qty);
// computes the hedges in the case of nlegs
// from crossing the hedge markets. If the
// crossing doesnt result in better hedge prices
// 0's are stored in the qty's in
void _compute_nlegs_crossed_hedges(size_t filled_leg_index,
Price filled_price,
double filled_quantity);
void _compute_hedge_price_quantity(size_t filled_leg_index,
Price filled_price,
double filled_quantity,
@@ -1,4 +1,5 @@
#include "SpreaderBookkeepingData.h"
#include "lib/os/os.h"
namespace bts{
namespace orderman{
@@ -18,12 +19,14 @@ SpreaderBookkeepingData::SpreaderBookkeepingData (
_inited_new (inited_new),
_n_legs(legs.size()),
_n_quoting_legs(_calc_n_quoting_legs(legs)),
_side(order_def.side()),
_order_def(order_def),
_reported_state(){
LOG(OrderMan, Info, "SpreaderBookkeepingData.cons started "
"key: {} n_legs: {}",
spreader_order_key.value(), _n_legs);
_leg_data.reserve(_n_legs);
_nlegs_crossed_hedges.reserve(_n_legs);
size_t i=0;
for (const auto& leg_property_data : legs){
_leg_data.emplace_back(spreader_pao_services,
@@ -33,6 +36,7 @@ _reported_state(){
quoter_ord_defs[i],
hedger_ord_defs[i],
leg_property_data);
_nlegs_crossed_hedges.emplace_back(std::pair<Price, double>(os::nan(),0.0));
bts_assert (_sec_key_to_index.find(leg_property_data.security_key())
== _sec_key_to_index.end());
_sec_key_to_index.insert(std::pair<uint32_t, size_t>(
@@ -24,6 +24,7 @@ private:
const bool _inited_new;
const size_t _n_legs;
const size_t _n_quoting_legs;
const api::Side _side;
// when the order is not created from the disk
// (ie created live) this is set to true
const api::orderman::OrderDefinition _order_def;
@@ -35,6 +36,10 @@ private:
Price _input_price;
Price _effective_price;
Quantity _quantity;
// this is used to pass in the calcuated hedge price/qty
// (preallocating so we dont have to allocate
// memory when calculating and calculating values)
std::vector<std::pair<Price,double>> _nlegs_crossed_hedges;
private:
size_t _calc_n_quoting_legs(const std::vector<LegPropertyData>& legs);
public:
@@ -61,10 +66,14 @@ public:
/////////////////////////////////
size_t n_legs() const { return _n_legs; }
bool all_legs_resolved() const {return n_legs() > 0;}
api::Side side() const {return _side;}
const api::orderman::OrderDefinition& order_def() const {return _order_def;}
Price input_price () const {return _input_price;}
Price effective_price () const {return _effective_price;}
Quantity quantity () const {return _quantity;}
std::vector<std::pair<Price,double>>& nlegs_crossed_hedges(){
return _nlegs_crossed_hedges;
}
// gets leg data from leg's sec key
SpreaderLegData& get_leg_data (SecurityKey security_key){
boost::container::flat_map<uint32_t, size_t>::const_iterator l_it = _sec_key_to_index.find(security_key.value());
@@ -121,7 +121,8 @@ public:
void static traverse_depth_for_quantity(const orderman::Book& leg_book,
const api::Side book_side,
Quantity target_quantity,
Price& out_price, Quantity& out_quantity){
Price& out_price,
Quantity& out_quantity){
uint32_t cum_quantity_u = 0;
const size_t n_levels = leg_book.n_levels();
// we could have kept a running price, updated at each level,
@@ -793,6 +794,47 @@ public:
quote_fill_quantity,
hedge_leg);
}
static bool compute_nlegs_crossed_hedges(
api::Side spr_side,
Price spr_price,
size_t n_legs,
const LegPropertyData& q_leg,
Price q_fill_price,
double q_fill_qty,
const ISpreaderManager& spreader,
std::vector<std::pair<Price,double>>& out_drivers){
// spr_cross_price is the spreader price computed by
// crossing all the hedges ie
// spr_cross_price=sum(ratio*price) where for the filled leg
// it is the fill price and for the hedging legs
// it is the cross that satisifies the size
double spr_cross_price=q_fill_price.value()*q_leg.price_multiplier();
for (size_t i=0;i<n_legs;i++)
if(i!=q_leg.leg_index()){
Price hedge_price;
Quantity hedge_qty;
const auto& hedge_leg=spreader.get_leg_data(i);
double hedge_qty_needed_raw =
get_leg_quantity_from_another_leg_quantity(q_leg,
q_fill_qty,
hedge_leg);
Quantity hedge_qty_needed_rounded_up =
Quantity(_round_hedge_target(hedge_qty_needed_raw));
traverse_depth_for_quantity(
spreader.get_book(i),
invert_side(hedge_leg.trading_side()),
hedge_qty_needed_rounded_up,
hedge_price,
hedge_qty);
if(hedge_qty.value()<hedge_qty_needed_rounded_up.value())
return false;
spr_cross_price += hedge_price.value()*hedge_leg.price_multiplier();
auto& driver_i=out_drivers[i];
driver_i.first=hedge_price;
driver_i.second=hedge_qty_needed_raw;
}
return securities::is_better(spr_side,Price(spr_cross_price),spr_price);
}
////////////////////////////////////////////////////
// Rounding functions //////////////////////////////
////////////////////////////////////////////////////