Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d66c8e0ad8 | ||
|
|
8673f366d7 | ||
|
|
d9b37efbbd | ||
|
|
d23b7942b6 | ||
|
|
f41c3a5334 | ||
|
|
d8e8f90131 | ||
|
|
0358afccf9 | ||
|
|
d3ed6e21e4 | ||
|
|
9d96fcaa45 | ||
|
|
d70bd63659 | ||
|
|
246f9240e7 | ||
|
|
02d1badf0d | ||
|
|
753221e429 | ||
|
|
d5f41d8405 | ||
|
|
3490834108 | ||
|
|
94c2d9182c | ||
|
|
f68aac2015 | ||
|
|
a9ef7e47b5 | ||
|
|
9762a81a59 | ||
|
|
744260bea5 | ||
|
|
e0f1137ee2 |
No files matched your search
+1
-1
Submodule docker/linux updated: 8ee9692597...aedfd79e02.
@@ -1,3 +1,11 @@
|
||||
1.3.8
|
||||
- Grid Footers
|
||||
- Grid footers have been added to all forms containing a grid
|
||||
|
||||
1.3.7
|
||||
- Net Change pricing
|
||||
- The ability to price synthetics based off of net change
|
||||
|
||||
1.3.5
|
||||
- Speed Enhanments
|
||||
- Further speed enhancements
|
||||
|
||||
@@ -16,29 +16,48 @@
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<AdornerDecorator>
|
||||
<c:DIYGrid
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<c:DIYGrid
|
||||
x:Name="_grid"
|
||||
Grid.Row="0"
|
||||
Columns="{Binding columns}"
|
||||
CurrentRow="{Binding current_row}"
|
||||
Rows="{Binding rows_view}"
|
||||
SelectionHighlight="{Binding grid_settings_manager.selection_highlight, Mode=OneWay}"
|
||||
>
|
||||
<c:DIYGrid.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
<KeyBinding Key="Return" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
</c:DIYGrid.InputBindings>
|
||||
<c:DIYGrid.CommandBindings>
|
||||
<CommandBinding
|
||||
<c:DIYGrid.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
<KeyBinding Key="Return" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
</c:DIYGrid.InputBindings>
|
||||
<c:DIYGrid.CommandBindings>
|
||||
<CommandBinding
|
||||
Command="{x:Static c:DIYGrid.DefaultRowCommand}"
|
||||
Executed="{x:Static c:DIYGrid.DefaultRowActionExecuted}"
|
||||
CanExecute="{x:Static c:DIYGrid.DefaultRowActionCanExecute}"
|
||||
/>
|
||||
</c:DIYGrid.CommandBindings>
|
||||
<c:DIYGrid.RowTemplate>
|
||||
<DataTemplate>
|
||||
<usp:MarketViewRowView usp:GridAnimation.RowAnimation="{Binding animations}"/>
|
||||
</DataTemplate>
|
||||
</c:DIYGrid.RowTemplate>
|
||||
</c:DIYGrid>
|
||||
</c:DIYGrid.CommandBindings>
|
||||
<c:DIYGrid.RowTemplate>
|
||||
<DataTemplate>
|
||||
<usp:MarketViewRowView usp:GridAnimation.RowAnimation="{Binding animations}"/>
|
||||
</DataTemplate>
|
||||
</c:DIYGrid.RowTemplate>
|
||||
</c:DIYGrid>
|
||||
<StatusBar Grid.Row="1" DockPanel.Dock="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Securities: "/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ElementName=_grid, Path=Rows.Count}"/>
|
||||
</Grid>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</AdornerDecorator>
|
||||
</UserControl>
|
||||
@@ -18,10 +18,18 @@
|
||||
</UserControl.Resources>
|
||||
<AdornerDecorator>
|
||||
<Grid>
|
||||
<c:DIYGrid Columns="{Binding columns}"
|
||||
Rows="{Binding rows_view}" CurrentRow="{Binding current_row}"
|
||||
SelectionHighlight="{Binding grid_settings_manager.selection_highlight, Mode=OneWay}"
|
||||
>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<c:DIYGrid
|
||||
x:Name="_grid"
|
||||
Grid.Row="0"
|
||||
Columns="{Binding columns}"
|
||||
Rows="{Binding rows_view}"
|
||||
CurrentRow="{Binding current_row}"
|
||||
SelectionHighlight="{Binding grid_settings_manager.selection_highlight, Mode=OneWay}"
|
||||
>
|
||||
<c:DIYGrid.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
<KeyBinding Key="Return" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
@@ -39,6 +47,17 @@
|
||||
</DataTemplate>
|
||||
</c:DIYGrid.RowTemplate>
|
||||
</c:DIYGrid>
|
||||
<StatusBar Grid.Row="1" DockPanel.Dock="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text=" "/>
|
||||
</Grid>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</AdornerDecorator>
|
||||
</UserControl>
|
||||
@@ -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
|
||||
|
||||
@@ -16,11 +16,16 @@
|
||||
</UserControl.Resources>
|
||||
<AdornerDecorator>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<c:DIYGrid
|
||||
x:Name="_grid"
|
||||
Columns="{Binding columns}"
|
||||
CurrentRow="{Binding current_row}"
|
||||
Rows="{Binding rows_view}"
|
||||
x:Name="_grid"
|
||||
Grid.Row="0"
|
||||
Columns="{Binding columns}"
|
||||
CurrentRow="{Binding current_row}"
|
||||
Rows="{Binding rows_view}"
|
||||
>
|
||||
<c:DIYGrid.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{x:Static c:DIYGrid.DefaultRowCommand}"/>
|
||||
@@ -39,6 +44,18 @@
|
||||
</DataTemplate>
|
||||
</c:DIYGrid.RowTemplate>
|
||||
</c:DIYGrid>
|
||||
<StatusBar Grid.Row="1" DockPanel.Dock="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Synthetics: "/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ElementName=_grid, Path=Rows.Count}"/>
|
||||
</Grid>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</AdornerDecorator>
|
||||
</UserControl>
|
||||
@@ -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,8 +19,13 @@
|
||||
</UserControl.Resources>
|
||||
<AdornerDecorator>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<c:DIYGrid
|
||||
x:Name="_grid"
|
||||
Grid.Row="0"
|
||||
Columns="{Binding columns}"
|
||||
CurrentRow="{Binding current_row}"
|
||||
Rows="{Binding rows_view}"
|
||||
@@ -42,6 +47,18 @@
|
||||
</DataTemplate>
|
||||
</c:DIYGrid.RowTemplate>
|
||||
</c:DIYGrid>
|
||||
<StatusBar Grid.Row="1" DockPanel.Dock="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Fills: "/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ElementName=_grid, Path=Rows.Count}"/>
|
||||
</Grid>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</AdornerDecorator>
|
||||
</UserControl>
|
||||
@@ -62,9 +62,14 @@
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<AdornerDecorator>
|
||||
<c:DIYGrid
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<c:DIYGrid
|
||||
x:Name="_grid"
|
||||
Grid.Row="2"
|
||||
Grid.Row="0"
|
||||
Columns="{Binding columns}"
|
||||
CurrentRow="{Binding current_row, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Rows="{Binding rows_view}"
|
||||
@@ -148,5 +153,22 @@
|
||||
/>
|
||||
</c:DIYGrid.CommandBindings>
|
||||
</c:DIYGrid>
|
||||
<StatusBar Grid.Row="1" DockPanel.Dock="Bottom">
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Orders: "/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding ElementName=_grid, Path=Rows.Count}"/>
|
||||
<TextBlock Grid.Column="2" Text=" of "/>
|
||||
<TextBlock Grid.Column="3" Text="{Binding rows_view.SourceCollection.Count}"/>
|
||||
</Grid>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</AdornerDecorator>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,34 @@
|
||||
<UserControl x:Class="mbts.ui.controls.WorkspaceItemControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:mbts.ui.controls"
|
||||
xmlns:ui="clr-namespace:mbts.ui"
|
||||
mc:Ignorable="d"
|
||||
ui:StateManager.VisualState="{Binding VisualState}"
|
||||
>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Overridden">
|
||||
<Storyboard>
|
||||
<ColorAnimation Storyboard.TargetName="_main_button"
|
||||
Storyboard.TargetProperty="Background.Color"
|
||||
To="{x:Static ui:BTSColors.success}"
|
||||
Duration="0:0:0.2"
|
||||
AutoReverse="True" RepeatBehavior="3x" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Button x:Name="_main_button" Command="{Binding ActivateCommand}" Style="{DynamicResource DialogListButton}">
|
||||
<Grid>
|
||||
<Image Source="{Binding Icon}" HorizontalAlignment="Left" Height="16" Margin="4" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="28,0,0,0" x:Name="text" />
|
||||
<Button Style="{StaticResource RoundCloseButton}" HorizontalAlignment="Right" VerticalAlignment="Center" Command="{Binding DeleteCommand}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace mbts.ui.controls {
|
||||
/// <summary>
|
||||
/// Interaction logic for WorkspaceItemControl.xaml
|
||||
/// </summary>
|
||||
public partial class WorkspaceItemControl : UserControl
|
||||
{
|
||||
public WorkspaceItemControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,10 @@ namespace mbts.ui.shell
|
||||
public object Icon {
|
||||
get { return Icons.Window; }
|
||||
}
|
||||
|
||||
private string _vstate = "Normal";
|
||||
public string VisualState { get { return _vstate; } set { _vstate = value; RaisePropertyChanged("VisualState"); } }
|
||||
|
||||
internal WorkspaceDefinition Definition { get; private set; }
|
||||
|
||||
public ICommand ActivateCommand {
|
||||
|
||||
@@ -59,13 +59,7 @@
|
||||
<ItemsControl ItemsSource="{Binding Workspaces}" Style="{StaticResource CommonList}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button Command="{Binding ActivateCommand}" Style="{DynamicResource DialogListButton}">
|
||||
<Grid>
|
||||
<Image Source="{Binding Icon}" HorizontalAlignment="Left" Height="16" Margin="4" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="28,0,0,0" x:Name="text" />
|
||||
<Button Style="{StaticResource RoundCloseButton}" HorizontalAlignment="Right" VerticalAlignment="Center" Command="{Binding DeleteCommand}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<controls:WorkspaceItemControl />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
@@ -45,8 +45,13 @@ namespace mbts.ui.shell
|
||||
{
|
||||
clear_error("SaveName");
|
||||
}
|
||||
var save_candidate_already_exists = Workspaces.Any(x => x.Name == SaveName);
|
||||
// Save
|
||||
_work_model.save_workspace(SaveName, ispublic: IsPublicWorkspace);
|
||||
|
||||
// if we just overwrote something, have the vm reflect it
|
||||
if (save_candidate_already_exists)
|
||||
Workspaces.Where(x => x.Name == SaveName).ForEach(x => x.VisualState = "Overridden");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace mbts.spark {
|
||||
Stopwatch stop_watch = new Stopwatch();
|
||||
TimeSpan elapsed_total = TimeSpan.Zero;
|
||||
ExceptionAssert.Argument.GreaterThan(excessive_cycle_ratio, 1.0, nameof(excessive_cycle_ratio));
|
||||
double excessive_cycle_ms = interval.Milliseconds * (double)sample_cycle_size * excessive_cycle_ratio;
|
||||
double excessive_cycle_ms = interval.TotalMilliseconds * (double)sample_cycle_size * excessive_cycle_ratio;
|
||||
int cycle_count = 0;
|
||||
DispatcherTimer timer = new DispatcherTimer(interval, priority, on_tick, Dispatcher.CurrentDispatcher);
|
||||
timer.Start();
|
||||
@@ -65,7 +65,7 @@ namespace mbts.spark {
|
||||
stop_watch.Stop();
|
||||
var cycle_ms = (stop_watch.Elapsed - elapsed_total).TotalMilliseconds;
|
||||
if (cycle_ms > excessive_cycle_ms)
|
||||
Log.Ui.warn($"{name} DispatcherTimer took {cycle_ms}ms to complete {sample_cycle_size} cycles, target rate is 1 per {interval.Milliseconds}ms.");
|
||||
Log.Ui.warn($"{name} DispatcherTimer took {cycle_ms}ms to complete {sample_cycle_size} cycles, target rate is 1 per {interval.TotalMilliseconds}ms.");
|
||||
elapsed_total = stop_watch.Elapsed;
|
||||
}
|
||||
work();
|
||||
|
||||
@@ -1 +1 @@
|
||||
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/services/AdminService.proto;api/services/ApiUnitTestService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/services/UserService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/Executor.conf;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/dynamic_orders.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/dynamic_orders.proto;config/protos/jetfix.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/quickbus_cfg.proto;config/protos/spreader.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;jetfix/codec/FIXArray.cpp;jetfix/common/OutFIX.cpp;jetfix/connection/AsyncReader.cpp;jetfix/connection/IConnection.cpp;jetfix/connection/SocketConnection.cpp;jetfix/gateway/CoreGateway.cpp;jetfix/gateway/JetFIXGateway.cpp;jetfix/gateway/Session.cpp;jetfix/store/FIXFileStore.cpp;jetfix/store/session_name.cpp;jetfix/tests/async_reader_tests.cpp;jetfix/tests/decoding_tests.cpp;jetfix/tests/fix_encoding_stream_tests.cpp;jetfix/tests/fix_fragment_tests.cpp;jetfix/tests/jetfix_performance_tests.cpp;jetfix/tests/sample_fix.cpp;jetfix/tests/store_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPriceLantencyTester.cpp;md/Diag/ShmDumper.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MDRecoverableConsumer.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/md2_tests.cpp;md/test/synthetic_book_merge_tests.cpp;mercury/actors/IPollableActor.cpp;mercury/broker/Broker.cpp;mercury/broker/BrokerProxy.cpp;mercury/broker/ILocalBroker.cpp;mercury/broker/IRemoteBroker.cpp;mercury/common/mercury_common.cpp;mercury/events/TimerEvent.cpp;mercury/executor/Executor.cpp;mercury/topics/Topic.cpp;metrics/metrics.cpp;metrics/system_metrics.cpp;orderman/actors/AsyncFactory.cpp;orderman/actors/ExecutionGateway.cpp;orderman/actors/FillStore.cpp;orderman/actors/MDSupplementarySource.cpp;orderman/actors/OrderStore.cpp;orderman/actors/SODPosition.cpp;orderman/actors/SecuritySrc.cpp;orderman/actors/ServiceBridge.cpp;orderman/actors/order_manager/OrderBuilder.cpp;orderman/actors/order_manager/OrderManager.cpp;orderman/actors/order_manager/OrderServicesData.cpp;orderman/events/CancelRejectEvent.cpp;orderman/events/NewExecutionReportEvent.cpp;orderman/limiter/LimitStore.cpp;orderman/limiter/Limiter.cpp;orderman/limiter/ProductLimitNode.cpp;orderman/limiter/ProductLimitTree.cpp;orderman/limiter/SecurityLimitNode.cpp;orderman/limiter/SecurityLimitTLine truncated
|
||||
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/services/AdminService.proto;api/services/ApiUnitTestService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/services/UserService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/Executor.conf;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/dynamic_orders.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/dynamic_orders.proto;config/protos/jetfix.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/quickbus_cfg.proto;config/protos/spreader.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPriceLantencyTester.cpp;md/Diag/ShmDumper.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MDRecoverableConsumer.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/md2_tests.cpp;md/test/synthetic_book_merge_tests.cpp;os/os.cpp;os/tests/os_tests.cpp;quickbus/core/LocalNode.cpp;quickbus/core/Quickbus.cpp;quickbus/core/SubscriptionID.cpp;quickbus/core/TableID.cpp;quickbus/message_model/Update.cpp;quickbus/message_model/merge_updates.cpp;quickbus/network/QBConnection.cpp;quickbus/network/QBConnectionManager.cpp;quickbus/network/endpoint_description.cpp;quickbus/network/quickbus_msgs.proto;quickbus/pubsub/TablePublisher.cpp;quickbus/pubsub/TableSubscriber.cpp;quickbus/pubsub/tests/qb_pubsub_tests.cpp;quickbus/routing/INode.cpp;quickbus/routing/NodeID.cpp;quickbus/routing/Router.cpp;quickbus/rpc/RPCClient.cpp;quickbus/rpc/RPCServer.cpp;quickbus/rpc/RPCSessionID.cpp;quickbus/rpc/rpc_utils.cpp;quickbus/rpc/tests/qb_rpc_tests.cpp;quickbus/tests/quickbus_tests.cpp;sparkproto/SparkProtos.proto;testing/catch_test_runner.cpp;utils/Dispatcher.cpp;utils/GrowableSPSCQueue.cpp;utils/HTTPStream.cpp;utils/PBUtils.cpp;utils/Puid.cpp;utils/SecureLogon.cpp;utils/SharedMemory.cpp;utils/Sqlite_utils.cpp;utils/Uuid.cpp;utils/datetime.cpp;utils/download.cpp;utils/file_utils.cpp;utils/init_spark_lib.cpp;utils/is_unittest_environment.cpp;utils/stats.cpp;utils/thread_manager.cpp)
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void ShellLatencyServer::report(
|
||||
// create metric
|
||||
auto metric =
|
||||
std::make_shared<AutoResetMetric>("spark_shell_latency",
|
||||
std::vector<Label>({{"shell",key}, {"user", request.user()}}));
|
||||
std::vector<Label>({{"host",request.host_name()}, {"version",request.version()}, {"user", request.user()}}));
|
||||
_metrics.insert(std::make_pair(key, metric));
|
||||
metric->max(delta);
|
||||
_mc.publish(metric);
|
||||
|
||||
Reference in new issue
Block a user