122 lines
3.5 KiB
C++
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|