Files
spark/src/lib/orderman/orders/book_algos/CoverOrder.cpp
T
2018-11-13 22:15:30 +00:00

122 lines
3.5 KiB
C++

#include "CoverOrder.h"
#include "lib/orderman/actors/order_manager/OrderBuilder.h"
#include "lib/orderman/orders/spreader_orders/spreader/SpreaderUtils.h"
#include "lib/utils/PBUtils.h"
#include <google/protobuf/timestamp.pb.h>
namespace bts {
namespace orderman {
using namespace api::orderman;
struct CoverOrder::PImpl
{
PImpl() {}
int hedge_ticks;
OrderDefinition hedge_def;
};
CoverOrder::CoverOrder() : me(new PImpl()) {}
CoverOrder::~CoverOrder() {}
void CoverOrder::setup_child(const api::orderman::OrderDefinition& this_def, const PreActivationOrderServices&,
api::orderman::OrderState& initial_state, api::orderman::OrderDefinition* out_child)
{
initial_state.mutable_cover();
auto const &cover_def = this_def.custom_def().cover();
*out_child->mutable_custom_def() = cover_def.child();
me->hedge_ticks = cover_def.hedge_ticks();
}
bool CoverOrder::setup_hedge(const api::orderman::OrderDefinition& this_def, const PreActivationOrderServices&,
api::orderman::OrderDefinition* out_hedge)
{
auto const &cover_def = this_def.custom_def().cover();
if(cover_def.has_hedge())
{
*out_hedge->mutable_custom_def() = cover_def.hedge();
if(definition().side() == api::SIDE_BUY)
out_hedge->set_side(api::SIDE_SELL);
else
out_hedge->set_side(api::SIDE_BUY);
return true;
}
else
return false;
}
void CoverOrder::send_hedge_if_new_fills(const api::orderman::OrderState& orig_state, const OrderStateUpdateEvent& new_state)
{
uint32_t qty = new_state.filled_quantity - orig_state.filled_quantity();
if(qty > 0)
{
double prx = new_state.last_price;
if(definition().side() == api::SIDE_BUY) //if this is a buy, I'm going to sell my hedge, nticks higher than the fill price
prx = prx + tick_size() * me->hedge_ticks;
else
prx = prx - tick_size() * me->hedge_ticks;
build_and_send_hedge(Price(prx), Quantity(qty));
}
}
void CoverOrder::on_book_update(const bts::orderman::BookUpdateEvent& )
{
switch (this_state().status())
{
case ORDER_STATUS_WORKING:
switch (child_state().status())
{
case ORDER_STATUS_INACTIVE:
{
activate_child(Price(this_state().price()), Quantity(this_state().quantity()));
transition(ORDER_STATUS_WORKING);
report_state();
}
break;
case ORDER_STATUS_WORKING:
{
}
break;
case ORDER_STATUS_PENDING_WORKING:
break;
// child cannot be in any of these states if we are in the working state
case ORDER_STATUS_DISCONNECTED:
case ORDER_STATUS_ERROR:
case ORDER_STATUS_REJECTED_BY_SPARK:
case ORDER_STATUS_COMPLETED:
case ORDER_STATUS_CANCELED:
case OrderStatus_INT_MIN_SENTINEL_DO_NOT_USE_:
case OrderStatus_INT_MAX_SENTINEL_DO_NOT_USE_:
bts_assert(false);
break;
}
break;
case ORDER_STATUS_COMPLETED:
case ORDER_STATUS_CANCELED:
case ORDER_STATUS_ERROR:
break;
case ORDER_STATUS_INACTIVE:
case ORDER_STATUS_REJECTED_BY_SPARK:
case ORDER_STATUS_PENDING_WORKING:
case ORDER_STATUS_DISCONNECTED:
case OrderStatus_INT_MIN_SENTINEL_DO_NOT_USE_:
case OrderStatus_INT_MAX_SENTINEL_DO_NOT_USE_:
bts_assert(false);
break;
}
}
}
}