Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e209ec59e4 | ||
|
|
92dbedf28f | ||
|
|
7993f75fb1 | ||
|
|
1cddd2bcf3 | ||
|
|
9f7e5846b8 | ||
|
|
f7b3aac11a | ||
|
|
ec32101cef | ||
|
|
4e0cf68fa3 |
No files matched your search
@@ -84,8 +84,11 @@ namespace bts.shell {
|
||||
public DoubleMinMaxState total_pnl;
|
||||
[ProtoMember(12)]
|
||||
public DoubleMinMaxState pnl_price;
|
||||
[ProtoMember(13)]
|
||||
public Fill.Types.FillKind[] fill_kind;
|
||||
|
||||
// [ProtoMember(13)]
|
||||
// ProtoMember 13 cannot be used further
|
||||
[ProtoMember(14)]
|
||||
public SecurityType[] security_types;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ namespace mbts.spark
|
||||
return x is SecurityImmutable && y is SecurityImmutable ? Compare((SecurityImmutable)x, (SecurityImmutable)y) : -1;
|
||||
}
|
||||
public int Compare(SecurityImmutable x, SecurityImmutable y) {
|
||||
return x.EarliestExpiration().CompareTo(y.EarliestExpiration());
|
||||
return SecurityHelper.Comparer.Compare(x, y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace mbts.spark {
|
||||
total_net_position_filter.load_state(fs.total_net_pos);
|
||||
total_pnl_filter.load_state(fs.total_pnl);
|
||||
pnl_price_filter.load_state(fs.pnl_price);
|
||||
fill_kind_filter.load_state(fs.fill_kind);
|
||||
security_type_filter.load_state(fs.security_types);
|
||||
}
|
||||
// restore sort state or supply default value
|
||||
if (startup_data?.sort_criteria?.Any() == true) {
|
||||
@@ -92,7 +92,7 @@ namespace mbts.spark {
|
||||
pnl_price_filter,
|
||||
weighted_average_buy_filter,
|
||||
weighted_average_sell_filter,
|
||||
fill_kind_filter),
|
||||
security_type_filter),
|
||||
WorkLoop.Start("PAndL", _UPDATE_PERIOD, _calculate_pnl)
|
||||
);
|
||||
}
|
||||
@@ -197,7 +197,7 @@ namespace mbts.spark {
|
||||
public IDataGridColumnPersistentFilter<PnLSummaryRow, DoubleMinMaxState> pnl_price_filter { get; } = new DoubleMinMax<PnLSummaryRow>(r => r.pnl_price, nameof(PnLSummaryRow.pnl_price));
|
||||
public IDataGridColumnPersistentFilter<PnLSummaryRow, DoubleMinMaxState> weighted_average_buy_filter { get; } = new DoubleMinMax<PnLSummaryRow>(r => r.weighted_average_buy, nameof(PnLSummaryRow.weighted_average_buy));
|
||||
public IDataGridColumnPersistentFilter<PnLSummaryRow, DoubleMinMaxState> weighted_average_sell_filter { get; } = new DoubleMinMax<PnLSummaryRow>(r => r.weighted_average_sell, nameof(PnLSummaryRow.weighted_average_sell));
|
||||
public IDataGridColumnPersistentFilter<PnLSummaryRow, FillKind[]> fill_kind_filter { get; } = DiscreteValuesFilterVM.Create<PnLSummaryRow, FillKind>(EnumHelper.get_values<FillKind>().ToArray(), r => r.fill_kind, nameof(PnLSummaryRow.fill_kind));
|
||||
public IDataGridColumnPersistentFilter<PnLSummaryRow, SecurityType[]> security_type_filter { get; } = DiscreteValuesFilterVM.Create<PnLSummaryRow, SecurityType>(EnumHelper.get_values_except<SecurityType>(SecurityType.Option, SecurityType.Stock, SecurityType.Synthetic).ToArray(), r => r.security_type, nameof(PnLSummaryRow.security_type));
|
||||
|
||||
public FilterStates get_filters_states() => new FilterStates {
|
||||
account_regex = account_filter.get_state(),
|
||||
@@ -212,7 +212,7 @@ namespace mbts.spark {
|
||||
total_net_pos = total_net_position_filter.get_state(),
|
||||
total_pnl = total_pnl_filter.get_state(),
|
||||
pnl_price = pnl_price_filter.get_state(),
|
||||
fill_kind = fill_kind_filter.get_state()
|
||||
security_types = security_type_filter.get_state()
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<Setter Property="TextAlignment" Value="Right" />
|
||||
</Style>
|
||||
<convert:NumericSignBrushConverter x:Key="PnLBackgroundColorConverter" Opacity="0.33"/>
|
||||
<convert:DoubleTextConverter x:Key="DoubleWithNaNHiddenConverter" Format="F2" />
|
||||
<convert:DoubleTextConverter x:Key="DoubleWithNaNHiddenConverter" Format="N0" />
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
@@ -64,12 +64,12 @@
|
||||
c:DataGridFilterProperties.FilterOpen="{Binding DataContext.security_filter.open, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource RegexTemplate}"
|
||||
/>
|
||||
<DataGridTextColumn x:Name="fill_kind" Header="Fill Kind" Binding="{Binding fill_kind}" IsReadOnly="true"
|
||||
c:DataGridFilterProperties.Filter="{Binding DataContext.fill_kind_filter, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterActive="{Binding DataContext.fill_kind_filter.active, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterOpen="{Binding DataContext.fill_kind_filter.open, Source={uc:DirectReference _grid}}"
|
||||
<DataGridTextColumn x:Name="security_type" Header="Security Type" Binding="{Binding security_type}" IsReadOnly="true"
|
||||
c:DataGridFilterProperties.Filter="{Binding DataContext.security_type_filter, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterActive="{Binding DataContext.security_type_filter.active, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterOpen="{Binding DataContext.security_type_filter.open, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DiscreteValuesTemplate}"
|
||||
/>
|
||||
/>
|
||||
<DataGridTextColumn x:Name="start_net_pos" Header="Start Net Pos" Binding="{Binding start_net_position}" IsReadOnly="true"
|
||||
ElementStyle="{StaticResource RightAlignedColumn}"
|
||||
c:DataGridFilterProperties.Filter="{Binding DataContext.start_position_filter, Source={uc:DirectReference _grid}}"
|
||||
@@ -78,16 +78,11 @@
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}"
|
||||
/>
|
||||
<DataGridTextColumn x:Name="start_pnl" Header="Start PnL" IsReadOnly="true" SortMemberPath="start_pnl"
|
||||
Binding="{Binding start_pnl, Converter={StaticResource DoubleWithNaNHiddenConverter}}"
|
||||
c:DataGridFilterProperties.Filter="{Binding DataContext.start_pnl_filter, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterActive="{Binding DataContext.start_pnl_filter.active, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterOpen="{Binding DataContext.start_pnl_filter.open, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}">
|
||||
<DataGridTextColumn.Binding>
|
||||
<MultiBinding Converter="{StaticResource TickDisplayConverter}">
|
||||
<Binding Path="start_pnl"/>
|
||||
<Binding Path="security.ContractSpec"/>
|
||||
</MultiBinding>
|
||||
</DataGridTextColumn.Binding>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="TextAlignment" Value="Right" />
|
||||
@@ -110,16 +105,11 @@
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}"
|
||||
/>
|
||||
<DataGridTextColumn x:Name="day_pnl" Header="Day PnL" IsReadOnly="true" SortMemberPath="day_pnl"
|
||||
Binding="{Binding day_pnl, Converter={StaticResource DoubleWithNaNHiddenConverter}}"
|
||||
c:DataGridFilterProperties.Filter="{Binding DataContext.day_pnl_filter, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterActive="{Binding DataContext.day_pnl_filter.active, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterOpen="{Binding DataContext.day_pnl_filter.open, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}">
|
||||
<DataGridTextColumn.Binding>
|
||||
<MultiBinding Converter="{StaticResource TickDisplayConverter}">
|
||||
<Binding Path="day_pnl"/>
|
||||
<Binding Path="security.ContractSpec"/>
|
||||
</MultiBinding>
|
||||
</DataGridTextColumn.Binding>
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="TextAlignment" Value="Right" />
|
||||
@@ -135,16 +125,11 @@
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}"
|
||||
/>
|
||||
<DataGridTextColumn x:Name="total_pnl" Header="Total PnL" IsReadOnly="true" SortMemberPath="total_pnl"
|
||||
Binding="{Binding total_pnl, Converter={StaticResource DoubleWithNaNHiddenConverter}}"
|
||||
c:DataGridFilterProperties.Filter="{Binding DataContext.total_pnl_filter, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterActive="{Binding DataContext.total_pnl_filter.active, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterOpen="{Binding DataContext.total_pnl_filter.open, Source={uc:DirectReference _grid}}"
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}">
|
||||
<DataGridTextColumn.Binding>
|
||||
<MultiBinding Converter="{StaticResource TickDisplayConverter}">
|
||||
<Binding Path="total_pnl"/>
|
||||
<Binding Path="security.ContractSpec"/>
|
||||
</MultiBinding>
|
||||
</DataGridTextColumn.Binding>
|
||||
c:DataGridFilterProperties.FilterTemplate="{StaticResource DoubleMinMaxTemplate}">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="TextAlignment" Value="Right" />
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace mbts.spark {
|
||||
|
||||
public IEnumerable<PnLSummaryRow> get_summary_position() {
|
||||
return (from pnl_item in _data
|
||||
group pnl_item by (pnl_item.account, pnl_item.exchange, pnl_item.symbol, pnl_item.security, pnl_item.sec_md, pnl_item.fill_kind) into grouping
|
||||
group pnl_item by (pnl_item.account, pnl_item.exchange, pnl_item.symbol, pnl_item.security, pnl_item.sec_md, pnl_item.security_type) into grouping
|
||||
/* let start_of_day = _get_start_of_day(grouping.Key.symbol) */
|
||||
select new PnLSummaryRow(_calc_type, _start_of_trading_day_utc, grouping.Key,
|
||||
grouping.Where(y => y.fill.Timestamp.ToDateTime() >= _start_of_trading_day_utc).Sum(y => (uint)y.buy_quantity),
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace mbts.spark {
|
||||
public SecurityImmutable? security => sec_md?.security;
|
||||
public double buy_quantity => (fill.Side == Side.Buy) ? fill.LastShares : 0;
|
||||
public double sell_quantity => (fill.Side == Side.Sell) ? fill.LastShares : 0;
|
||||
public Fill.Types.FillKind fill_kind => fill.FillKind;
|
||||
public SecurityType? security_type => security?.security_type();
|
||||
|
||||
public override string ToString() {
|
||||
return $"Fill: ( {account} {exchange} {security.ToString()} buy: {buy_quantity} sell: {sell_quantity} ) Security: {security.ToString()}";
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace mbts.spark {
|
||||
|
||||
internal class PnLSummaryRow : ViewModelBase, IEquatable<PnLSummaryRow> {
|
||||
DateTime _start_of_day;
|
||||
(string account, Venue? exchange, string symbol, SecurityImmutable? security, SecurityMD? sec_md, Fill.Types.FillKind fill_kind) key;
|
||||
(string account, Venue? exchange, string symbol, SecurityImmutable? security, SecurityMD? sec_md, SecurityType? sec_type) key;
|
||||
int _start_net_position, _total_net_position;
|
||||
uint _day_long_quantity, _day_short_quantity;
|
||||
double _total_pnl, _sod_pnl, _start_pnl, _pnl_price, _weighted_average_buy, _weighted_average_sell;
|
||||
@@ -24,7 +24,7 @@ namespace mbts.spark {
|
||||
|
||||
public PnLSummaryRow(pnl_calc_type calc_type,
|
||||
DateTime start_of_day,
|
||||
(string, Venue?, string, SecurityImmutable?, SecurityMD?, Fill.Types.FillKind) key,
|
||||
(string, Venue?, string, SecurityImmutable?, SecurityMD?, SecurityType?) key,
|
||||
uint day_buy_quant, uint day_sell_quant, int net_pos, int sod_pos, double wavg_buy, double wavg_sell, IEnumerable<FillImmutable> fills) {
|
||||
this._start_of_day = start_of_day;
|
||||
this.key = key;
|
||||
@@ -41,19 +41,21 @@ namespace mbts.spark {
|
||||
update_pnl(calc_type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up the cash per point (cpp) for the given SecurityImmutable.
|
||||
/// If the SecurityImmutable is a cross-product exchange-traded spread,
|
||||
/// such as a crack spread, where the legs have differing cpps, then
|
||||
/// we'll return Double.Nan;
|
||||
/// </summary>
|
||||
/// <param name="s">The SecurityImmutable for which we will look up a cpp</param>
|
||||
/// <returns>The found cpp, else Double.NaN</returns>
|
||||
private double _get_cpp_for_security(SecurityImmutable s) {
|
||||
if (s.security_type() == SecurityType.Spread) {
|
||||
var distinct_cpps = s.Spread.Legs
|
||||
.Select(l => get_cpp_for_symbol(l.Security))
|
||||
.Distinct();
|
||||
bool all_legs_have_same_cpp = distinct_cpps.Count() < 2;
|
||||
if (all_legs_have_same_cpp) {
|
||||
return distinct_cpps.First();
|
||||
} else {
|
||||
Logger.error(bts.log.Subsystem.Ui,
|
||||
$"Security {s} contains legs with the following cash multipliers: { string.Join(",", distinct_cpps.Select(d => d.ToString())) } ");
|
||||
return Double.NaN;
|
||||
}
|
||||
return all_legs_have_same_cpp ? distinct_cpps.First() : Double.NaN;
|
||||
} else {
|
||||
return get_cpp_for_symbol(s);
|
||||
}
|
||||
@@ -62,8 +64,6 @@ namespace mbts.spark {
|
||||
double get_cpp_for_symbol(SecurityImmutable si) {
|
||||
if (cpp_dict.TryGetValue(si.Symbol, out double cpp_out)) {
|
||||
return cpp_out;
|
||||
} else {
|
||||
Logger.error(bts.log.Subsystem.Ui, $"No cash multiplier found for Security {si}, Symbol {si.Symbol}");
|
||||
}
|
||||
return double.NaN;
|
||||
}
|
||||
@@ -170,14 +170,13 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
public SecurityImmutable? security => key.security;
|
||||
public SecurityType security_type => key.sec_type.GetValueOrDefault();
|
||||
|
||||
public string security_text {
|
||||
get => security.HasValue ? security.Value.ToString() : "Unknown Security";
|
||||
set => ignore();
|
||||
}
|
||||
|
||||
public Fill.Types.FillKind fill_kind => key.fill_kind;
|
||||
|
||||
|
||||
public int start_net_position {
|
||||
get => _start_net_position;
|
||||
|
||||
@@ -99,7 +99,7 @@ struct ApiGatewayImpl {
|
||||
// buffer = [size][ResponseHeader][Payload].
|
||||
GatewayResponse response;
|
||||
response.set_call_result(buffer, length);
|
||||
LOG(Api,Info, "Gateway Result: {}", api::toJSON(response));
|
||||
LOG(Api,Diag, "Gateway Result: {}", api::toJSON(response));
|
||||
// in response send to client
|
||||
const Responder* r = static_cast<const Responder*>(extra);
|
||||
if (r != nullptr) {
|
||||
|
||||
@@ -73,7 +73,7 @@ void ErrorReportServer::send_report(
|
||||
}
|
||||
|
||||
// log error for visibility
|
||||
LOG(Gen, Error, "Support request from {} - {} \n{}", request.user(), request.contact(), request.user_description());
|
||||
LOG(Gen, Error, "Support request from {} - {} {}", request.user(), request.contact(), request.user_description());
|
||||
|
||||
ErrorResponse r;
|
||||
reply(r);
|
||||
|
||||
Reference in new issue
Block a user