Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d66c8e0ad8 | ||
|
|
8673f366d7 | ||
|
|
d9b37efbbd | ||
|
|
d23b7942b6 | ||
|
|
f41c3a5334 | ||
|
|
d8e8f90131 | ||
|
|
0358afccf9 | ||
|
|
d3ed6e21e4 | ||
|
|
9d96fcaa45 | ||
|
|
d70bd63659 | ||
|
|
246f9240e7 | ||
|
|
02d1badf0d |
No files matched your search
+1
-1
Submodule docker/linux updated: 8ee9692597...aedfd79e02.
@@ -56,6 +56,7 @@
|
||||
UIntTemplate="{StaticResource SimpleValueTextTemplate}"
|
||||
MarketDataTypeTemplate="{StaticResource SimpleValueTextTemplate}"
|
||||
MarketDataCalculationTemplate="{StaticResource SimpleValueTextTemplate}"
|
||||
ConditionalPriceTypeTemplate="{StaticResource SimpleValueTextTemplate}"
|
||||
>
|
||||
<usp:DataGridParameterCellTemplateConverter.BooleanTemplate>
|
||||
<DataTemplate>
|
||||
@@ -122,6 +123,11 @@
|
||||
<ComboBox SelectedItem="{Binding value}" ItemsSource="{u:EnumBindingSource {u:Nested sp:LegSpreaderParams.Types.LegMarketDataCalculation}}" ItemTemplate="{StaticResource EnumDescriptionTemplate}"/>
|
||||
</DataTemplate>
|
||||
</usp:DataGridParameterCellTemplateConverter.MarketDataCalculationTemplate>
|
||||
<usp:DataGridParameterCellTemplateConverter.ConditionalPriceTypeTemplate>
|
||||
<DataTemplate>
|
||||
<ComboBox SelectedItem="{Binding value}" ItemsSource="{u:EnumBindingSource {u:Nested sp:ConditionalQuoting.Types.PriceType}}" ItemTemplate="{StaticResource EnumDescriptionTemplate}"/>
|
||||
</DataTemplate>
|
||||
</usp:DataGridParameterCellTemplateConverter.ConditionalPriceTypeTemplate>
|
||||
<usp:DataGridParameterCellTemplateConverter.QuantityMeasureTemplate>
|
||||
<DataTemplate>
|
||||
<Grid IsEnabled="{Binding enabled}">
|
||||
|
||||
@@ -304,6 +304,7 @@ namespace mbts.ui.spark {
|
||||
public DataTemplate QuantityMeasureTemplate { get; set; }
|
||||
public DataTemplate MarketDataTypeTemplate { get; set; }
|
||||
public DataTemplate MarketDataCalculationTemplate { get; set; }
|
||||
public DataTemplate ConditionalPriceTypeTemplate { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
||||
Type t = (Type)value;
|
||||
@@ -314,6 +315,7 @@ namespace mbts.ui.spark {
|
||||
else if (t == typeof(QuantityMeasure)) return QuantityMeasureTemplate;
|
||||
else if (t == typeof(LegSpreaderParams.Types.MarketDataType)) return MarketDataTypeTemplate;
|
||||
else if (t == typeof(LegSpreaderParams.Types.LegMarketDataCalculation)) return MarketDataCalculationTemplate;
|
||||
else if (t == typeof(ConditionalQuoting.Types.PriceType)) return ConditionalPriceTypeTemplate;
|
||||
else return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,11 @@ namespace bts.shell {
|
||||
OutsideTicks = 3,
|
||||
Priority = RulePriority
|
||||
};
|
||||
public static ConditionalQuoting ConditionalQuoting => new ConditionalQuoting
|
||||
{
|
||||
NTicks = 2,
|
||||
PriceType = ConditionalQuoting.Types.PriceType.Leg
|
||||
};
|
||||
public static QuoteInsideMarketDistanceWithTravel QuoteInsideMarketDistanceWithTravel => new QuoteInsideMarketDistanceWithTravel { Priority = RulePriority };
|
||||
public static QuoteInsideMarketDistance QuoteInsideMarketDistance => new QuoteInsideMarketDistance { Priority = RulePriority };
|
||||
#endregion
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using mbts.ui.spark;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace mbts.spark {
|
||||
partial class SyntheticEditorVM {
|
||||
class EnableHedgeModel : RowModelBase<bool> {
|
||||
public override string display_name { get; } = "Enable Hedging";
|
||||
public override string help_text { get; } = "Send a hedge for this leg?";
|
||||
public override string man_page { get; } = string.Empty;
|
||||
|
||||
public override bool get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
leg_tup.leg_params.EnableHedging;
|
||||
|
||||
public override void set_value(LegSpreaderParamsTuple leg_tup, bool value) =>
|
||||
leg_tup.leg_params.EnableHedging = value;
|
||||
|
||||
public override bool has_errors(IReadOnlyCollection<LegSpreaderParamsTuple> leg_tups) =>
|
||||
!leg_tups.Any(lt => lt.leg_params.EnableHedging);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using mbts.ui.spark;
|
||||
using System;
|
||||
|
||||
namespace mbts.spark {
|
||||
partial class SyntheticEditorVM {
|
||||
class MinLeanQtyModel : RowModelBase<System.UInt32> {
|
||||
public override string display_name { get; } = "Min Lean Qty";
|
||||
public override string help_text { get; } = "Minimum Quantity required at this leg to quote";
|
||||
public override string man_page { get; } = string.Empty;
|
||||
|
||||
public override System.UInt32 get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
leg_tup.leg_params.QuoteParams.MinLeanQty;
|
||||
|
||||
public override void set_value(LegSpreaderParamsTuple leg_tup, System.UInt32 value) =>
|
||||
leg_tup.leg_params.QuoteParams.MinLeanQty = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
using bts.shell;
|
||||
using mbts.ui.spark;
|
||||
|
||||
namespace mbts.spark {
|
||||
partial class SyntheticEditorVM {
|
||||
class ConditionalQuoteEnabledModel : RowModelBase<bool> {
|
||||
readonly ConditionalQuotingTicksModel _ticks;
|
||||
readonly ConditionalQuotingPriceTypeModel _price_type;
|
||||
|
||||
public ConditionalQuoteEnabledModel(ConditionalQuotingTicksModel ticks, ConditionalQuotingPriceTypeModel price_type)
|
||||
{
|
||||
_ticks = ticks;
|
||||
_price_type = price_type;
|
||||
}
|
||||
|
||||
public override string display_name { get; } = string.Empty;
|
||||
public override string help_text { get; } = string.Empty;
|
||||
public override string man_page { get; } = string.Empty;
|
||||
public override ParameterSection[] section_path { get; } = new[] { Sections.Quote, Subsections.Conditional };
|
||||
|
||||
public override bool get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
leg_tup.leg_params.QuoteParams.ConditionalQuoting != null;
|
||||
|
||||
public override void set_value(LegSpreaderParamsTuple leg_tup, bool value) {
|
||||
if (value) {
|
||||
if (leg_tup.leg_params.QuoteParams.ConditionalQuoting == null) {
|
||||
leg_tup.leg_params.QuoteParams.ConditionalQuoting = SyntheticDataHelper.Defaults.ConditionalQuoting;
|
||||
_ticks.apply_value(leg_tup);
|
||||
_price_type.apply_value(leg_tup);
|
||||
}
|
||||
} else {
|
||||
leg_tup.leg_params.QuoteParams.ConditionalQuoting = null;
|
||||
}
|
||||
_ticks.set_enabled(leg_tup, value);
|
||||
_price_type.set_enabled(leg_tup, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
using mbts.ui.spark;
|
||||
using bts.spark;
|
||||
using PriceType = bts.spark.ConditionalQuoting.Types.PriceType;
|
||||
using mbts.collections.extensions;
|
||||
using System.Collections.Generic;
|
||||
using bts.shell;
|
||||
|
||||
namespace mbts.spark
|
||||
{
|
||||
partial class SyntheticEditorVM
|
||||
{
|
||||
class ConditionalQuotingPriceTypeModel : RowModelBase<PriceType>
|
||||
{
|
||||
IDictionary<uint, PriceType> _value_store = new Dictionary<uint, PriceType>();
|
||||
|
||||
public override string display_name { get; } = "Price Type";
|
||||
public override string help_text { get; } = string.Empty;
|
||||
public override string man_page { get; } = string.Empty;
|
||||
public override ParameterSection[] section_path { get; } = new[] { Sections.Quote, Subsections.Conditional };
|
||||
|
||||
public void apply_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
_get_value(leg_tup).PriceType = _value_from_store(leg_tup);
|
||||
|
||||
public override PriceType get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
_get_value(leg_tup) is ConditionalQuoting cond ?
|
||||
cond.PriceType :
|
||||
_value_from_store(leg_tup);
|
||||
|
||||
public override void set_value(LegSpreaderParamsTuple leg_tup, PriceType value)
|
||||
{
|
||||
_value_store[leg_tup.SecurityKey] = value;
|
||||
if (_get_value(leg_tup) is ConditionalQuoting cond)
|
||||
cond.PriceType = value;
|
||||
}
|
||||
|
||||
protected override bool _get_enabled(LegSpreaderParamsTuple leg_tup) => _get_value(leg_tup) != null; //TAHA_SPREADER
|
||||
|
||||
ConditionalQuoting _get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
leg_tup.leg_params.QuoteParams.ConditionalQuoting;
|
||||
|
||||
PriceType _value_from_store(LegSpreaderParamsTuple leg_tup) =>
|
||||
_value_store.GetValueOrDefault(leg_tup.SecurityKey, _ => SyntheticDataHelper.Defaults.ConditionalQuoting.PriceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using bts.shell;
|
||||
using bts.spark;
|
||||
using mbts.collections.extensions;
|
||||
using mbts.ui.spark;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace mbts.spark {
|
||||
partial class SyntheticEditorVM {
|
||||
class ConditionalQuotingTicksModel : RowModelBase<int> {
|
||||
IDictionary<uint, int> _value_store = new Dictionary<uint, int>();
|
||||
|
||||
public override string display_name { get; } = "Ticks";
|
||||
public override string help_text { get; } = string.Empty;
|
||||
public override string man_page { get; } = string.Empty;
|
||||
public override ParameterSection[] section_path { get; } = new[] { Sections.Quote, Subsections.Conditional };
|
||||
|
||||
public void apply_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
_get_value(leg_tup).NTicks = _value_from_store(leg_tup);
|
||||
|
||||
public override int get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
_get_value(leg_tup) is ConditionalQuoting cond ?
|
||||
cond.NTicks :
|
||||
_value_from_store(leg_tup);
|
||||
|
||||
public override void set_value(LegSpreaderParamsTuple leg_tup, int value) {
|
||||
_value_store[leg_tup.SecurityKey] = value;
|
||||
if (_get_value(leg_tup) is ConditionalQuoting cond)
|
||||
cond.NTicks = value;
|
||||
}
|
||||
|
||||
protected override bool _get_enabled(LegSpreaderParamsTuple leg_tup) =>
|
||||
_get_value(leg_tup) != null;
|
||||
|
||||
ConditionalQuoting _get_value(LegSpreaderParamsTuple leg_tup) =>
|
||||
leg_tup.leg_params.QuoteParams.ConditionalQuoting;
|
||||
|
||||
int _value_from_store(LegSpreaderParamsTuple leg_tup) =>
|
||||
_value_store.GetValueOrDefault(leg_tup.SecurityKey, _ => SyntheticDataHelper.Defaults.ConditionalQuoting.NTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,13 @@ namespace mbts.spark {
|
||||
"Reduces re-quoting updates by defining a region on either side " +
|
||||
"of the working quoting order, inside which quote updates will not be sent.");
|
||||
|
||||
public static ParameterSection Conditional =>
|
||||
new ParameterSection("Conditional", true,
|
||||
"Reduces re-quoting updates by only quoting if N ticks away from the opposite " +
|
||||
"inside market. Quotes are cancelled when it gets further away. 'Price Type' " +
|
||||
"dictates if this logic applies to the quoting market or to the synthetic spread " +
|
||||
"market");
|
||||
|
||||
public static ParameterSection InsideMarketThrottleThresholds =>
|
||||
new ParameterSection("Inside Market Throttle Thresholds", true,
|
||||
"Reduces re-quoting for quotes that are moving toward the inside market. " +
|
||||
|
||||
@@ -180,6 +180,9 @@ namespace mbts.spark {
|
||||
var quote_throttle_outside_ticks = new QuoteThrottleOutsideTicksModel();
|
||||
var quote_throttle_inside_ticks = new QuoteThrottleInsideTicksModel();
|
||||
|
||||
var conditional_quoting_ticks = new ConditionalQuotingTicksModel();
|
||||
var conditional_quoting_price_type = new ConditionalQuotingPriceTypeModel();
|
||||
|
||||
var quote_inside_market_throttle_ticks = new QuoteInsideMarketThrottleTicksModel();
|
||||
var quote_inside_market_throttle_min_move = new QuoteInsideMarketThrottleMinMoveModel();
|
||||
|
||||
@@ -201,13 +204,18 @@ namespace mbts.spark {
|
||||
_quantity_model,
|
||||
_price_mult_model,
|
||||
new IsQuoteModel(),
|
||||
//new EnableHedgeModel(), //TAHA_SPREADER
|
||||
new HedgeRatioModel(),
|
||||
//new MinLeanQtyModel(), //TAHA_SPREADER
|
||||
new QuoteHiddenModel(),
|
||||
new MarketDataTypeModel(),
|
||||
new MarketDataCalculationModel(),
|
||||
new QuoteThrottleEnabledModel(quote_throttle_inside_ticks, quote_throttle_outside_ticks),
|
||||
quote_throttle_inside_ticks,
|
||||
quote_throttle_outside_ticks,
|
||||
new ConditionalQuoteEnabledModel(conditional_quoting_ticks, conditional_quoting_price_type),
|
||||
conditional_quoting_ticks,
|
||||
conditional_quoting_price_type,
|
||||
//new QuoteInsideMarketThrottleEnabledModel(quote_inside_market_throttle_ticks, quote_inside_market_throttle_min_move),
|
||||
//quote_inside_market_throttle_ticks,
|
||||
//quote_inside_market_throttle_min_move,
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace bts.spark {
|
||||
TITLE_PANEL_HEIGHT = 30,
|
||||
COLUMN_HEADER_HEIGHT = 27,
|
||||
SPARK_MENU_ITEM_HEIGHT = 45,
|
||||
GRID_FOOTER_HEIGHT = 30,
|
||||
ABSOLUTE_MIN_HEIGHT = 230;
|
||||
|
||||
protected static readonly TimeSpan CONTENT_MEASURE_WAIT_PERIOD = TimeSpan.FromSeconds(0.3);
|
||||
@@ -60,7 +61,7 @@ namespace bts.spark {
|
||||
public abstract UIElement Content { get; }
|
||||
public virtual IEnumerable<SparkCommand> Commands => Enumerable.Empty<SparkCommand>();
|
||||
public virtual double MinWidth => 400;
|
||||
public virtual double MinHeight => Math.Max(ABSOLUTE_MIN_HEIGHT, TITLE_PANEL_HEIGHT + COLUMN_HEADER_HEIGHT + Commands.Count() * SPARK_MENU_ITEM_HEIGHT);
|
||||
public virtual double MinHeight => Math.Max(ABSOLUTE_MIN_HEIGHT, TITLE_PANEL_HEIGHT + COLUMN_HEADER_HEIGHT + GRID_FOOTER_HEIGHT + Commands.Count() * SPARK_MENU_ITEM_HEIGHT);
|
||||
|
||||
public ShellWindowUI GetContent() =>
|
||||
new ShellWindowUI(new SparkWindowView(_bus, Commands, Content));
|
||||
|
||||
@@ -33,8 +33,11 @@ string dump(IntPrice price) {
|
||||
string dump(PriceSize ps) {
|
||||
stringstream res;
|
||||
res << "{";
|
||||
res << "'price': " << std::setprecision(11) << ps.price() << ", ";
|
||||
res << "'size': " << ps.size() << " ";
|
||||
res << "'price': " << std::setprecision(11) << ps.price();
|
||||
if (!ps.is_nan()) {
|
||||
res << " (^" << (int)ps.exponent() << ")";
|
||||
}
|
||||
res << ", 'size': " << ps.size() << " ";
|
||||
// res << "'mant': " << ps.mantissa() << ", ";
|
||||
// res << "'exp': " << (int)ps.exponent() << " ";
|
||||
res << "}";
|
||||
@@ -162,34 +165,42 @@ string dump_entry(const HotDepthEntry& entry) {
|
||||
res << "{ ";
|
||||
res << "'timestamp': " << dump(entry.time()) << ", ";
|
||||
res << "'key': " << entry.key << ", ";
|
||||
|
||||
res << "\n'bid': [";
|
||||
for (const auto& level : entry.direct) {
|
||||
res << dump(level.bid()) << ", ";
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "\n'ask': [";
|
||||
for (const auto& level : entry.direct) {
|
||||
res << dump(level.ask()) << ", ";
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "'\nimplied_bid': [";
|
||||
for (const auto& level : entry.implied) {
|
||||
res << dump(level.bid()) << ", ";
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "'\nimplied_ask': [";
|
||||
for (const auto& level : entry.implied) {
|
||||
res << dump(level.ask()) << ", ";
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "\n'settlement': '" << dump(entry.settlement) << "', ";
|
||||
res << "'settlement': '" << dump(entry.settlement) << "', ";
|
||||
res << "'status': '" << CoconutSecurityStatus_Name((CoconutSecurityStatus)entry.status) << "', ";
|
||||
res << "'sequence': '" << entry.sequence << "', ";
|
||||
|
||||
res << "\n 'bid': [";
|
||||
for (const auto& level : entry.direct) {
|
||||
if (!level.bid().is_nan()) {
|
||||
res << dump(level.bid()) << ", ";
|
||||
}
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "\n 'ask': [";
|
||||
for (const auto& level : entry.direct) {
|
||||
if (!level.ask().is_nan()) {
|
||||
res << dump(level.ask()) << ", ";
|
||||
}
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "\n 'implied_bid': [";
|
||||
for (const auto& level : entry.implied) {
|
||||
if (!level.bid().is_nan()) {
|
||||
res << dump(level.bid()) << ", ";
|
||||
}
|
||||
}
|
||||
res << "], ";
|
||||
|
||||
res << "\n 'implied_ask': [";
|
||||
for (const auto& level : entry.implied) {
|
||||
if (!level.ask().is_nan()) {
|
||||
res << dump(level.ask()) << ", ";
|
||||
}
|
||||
}
|
||||
res << "]";
|
||||
|
||||
res << " }";
|
||||
return res.str();
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ private:
|
||||
Quantity quantity) {
|
||||
_child_order_state.place_order(price,
|
||||
quantity,
|
||||
_spreader.current_time(),
|
||||
_fill_trace);
|
||||
}
|
||||
void _modify_order (Price new_price){
|
||||
|
||||
@@ -171,6 +171,22 @@ void SingleLegQuoter::_compute_price_quantity(Price& price,
|
||||
_drivers_temp_usage,
|
||||
price,
|
||||
quantity);
|
||||
if(!_apply_quote_entry_params(price, quantity))
|
||||
quantity=Quantity(0);
|
||||
}
|
||||
bool SingleLegQuoter::_apply_quote_entry_params(
|
||||
Price new_price,
|
||||
Quantity new_quantity){
|
||||
bool working_and_new = is_active_order() &&
|
||||
ms_diff(
|
||||
_spreader.current_time(),
|
||||
_price_quantity_state.order_state().order_place_time())
|
||||
<= 5000;
|
||||
return working_and_new ? true : SpreaderUtils::conditional_quoting(
|
||||
new_price,
|
||||
new_quantity,
|
||||
_this_leg_data.leg_index(),
|
||||
_spreader);
|
||||
}
|
||||
void SingleLegQuoter::_adjust_for_hidden_order(Price& price,
|
||||
Quantity& quantity){
|
||||
|
||||
@@ -169,8 +169,13 @@ private:
|
||||
bool _target_reached(){
|
||||
return _price_quantity_state.target_reached();
|
||||
}
|
||||
void _place_order (Price price, Quantity quantity, const PerfTrace &trace = PerfTrace()) {
|
||||
_child_order_state.place_order(price, quantity,trace);
|
||||
void _place_order (Price price,
|
||||
Quantity quantity,
|
||||
const PerfTrace &trace) {
|
||||
_child_order_state.place_order(price,
|
||||
quantity,
|
||||
_spreader.current_time(),
|
||||
trace);
|
||||
}
|
||||
void _modify_order (Price price, Quantity quantity, PerfTrace &trace) {
|
||||
_child_order_state.modify_order(price, quantity, trace);
|
||||
@@ -181,6 +186,17 @@ private:
|
||||
// this is the function that computes the quoting price and the
|
||||
// quantity for this leg.
|
||||
void _compute_price_quantity(Price& price, Quantity& quantity);
|
||||
// applies the applicable throttling params that are
|
||||
// parts of the quoting params
|
||||
void _apply_quote_throttling_params (
|
||||
Price new_price, Quantity new_quantity,
|
||||
Price& out_price, Quantity& out_quantity);
|
||||
// applies the applicable quoting params that control
|
||||
// whether there should be a quote out there or not.
|
||||
// returns false is the quote shoudl not be out
|
||||
// there
|
||||
bool _apply_quote_entry_params (
|
||||
Price new_price, Quantity new_quantity);
|
||||
// this takes in a price and qty that already has
|
||||
// computed values and applies the hidden order logic
|
||||
// to them (ie if the price results in a cross, and adjusts
|
||||
|
||||
@@ -20,7 +20,10 @@ _filled_price(src._filled_price),
|
||||
_filled_quantity(src._filled_quantity),
|
||||
_last_filled_price(src._last_filled_price),
|
||||
_last_reported_order_price(src._last_reported_order_price),
|
||||
_last_filled_quantity(src._last_filled_quantity)
|
||||
_last_filled_quantity(src._last_filled_quantity),
|
||||
_out_price(src._out_price),
|
||||
_out_quantity(src._out_quantity),
|
||||
_order_place_time(src._order_place_time)
|
||||
{ }
|
||||
SpreaderChildOrderState::SpreaderChildOrderState (bts::orderman::ChildOrder& child_order,
|
||||
SecurityKey sec_key,
|
||||
@@ -50,6 +53,7 @@ void SpreaderChildOrderState::_init_running_values(){
|
||||
_last_filled_quantity = Quantity(0);
|
||||
_out_price = Price(0);
|
||||
_out_quantity = Quantity(0);
|
||||
_order_place_time=bts::TimeStamp();
|
||||
}
|
||||
void SpreaderChildOrderState::re_init(){
|
||||
SpreaderUtils::compute_average_price(_base_price, _base_quantity,
|
||||
|
||||
@@ -33,6 +33,7 @@ private:
|
||||
Quantity _last_filled_quantity;
|
||||
Price _out_price;
|
||||
Quantity _out_quantity;
|
||||
bts::TimeStamp _order_place_time;
|
||||
public:
|
||||
// constructors ///////////////////
|
||||
///////////////////////////////////
|
||||
@@ -93,6 +94,9 @@ public:
|
||||
Quantity out_quantity () const {
|
||||
return _out_quantity;
|
||||
}
|
||||
bts::TimeStamp order_place_time() const{
|
||||
return _order_place_time;
|
||||
}
|
||||
// init ///////////////////
|
||||
///////////////////////////
|
||||
// zero's out base values
|
||||
@@ -125,9 +129,11 @@ public:
|
||||
/////////////////////////////////////
|
||||
void place_order(Price price,
|
||||
Quantity quantity,
|
||||
const PerfTrace & trace = PerfTrace()){
|
||||
bts::TimeStamp curr_time,
|
||||
const PerfTrace& trace){
|
||||
_out_price = price;
|
||||
_out_quantity = quantity;
|
||||
_order_place_time=curr_time;
|
||||
bts_assert(_n_place_orders == 0);
|
||||
_n_place_orders++;
|
||||
LOG(OrderMan, Info, "SpreaderChildOrderState::place_order "
|
||||
|
||||
@@ -238,6 +238,12 @@ public:
|
||||
price_qty = Quantity(0); cumm_qty = Quantity(0);
|
||||
return false;
|
||||
}
|
||||
// find the top of the synthetic book
|
||||
static Price top_of_book_price (const ISpreaderManager&,
|
||||
api::Side){
|
||||
Price rv(os::nan());
|
||||
return rv;
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
// quoting params //////////////////////////////////
|
||||
////////////////////////////////////////////////////
|
||||
@@ -270,6 +276,60 @@ public:
|
||||
else
|
||||
return false;
|
||||
}
|
||||
static bool conditional_quoting(Price quoting_price,
|
||||
Quantity quoting_qty,
|
||||
size_t leg_idx,
|
||||
const ISpreaderManager& spreader){
|
||||
const auto& leg_data=spreader.get_leg_data(leg_idx);
|
||||
const auto& leg_params=leg_data.leg_params();
|
||||
if(leg_params.has_quote_params() &&
|
||||
leg_params.quote_params().has_conditional_quoting()){
|
||||
const auto& cond_quoting_params=
|
||||
leg_params.quote_params().conditional_quoting();
|
||||
// if(cond_quoting_params.price_type()==spark::ConditionalQuoting::LEG)
|
||||
// TODO: for synthetic condition
|
||||
return conditional_quoting_leg(quoting_price,
|
||||
quoting_qty,
|
||||
leg_data.trading_side(),
|
||||
leg_data.tick_size(),
|
||||
spreader.get_book(leg_idx),
|
||||
cond_quoting_params.n_ticks());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// applies the conditional quoting logic, when the
|
||||
// setting applies to the quoting leg.
|
||||
// if the calculated quoting price (first arg)
|
||||
// is not n ticks within (or through, depending
|
||||
// on the value of n_ticks) it returns false
|
||||
static bool conditional_quoting_leg (Price quoting_price,
|
||||
Quantity,
|
||||
api::Side quote_side,
|
||||
double tick_size,
|
||||
const Book& book,
|
||||
int n_ticks){
|
||||
if(quote_side==api::SIDE_BUY){
|
||||
const md::PriceSize& top_ask=book.ask()[0];
|
||||
if(top_ask.size()==0)
|
||||
return false;
|
||||
int t_diff=securities::price_diff_to_ticks(
|
||||
quoting_price.value(),
|
||||
top_ask.price(),
|
||||
tick_size);
|
||||
return t_diff<=n_ticks;
|
||||
}
|
||||
else{
|
||||
const md::PriceSize& top_bid=book.bid()[0];
|
||||
if(top_bid.size()==0)
|
||||
return false;
|
||||
int t_diff=securities::price_diff_to_ticks(
|
||||
top_bid.price(),
|
||||
quoting_price.value(),
|
||||
tick_size);
|
||||
return t_diff<=n_ticks;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// pre-hedge params ////////////////////////////////
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
@@ -47,7 +47,9 @@ TEST_CASE ("quoter price quantity state", "[spreader]")
|
||||
REQUIRE (s.out_price() == Price (0.0));
|
||||
REQUIRE (s.out_quantity() == Quantity (0));
|
||||
// set out price and quantity
|
||||
order.place_order(Price (-0.35), Quantity (123));
|
||||
PerfTrace dont_care;
|
||||
bts::TimeStamp ts;
|
||||
order.place_order(Price (-0.35), Quantity (123),ts,dont_care);
|
||||
REQUIRE (s.target_spread_price() == Price (-1.0));
|
||||
REQUIRE (s.target_leg_quantity() == Quantity (200));
|
||||
REQUIRE (s.aggregated_filled_quantity() == Quantity (25));
|
||||
@@ -100,7 +102,9 @@ TEST_CASE ("quoter price quantity state", "[spreader]")
|
||||
s.add_hedged_reduction (Quantity(5));
|
||||
s.add_hedged_reduction (Quantity(15));
|
||||
// set out values
|
||||
order_2.place_order (Price(1), Quantity (50));
|
||||
PerfTrace dont_care;
|
||||
bts::TimeStamp ts;
|
||||
order_2.place_order (Price(1), Quantity (50),ts,dont_care);
|
||||
REQUIRE (s.target_spread_price() == Price (-1.0));
|
||||
REQUIRE (s.target_leg_quantity() == Quantity (200));
|
||||
REQUIRE (s.aggregated_filled_quantity() == Quantity (40));
|
||||
@@ -121,7 +125,7 @@ TEST_CASE ("quoter price quantity state", "[spreader]")
|
||||
on_order_update (order_2, api::orderman::OrderStatus::ORDER_STATUS_WORKING, Quantity (10), Price (2000));
|
||||
s.add_hedged_reduction (Quantity(3));
|
||||
s.add_hedged_reduction (Quantity(7));
|
||||
order_2.place_order (Price(0.75), Quantity (50));
|
||||
order_2.place_order (Price(0.75), Quantity (50),ts,dont_care);
|
||||
REQUIRE (s.target_spread_price() == Price (-1.0));
|
||||
REQUIRE (s.target_leg_quantity() == Quantity (200));
|
||||
REQUIRE (s.aggregated_filled_quantity() == Quantity (10));
|
||||
|
||||
@@ -60,6 +60,7 @@ message QuoteParams
|
||||
// e.g. If you are working N lots of 2 (leg_1) by 3 spread, you will work leg_1 at a price determined by
|
||||
// the price level at which you can sell N*3*lean_quantity_ratio.
|
||||
double lean_quantity_ratio = 20;
|
||||
uint32 min_lean_qty = 30;
|
||||
|
||||
QuoteMuteZone quote_mute_zone = 1000;
|
||||
QuoteRepriceThrottle quote_reprice_throttle = 1010;
|
||||
@@ -67,6 +68,7 @@ message QuoteParams
|
||||
QuoteInsideMarketDistanceWithTravel quote_inside_market_distance_with_travel = 1030;
|
||||
QuoteMaxOrderMove quote_max_order_move = 1040;
|
||||
QuoteHidden quote_hidden = 1050;
|
||||
ConditionalQuoting conditional_quoting=1060;
|
||||
}
|
||||
|
||||
/*************************************Quote MuteZone***********************************
|
||||
@@ -100,6 +102,27 @@ message QuoteMuteZone
|
||||
uint32 inside_ticks = 20;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Conditional Quoting //////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////
|
||||
message ConditionalQuoting{
|
||||
// for a leg to be quoted, the quote (or spreader) price has
|
||||
// to be within N ticks from the opposite inside market.
|
||||
// If there is an active quote and the condition ceases
|
||||
// to exist, its pulled.
|
||||
// negative values mean it has to penetrate that
|
||||
// many ticks into the opposite inside market
|
||||
int32 n_ticks = 1;
|
||||
// this tells if the logic applies wrt to the
|
||||
// quoting order (and its market), or the synthetic itself
|
||||
enum PriceType
|
||||
{
|
||||
LEG = 0;
|
||||
SYNTHETIC = 1;
|
||||
}
|
||||
PriceType price_type=10;
|
||||
}
|
||||
|
||||
/*************************************Quote RepriceThrottled (unused)*******************************
|
||||
(Stellar's sensitivity)
|
||||
This parameter defines regions (wrt their distance from the inside market)
|
||||
|
||||
@@ -195,6 +195,15 @@ void dump_db(const vector<string> args) {
|
||||
md::db::load_securities(symbols, [&](const api::Security& security) {
|
||||
if (all || keys.find(security.id()) != keys.end()) {
|
||||
security.PrintDebugString();
|
||||
if (md::securitytype_of(security) == api::SECURITYTYPE_SYNTHETIC) {
|
||||
auto metadata = md::db::load_metadata();
|
||||
for (const auto &m : metadata) {
|
||||
if(m.security_key() == security.id()) {
|
||||
m.PrintDebugString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user