Compare commits

..
21 Commits
Author SHA1 Message Date
Taha Afzal d66c8e0ad8 Added a line to Conditional Quoting help tooltips 2018-11-10 17:34:55 -05:00
Taha Afzal 8673f366d7 conditional quotes are not pulled until after 5 secs of the condition 2018-11-09 18:02:58 -05:00
Kevin Darby d9b37efbbd wrong enum 2018-11-09 10:42:51 -05:00
Taha Afzal d23b7942b6 removing the hard coded n_ticks used for testing 2018-11-08 19:53:25 -05:00
Kevin Darby f41c3a5334 ConditionalQuoteEnabledModel.cs edited online with Bitbucket 2018-11-09 00:08:29 +00:00
Kevin Darby d8e8f90131 something is smishing this UI, but I've asked John for help 2018-11-08 18:32:36 -05:00
Taha Afzal 0358afccf9 simplified the n ticks away logic 2018-11-08 17:49:05 -05:00
Taha Afzal d3ed6e21e4 integrated with SingleLegquoter._compute_price_quantity 2018-11-08 14:45:28 -05:00
Taha Afzal 9d96fcaa45 added proto 2018-11-07 01:52:23 -05:00
Eric Harding d70bd63659 sparkd md dumpsecurity should dump synthetic metadata 2018-11-01 13:26:29 -04:00
Eric Harding 246f9240e7 Tweak md dump tool for easier human consumption 2018-11-01 11:53:47 -04:00
Jake Norbut 02d1badf0d Adding vertical fudge factor so that no scrollbar is initally present on the SparkCommands; nice catch Eric 2018-10-30 16:17:08 -05:00
Eric Harding 753221e429 Easier to see shell latency across version upgrades 2018-10-30 12:07:48 -04:00
Jake Norbut d5f41d8405 WorkLoop execessive_cycle_ms to use TotalMilliseconds and not Milliseconds 2018-10-30 11:04:42 -05:00
Jake Norbut 3490834108 Merged in SPARK-1403 (pull request #87)
SPARK-1403

Approved-by: Eric Harding <eric.harding@bluetradesys.com>
2018-10-30 13:49:58 +00:00
Jake Norbut 94c2d9182c Updating release notes for footers and 1.3.7 here in this txt file 2018-10-29 17:43:32 -05:00
Jake Norbut f68aac2015 Merge branch 'footers' into prod 2018-10-29 17:19:18 -05:00
Jake Norbut a9ef7e47b5 tweaking animation to make it more pronounced 2018-10-25 17:08:24 -05:00
Jake Norbut 9762a81a59 this is working now, thx Eric 2018-10-25 16:45:53 -05:00
Jake Norbut 744260bea5 Workspaces - trying to just get a proof of conept of something happenning in the UI; not working in our UI at the moment, but I can see it kind of working in snoop? 2018-10-25 15:22:51 -05:00
Jake Norbut e0f1137ee2 initial commit of fotters; waiting until after john does the OB perf commit until revisiting this again 2018-10-25 07:43:26 -05:00
36 changed files with 582 additions and 72 deletions

No files matched your search

+8
View File
@@ -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;
}
}
}
@@ -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);
}
}
}
}
@@ -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);
}
}
}
@@ -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");
});
}
}
+2 -1
View File
@@ -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
View File
@@ -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)
+39 -28
View File
@@ -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));
+23
View File
@@ -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)
+9
View File
@@ -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);