Compare commits
211
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd5c680155 | ||
|
|
5a1cc4cf2b | ||
|
|
9be3a09749 | ||
|
|
61745d0ed7 | ||
|
|
db1610591e | ||
|
|
bb1571540a | ||
|
|
342d89724e | ||
|
|
07d3903d11 | ||
|
|
d08b134d7f | ||
|
|
92f67d1d2d | ||
|
|
43a18941a4 | ||
|
|
b102b271b0 | ||
|
|
b129bea129 | ||
|
|
38d79eb58b | ||
|
|
dfd0cfc217 | ||
|
|
a123ac2ed8 | ||
|
|
ad4fd13189 | ||
|
|
8a1180835c | ||
|
|
f65f34c2fe | ||
|
|
34401960f9 | ||
|
|
34b7c99c81 | ||
|
|
044ef0b812 | ||
|
|
9cc4b5aa87 | ||
|
|
821274f544 | ||
|
|
ca6c0f984c | ||
|
|
80e337c599 | ||
|
|
5b71918a1f | ||
|
|
d2a9d21700 | ||
|
|
16fee6e478 | ||
|
|
3cf701a211 | ||
|
|
5392d05ec8 | ||
|
|
7838bdf04f | ||
|
|
546553406b | ||
|
|
02d0f6191c | ||
|
|
36722e27ad | ||
|
|
dcfbb6e62f | ||
|
|
ff2d150dc4 | ||
|
|
6692797c3f | ||
|
|
b059aedbce | ||
|
|
73c9be3bec | ||
|
|
bc35e773ce | ||
|
|
4c8d0a4217 | ||
|
|
05abbc4a50 | ||
|
|
95500187f0 | ||
|
|
8716099ac6 | ||
|
|
d7850d6b70 | ||
|
|
905c1cab2c | ||
|
|
6181548902 | ||
|
|
c32eada3ac | ||
|
|
42feedfd36 | ||
|
|
d76c2a30ce | ||
|
|
c312a880a7 | ||
|
|
b2ed88fb4a | ||
|
|
567edafe18 | ||
|
|
9a39d84739 | ||
|
|
d9b4e21c61 | ||
|
|
fa287b14ef | ||
|
|
096bf3338c | ||
|
|
a646f28831 | ||
|
|
391397692c | ||
|
|
8130d5a0f8 | ||
|
|
d89f93c323 | ||
|
|
a376fe9e22 | ||
|
|
7381088d6d | ||
|
|
5f9a421490 | ||
|
|
f7fd81f3af | ||
|
|
f6c0f393bd | ||
|
|
adec1bdfd0 | ||
|
|
a3de83dd04 | ||
|
|
5ba7cd561c | ||
|
|
5ff9f13e7e | ||
|
|
f4b65b21bb | ||
|
|
c1789bb4a1 | ||
|
|
0cf4b5c2c8 | ||
|
|
a101a267ed | ||
|
|
d76b098c51 | ||
|
|
06aa540110 | ||
|
|
9fd7db55ca | ||
|
|
5b118d8fa0 | ||
|
|
b570762054 | ||
|
|
b664c42cae | ||
|
|
a25c17306f | ||
|
|
b0c52f542a | ||
|
|
dabeb63eac | ||
|
|
f0d3cabd14 | ||
|
|
418a1078c2 | ||
|
|
3d37dc481f | ||
|
|
d24b7a3707 | ||
|
|
12362d9719 | ||
|
|
01128639ce | ||
|
|
71d2e01187 | ||
|
|
c923be6ced | ||
|
|
4cf9d544aa | ||
|
|
79f37f7130 | ||
|
|
19c0b94803 | ||
|
|
57fc50ce61 | ||
|
|
3cff5343a3 | ||
|
|
a6ec93e87e | ||
|
|
25acf771ab | ||
|
|
22cc946f52 | ||
|
|
6d0eb62712 | ||
|
|
369b89b3a7 | ||
|
|
8793c6c527 | ||
|
|
df14522433 | ||
|
|
086e90acbe | ||
|
|
16acc4f5b0 | ||
|
|
b8a94f2540 | ||
|
|
3af7e561b9 | ||
|
|
467dba98f8 | ||
|
|
f871dfe142 | ||
|
|
d44de204ee | ||
|
|
04beea61eb | ||
|
|
2181b92970 | ||
|
|
693c730f51 | ||
|
|
0ccba5bb0b | ||
|
|
3458be59d7 | ||
|
|
7dc9aa0710 | ||
|
|
88d6dd0f00 | ||
|
|
ce4c46da04 | ||
|
|
59c1f6a511 | ||
|
|
938caf9a4f | ||
|
|
df4f061b6c | ||
|
|
8afee21df7 | ||
|
|
f34014eb25 | ||
|
|
f513f7d9f2 | ||
|
|
b07eec08b4 | ||
|
|
964274f5c4 | ||
|
|
c16941977c | ||
|
|
6b19119ab2 | ||
|
|
ea42086e96 | ||
|
|
292873b189 | ||
|
|
8545a5ef38 | ||
|
|
6a52fff3d5 | ||
|
|
4ec6fafbc2 | ||
|
|
b08e2c2ee6 | ||
|
|
8bdd033501 | ||
|
|
76466e83f0 | ||
|
|
69f9f2791e | ||
|
|
ad6fc6d23b | ||
|
|
a4575e3fa3 | ||
|
|
2540dc0510 | ||
|
|
dc1a80afd2 | ||
|
|
e1cfa7bf0b | ||
|
|
2020221e65 | ||
|
|
ce438e93a6 | ||
|
|
f0132c84b6 | ||
|
|
57ca9596c8 | ||
|
|
bad5bc3097 | ||
|
|
e9da338402 | ||
|
|
bf4953f6dc | ||
|
|
c277fcd503 | ||
|
|
dff57a43dd | ||
|
|
39c71d0c16 | ||
|
|
be6c916691 | ||
|
|
009e72953c | ||
|
|
635163c895 | ||
|
|
95e96a6afc | ||
|
|
c7f0e2dd58 | ||
|
|
f5e79a65a3 | ||
|
|
c958f4bf1a | ||
|
|
95939a5534 | ||
|
|
9a7164b42b | ||
|
|
f347fda47f | ||
|
|
d75ab3a63f | ||
|
|
b30f59227e | ||
|
|
ef60d4200a | ||
|
|
ed6f0b8bdb | ||
|
|
766116eac4 | ||
|
|
8d49de3f61 | ||
|
|
16cf4554c5 | ||
|
|
6b17efee60 | ||
|
|
5d64213455 | ||
|
|
0ef44e92aa | ||
|
|
4d60376cb1 | ||
|
|
ee2f76553b | ||
|
|
c1887b9786 | ||
|
|
1fd5e51b9e | ||
|
|
56d3a27e7f | ||
|
|
1c65b1d87a | ||
|
|
693910f093 | ||
|
|
498b38ebcb | ||
|
|
fb91206e0f | ||
|
|
91f4de00f8 | ||
|
|
28980f10ae | ||
|
|
04e006b812 | ||
|
|
5b959ca5bd | ||
|
|
7ac54242e0 | ||
|
|
1ebf8219c2 | ||
|
|
f0b14cb8dc | ||
|
|
7259f81ab5 | ||
|
|
3b902b61dd | ||
|
|
6cfef51e3d | ||
|
|
76edb94905 | ||
|
|
e4bf9fc747 | ||
|
|
d488ff23ba | ||
|
|
6b6fd9c40a | ||
|
|
f7265740e7 | ||
|
|
724da31316 | ||
|
|
2ae5b50445 | ||
|
|
dfcf38289f | ||
|
|
1c54b0140b | ||
|
|
e034fd2623 | ||
|
|
a3b8d579a1 | ||
|
|
9d2cdb702d | ||
|
|
d0784feddd | ||
|
|
4a64e45d36 | ||
|
|
97f09768bb | ||
|
|
2b4add85a2 | ||
|
|
4c798f6db4 | ||
|
|
b2e275124f | ||
|
|
36e4f62a53 |
No files matched your search
Vendored
+10
-4
@@ -75,6 +75,7 @@
|
||||
"name": "SparkVM Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
|
||||
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
|
||||
"args": ["run"],
|
||||
"stopAtEntry": false,
|
||||
@@ -96,7 +97,12 @@
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "LD LIBRARY",
|
||||
"text": "set env LD_LIBRARY_PATH=.",
|
||||
"ignoreFailures": false
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
@@ -208,10 +214,10 @@
|
||||
"name": "MD Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": ["test", "[md]"],
|
||||
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
|
||||
"args": ["test", "[mbo]"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
|
||||
@@ -55,6 +55,8 @@ else ()
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/web ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/data_files ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/lib/libspark.so ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.13.0.0 ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libACE-5.7.5.so ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/server/plugins
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/sdk/examples/order_plugin_example.so ${CMAKE_BINARY_DIR}/server/plugins/
|
||||
COMMENT "Creating server runtime layout"
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
+++
|
||||
title = "BTS Basic Algos"
|
||||
weight = 10
|
||||
sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
|
||||
|
||||
## Lean
|
||||
|
||||
The goal of the lean order is to watch the opposite-inside market size and cross when that size goes below the threshold (this also implies a cross if that size goes to zero and the market trades away from you) If the market trades toward you, you can opt into several different behaviors
|
||||
|
||||
##### Parameters
|
||||
* Cross Thresh - size thresh in absolute or ratio terms
|
||||
* Max Chase Ticks - max levels to pay up, in ticks
|
||||
|
||||
|
||||
## Join
|
||||
The goal of the join order is to watch the opposite-inside market and join when the market flips (that is, when the best offer becomes the best bid) and has at least threshold size.
|
||||
|
||||
##### Parameters
|
||||
* Join Thresh - size thresh in absolute or ratio terms
|
||||
|
||||
|
||||
## Top
|
||||
|
||||
The goal of the top order is to not trade by yourself, but the intent at the time of order entry is to get filled.If the order is on the market (say current bid price) AND the quantity on that bid price is below top thresh then cancel the order else remain working.
|
||||
|
||||
##### Parameters
|
||||
* Top Thresh - size thresh in absolute or ratio terms
|
||||
|
||||
|
||||
## Cover
|
||||
A Cover order’s purpose is to fire a hedge order (of any type) in response to fills from it’s child order on the opposite side of the market N ticks away
|
||||
|
||||
##### Parameters
|
||||
* Profit Ticks - ticks above or below fill price to place profit / cover order
|
||||
|
||||
|
||||
## OCO
|
||||
An OCO order creates a relationship between a child order and a 'stop' or 'other' order such that when one of these is cancelled, both cancel, or when one is filled, the other order's size is debited in the amount of the fill.
|
||||
|
||||
Composing this order with Cover simulates scalping functionality
|
||||
|
||||
##### Parameters
|
||||
* Stop Ticks - ticks below or above main order to place stop / other order
|
||||
@@ -5,6 +5,7 @@ sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
|
||||
{{ youtube(id="RZU9Wj0cETo") }}
|
||||
|
||||
<div>
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/XEZpuPAgMC0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
@@ -406,6 +406,8 @@ insert_anchor_links = "right"
|
||||
|
||||
## Algo Studio
|
||||
|
||||
{{ youtube(id="DHIa5tnifKc") }}
|
||||
|
||||
- The BTS Algo Studio was built for users to experience algo composability
|
||||
never seen before in a professional futures trading system.
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title = "Client"
|
||||
weight = 1
|
||||
sort_by = "weight"
|
||||
redirect_to = "bts_spark_sdk/Client/overview/"
|
||||
+++
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title = "Server"
|
||||
weight = 2
|
||||
sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title = "BTS Spark SDK"
|
||||
weight = 2
|
||||
sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
@@ -4,6 +4,43 @@ weight = 3
|
||||
sort_by = "weight"
|
||||
insert_anchor_links = "right"
|
||||
+++
|
||||
## 1.6.0
|
||||
### User Visible Changes
|
||||
#### New Features
|
||||
- You can now view your order's position in queue in the ladder
|
||||
#### Bug Fixes
|
||||
- Fix a bug in the order popup in the ladder which could lead to a crash.
|
||||
|
||||
## 1.5.9
|
||||
### User Visible Changes
|
||||
- Fix for stunnel connections on Windows 7
|
||||
|
||||
## 1.5.8
|
||||
### User Visible Changes
|
||||
- Fixed a bug where it was possible to crash the UI by entering an order through the order ticket if Enter was used to dismiss the dialog.
|
||||
- Fixed a spreader reporting bug which could cause the server to crash if an algo was used to control certain types of synthetics
|
||||
- Improved user message when the UI fails to login
|
||||
- Integrated stunnel into UI to make VPN setup unnecessary in unsecured environments.
|
||||
## 1.5.7
|
||||
### User Visible Changes
|
||||
- New videos have been added to the manual describing the [Algo Studio](./bts_spark/Trading/index.md#algo-studio) and [Spreader](./bts_spark/Spreader/index.md)
|
||||
- Fixed a bug that occasionally would cause windows to be position outside the visible screen on startup
|
||||
- Fixed a bug in the order book form that would occasionally cause the Recreate Order option to be unavailable
|
||||
- Added a confirmation step to Cancel All, Cancel Buys and Cancel Sells commands
|
||||
- Fixed Aggressor coloring and ladder high/low coloring in the SIM execution gateway
|
||||
- Added initial support for ICE market data
|
||||
- In an effort to streamline the PnL report we've made the following changes:
|
||||
- The PnL report will by default filter for Futures contracts only
|
||||
- If you wish to see Spread contracts again you may change Security Type column filter
|
||||
- The PnL report will now only show rows in which there is a position (net and/or day)
|
||||
- The Exchange, Start PnL, Total Net Pos, and Total Net PnL columns are now hidden by default
|
||||
- These columns can be restored by toggling their visibility within the PnL's Settings form
|
||||
- A new Traded Today column has been added to the PnL
|
||||
- Filtering on this column will allow a user to restrict the report to only show today's position
|
||||
### Internal changes
|
||||
- Improved organization of the shell notification architecture
|
||||
- Added logging to help troubleshoot shell exit hang
|
||||
|
||||
## 1.5.6
|
||||
### User Visible Changes
|
||||
- Fixed a bug that could cause limits to be erroneously enforced
|
||||
|
||||
@@ -54,3 +54,8 @@ img {
|
||||
background: #ccc;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width:560px;
|
||||
height:315px;
|
||||
}
|
||||
+1
-1
Submodule externals updated: fc3db9b691...67a79263ba.
@@ -1,3 +1,6 @@
|
||||
1.5.7
|
||||
- Fixed Aggressor coloring and ladder high/low coloring in SIM
|
||||
|
||||
1.4.2
|
||||
- Be sure the system has a bts user before deployment. bts is the superuser, he has all permissions and can see all market data
|
||||
- After deployment re-permission all existing users for trading, riskadmin, and/or md admin permissions as appropriate
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
@@ -66,18 +68,77 @@ namespace mbts.ui.shell
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
Log.Gen.info("Application.OnExit");
|
||||
if (_runtime != null) _runtime.Dispose();
|
||||
utils.BTSNativeMethods.finit_spark_lib();
|
||||
base.OnExit(e);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
void start_stunnel(string path, uint job_error)
|
||||
{
|
||||
string config_error;
|
||||
if (!mbts.config.Configuration.try_initialize(out config_error))
|
||||
{
|
||||
_stunnel_process = Process.Start(path + "bin\\stunnel.exe");
|
||||
if (_stunnel_process != null)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (mbts.config.Configuration.try_initialize(out config_error))
|
||||
break;
|
||||
System.Threading.Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
else
|
||||
stunnel_job_error = "Stunnel Job Error code: " + job_error +
|
||||
" could not start stunnel " + (config_error ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
void kill_stunnel()
|
||||
{
|
||||
try
|
||||
{
|
||||
Process[] ps = Process.GetProcessesByName("stunnel");
|
||||
ps.ForEach(p =>
|
||||
{
|
||||
try { p.Kill(); }
|
||||
catch {}
|
||||
});
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
Process _stunnel_process;
|
||||
static internal string stunnel_job_error { get; private set;}
|
||||
void init_stunnel(string[] argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\BTS\\stunnel\\";
|
||||
if (File.Exists(path + "config\\stunnel.conf"))
|
||||
{
|
||||
uint job_error = BTSUINativeMethods.setup_process_job_object();
|
||||
//if we can't put this process and stunnel into a job, try to stop stunnel then restart
|
||||
if(job_error != 0)
|
||||
kill_stunnel();
|
||||
start_stunnel(path, job_error);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
stunnel_job_error = "Error starting stunnel: " + ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public new int Run() {
|
||||
var argv = Environment.GetCommandLineArgs();
|
||||
try {
|
||||
if (argv.Contains("-multiple") ||
|
||||
_mutex == null ||
|
||||
_mutex.WaitOne(TimeSpan.Zero, true)) {
|
||||
try {
|
||||
if (argv.Contains("-multiple") || _mutex == null || _mutex.WaitOne(TimeSpan.Zero, true))
|
||||
{
|
||||
if(_mutex == null || _mutex.WaitOne(TimeSpan.Zero, true))
|
||||
init_stunnel(argv);
|
||||
return base.Run();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -6,6 +6,7 @@ using bts.api.persistence;
|
||||
using bts.api.position;
|
||||
using bts.api.synthetic;
|
||||
using bts.co2;
|
||||
using bts.md;
|
||||
using bts.metrics;
|
||||
using bts.support;
|
||||
using System.ComponentModel.Composition;
|
||||
@@ -50,6 +51,9 @@ namespace Spark {
|
||||
AlgoServiceWrapper _algo_service_wrapper;
|
||||
[Export]
|
||||
public AlgoServiceWrapper algo_service_wrapper => _algo_service_wrapper ?? (_algo_service_wrapper = new AlgoServiceWrapper(context));
|
||||
|
||||
[Export]
|
||||
public MBOService mbo_service => context.locate<MBOService>();
|
||||
}
|
||||
|
||||
class AlgoServiceWrapper {
|
||||
|
||||
@@ -137,6 +137,12 @@ namespace mbts.spark {
|
||||
public ICommand ask_implied_size_click { get; }
|
||||
public ICommand working_asks_click { get; }
|
||||
public ICommand default_command { get; }
|
||||
public string market_description {get;}
|
||||
public string cleared_alias { get; }
|
||||
public string product_description { get; }
|
||||
public string hub_alias { get; }
|
||||
public string strip_name{ get; }
|
||||
public string mic_code { get; }
|
||||
|
||||
public ObservableCollection<RowAnimation> row_animations { get; } = new ObservableCollection<RowAnimation>();
|
||||
|
||||
|
||||
@@ -57,6 +57,13 @@ namespace mbts.spark {
|
||||
add_col(Columns.SessionLow, "Low", r => r.format_price(r.session_low), nameof(Row.session_low), DefaultColumnWidths.Price, session_low_filter, DataGridFilterKnownTemplates.DoubleMinMax, h_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
add_col(Columns.SessionHigh, "High", r => r.format_price(r.session_high), nameof(Row.session_high), DefaultColumnWidths.Price, session_high_filter, DataGridFilterKnownTemplates.DoubleMinMax, h_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
add_col(Columns.SecurityKey, "Security Key", r => r.security_key.ToString(), nameof(Row.security_key), DefaultColumnWidths.SecurityKey, security_key_filter, DataGridFilterKnownTemplates.Regex);
|
||||
|
||||
add_col(Columns.MarketDescription, "Market Description", r => r.md.security.HasIce ? r.md.security.Ice.MarketDescription : string.Empty, nameof(Row.market_description), DefaultColumnWidths.SecurityKey, market_description_filter, DataGridFilterKnownTemplates.Regex);
|
||||
add_col(Columns.ClearedAlias, "Cleared Alias", r => r.md.security.HasIce ? r.md.security.Ice.ClearedAlias : string.Empty, nameof(Row.cleared_alias), DefaultColumnWidths.SecurityKey, cleared_alias_filter, DataGridFilterKnownTemplates.Regex);
|
||||
add_col(Columns.ProductDescription, "Product Description", r => r.md.security.HasIce ? r.md.security.Ice.ProductName : string.Empty, nameof(Row.product_description), DefaultColumnWidths.SecurityKey, product_description_filter, DataGridFilterKnownTemplates.Regex);
|
||||
add_col(Columns.HubAlias, "Hub Alias", r => r.md.security.HasIce ? r.md.security.Ice.HubAlias : string.Empty, nameof(Row.hub_alias), DefaultColumnWidths.SecurityKey, hub_alias_filter, DataGridFilterKnownTemplates.Regex);
|
||||
add_col(Columns.StripName, "Strip Name", r => r.md.security.HasIce ? r.md.security.Ice.StripName : string.Empty, nameof(Row.strip_name), DefaultColumnWidths.SecurityKey, strip_name_filter, DataGridFilterKnownTemplates.Regex);
|
||||
add_col(Columns.MicCode, "Mic Code", r => r.md.security.HasIce ? r.md.security.Ice.MicCode : string.Empty, nameof(Row.mic_code), DefaultColumnWidths.SecurityKey, mic_code_filter, DataGridFilterKnownTemplates.Regex);
|
||||
//
|
||||
void add_col(Columns col_key, string header, Func<Row, string> get_text, string prop, double width, IDataGridColumnFilter filter, string filter_template, bool is_animatable = false, Color? font_color = null, System.Windows.HorizontalAlignment h_alignment = System.Windows.HorizontalAlignment.Left) =>
|
||||
columns.Add(new RenderTextColumn<Row, Columns>(col_key, get_text, filter, filter_template) {
|
||||
@@ -194,6 +201,14 @@ namespace mbts.spark {
|
||||
public IDataGridColumnPersistentFilter<Row, IntMinMaxState> working_ask_volume_filter { get; } = new IntMinMax<Row>(r => r.working_ask_volume, nameof(Row.working_ask_volume));
|
||||
public IDataGridColumnPersistentFilter<Row, ULongMinMaxState> volume_filter { get; } = new ULongMinMax<Row>(r => r.volume, nameof(Row.volume));
|
||||
public IDataGridColumnPersistentFilter<Row, string> security_key_filter { get; } = new RegexFilterVM<Row>(r => r.security_key.ToString(), nameof(Row.security_key));
|
||||
|
||||
public IDataGridColumnPersistentFilter<Row, string> market_description_filter { get; } = new RegexFilterVM<Row>(r => r.security.HasIce ? r.security.Ice.MarketDescription : "", nameof(Row.market_description));
|
||||
public IDataGridColumnPersistentFilter<Row, string> cleared_alias_filter { get; } = new RegexFilterVM<Row>(r => r.security.HasIce ? r.security.Ice.ClearedAlias : "", nameof(Row.cleared_alias));
|
||||
public IDataGridColumnPersistentFilter<Row, string> product_description_filter { get; } = new RegexFilterVM<Row>(r => r.security.HasIce ? r.security.Ice.ProductName : "", nameof(Row.product_description));
|
||||
public IDataGridColumnPersistentFilter<Row, string> hub_alias_filter { get; } = new RegexFilterVM<Row>(r => r.security.HasIce ? r.security.Ice.HubAlias : "", nameof(Row.hub_alias));
|
||||
public IDataGridColumnPersistentFilter<Row, string> strip_name_filter { get; } = new RegexFilterVM<Row>(r => r.security.HasIce ? r.security.Ice.StripName : "", nameof(Row.strip_name));
|
||||
public IDataGridColumnPersistentFilter<Row, string> mic_code_filter { get; } = new RegexFilterVM<Row>(r => r.security.HasIce ? r.security.Ice.MicCode : "", nameof(Row.mic_code));
|
||||
|
||||
|
||||
public FilterStates get_filter_states() {
|
||||
return new FilterStates {
|
||||
@@ -216,7 +231,13 @@ namespace mbts.spark {
|
||||
working_bid_volume = working_bid_volume_filter.get_state(),
|
||||
working_ask_volume = working_ask_volume_filter.get_state(),
|
||||
volume = volume_filter.get_state(),
|
||||
security_key = security_key_filter.get_state()
|
||||
security_key = security_key_filter.get_state(),
|
||||
market_description = market_description_filter.get_state(),
|
||||
cleared_alias = cleared_alias_filter.get_state(),
|
||||
product_description = product_description_filter.get_state(),
|
||||
hub_alias = hub_alias_filter.get_state(),
|
||||
strip_name = strip_name_filter.get_state(),
|
||||
mic_code = mic_code_filter.get_state(),
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -8,7 +8,9 @@ namespace mbts.ui.spark {
|
||||
/// Interaction logic for MarketSheetsView.xaml
|
||||
/// </summary>
|
||||
partial class MarketViewView : UserControl {
|
||||
public enum Columns { Security, Volume, Last, LastSize, Position, WorkingBids, Bid, BidMergedSize, BidDirectSize, BidImpliedSize, Ask, AskMergedSize, AskDirectSize, AskImpliedSize, WorkingAsks, Settlement, DayChange, SessionLow, SessionHigh, SecurityKey }
|
||||
public enum Columns { Security, Volume, Last, LastSize, Position, WorkingBids, Bid, BidMergedSize, BidDirectSize, BidImpliedSize, Ask, AskMergedSize, AskDirectSize, AskImpliedSize, WorkingAsks, Settlement, DayChange, SessionLow, SessionHigh, SecurityKey,
|
||||
MarketDescription, ClearedAlias, ProductDescription, HubAlias, StripName, MicCode
|
||||
}
|
||||
|
||||
public MarketViewView() {
|
||||
InitializeComponent();
|
||||
|
||||
@@ -97,6 +97,12 @@ namespace bts.shell {
|
||||
public static GridColumnSettings session_low => new GridColumnSettings(col_id(Columns.SessionLow), DefaultColumnHeaders.SessionLow, width: DefaultColumnWidths.Price, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings session_high => new GridColumnSettings(col_id(Columns.SessionHigh), DefaultColumnHeaders.SessionHigh, width: DefaultColumnWidths.Price, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings security_key => new GridColumnSettings(col_id(Columns.SecurityKey), DefaultColumnHeaders.SecurityKey, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
public static GridColumnSettings market_description => new GridColumnSettings(col_id(Columns.MarketDescription), DefaultColumnHeaders.MarketDescription, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
public static GridColumnSettings cleared_alias => new GridColumnSettings(col_id(Columns.ClearedAlias), DefaultColumnHeaders.ClearedAlias, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
public static GridColumnSettings product_description => new GridColumnSettings(col_id(Columns.ProductDescription), DefaultColumnHeaders.ProductDescription, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
public static GridColumnSettings hub_alias => new GridColumnSettings(col_id(Columns.HubAlias), DefaultColumnHeaders.HubAlias, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
public static GridColumnSettings strip_name => new GridColumnSettings(col_id(Columns.StripName), DefaultColumnHeaders.StripName, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
public static GridColumnSettings mic_code => new GridColumnSettings(col_id(Columns.MicCode), DefaultColumnHeaders.MicCode, is_visible: false, width: DefaultColumnWidths.SecurityKey);
|
||||
|
||||
|
||||
|
||||
@@ -128,6 +134,12 @@ namespace bts.shell {
|
||||
yield return session_low;
|
||||
yield return session_high;
|
||||
yield return security_key;
|
||||
yield return market_description;
|
||||
yield return cleared_alias;
|
||||
yield return product_description;
|
||||
yield return hub_alias;
|
||||
yield return strip_name;
|
||||
yield return mic_code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +189,18 @@ namespace bts.shell {
|
||||
public UIntMinMaxState ask_direct_size;
|
||||
[ProtoMember(20)]
|
||||
public UIntMinMaxState ask_implied_size;
|
||||
[ProtoMember(21)]
|
||||
public string market_description;
|
||||
[ProtoMember(22)]
|
||||
public string cleared_alias;
|
||||
[ProtoMember(23)]
|
||||
public string product_description;
|
||||
[ProtoMember(24)]
|
||||
public string hub_alias;
|
||||
[ProtoMember(25)]
|
||||
public string strip_name;
|
||||
[ProtoMember(26)]
|
||||
public string mic_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,13 @@ using mbts.ui;
|
||||
using mbts.ui.controls;
|
||||
using mbts.ui.shell;
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
namespace mbts.spark {
|
||||
partial class OrderBookRowVM : DisposableViewModelBase, IEquatable<OrderBookRowVM>, DIYGrid.IRowVM, DIYGrid.IActionableRowVM {
|
||||
@@ -44,6 +46,19 @@ namespace mbts.spark {
|
||||
modify_order_price?.TryRaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
//// This takes care of the case where the OB has all rows visible
|
||||
//// and an order is cancelled outside of the OB (say via the ladder).
|
||||
//// Since the OB window Commands only revaluate their CanExecuteChanged
|
||||
//// when the OrderBookVM.selected_order_changes, this emulates the selected
|
||||
//// order changing since the current_row setter invokes the selected_order_changed
|
||||
//// handler
|
||||
public IObservable<OrderSecurityAlgoMeta> subscribe_data() {
|
||||
return Observable.FromEvent<Action, OrderSecurityAlgoMeta>(
|
||||
cb => () => cb(order_tuple),
|
||||
cb => invalidated += cb,
|
||||
cb => invalidated -= cb);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing) {
|
||||
this.invalidated -= OrderBookRowVM_invalidated;
|
||||
base.Dispose(disposing);
|
||||
|
||||
@@ -19,12 +19,11 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using static bts.shell.OrderBookWindowFactory;
|
||||
using static mbts.spark.OrderBookView;
|
||||
using _GridSettingsManager =
|
||||
using _GridSettingsManager =
|
||||
mbts.ui.GridSettingsManager<
|
||||
mbts.spark.OrderBookRowVM,
|
||||
bts.api.orderman.OrderSecurity,
|
||||
bts.shell.INotificationServiceDataCache,
|
||||
mbts.OrderRecordTuplePredicate,
|
||||
mbts.spark.OrderBookRowVM,
|
||||
bts.api.orderman.OrderSecurity,
|
||||
mbts.OrderRecordTuplePredicate,
|
||||
bts.shell.OrderBookWindowFactory.OrderBookGridSettings>;
|
||||
|
||||
namespace mbts.spark {
|
||||
@@ -54,6 +53,7 @@ namespace mbts.spark {
|
||||
collapse_all_rows_command = new DelegateCommand(_row_collection.collapse_all);
|
||||
expand_all_rows_command = new DelegateCommand(_row_collection.expand_all);
|
||||
grid_settings_manager = _create_grid_settings_manager(owner_title, bus, notification_service, model, rows, core_columns);
|
||||
|
||||
_resources = new List<IDisposable> {
|
||||
model.on_order_tuples.OnDispatcher().Subscribe(_row_collection.update),
|
||||
grid_settings_manager,
|
||||
@@ -62,7 +62,12 @@ namespace mbts.spark {
|
||||
_row_collection.CollectionChanged -= _row_collection_CollectionChanged;
|
||||
Disposable.dispose(_row_collection);
|
||||
}),
|
||||
_columns
|
||||
_columns,
|
||||
_current_row.SubscribeHookLatest(
|
||||
r => r.newval?.subscribe_data().Subscribe(
|
||||
data => selected_order_changed?.Invoke(data.order)
|
||||
)
|
||||
)
|
||||
};
|
||||
if (settings_manager != null) {
|
||||
_resources.Add(settings_manager.subscribe_current().OnDispatcher().Subscribe(grid_settings_manager));
|
||||
@@ -231,21 +236,25 @@ namespace mbts.spark {
|
||||
col_settings_flags[c.ToString()] = GridColumnSettingsFeatureFlags.ImmutableFontColor | GridColumnSettingsFeatureFlags.ImmutableFontWeight;
|
||||
}
|
||||
return new _GridSettingsManager(
|
||||
owner_title, bus, notification_service, model, rows, columns,
|
||||
owner_title, bus, model, rows, columns,
|
||||
() => new OrderRecordTuplePredicate(),
|
||||
() => {
|
||||
var pvm = PredicateBuilderVMWrapper.create<OrderSecurity, OrderRecordTuplePredicate, OrderRecordTuplePredicate.PredicateTypeOneofCase>(
|
||||
var pvm = PredicateVMWrapper.create<OrderSecurity, OrderRecordTuplePredicate, OrderRecordTuplePredicate.PredicateTypeOneofCase>(
|
||||
OrderRecordTuplePredicateVMFactory.get_oneofs(bus, model), rp => rp.predicate_type_case);
|
||||
pvm.selected_predicate_type = pvm.predicate_types.FirstOrDefault();
|
||||
return pvm;
|
||||
},
|
||||
col_id => {
|
||||
var pvm = PredicateBuilderVMWrapper.create<OrderSecurity, OrderRecordTuplePredicate, OrderRecordTuplePredicate.PredicateTypeOneofCase>(
|
||||
var pvm = PredicateVMWrapper.create<OrderSecurity, OrderRecordTuplePredicate, OrderRecordTuplePredicate.PredicateTypeOneofCase>(
|
||||
OrderRecordTuplePredicateVMFactory.get_oneofs(bus, model), rp => rp.predicate_type_case);
|
||||
pvm.selected_predicate_type = _corresponding_predicate_type(EnumHelper.parse_or_default<Columns>(col_id));
|
||||
return pvm;
|
||||
},
|
||||
(gen, anims) => new OrderBookGridSettings(gen, anims.Select(a => new OrderRecordTuplePredicateAnimations(a.predicate_builder, a.cell_animations, a.row_animations, a.sound_notifications))),
|
||||
(notification_service == null) ? null : notification_service.data_cache,
|
||||
(gen, anims) => new OrderBookGridSettings(gen, anims.Select(a => new OrderRecordTuplePredicateAnimations(a.predicate_data, a.cell_animations, a.row_animations, a.sound_notifications))),
|
||||
p => p.create_predicate(notification_service.data_cache),
|
||||
p => p.create_notification_predicate(notification_service.data_cache),
|
||||
notification_service == null ? new Func<IPredicate<OrderSecurity>, SoundNotification, IDisposable>((p, sn) => Disposable.empty) : notification_service.link_to_order,
|
||||
notification_service == null ? new Func<INotificationPredicate<OrderSecurity>, IDisposable>(t => Disposable.empty) : notification_service.link_to_order,
|
||||
col_settings_flags);
|
||||
}
|
||||
|
||||
@@ -275,4 +284,4 @@ namespace mbts.spark {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,17 +87,41 @@ namespace mbts.spark {
|
||||
|
||||
_cancel_buy_orders_command = SparkCommands.CancelBuyOrders.complete(
|
||||
_model.working_orders.Select(os => os.Values.Where(o => o.order.side() == Side.Buy).Select(o => o.order.Key)),
|
||||
wbids => wbids.Any()
|
||||
wbids => wbids.Any(),
|
||||
() => {
|
||||
var resp = BTSMessageBox.Show(
|
||||
"Are you sure you want to cancel all BUY orders?",
|
||||
"Cancel Buy Orders",
|
||||
BTSMessageBoxButtons.Yes | BTSMessageBoxButtons.No,
|
||||
MessageBoxImage.Question);
|
||||
return resp == BTSMessageBoxButtons.Yes;
|
||||
}
|
||||
);
|
||||
|
||||
_cancel_sell_orders_command = SparkCommands.CancelSellOrders.complete(
|
||||
_model.working_orders.Select(os => os.Values.Where(o => o.order.side() == Side.Sell).Select(o => o.order.Key)),
|
||||
wasks => wasks.Any()
|
||||
wasks => wasks.Any(),
|
||||
() => {
|
||||
var resp = BTSMessageBox.Show(
|
||||
"Are you sure you want to cancel all SELL orders?",
|
||||
"Cancel Sell Orders",
|
||||
BTSMessageBoxButtons.Yes | BTSMessageBoxButtons.No,
|
||||
MessageBoxImage.Question);
|
||||
return resp == BTSMessageBoxButtons.Yes;
|
||||
}
|
||||
);
|
||||
|
||||
_cancel_all_orders_command = SparkCommands.CancelOrders.complete(
|
||||
_model.working_orders.Select(os => os.Select(o => o.Key)),
|
||||
worders => worders.Any()
|
||||
worders => worders.Any(),
|
||||
() => {
|
||||
var resp = BTSMessageBox.Show(
|
||||
"Are you sure you want to cancel ALL orders?",
|
||||
"Cancel All Orders",
|
||||
BTSMessageBoxButtons.Yes | BTSMessageBoxButtons.No,
|
||||
MessageBoxImage.Question);
|
||||
return resp == BTSMessageBoxButtons.Yes;
|
||||
}
|
||||
);
|
||||
|
||||
_cancel_selected_orders_command = SparkCommands.CancelSelectedOrders.complete(
|
||||
|
||||
@@ -84,17 +84,17 @@ namespace bts.shell {
|
||||
static class DefaultColumns {
|
||||
|
||||
public static GridColumnSettings account => new GridColumnSettings(col_id(Columns.Account), DefaultColumnHeaders.Account, width: DefaultColumnWidths.Account);
|
||||
public static GridColumnSettings exchange => new GridColumnSettings(col_id(Columns.Exchange), DefaultColumnHeaders.Exchange, width: DefaultColumnWidths.Exchange);
|
||||
public static GridColumnSettings exchange => new GridColumnSettings(col_id(Columns.Exchange), DefaultColumnHeaders.Exchange, false, width: DefaultColumnWidths.Exchange);
|
||||
public static GridColumnSettings symbol => new GridColumnSettings(col_id(Columns.Symbol), DefaultColumnHeaders.Symbol, width: DefaultColumnWidths.Symbol);
|
||||
public static GridColumnSettings security => new GridColumnSettings(col_id(Columns.Security), DefaultColumnHeaders.Security, width: DefaultColumnWidths.Security);
|
||||
public static GridColumnSettings security_type => new GridColumnSettings(col_id(Columns.SecurityType), DefaultColumnHeaders.SecurityType, width: DefaultColumnWidths.SecurityType);
|
||||
public static GridColumnSettings start_net_position => new GridColumnSettings(col_id(Columns.StartNetPos), DefaultColumnHeaders.StartNetPos, width: DefaultColumnWidths.Start_Net_Pos, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings start_pnl => new GridColumnSettings(col_id(Columns.StartPNL), DefaultColumnHeaders.StartPnL, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings start_pnl => new GridColumnSettings(col_id(Columns.StartPNL), DefaultColumnHeaders.StartPnL, false, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings day_long_pnl => new GridColumnSettings(col_id(Columns.DayLong), DefaultColumnHeaders.DayLong, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings day_short_pnl => new GridColumnSettings(col_id(Columns.DayShort), DefaultColumnHeaders.DayShort, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings day_pnl => new GridColumnSettings(col_id(Columns.DayPNL), DefaultColumnHeaders.DayPnL, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings total_net_pos => new GridColumnSettings(col_id(Columns.TotalNetPos), DefaultColumnHeaders.TotalNetPos, width: DefaultColumnWidths.Total_Net_Pos, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings total_pnl => new GridColumnSettings(col_id(Columns.TotalPNL), DefaultColumnHeaders.TotalPnL, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings total_net_pos => new GridColumnSettings(col_id(Columns.TotalNetPos), DefaultColumnHeaders.TotalNetPos, false, width: DefaultColumnWidths.Total_Net_Pos, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings total_pnl => new GridColumnSettings(col_id(Columns.TotalPNL), DefaultColumnHeaders.TotalPnL, false, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
public static GridColumnSettings pnl_price => new GridColumnSettings(col_id(Columns.PNLPrice), DefaultColumnHeaders.PnLPrice, width: DefaultColumnWidths.PnL_Generic, horizontal_alignment: System.Windows.HorizontalAlignment.Right);
|
||||
|
||||
public static IEnumerable<SortingCriteria> default_sorting_criterion {
|
||||
@@ -158,6 +158,8 @@ namespace bts.shell {
|
||||
// ProtoMember 13 cannot be used further
|
||||
[ProtoMember(14)]
|
||||
public SecurityType[] security_types;
|
||||
[ProtoMember(15)]
|
||||
public bool[] has_day_trades;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using OrderTuple = System.ValueTuple<bts.api.SecurityImmutable?, bts.api.orderman.OrderRecordImmutable>;
|
||||
|
||||
namespace bts.shell {
|
||||
interface INotificationService {
|
||||
@@ -20,40 +19,14 @@ namespace bts.shell {
|
||||
INotificationServiceDataCache data_cache { get; }
|
||||
IDisposable link_to_activity(IPredicate<Activity> predicate, SoundNotification sound);
|
||||
IDisposable link_to_activity(INotificationPredicate<Activity> toast_notification_predicate);
|
||||
IDisposable link_to_order(IPredicate<OrderTuple> predicate, SoundNotification sound);
|
||||
IDisposable link_to_order(INotificationPredicate<OrderTuple> toast_notification_predicate);
|
||||
}
|
||||
|
||||
static class NotificationServiceExtensions {
|
||||
/// TODO: remove this extension and force callers to use the appropriate 'link' method in <see cref="INotificationService"/> (it is smelly, and is NOT ACTUALLY STRONGLY TYPED)
|
||||
public static IDisposable link<T>(this INotificationService notification_service, IPredicate<T> predicate, SoundNotification sound) {
|
||||
if (predicate is IPredicate<OrderTuple> orp)
|
||||
return notification_service.link_to_order(orp, sound);
|
||||
if (predicate is IPredicate<OrderSecurity> osp) {
|
||||
// Note: watch out for implicit types as generic type arguments (although OrderSecurity can be implicitly cast to OrderTuple, IPredicate<OrderSecurity> CANNOT be implicitly cast to IPredicate<OrderTuple>)
|
||||
return notification_service.link_to_order(PredicateBuilder.create<OrderTuple>(ot => osp.trigger(new OrderSecurity(ot.Item1, ot.Item2))), sound);
|
||||
}
|
||||
if (predicate is IPredicate<Activity> ap)
|
||||
return notification_service.link_to_activity(ap, sound);
|
||||
Log.Ui.error($"Unable to activate sound-trigger (unrecognized predicate type '{typeof(T)}').");
|
||||
return Disposable.empty;
|
||||
}
|
||||
|
||||
/// TODO: remove this extension and force callers to use the appropriate 'link' method in <see cref="INotificationService"/> (it is smelly, and is NOT ACTUALLY STRONGLY TYPED)
|
||||
public static IDisposable link<T>(this INotificationService notification_service, INotificationPredicate<T> toast_notification_predicate) {
|
||||
if (toast_notification_predicate is INotificationPredicate<OrderTuple> orp)
|
||||
return notification_service.link_to_order(orp);
|
||||
if (toast_notification_predicate is INotificationPredicate<Activity> ap)
|
||||
return notification_service.link_to_activity(ap);
|
||||
Log.Ui.error($"Unable to activate toast-notification-trigger (unrecognized predicate type '{typeof(T)}').");
|
||||
return Disposable.empty;
|
||||
}
|
||||
IDisposable link_to_order(IPredicate<OrderSecurity> predicate, SoundNotification sound);
|
||||
IDisposable link_to_order(INotificationPredicate<OrderSecurity> toast_notification_predicate);
|
||||
}
|
||||
|
||||
[Export(typeof(INotificationService))]
|
||||
partial class NotificationService : INotificationService, IDisposable {
|
||||
readonly NotificationProcessor<Activity> _activity_notifications;
|
||||
readonly NotificationProcessor<OrderTuple> _order_notifications;
|
||||
readonly NotificationProcessor<OrderSecurity> _order_notifications;
|
||||
readonly DataCache _data_cache = new DataCache();
|
||||
|
||||
IDisposable _dispose;
|
||||
@@ -62,7 +35,7 @@ namespace bts.shell {
|
||||
public NotificationService(IBus bus, INotifier notifier, OrdersModel orders_model) {
|
||||
this.notifier = notifier;
|
||||
_activity_notifications = new NotificationProcessor<Activity>(notifier);
|
||||
_order_notifications = new NotificationProcessor<OrderTuple>(notifier);
|
||||
_order_notifications = new NotificationProcessor<OrderSecurity>(notifier);
|
||||
_dispose = Disposable.Create(
|
||||
bus.subscribe(SparkTags.LogActivity).Subscribe(_on_activity),
|
||||
orders_model.on_orders.Subscribe(_on_orders)
|
||||
@@ -75,14 +48,14 @@ namespace bts.shell {
|
||||
|
||||
public IDisposable link_to_activity(IPredicate<Activity> predicate, SoundNotification sound) => _activity_notifications.link(predicate, sound);
|
||||
public IDisposable link_to_activity(INotificationPredicate<Activity> toast_notification_predicate) => _activity_notifications.link(toast_notification_predicate);
|
||||
public IDisposable link_to_order(IPredicate<OrderTuple> predicate, SoundNotification sound) => _order_notifications.link(predicate, sound);
|
||||
public IDisposable link_to_order(INotificationPredicate<OrderTuple> toast_notification_predicate) => _order_notifications.link(toast_notification_predicate);
|
||||
public IDisposable link_to_order(IPredicate<OrderSecurity> predicate, SoundNotification sound) => _order_notifications.link(predicate, sound);
|
||||
public IDisposable link_to_order(INotificationPredicate<OrderSecurity> toast_notification_predicate) => _order_notifications.link(toast_notification_predicate);
|
||||
public void Dispose() => Disposable.dispose(ref _dispose);
|
||||
|
||||
void _on_activity(Activity activity) =>
|
||||
_activity_notifications.process_item(activity);
|
||||
|
||||
void _on_orders(TableUpdate<(SecurityImmutable?,OrderRecordImmutable),uint> update) {
|
||||
void _on_orders(TableUpdate<(SecurityImmutable? sec, OrderRecordImmutable order), uint> update) {
|
||||
// must update notification_service_data_cache first, some of the predicate/triggers (esp. ToastNotifications) will use the notification_service_data_cache to lookup order-history
|
||||
_data_cache.update(update.as_iincremental());
|
||||
foreach (var o in update.added.Concat(update.changed))
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace bts.spark {
|
||||
static readonly IEqualityComparer<OrderRecordImmutable> _id_comparer =
|
||||
bts.utils.EqualityComparer.Create<OrderRecordImmutable, uint>(a => a.Key);
|
||||
|
||||
public OrderActivitySummarizer(IBus bus, IObservable<TableUpdate<(SecurityImmutable? sec,OrderRecordImmutable order), uint>> orders) {
|
||||
public OrderActivitySummarizer(IBus bus, IObservable<TableUpdate<(SecurityImmutable? sec, OrderRecordImmutable order), uint>> orders) {
|
||||
_bus = bus;
|
||||
_dispose = Disposable.Create(
|
||||
bus.subscribe(SparkTags.SecuritiesTag).Subscribe(sec => _security = sec),
|
||||
|
||||
@@ -7,18 +7,31 @@ namespace bts.api.orderman {
|
||||
public OrderSecurity(SecurityImmutable? sec, OrderRecordImmutable order) {
|
||||
this.security = sec;
|
||||
this.order = order;
|
||||
piq = null;
|
||||
}
|
||||
public OrderSecurity((SecurityImmutable? sec, OrderRecordImmutable order) t) {
|
||||
security = t.sec;
|
||||
order = t.order;
|
||||
piq = null;
|
||||
}
|
||||
public OrderSecurity(SecurityImmutable? sec, OrderRecordImmutable order, uint? piq) {
|
||||
this.security = sec;
|
||||
this.order = order;
|
||||
this.piq = piq;
|
||||
}
|
||||
//public OrderSecurity(OrderSecurity t) {
|
||||
// security = t.security;
|
||||
// order = t.order;
|
||||
// piq = t.piq;
|
||||
//}
|
||||
public static implicit operator OrderSecurity(ValueTuple<SecurityImmutable?, OrderRecordImmutable> x) => new OrderSecurity(x);
|
||||
public SecurityImmutable? security { get; }
|
||||
public OrderRecordImmutable order { get; }
|
||||
public uint? piq { get; }
|
||||
|
||||
public override bool Equals(object obj) => (obj is OrderSecurity os) && Equals(os);
|
||||
public bool Equals(OrderSecurity other) => order.Equals(other.order) && security == other.security;
|
||||
public override int GetHashCode() => (security, order).GetHashCode();
|
||||
public bool Equals(OrderSecurity other) => order.Equals(other.order) && security == other.security && piq == other.piq;
|
||||
public override int GetHashCode() => (security, order, piq).GetHashCode();
|
||||
|
||||
public static bool operator == (OrderSecurity left, OrderSecurity right) => left.Equals(right);
|
||||
public static bool operator != (OrderSecurity left, OrderSecurity right) => !left.Equals(right);
|
||||
|
||||
@@ -3,9 +3,11 @@ using bts.api;
|
||||
using bts.api.core;
|
||||
using bts.api.orderman;
|
||||
using bts.api.position;
|
||||
using bts.md;
|
||||
using bts.spark;
|
||||
using bts.utils;
|
||||
using mbts.collections;
|
||||
using mbts.config;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.utils;
|
||||
using System;
|
||||
@@ -16,8 +18,10 @@ using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Reactive.Concurrency;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Threading.Tasks;
|
||||
using OrderUpdate = bts.api.core.TableUpdate<(bts.api.SecurityImmutable? sec, bts.api.orderman.OrderRecordImmutable order), uint>;
|
||||
using OrderUpdatePiq = bts.api.core.TableUpdate<bts.api.orderman.OrderSecurity, uint>;
|
||||
|
||||
namespace mbts.spark {
|
||||
[Export]
|
||||
@@ -26,21 +30,26 @@ namespace mbts.spark {
|
||||
readonly OrderFactory _factory;
|
||||
readonly OrderService _service;
|
||||
readonly PositionService _position_service;
|
||||
readonly MBOService _mbo_service;
|
||||
readonly SpreaderModel _spreader;
|
||||
readonly ErrorReporter _error;
|
||||
readonly DynamicOrderHelper _dynamic_helper;
|
||||
readonly OrderActivitySummarizer _activity;
|
||||
readonly TableUpdateDemuxer<OrderRecordImmutable, uint, uint> _security_orders_demuxer;
|
||||
// we need a new one of these for the time being since the ladder is subscribing to orders with piq
|
||||
readonly TableUpdateDemuxer<OrderRecordImmutable, uint, uint> _security_orders_piq_demuxer;
|
||||
readonly TableUpdateDemuxer<PositionUnitImmutable, int, uint> _security_positions_demuxer;
|
||||
IDisposable _dispose;
|
||||
static readonly bool _piq_enabled = Configuration.get<bts.config.toggles.PlacementInQueue>().enabled;
|
||||
|
||||
[ImportingConstructor]
|
||||
OrdersModel(IBus bus, OrderFactory factory, OrderService service, PositionService position_service,
|
||||
OrdersModel(IBus bus, OrderFactory factory, OrderService service, PositionService position_service, MBOService mbo_service,
|
||||
SpreaderModel spreader, DynamicOrderHelper dynamic_helper, AdminModel admin_model, IAlgoStudioModel algo_model, SecurityStore sstore, ErrorReporter error) {
|
||||
_bus = bus;
|
||||
_factory = factory;
|
||||
_service = service;
|
||||
_position_service = position_service;
|
||||
_mbo_service = mbo_service;
|
||||
_spreader = spreader;
|
||||
_error = error;
|
||||
_dynamic_helper = dynamic_helper;
|
||||
@@ -48,13 +57,34 @@ namespace mbts.spark {
|
||||
this.algo_model = algo_model;
|
||||
var scheduler = ThreadPoolScheduler.Instance;
|
||||
var interval = TimeSpan.FromMilliseconds(100);
|
||||
on_orders =
|
||||
on_orders =
|
||||
_service
|
||||
.subscribei_orders()
|
||||
.Naggle(interval, scheduler)
|
||||
.PermissionFilter(admin_model.on_admin_data)
|
||||
.join(sstore, order => order.security_key())
|
||||
.Table().Cache();
|
||||
.Table()
|
||||
.Cache();
|
||||
|
||||
if (_piq_enabled) {
|
||||
on_orders_with_piq = on_orders
|
||||
.LeftJoin<
|
||||
(SecurityImmutable?, OrderRecordImmutable),
|
||||
OrderPIQImmutable,
|
||||
OrderSecurity,
|
||||
uint
|
||||
>(mbo_service.subscribei_piq().Table(),
|
||||
si_ort => si_ort.Item2.Key,
|
||||
p => p.OrderId,
|
||||
(si_ort, r, p) => new OrderSecurity(si_ort.Item1, si_ort.Item2, p.Position),
|
||||
(si_ort, r) => new OrderSecurity(si_ort.Item1, si_ort.Item2, null),
|
||||
osp => osp.order.Key);
|
||||
} else {
|
||||
on_orders_with_piq = on_orders
|
||||
.Select((ft) => new OrderSecurity(ft.Item1, ft.Item2, null), os => os.order.Key)
|
||||
.Replay(1);
|
||||
}
|
||||
|
||||
on_positions = _position_service.subscribei_position_data().Naggle(interval, scheduler).PermissionFilter(admin_model.on_admin_data).Table().Cache();
|
||||
working_orders =
|
||||
on_orders.Scan(
|
||||
@@ -62,6 +92,13 @@ namespace mbts.spark {
|
||||
(workers, table) => _update_working_orders(workers, table))
|
||||
.Replay(1).RefCount();
|
||||
|
||||
working_orders_with_piq =
|
||||
on_orders_with_piq.Scan(
|
||||
ImmutableDictionary<uint, OrderSecurity>.Empty,
|
||||
(workers, table) => _update_working_orders(workers, table))
|
||||
.Replay(1).RefCount();
|
||||
|
||||
|
||||
on_order_securities =
|
||||
on_orders
|
||||
.as_iincremental()
|
||||
@@ -70,6 +107,7 @@ namespace mbts.spark {
|
||||
|
||||
_activity = new OrderActivitySummarizer(bus, on_orders);
|
||||
_security_orders_demuxer = new TableUpdateDemuxer<OrderRecordImmutable, uint, uint>(o => o.Key, o => o.security_key());
|
||||
_security_orders_piq_demuxer = new TableUpdateDemuxer<OrderRecordImmutable, uint, uint>(o => o.Key, o => o.security_key());
|
||||
_security_positions_demuxer = new TableUpdateDemuxer<PositionUnitImmutable, int, uint>(o => o.RecordId, p => p.SecurityId);
|
||||
var algo_meta_join = algo_model.definitions.LeftJoin<AlgoData, AlgoDefinitionMetadata, (AlgoData algo, AlgoDefinitionMetadata? meta), AlgoKey>(
|
||||
algo_model.metadata_service.subscribe_metadata().Table(m => m.id),
|
||||
@@ -104,6 +142,7 @@ namespace mbts.spark {
|
||||
on_fill_tuples = fill_order_tuples_join;
|
||||
_dispose = Disposable.Create(
|
||||
on_orders.Select(t => t.order, o => o.Key).Subscribe(_security_orders_demuxer),
|
||||
on_orders_with_piq.RefCount().Select(t => t.order, o => o.Key).Subscribe(_security_orders_piq_demuxer),
|
||||
on_positions.Subscribe(_security_positions_demuxer),
|
||||
order_secs_algo_meta_join.Connect(),
|
||||
algo_meta_join.Connect(),
|
||||
@@ -121,11 +160,14 @@ namespace mbts.spark {
|
||||
public SpreaderModel spreader => _spreader;
|
||||
public DynamicOrderHelper dynamic_helper => _dynamic_helper;
|
||||
public IObservable<OrderUpdate> on_orders { get; }
|
||||
public IConnectableObservable<OrderUpdatePiq> on_orders_with_piq { get; }
|
||||
public IObservable<TableUpdate<OrderSecurityAlgoMeta, uint>> on_order_tuples { get; }
|
||||
public IObservable<IIncrementalUpdate<SecurityImmutable, uint>> on_order_securities { get; }
|
||||
public IObservable<TableUpdate<FillTuple, string>> on_fill_tuples { get; }
|
||||
public IObservable<IReadOnlyDictionary<uint,OrderSecurity>> working_orders { get; }
|
||||
public IObservable<IReadOnlyDictionary<uint, OrderSecurity>> working_orders_with_piq { get; }
|
||||
public IObservable<TableUpdate<PositionUnitImmutable, int>> on_positions { get; }
|
||||
|
||||
public AdminModel admin_model { get; }
|
||||
public IAlgoStudioModel algo_model { get; }
|
||||
|
||||
@@ -197,8 +239,30 @@ namespace mbts.spark {
|
||||
public void Dispose() =>
|
||||
Disposable.dispose(ref _dispose);
|
||||
|
||||
static ImmutableDictionary<uint, OrderSecurity>
|
||||
_update_working_orders(ImmutableDictionary<uint, OrderSecurity> target, OrderUpdate table) {
|
||||
static ImmutableDictionary<uint, OrderSecurity> _update_working_orders(ImmutableDictionary<uint, OrderSecurity> target, OrderUpdate table) {
|
||||
var clone = target.ToBuilder();
|
||||
foreach (var o in table.removed) {
|
||||
if (o.order.is_active()) {
|
||||
clone.Remove(o.order.Key);
|
||||
}
|
||||
}
|
||||
foreach (var o in table.changes) {
|
||||
if (o.Old.order.is_active()) {
|
||||
clone.Remove(o.Old.order.Key);
|
||||
}
|
||||
if (o.New.order.is_active()) {
|
||||
clone.Add(o.New.order.Key, o.New);
|
||||
}
|
||||
}
|
||||
foreach (var o in table.added) {
|
||||
if (o.order.is_active()) {
|
||||
clone.Add(o.order.Key, o);
|
||||
}
|
||||
}
|
||||
return clone.ToImmutableDictionary();
|
||||
}
|
||||
|
||||
static ImmutableDictionary<uint, OrderSecurity> _update_working_orders(ImmutableDictionary<uint, OrderSecurity> target, OrderUpdatePiq table) {
|
||||
var clone = target.ToBuilder();
|
||||
foreach (var o in table.removed) {
|
||||
if (o.order.is_active()) {
|
||||
@@ -222,6 +286,7 @@ namespace mbts.spark {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// usinig new OrdersModel extensions to reduce the amount of code change needed to switch uis over to the new OrdersModel,
|
||||
// without changing any code in the actual new OrdersModel class.
|
||||
static class OrdersModelExtensions {
|
||||
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class DiscreteStringPredicate : IDiscreteValuesPredicateBuilder<string>, IEquatable<DiscreteStringPredicate> {
|
||||
class DiscreteStringPredicate : IDiscreteValuesPredicateData<string>, IEquatable<DiscreteStringPredicate> {
|
||||
[ProtoMember(1)]
|
||||
string[] _values;
|
||||
[ProtoMember(2)]
|
||||
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class DiscreteUIntPredicate : IDiscreteValuesPredicateBuilder<uint, uint?, uint[]>, IEquatable<DiscreteUIntPredicate> {
|
||||
class DiscreteUIntPredicate : IDiscreteValuesPredicateData<uint, uint?, uint[]>, IEquatable<DiscreteUIntPredicate> {
|
||||
[ProtoMember(1)]
|
||||
uint[] _values;
|
||||
[ProtoMember(2)]
|
||||
@@ -16,7 +16,7 @@ namespace mbts {
|
||||
public uint[] not_in_set { get => _get_set(true); set => _set(true, value); }
|
||||
|
||||
public DiscreteValuesOneofCase predicate_type_case => DiscreteValuesPredicateUtils.get_predicate_type_case(_values, _negated);
|
||||
public IPredicate<uint> create(object obj) => DiscreteValuesPredicateUtils.create(this);
|
||||
public IPredicate<uint> create() => DiscreteValuesPredicateUtils.create(this);
|
||||
|
||||
public bool Equals(DiscreteUIntPredicate other) => DiscreteValuesPredicateUtils.equals(this, other);
|
||||
public override bool Equals(object obj) => Equals(obj as DiscreteUIntPredicate);
|
||||
|
||||
@@ -8,14 +8,14 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace mbts {
|
||||
interface IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> : IPredicateBuilder<T> {
|
||||
interface IDiscreteValuesPredicateData<T, TSingle, TMulti> {
|
||||
TSingle is_value { get; set; }
|
||||
TSingle not_value { get; set; }
|
||||
TMulti in_set { get; set; }
|
||||
TMulti not_in_set { get; set; }
|
||||
DiscreteValuesOneofCase predicate_type_case { get; }
|
||||
}
|
||||
interface IDiscreteValuesPredicateBuilder<T> : IDiscreteValuesPredicateBuilder<T, T, T[]> { }
|
||||
interface IDiscreteValuesPredicateData<T> : IDiscreteValuesPredicateData<T, T, T[]> { }
|
||||
|
||||
public enum DiscreteValuesOneofCase {
|
||||
None,
|
||||
@@ -32,8 +32,8 @@ namespace mbts {
|
||||
|
||||
namespace mbts.ui.settings {
|
||||
static class DiscreteValuesPredicateUtils {
|
||||
public static bool equals<T>(IDiscreteValuesPredicateBuilder<T> a, IDiscreteValuesPredicateBuilder<T> b) => a.safe_equals(b, _equals);
|
||||
static bool _equals<T>(IDiscreteValuesPredicateBuilder<T> a, IDiscreteValuesPredicateBuilder<T> b) {
|
||||
public static bool equals<T>(IDiscreteValuesPredicateData<T> a, IDiscreteValuesPredicateData<T> b) => a.safe_equals(b, _equals);
|
||||
static bool _equals<T>(IDiscreteValuesPredicateData<T> a, IDiscreteValuesPredicateData<T> b) {
|
||||
var dvoc = a.predicate_type_case;
|
||||
if (dvoc != b.predicate_type_case)
|
||||
return false;
|
||||
@@ -47,8 +47,8 @@ namespace mbts.ui.settings {
|
||||
}
|
||||
}
|
||||
|
||||
public static bool equals<T, TSingle, TMulti>(IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> a, IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> b) => a.safe_equals(b, _equals);
|
||||
public static bool _equals<T, TSingle, TMulti>(IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> a, IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> b) {
|
||||
public static bool equals<T, TSingle, TMulti>(IDiscreteValuesPredicateData<T, TSingle, TMulti> a, IDiscreteValuesPredicateData<T, TSingle, TMulti> b) => a.safe_equals(b, _equals);
|
||||
public static bool _equals<T, TSingle, TMulti>(IDiscreteValuesPredicateData<T, TSingle, TMulti> a, IDiscreteValuesPredicateData<T, TSingle, TMulti> b) {
|
||||
var dvoc = a.predicate_type_case;
|
||||
if (dvoc != b.predicate_type_case)
|
||||
return false;
|
||||
@@ -62,7 +62,7 @@ namespace mbts.ui.settings {
|
||||
}
|
||||
}
|
||||
|
||||
public static int hash<T>(IDiscreteValuesPredicateBuilder<T> a) {
|
||||
public static int hash<T>(IDiscreteValuesPredicateData<T> a) {
|
||||
switch (a.predicate_type_case) {
|
||||
case DiscreteValuesOneofCase.IsValue: return a.is_value.GetHashCode() % MathUtils.Primes.P_17191;
|
||||
case DiscreteValuesOneofCase.NotValue: return a.not_value.GetHashCode() % MathUtils.Primes.P_83987;
|
||||
@@ -72,7 +72,7 @@ namespace mbts.ui.settings {
|
||||
}
|
||||
}
|
||||
|
||||
public static int hash<T, TSingle, TMulti>(IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> a) {
|
||||
public static int hash<T, TSingle, TMulti>(IDiscreteValuesPredicateData<T, TSingle, TMulti> a) {
|
||||
switch (a.predicate_type_case) {
|
||||
case DiscreteValuesOneofCase.IsValue: return a.is_value.GetHashCode() % MathUtils.Primes.P_17191;
|
||||
case DiscreteValuesOneofCase.NotValue: return a.not_value.GetHashCode() % MathUtils.Primes.P_83987;
|
||||
@@ -88,7 +88,7 @@ namespace mbts.ui.settings {
|
||||
(negated ? DiscreteValuesOneofCase.NotValue : DiscreteValuesOneofCase.IsValue) :
|
||||
(negated ? DiscreteValuesOneofCase.NotInSet : DiscreteValuesOneofCase.IsInSet);
|
||||
|
||||
public static DiscreteValuesOneofCase get_predicate_type_case<T, TSingle, TMulti>(IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> predicate_builder) {
|
||||
public static DiscreteValuesOneofCase get_predicate_type_case<T, TSingle, TMulti>(IDiscreteValuesPredicateData<T, TSingle, TMulti> predicate_builder) {
|
||||
if (predicate_builder.is_value != null) return DiscreteValuesOneofCase.IsValue;
|
||||
if (predicate_builder.not_value != null) return DiscreteValuesOneofCase.NotValue;
|
||||
if (predicate_builder.in_set != null) return DiscreteValuesOneofCase.IsInSet;
|
||||
@@ -96,7 +96,7 @@ namespace mbts.ui.settings {
|
||||
return DiscreteValuesOneofCase.None;
|
||||
}
|
||||
|
||||
public static IPredicate<T> create<T>(IDiscreteValuesPredicateBuilder<T> predicate_builder) {
|
||||
public static IPredicate<T> create<T>(IDiscreteValuesPredicateData<T> predicate_builder) {
|
||||
switch (predicate_builder.predicate_type_case) {
|
||||
case DiscreteValuesOneofCase.IsValue: return PredicateBuilder.equals(predicate_builder.is_value);
|
||||
case DiscreteValuesOneofCase.NotValue: return PredicateBuilder.not_equals(predicate_builder.not_value);
|
||||
@@ -106,7 +106,7 @@ namespace mbts.ui.settings {
|
||||
}
|
||||
}
|
||||
|
||||
public static IPredicate<T> create<T>(IDiscreteValuesPredicateBuilder<T, T?, T[]> predicate_builder) where T : struct {
|
||||
public static IPredicate<T> create<T>(IDiscreteValuesPredicateData<T, T?, T[]> predicate_builder) where T : struct {
|
||||
switch (predicate_builder.predicate_type_case) {
|
||||
case DiscreteValuesOneofCase.IsValue: return PredicateBuilder.equals(predicate_builder.is_value.Value);
|
||||
case DiscreteValuesOneofCase.NotValue: return PredicateBuilder.not_equals(predicate_builder.not_value.Value);
|
||||
@@ -118,13 +118,13 @@ namespace mbts.ui.settings {
|
||||
}
|
||||
static class DiscreteValuesPredicateVMFactory {
|
||||
public static Dictionary<DiscreteValuesOneofCase, ITemplatedPropertyWrapperVM<TPredicate>> get_oneofs_value_type<T, TPredicate>(IEnumerable<T> items)
|
||||
where T : struct where TPredicate : IDiscreteValuesPredicateBuilder<T, T?, T[]> =>
|
||||
where T : struct where TPredicate : IDiscreteValuesPredicateData<T, T?, T[]> =>
|
||||
//
|
||||
get_oneofs<T, T?, T[], TPredicate>(identity_view_value_collection(items), val => val.Value, val => val, vals => vals ?? Enumerable.Empty<T>(), vals => vals?.ToArray() ?? new T[0], get_identity_view);
|
||||
|
||||
public static Dictionary<DiscreteValuesOneofCase, ITemplatedPropertyWrapperVM<TPredicate>> get_oneofs<T, TSingle, TMulti, TPredicate>(
|
||||
IObservableCollection<IViewValue<T>> items, Func<TSingle, T> from_single, Func<T, TSingle> to_single, Func<TMulti,IEnumerable<T>> from_multi, Func<IEnumerable<T>, TMulti> to_multi, Func<T, object> get_view)
|
||||
where TPredicate : IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> {
|
||||
where TPredicate : IDiscreteValuesPredicateData<T, TSingle, TMulti> {
|
||||
//
|
||||
return new Dictionary<DiscreteValuesOneofCase, ITemplatedPropertyWrapperVM<TPredicate>> {
|
||||
{ DiscreteValuesOneofCase.IsValue, PropertyWrapperVMUtils.create_selector_vm(
|
||||
@@ -153,14 +153,14 @@ namespace mbts.ui.settings {
|
||||
public static Dictionary<DiscreteValuesOneofCase, ITemplatedPropertyWrapperVM<TPredicate>> get_oneofs<T, TKey, TSingle, TMulti, TPredicate>(
|
||||
IEnumerable<T> items, Func<T, TKey> key, Func<TSingle, TKey> from_single, Func<TKey, TSingle> to_single, Func<TMulti, IEnumerable<TKey>> from_multi, Func<IEnumerable<TKey>, TMulti> to_multi)
|
||||
where TKey : struct, IEquatable<TKey>
|
||||
where TPredicate : IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> =>
|
||||
where TPredicate : IDiscreteValuesPredicateData<T, TSingle, TMulti> =>
|
||||
//
|
||||
get_oneofs<T, TKey, TSingle, TMulti, TPredicate>(RXCollection.from_enumerable(items.Select<T, IViewValue<T>>(v => new ViewValueTuple<T>(v, v))), key, from_single, to_single, from_multi, to_multi);
|
||||
|
||||
public static Dictionary<DiscreteValuesOneofCase, ITemplatedPropertyWrapperVM<TPredicate>> get_oneofs<T, TKey, TSingle, TMulti, TPredicate>(
|
||||
IObservableCollection<IViewValue<T>> items, Func<T, TKey> key, Func<TSingle, TKey> from_single, Func<TKey, TSingle> to_single, Func<TMulti, IEnumerable<TKey>> from_multi, Func<IEnumerable<TKey>, TMulti> to_multi)
|
||||
where TKey : struct, IEquatable<TKey>
|
||||
where TPredicate : IDiscreteValuesPredicateBuilder<T, TSingle, TMulti> {
|
||||
where TPredicate : IDiscreteValuesPredicateData<T, TSingle, TMulti> {
|
||||
//
|
||||
return new Dictionary<DiscreteValuesOneofCase, ITemplatedPropertyWrapperVM<TPredicate>> {
|
||||
{ DiscreteValuesOneofCase.IsValue, PropertyWrapperVMUtils.create_keyed_selector_vm<TPredicate, IViewValue<T>, TKey>(
|
||||
|
||||
@@ -5,7 +5,7 @@ using System;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class ExchangePredicate : IDiscreteValuesPredicateBuilder<Venue, Venue?, Venue[]>, IEquatable<ExchangePredicate> {
|
||||
class ExchangePredicate : IDiscreteValuesPredicateData<Venue, Venue?, Venue[]>, IEquatable<ExchangePredicate> {
|
||||
[ProtoMember(1)]
|
||||
Venue[] _values;
|
||||
[ProtoMember(2)]
|
||||
@@ -17,7 +17,7 @@ namespace mbts {
|
||||
public Venue[] not_in_set { get => _get_set(true); set => _set(true, value); }
|
||||
|
||||
public DiscreteValuesOneofCase predicate_type_case => DiscreteValuesPredicateUtils.get_predicate_type_case(_values, _negated);
|
||||
public IPredicate<Venue> create(object obj) => DiscreteValuesPredicateUtils.create(this);
|
||||
public IPredicate<Venue> create() => DiscreteValuesPredicateUtils.create(this);
|
||||
|
||||
public bool Equals(ExchangePredicate other) => DiscreteValuesPredicateUtils.equals(this, other);
|
||||
public override bool Equals(object obj) => Equals(obj as ExchangePredicate);
|
||||
|
||||
@@ -5,7 +5,7 @@ using System;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class OrderStatusPredicate : IDiscreteValuesPredicateBuilder<OrderStatus, OrderStatus?, OrderStatus[]>, IEquatable<OrderStatusPredicate> {
|
||||
class OrderStatusPredicate : IDiscreteValuesPredicateData<OrderStatus, OrderStatus?, OrderStatus[]>, IEquatable<OrderStatusPredicate> {
|
||||
[ProtoMember(1)]
|
||||
OrderStatus[] _values;
|
||||
[ProtoMember(2)]
|
||||
@@ -17,7 +17,7 @@ namespace mbts {
|
||||
public OrderStatus[] not_in_set { get => _get_set(true); set => _set(true, value); }
|
||||
|
||||
public DiscreteValuesOneofCase predicate_type_case => DiscreteValuesPredicateUtils.get_predicate_type_case(_values, _negated);
|
||||
public IPredicate<OrderStatus> create(object obj) => DiscreteValuesPredicateUtils.create(this);
|
||||
public IPredicate<OrderStatus> create() => DiscreteValuesPredicateUtils.create(this);
|
||||
|
||||
public bool Equals(OrderStatusPredicate other) => DiscreteValuesPredicateUtils.equals(this, other);
|
||||
public override bool Equals(object obj) => Equals(obj as OrderStatusPredicate);
|
||||
|
||||
@@ -5,7 +5,7 @@ using System;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class OrderSubTypePredicate : IDiscreteValuesPredicateBuilder<OrderSubType, OrderSubType?, OrderSubType[]>, IEquatable<OrderSubTypePredicate> {
|
||||
class OrderSubTypePredicate : IDiscreteValuesPredicateData<OrderSubType, OrderSubType?, OrderSubType[]>, IEquatable<OrderSubTypePredicate> {
|
||||
[ProtoMember(1)]
|
||||
OrderSubType[] _values;
|
||||
[ProtoMember(2)]
|
||||
@@ -17,7 +17,7 @@ namespace mbts {
|
||||
public OrderSubType[] not_in_set { get => _get_set(true); set => _set(true, value); }
|
||||
|
||||
public DiscreteValuesOneofCase predicate_type_case => DiscreteValuesPredicateUtils.get_predicate_type_case(_values, _negated);
|
||||
public IPredicate<OrderSubType> create(object obj) => DiscreteValuesPredicateUtils.create(this);
|
||||
public IPredicate<OrderSubType> create() => DiscreteValuesPredicateUtils.create(this);
|
||||
|
||||
public bool Equals(OrderSubTypePredicate other) => DiscreteValuesPredicateUtils.equals(this, other);
|
||||
public override bool Equals(object obj) => Equals(obj as OrderSubTypePredicate);
|
||||
|
||||
@@ -5,7 +5,7 @@ using OrderType = bts.api.orderman.CustomOrderDefinition.CustomOneofCase;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class OrderTypePredicate : IDiscreteValuesPredicateBuilder<OrderType, OrderType?, OrderType[]>, IEquatable<OrderTypePredicate> {
|
||||
class OrderTypePredicate : IDiscreteValuesPredicateData<OrderType, OrderType?, OrderType[]>, IEquatable<OrderTypePredicate> {
|
||||
[ProtoMember(1)]
|
||||
OrderType[] _values;
|
||||
[ProtoMember(2)]
|
||||
@@ -17,7 +17,7 @@ namespace mbts {
|
||||
public OrderType[] not_in_set { get => _get_set(true); set => _set(true, value); }
|
||||
|
||||
public DiscreteValuesOneofCase predicate_type_case => DiscreteValuesPredicateUtils.get_predicate_type_case(_values, _negated);
|
||||
public IPredicate<OrderType> create(object obj) => DiscreteValuesPredicateUtils.create(this);
|
||||
public IPredicate<OrderType> create() => DiscreteValuesPredicateUtils.create(this);
|
||||
|
||||
public bool Equals(OrderTypePredicate other) => DiscreteValuesPredicateUtils.equals(this, other);
|
||||
public override bool Equals(object obj) => Equals(obj as OrderTypePredicate);
|
||||
|
||||
@@ -5,7 +5,7 @@ using System;
|
||||
|
||||
namespace mbts {
|
||||
[ProtoContract]
|
||||
class TimeInForcePredicate : IDiscreteValuesPredicateBuilder<TimeInForce, TimeInForce?, TimeInForce[]>, IEquatable<TimeInForcePredicate> {
|
||||
class TimeInForcePredicate : IDiscreteValuesPredicateData<TimeInForce, TimeInForce?, TimeInForce[]>, IEquatable<TimeInForcePredicate> {
|
||||
[ProtoMember(1)]
|
||||
TimeInForce[] _values;
|
||||
[ProtoMember(2)]
|
||||
@@ -17,7 +17,7 @@ namespace mbts {
|
||||
public TimeInForce[] not_in_set { get => _get_set(true); set => _set(true, value); }
|
||||
|
||||
public DiscreteValuesOneofCase predicate_type_case => DiscreteValuesPredicateUtils.get_predicate_type_case(_values, _negate);
|
||||
public IPredicate<TimeInForce> create(object obj) => DiscreteValuesPredicateUtils.create(this);
|
||||
public IPredicate<TimeInForce> create() => DiscreteValuesPredicateUtils.create(this);
|
||||
|
||||
public bool Equals(TimeInForcePredicate other) => DiscreteValuesPredicateUtils.equals(this, other);
|
||||
public override bool Equals(object obj) => Equals(obj as TimeInForcePredicate);
|
||||
|
||||
@@ -4,7 +4,6 @@ using bts.shell;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.ui.settings;
|
||||
using mbts.utils;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,7 +13,7 @@ namespace mbts {
|
||||
static class OrderCanceledEventPredicateVMFactory {
|
||||
public static Dictionary<OrderCanceledEventPredicate.PredicateTypeOneofCase, ITemplatedPropertyWrapperVM<OrderCanceledEventPredicate>> get_oneofs(IBus bus) =>
|
||||
new Dictionary<OrderCanceledEventPredicate.PredicateTypeOneofCase, ITemplatedPropertyWrapperVM<OrderCanceledEventPredicate>> {
|
||||
{ OrderCanceledEventPredicate.PredicateTypeOneofCase.AnyOrder, PredicateBuilderVMWrapper.create<OrderCanceledEventPredicate>(p => p.security = null) },
|
||||
{ OrderCanceledEventPredicate.PredicateTypeOneofCase.AnyOrder, PredicateVMWrapper.create<OrderCanceledEventPredicate>(p => p.security = null) },
|
||||
{ OrderCanceledEventPredicate.PredicateTypeOneofCase.SecurityOrder, SecurityCriteriaVMFactory.create<OrderCanceledEventPredicate>(bus, o => o.security?.is_value ?? new SecurityCriteria(),
|
||||
(p, s) => {
|
||||
if (p.security == null)
|
||||
@@ -26,7 +25,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class OrderCanceledEventPredicate : IPredicateBuilder<OrderSecurity, INotificationServiceDataCache>, IEquatable<OrderCanceledEventPredicate> {
|
||||
class OrderCanceledEventPredicate : IEquatable<OrderCanceledEventPredicate> {
|
||||
public enum PredicateTypeOneofCase {
|
||||
[Description("(any order)")]
|
||||
AnyOrder,
|
||||
@@ -52,7 +51,7 @@ namespace mbts {
|
||||
OrderEventPredicateHelper.create_status_transition_predicate(OrderStatus.Canceled, security, data_cache);
|
||||
|
||||
public INotificationPredicate<OrderSecurity> create_toast(INotificationServiceDataCache data_cache) =>
|
||||
new MyToaster(security?.create(data_cache), data_cache);
|
||||
new MyToaster(security?.create(), data_cache);
|
||||
|
||||
public bool Equals(OrderCanceledEventPredicate other) => other != null && other.security.safe_equals(other.security);
|
||||
public override bool Equals(object obj) => Equals(obj as OrderCanceledEventPredicate);
|
||||
|
||||
@@ -4,7 +4,6 @@ using bts.shell;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.ui.settings;
|
||||
using mbts.utils;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,7 +13,7 @@ namespace mbts {
|
||||
static class OrderCompletedEventPredicateVMFactory {
|
||||
public static Dictionary<OrderCompletedEventPredicate.PredicateTypeOneofCase, ITemplatedPropertyWrapperVM<OrderCompletedEventPredicate>> get_oneofs(IBus bus) =>
|
||||
new Dictionary<OrderCompletedEventPredicate.PredicateTypeOneofCase, ITemplatedPropertyWrapperVM<OrderCompletedEventPredicate>> {
|
||||
{ OrderCompletedEventPredicate.PredicateTypeOneofCase.AnyOrder, PredicateBuilderVMWrapper.create<OrderCompletedEventPredicate>(p => p.security = null) },
|
||||
{ OrderCompletedEventPredicate.PredicateTypeOneofCase.AnyOrder, PredicateVMWrapper.create<OrderCompletedEventPredicate>(p => p.security = null) },
|
||||
{ OrderCompletedEventPredicate.PredicateTypeOneofCase.SecurityOrder, SecurityCriteriaVMFactory.create<OrderCompletedEventPredicate>(bus, o => o.security?.is_value ?? new SecurityCriteria(),
|
||||
(p, s) => {
|
||||
if (p.security == null)
|
||||
@@ -26,7 +25,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class OrderCompletedEventPredicate : IPredicateBuilder<OrderSecurity, INotificationServiceDataCache>, IEquatable<OrderCompletedEventPredicate> {
|
||||
class OrderCompletedEventPredicate : IEquatable<OrderCompletedEventPredicate> {
|
||||
public enum PredicateTypeOneofCase {
|
||||
[Description("(any order)")]
|
||||
AnyOrder,
|
||||
@@ -52,7 +51,7 @@ namespace mbts {
|
||||
OrderEventPredicateHelper.create_status_transition_predicate(OrderStatus.Completed, security, data_cache);
|
||||
|
||||
public INotificationPredicate<OrderSecurity> create_toast(INotificationServiceDataCache data_cache) =>
|
||||
new MyToaster(security?.create(data_cache), data_cache);
|
||||
new MyToaster(security?.create(), data_cache);
|
||||
|
||||
public bool Equals(OrderCompletedEventPredicate other) => other != null && other.security.safe_equals(other.security);
|
||||
public override bool Equals(object obj) => Equals(obj as OrderCompletedEventPredicate);
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
using bts.api.orderman;
|
||||
using bts.shell;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.utils;
|
||||
using System;
|
||||
|
||||
namespace mbts {
|
||||
@@ -39,7 +37,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
public static IPredicate<OrderSecurity> create_status_transition_predicate(OrderStatus status, SecurityPredicate security_predicate, INotificationServiceDataCache data_cache) =>
|
||||
new OrderStatusTransitionPredicate(status, security_predicate?.create(data_cache), data_cache);
|
||||
new OrderStatusTransitionPredicate(status, security_predicate?.create(), data_cache);
|
||||
|
||||
class OrderStatusTransitionPredicate : IPredicate<OrderSecurity>, IEquatable<OrderStatusTransitionPredicate> {
|
||||
readonly IPredicate<SecurityImmutable> _security_predicate;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace mbts {
|
||||
static class OrderFilledEventPredicateVMFactory {
|
||||
public static Dictionary<OrderFilledEventPredicate.PredicateTypeOneofCase, ITemplatedPropertyWrapperVM<OrderFilledEventPredicate>> get_oneofs(IBus bus) =>
|
||||
new Dictionary<OrderFilledEventPredicate.PredicateTypeOneofCase, ITemplatedPropertyWrapperVM<OrderFilledEventPredicate>> {
|
||||
{ OrderFilledEventPredicate.PredicateTypeOneofCase.AnyOrder, PredicateBuilderVMWrapper.create<OrderFilledEventPredicate>(p => p.security = null) },
|
||||
{ OrderFilledEventPredicate.PredicateTypeOneofCase.AnyOrder, PredicateVMWrapper.create<OrderFilledEventPredicate>(p => p.security = null) },
|
||||
{ OrderFilledEventPredicate.PredicateTypeOneofCase.SecurityOrder, SecurityCriteriaVMFactory.create<OrderFilledEventPredicate>(bus, o => o.security?.is_value ?? new SecurityCriteria(),
|
||||
(p, s) => {
|
||||
if (p.security == null) {
|
||||
@@ -24,7 +24,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class OrderFilledEventPredicate : IPredicateBuilder<OrderSecurity, INotificationServiceDataCache>, IEquatable<OrderFilledEventPredicate> {
|
||||
class OrderFilledEventPredicate : IEquatable<OrderFilledEventPredicate> {
|
||||
public enum PredicateTypeOneofCase {
|
||||
[PredicateCase("(any order)")]
|
||||
AnyOrder,
|
||||
@@ -59,7 +59,7 @@ namespace mbts {
|
||||
public override int GetHashCode() => security == null ? 0 : security.GetHashCode();
|
||||
|
||||
FillTriggerModel _create_model(INotificationServiceDataCache nsdc) =>
|
||||
new FillTriggerModel(nsdc, security?.create(nsdc));
|
||||
new FillTriggerModel(nsdc, security?.create());
|
||||
|
||||
class FillTriggerModel {
|
||||
readonly IPredicate<SecurityImmutable> _security_predicate;
|
||||
@@ -82,7 +82,7 @@ namespace mbts {
|
||||
// old order will be a copy of new order, except with filledQuantity set to 0
|
||||
var old_state = ort.order.State.CloneToMutable();
|
||||
old_state.FilledQuantity = 0;
|
||||
return (new OrderSecurity(ort.security, ort.order.with(state: old_state)), ort);
|
||||
return (new OrderSecurity(ort.security, ort.order.with(state: old_state), ort.piq), ort);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -56,12 +56,12 @@ namespace mbts {
|
||||
Func<TChildPredicate, TChildPredicateOneof> key,
|
||||
Dictionary<TChildPredicateOneof, ITemplatedPropertyWrapperVM<TChildPredicate>> oneofs) where TChildPredicateOneof : struct where TChildPredicate : new() =>
|
||||
//
|
||||
PredicateBuilderVMWrapper.wrap_child_oneof<OrderRecordTuplePredicate, TChildPredicate, TChildPredicateOneof>(get, set, key, oneofs);
|
||||
PredicateVMWrapper.wrap_child_oneof<OrderRecordTuplePredicate, TChildPredicate, TChildPredicateOneof>(get, set, key, oneofs);
|
||||
}
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class OrderRecordTuplePredicate : INotificationPredicateBuilder<OrderSecurity, INotificationServiceDataCache>, IEquatable<OrderRecordTuplePredicate> {
|
||||
class OrderRecordTuplePredicate : IEquatable<OrderRecordTuplePredicate> {
|
||||
SecurityPredicate _security;
|
||||
SidePredicate _side;
|
||||
DoublePredicate _price, _last_price, _avg_price;
|
||||
@@ -208,39 +208,36 @@ namespace mbts {
|
||||
|
||||
public IPredicate<OrderSecurity> create_predicate(INotificationServiceDataCache data_cache) {
|
||||
switch (predicate_type_case) {
|
||||
case PTOC.Security: return wrap(_security, r => r.security ?? SecurityDataHelper.Defaults.SecurityImmutable);
|
||||
case PTOC.Time: return wrap(_time_created, r => r.order.created());
|
||||
case PTOC.LastChange: return wrap(_last_change, r => r.order.last_change());
|
||||
case PTOC.User: return wrap(_user, r => r.order.user_id());
|
||||
case PTOC.Account: return wrap(_account, r => r.order.account_id());
|
||||
case PTOC.Exchange: return wrap(_exchange, r => r.security.exchange_or_default());
|
||||
case PTOC.TimeInForce: return wrap(_time_in_force, r => r.order.time_in_force());
|
||||
case PTOC.OrderType: return wrap(_order_type, r => r.order.order_type());
|
||||
case PTOC.SubType: return wrap(_order_sub_type, r => r.order.sub_type());
|
||||
case PTOC.Side: return wrap(_side, r => r.order.side());
|
||||
case PTOC.Size: return wrap(_quantity, r => r.order.quantity());
|
||||
case PTOC.Price: return wrap(_price, r => r.order.price());
|
||||
case PTOC.Filled: return wrap(_filled_quantity, r => r.order.filled());
|
||||
case PTOC.AvgFilled: return wrap(_avg_price, r => r.order.avg_price());
|
||||
case PTOC.LastPrice: return wrap(_last_price, r => r.order.last_price());
|
||||
case PTOC.Status: return wrap(_order_status, r => r.order.status());
|
||||
case PTOC.LastMessage: return wrap(_last_message, r => r.order.last_msg());
|
||||
case PTOC.SecurityKey: return wrap(_security_key, r => r.order.security_key());
|
||||
case PTOC.OrderKey: return wrap(_order_key, r => r.order.Key);
|
||||
case PTOC.ParentKey: return wrap(_parent_key, r => r.order.ParentKey);
|
||||
case PTOC.Security: return wrap(_security.create(), r => r.security ?? SecurityDataHelper.Defaults.SecurityImmutable);
|
||||
case PTOC.Time: return wrap(_time_created.create(), r => r.order.created());
|
||||
case PTOC.LastChange: return wrap(_last_change.create(), r => r.order.last_change());
|
||||
case PTOC.User: return wrap(_user.create(), r => r.order.user_id());
|
||||
case PTOC.Account: return wrap(_account.create(), r => r.order.account_id());
|
||||
case PTOC.Exchange: return wrap(_exchange.create(), r => r.security.exchange_or_default());
|
||||
case PTOC.TimeInForce: return wrap(_time_in_force.create(), r => r.order.time_in_force());
|
||||
case PTOC.OrderType: return wrap(_order_type.create(), r => r.order.order_type());
|
||||
case PTOC.SubType: return wrap(_order_sub_type.create(), r => r.order.sub_type());
|
||||
case PTOC.Side: return wrap(_side.create(), r => r.order.side());
|
||||
case PTOC.Size: return wrap(_quantity.create(), r => r.order.quantity());
|
||||
case PTOC.Price: return wrap(_price.create(), r => r.order.price());
|
||||
case PTOC.Filled: return wrap(_filled_quantity.create(), r => r.order.filled());
|
||||
case PTOC.AvgFilled: return wrap(_avg_price.create(), r => r.order.avg_price());
|
||||
case PTOC.LastPrice: return wrap(_last_price.create(), r => r.order.last_price());
|
||||
case PTOC.Status: return wrap(_order_status.create(), r => r.order.status());
|
||||
case PTOC.LastMessage: return wrap(_last_message.create(), r => r.order.last_msg());
|
||||
case PTOC.SecurityKey: return wrap(_security_key.create(), r => r.order.security_key());
|
||||
case PTOC.OrderKey: return wrap(_order_key.create(), r => r.order.Key);
|
||||
case PTOC.ParentKey: return wrap(_parent_key.create(), r => r.order.ParentKey);
|
||||
case PTOC.FilledEvent: return _filled_event.create_predicate(data_cache);
|
||||
case PTOC.CompletedEvent: return _completed_event.create_predicate(data_cache);
|
||||
case PTOC.CanceledEvent: return _canceled_event.create(data_cache);
|
||||
default: return null;
|
||||
}
|
||||
//
|
||||
IPredicate<OrderSecurity> wrap<T>(IPredicateBuilder<T> trigger, Func<OrderSecurity, T> select) =>
|
||||
trigger.create(data_cache).wrap<OrderSecurity,T>(select);
|
||||
IPredicate<OrderSecurity> wrap<T>(IPredicate<T> trigger, Func<OrderSecurity, T> select) =>
|
||||
trigger.wrap<OrderSecurity, T>(select);
|
||||
}
|
||||
|
||||
IPredicate<OrderSecurity> IPredicateBuilder<OrderSecurity>.create(object obj) =>
|
||||
create_predicate((INotificationServiceDataCache)obj);
|
||||
|
||||
public INotificationPredicate<OrderSecurity> create_notification_predicate(INotificationServiceDataCache notification_service_data_cache) {
|
||||
if (!is_toast_enabled)
|
||||
return null;
|
||||
@@ -252,9 +249,6 @@ namespace mbts {
|
||||
}
|
||||
}
|
||||
|
||||
INotificationPredicate<OrderSecurity> INotificationPredicateBuilder<OrderSecurity>.create_notification_predicate(object obj) =>
|
||||
create_notification_predicate((INotificationServiceDataCache)obj);
|
||||
|
||||
public bool Equals(OrderRecordTuplePredicate other) {
|
||||
if (other == null)
|
||||
return false;
|
||||
@@ -378,9 +372,9 @@ namespace mbts {
|
||||
_sound_animations = new List<SoundNotification> ( sound_animations );
|
||||
}
|
||||
|
||||
public OrderRecordTuplePredicate predicate_builder => _predicate;
|
||||
public OrderRecordTuplePredicate predicate_data => _predicate;
|
||||
public IReadOnlyList<CellAnimation> cell_animations => _cell_animations ?? (_cell_animations = new List<CellAnimation>());
|
||||
public IReadOnlyList<RowAnimation> row_animations => _row_animations ?? (_row_animations = new List<RowAnimation>());
|
||||
public IReadOnlyList<SoundNotification> sound_notifications => _sound_animations ?? (_sound_animations = new List<SoundNotification>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using bts.proto;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui.spark;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
@@ -24,7 +23,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class DoublePredicate : IPredicateBuilder<double>, IEquatable<DoublePredicate> {
|
||||
class DoublePredicate : IEquatable<DoublePredicate> {
|
||||
// not using a 'negate' flag here bc its meaning is not consistent for all value-types
|
||||
// greater than vs less than for specific values, or inside vs outside for value-ranges
|
||||
// trading a little more code for more clarity
|
||||
@@ -62,7 +61,7 @@ namespace mbts {
|
||||
}
|
||||
}
|
||||
|
||||
public IPredicate<double> create(object obj) {
|
||||
public IPredicate<double> create() {
|
||||
switch (predicate_type_case) {
|
||||
case PredicateTypeOneofCase.GreaterThan: return PredicateBuilder.greater_than(_greater_than.Value);
|
||||
case PredicateTypeOneofCase.LessThan: return PredicateBuilder.less_than(_less_than.Value);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using bts.api;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui.spark;
|
||||
using mbts.ui.utility;
|
||||
using ProtoBuf;
|
||||
@@ -23,7 +22,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class SidePredicate : IPredicateBuilder<Side>, IEquatable<SidePredicate> {
|
||||
class SidePredicate : IEquatable<SidePredicate> {
|
||||
Side? _is_value;
|
||||
Side? _not_value;
|
||||
|
||||
@@ -48,7 +47,7 @@ namespace mbts {
|
||||
}
|
||||
}
|
||||
|
||||
public IPredicate<Side> create(object obj) {
|
||||
public IPredicate<Side> create() {
|
||||
switch (predicate_type_case) {
|
||||
case PredicateTypeOneofCase.IsValue: return PredicateBuilder.equals(_is_value.Value);
|
||||
case PredicateTypeOneofCase.NotValue: return PredicateBuilder.not_equals(_not_value.Value);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using bts.proto;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui.spark;
|
||||
using mbts.utils;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -27,7 +25,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class StringPredicate : IPredicateBuilder<string>, IEquatable<StringPredicate> {
|
||||
class StringPredicate : IEquatable<StringPredicate> {
|
||||
StringIgnoreCase? _is_string, _not_string, _contains_string, _not_contains_string;
|
||||
|
||||
public enum PredicateTypeOneofCase {
|
||||
@@ -61,7 +59,7 @@ namespace mbts {
|
||||
}
|
||||
}
|
||||
|
||||
public IPredicate<string> create(object obj) {
|
||||
public IPredicate<string> create() {
|
||||
switch (predicate_type_case) {
|
||||
case PTOC.IsMatch: return PredicateBuilder.equals(_is_string.Value.text, _get_eq_comparer(_is_string));
|
||||
case PTOC.NotMatch: return PredicateBuilder.not_equals(_not_string.Value.text, _get_eq_comparer(_not_string));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using bts.proto;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui.spark;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
@@ -21,7 +20,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class TimePredicate : IPredicateBuilder<DateTime>, IEquatable<TimePredicate> {
|
||||
class TimePredicate : IEquatable<TimePredicate> {
|
||||
// not using a 'negate' flag here bc its meaning is not consistent for all value-types
|
||||
// before vs after for specific times, or inside vs outside for time-ranges
|
||||
// trading a little more code for clarity
|
||||
@@ -59,7 +58,7 @@ namespace mbts {
|
||||
}
|
||||
}
|
||||
|
||||
public IPredicate<DateTime> create(object obj) {
|
||||
public IPredicate<DateTime> create() {
|
||||
switch (predicate_type_case) {
|
||||
case PTOC.Before: return PredicateBuilder.less_than(_before.Value.get_date_time());
|
||||
case PTOC.After: return PredicateBuilder.greater_than(_after.Value.get_date_time());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using bts.proto;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui.spark;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
@@ -24,7 +23,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class UIntPredicate : IPredicateBuilder<uint>, IEquatable<UIntPredicate> {
|
||||
class UIntPredicate : IEquatable<UIntPredicate> {
|
||||
// not using a 'negate' flag here bc its meaning is not consistent for all value-types
|
||||
// greater than vs less than for specific values, or inside vs outside for value-ranges
|
||||
// trading a little more code for more clarity
|
||||
@@ -62,7 +61,7 @@ namespace mbts {
|
||||
}
|
||||
}
|
||||
|
||||
public IPredicate<uint> create(object obj) {
|
||||
public IPredicate<uint> create() {
|
||||
switch (predicate_type_case) {
|
||||
case PredicateTypeOneofCase.GreaterThan: return PredicateBuilder.greater_than(_greater_than.Value);
|
||||
case PredicateTypeOneofCase.LessThan: return PredicateBuilder.less_than(_less_than.Value);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using bts.proto;
|
||||
using bts.utils;
|
||||
using mbts.spark;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui.spark;
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
@@ -24,7 +23,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class UShortPredicate : IPredicateBuilder<ushort>, IEquatable<UShortPredicate> {
|
||||
class UShortPredicate : IEquatable<UShortPredicate> {
|
||||
// not using a 'negate' flag here bc its meaning is not consistent for all value-types
|
||||
// greater than vs less than for specific values, or inside vs outside for value-ranges
|
||||
// trading a little more code for more clarity
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace mbts {
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
class SecurityPredicate : IPredicateBuilder<SecurityImmutable>, IEquatable<SecurityPredicate> {
|
||||
class SecurityPredicate : IEquatable<SecurityPredicate> {
|
||||
[ProtoMember(1)]
|
||||
SecurityCriteria _criteria;
|
||||
[ProtoMember(2)]
|
||||
@@ -43,7 +43,8 @@ namespace mbts {
|
||||
_criteria == null ? PTOC.None :
|
||||
_negate ? PTOC.NotInCriteria : PTOC.InCriteria;
|
||||
|
||||
public IPredicate<SecurityImmutable> create(object obj) => _criteria.is_defined() ? new MyPredicate(_criteria, _negate) : null;
|
||||
public IPredicate<SecurityImmutable> create() => _criteria.is_defined() ? new MyPredicate(_criteria, _negate) : null;
|
||||
|
||||
public bool Equals(SecurityPredicate other) =>
|
||||
other != null &&
|
||||
_negate == other._negate &&
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using bts.shell;
|
||||
using bts.utils;
|
||||
using mbts.utils;
|
||||
using bts.utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -14,23 +12,6 @@ namespace mbts {
|
||||
bool trigger(T value);
|
||||
}
|
||||
|
||||
interface IPredicateBuilder<T> {
|
||||
IPredicate<T> create(object obj);
|
||||
}
|
||||
|
||||
interface INotificationPredicateBuilder<T> : IPredicateBuilder<T> {
|
||||
bool is_toast_enabled { get; set; }
|
||||
INotificationPredicate<T> create_notification_predicate(object obj);
|
||||
}
|
||||
|
||||
interface IPredicateBuilder<T, TArg> : IPredicateBuilder<T> {
|
||||
IPredicate<T> create_predicate(TArg arg);
|
||||
}
|
||||
|
||||
interface INotificationPredicateBuilder<T, TArg> : IPredicateBuilder<T, TArg>, INotificationPredicateBuilder<T> {
|
||||
INotificationPredicate<T> create_notification_predicate(TArg arg);
|
||||
}
|
||||
|
||||
public enum PredicateCategory {
|
||||
Normal,
|
||||
Event
|
||||
|
||||
+36
-41
@@ -13,25 +13,23 @@ using System.Reactive.Linq;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace mbts.ui.settings {
|
||||
interface IPredicateBuilderVM<TRowData, TPredicateBuilder, TPredicateBuilderOneof> : ITemplatedPropertyWrapperVM<TPredicateBuilder>
|
||||
where TPredicateBuilder : IPredicateBuilder<TRowData>
|
||||
where TPredicateBuilderOneof : struct {
|
||||
IReadOnlyCollection<TPredicateBuilderOneof> predicate_types { get; }
|
||||
interface IPredicateVM<TRowData, TPredicateData, TPredicateDataOneof> : ITemplatedPropertyWrapperVM<TPredicateData> where TPredicateDataOneof : struct {
|
||||
IReadOnlyCollection<TPredicateDataOneof> predicate_types { get; }
|
||||
ICollectionView predicate_types_view { get; }
|
||||
TPredicateBuilderOneof selected_predicate_type { get; set; }
|
||||
ITemplatedPropertyWrapperVM<TPredicateBuilder> selected_predicate { get; }
|
||||
TPredicateDataOneof selected_predicate_type { get; set; }
|
||||
ITemplatedPropertyWrapperVM<TPredicateData> selected_predicate { get; }
|
||||
bool can_enable_toast_notifications { get; }
|
||||
bool toast_notifications_enabled { get; }
|
||||
}
|
||||
|
||||
interface IChildPredicateBuilderVM<TSource, TChildPredicateBuilder, TChildPredicateBuilderOneof> : ITemplatedPropertyWrapperVM<TSource> where TChildPredicateBuilderOneof : struct {
|
||||
IReadOnlyCollection<TChildPredicateBuilderOneof> predicate_types { get; }
|
||||
interface IChildPredicateVM<TSource, TChildPredicate, TChildPredicateOneof> : ITemplatedPropertyWrapperVM<TSource> where TChildPredicateOneof : struct {
|
||||
IReadOnlyCollection<TChildPredicateOneof> predicate_types { get; }
|
||||
ICollectionView predicate_types_view { get; }
|
||||
TChildPredicateBuilderOneof selected_predicate_type { get; set; }
|
||||
ITemplatedPropertyWrapperVM<TChildPredicateBuilder> selected_predicate { get; }
|
||||
TChildPredicateOneof selected_predicate_type { get; set; }
|
||||
ITemplatedPropertyWrapperVM<TChildPredicate> selected_predicate { get; }
|
||||
}
|
||||
|
||||
static class PredicateBuilderVMWrapper {
|
||||
static class PredicateVMWrapper {
|
||||
static readonly bool _toast_notifications_enabled_global = Configuration.get<bts.config.toggles.ToastNotifications>().enabled;
|
||||
|
||||
public static ITemplatedPropertyWrapperVM<TSource> wrap_child_oneof<TSource, TChild, TChildOneof>(
|
||||
@@ -39,14 +37,17 @@ namespace mbts.ui.settings {
|
||||
where TChildOneof : struct
|
||||
where TChild : new() =>
|
||||
//
|
||||
new PredicateChildWrapperVM<TSource, TChild, TChildOneof>(get, set, get_child_oneof, oneof_vms);
|
||||
new ChildImpl<TSource, TChild, TChildOneof>(get, set, get_child_oneof, oneof_vms);
|
||||
|
||||
public static IPredicateBuilderVM<TRowData, TPredicate, TPredicateOneof> create<TRowData, TPredicate, TPredicateOneof>(
|
||||
Dictionary<TPredicateOneof, ITemplatedPropertyWrapperVM<TPredicate>> oneofs, Func<TPredicate, TPredicateOneof> key)
|
||||
where TPredicateOneof : struct
|
||||
where TPredicate : IPredicateBuilder<TRowData>, new() =>
|
||||
public static IPredicateVM<TRowData, TPredicate, TPredicateOneof> create<TRowData, TPredicate, TPredicateOneof>(
|
||||
Dictionary<TPredicateOneof, ITemplatedPropertyWrapperVM<TPredicate>> oneofs, Func<TPredicate, TPredicateOneof> key) where TPredicateOneof : struct =>
|
||||
//
|
||||
new PredicateWrapperVM<TRowData, TPredicate, TPredicateOneof>(oneofs, key);
|
||||
new Impl<TRowData, TPredicate, TPredicateOneof>(oneofs, key, _ => false, (p, b) => { });
|
||||
|
||||
public static IPredicateVM<TRowData, TPredicate, TPredicateOneof> create<TRowData, TPredicate, TPredicateOneof>(
|
||||
Dictionary<TPredicateOneof, ITemplatedPropertyWrapperVM<TPredicate>> oneofs, Func<TPredicate, TPredicateOneof> key, Func<TPredicate, bool> get_is_toast_enabled, Action<TPredicate, bool> set_is_toast_enabled) where TPredicateOneof : struct =>
|
||||
//
|
||||
new Impl<TRowData, TPredicate, TPredicateOneof>(oneofs, key, get_is_toast_enabled, set_is_toast_enabled);
|
||||
|
||||
public static ITemplatedPropertyWrapperVM<TSource> create<TSource>(Action<TSource> set = null) =>
|
||||
new PredicatePlaceholderVM<TSource>(set);
|
||||
@@ -63,35 +64,30 @@ namespace mbts.ui.settings {
|
||||
return cv;
|
||||
}
|
||||
|
||||
class PredicateWrapperVM<TRowData, TPredicate, TPredicateOneof> : DisposableViewModelBase, IPredicateBuilderVM<TRowData, TPredicate, TPredicateOneof>, ITemplatedPropertyWrapperVM<TPredicate>
|
||||
where TPredicateOneof : struct
|
||||
where TPredicate : IPredicateBuilder<TRowData>, new() {
|
||||
class Impl<TRowData, TPredicate, TPredicateOneof> : DisposableViewModelBase, IPredicateVM<TRowData, TPredicate, TPredicateOneof>, ITemplatedPropertyWrapperVM<TPredicate>
|
||||
where TPredicateOneof : struct {
|
||||
readonly Dictionary<TPredicateOneof, ITemplatedPropertyWrapperVM<TPredicate>> _oneofs;
|
||||
readonly Property<TPredicateOneof> _selected_predicate_type;
|
||||
readonly Property<ITemplatedPropertyWrapperVM<TPredicate>> _selected_predicate;
|
||||
readonly DelegateProperty<bool> _can_enable_toast_notifications;
|
||||
readonly Property<bool> _toast_notifications_enabled;
|
||||
readonly Func<TPredicate, TPredicateOneof> _key_selector;
|
||||
readonly Func<TPredicate, bool> _get_is_toast_enabled;
|
||||
readonly Action<TPredicate, bool> _set_is_toast_enabeled;
|
||||
|
||||
public PredicateWrapperVM(Dictionary<TPredicateOneof, ITemplatedPropertyWrapperVM<TPredicate>> oneofs, Func<TPredicate, TPredicateOneof> key_selector) {
|
||||
public Impl(Dictionary<TPredicateOneof, ITemplatedPropertyWrapperVM<TPredicate>> oneofs, Func<TPredicate, TPredicateOneof> key_selector, Func<TPredicate, bool> get_is_toast_enabled, Action<TPredicate, bool> set_is_toast_enabled) {
|
||||
_oneofs = oneofs;
|
||||
_key_selector = key_selector;
|
||||
_get_is_toast_enabled = get_is_toast_enabled;
|
||||
_set_is_toast_enabeled = set_is_toast_enabled;
|
||||
_selected_predicate = backing<ITemplatedPropertyWrapperVM<TPredicate>>(nameof(selected_predicate));
|
||||
_selected_predicate_type = backing<TPredicateOneof>(nameof(selected_predicate_type));
|
||||
predicate_types_view = _create_predicate_types_view(predicate_types);
|
||||
if (typeof(TPredicate).GetInterfaces().Contains(typeof(INotificationPredicateBuilder<TRowData>))) {
|
||||
// simple_predicates are only referred to when TPredicate is an INotificationPredicateBuilder, but does not support INotificationPredicates for every predicate-case
|
||||
// (this way we can gradually add notifications as-needed beasis)
|
||||
// for ex: we may release a cut that supports fill notifications without having to create a notification-predicate for every predicate-case in OrderRecordTuplePredicate.
|
||||
// Note: it is assumed that all TPredicateOneof cases DO SUPPORT notification-predicates UNLESS THEY SPECIFY OTHERWISE IN A PREDICATECASEATTRIBUTE.
|
||||
var simple_predicates = new HashSet<TPredicateOneof>(oneofs.Keys.Where(k => {
|
||||
var pca = EnumHelper.get_attribute<TPredicateOneof, PredicateCaseAttribute>(k);
|
||||
return pca != null && !pca.is_toastable;
|
||||
}));
|
||||
_can_enable_toast_notifications = backing(nameof(can_enable_toast_notifications), () => !simple_predicates.Contains(selected_predicate_type), nameof(selected_predicate_type));
|
||||
} else {
|
||||
_can_enable_toast_notifications = backing(nameof(can_enable_toast_notifications), () => false);
|
||||
}
|
||||
var toastable_predicates = new HashSet<TPredicateOneof>(oneofs.Keys.Where(k => {
|
||||
var pca = EnumHelper.get_attribute<TPredicateOneof, PredicateCaseAttribute>(k);
|
||||
return pca != null && pca.is_toastable;
|
||||
}));
|
||||
_can_enable_toast_notifications = backing(nameof(can_enable_toast_notifications), () => toastable_predicates.Contains(selected_predicate_type), nameof(selected_predicate_type));
|
||||
_toast_notifications_enabled = backing<bool>(nameof(toast_notifications_enabled));
|
||||
selected_predicate_type = predicate_types.FirstOrDefault();
|
||||
}
|
||||
@@ -118,19 +114,18 @@ namespace mbts.ui.settings {
|
||||
public void load_from(TPredicate value) {
|
||||
selected_predicate_type = _key_selector(value);
|
||||
selected_predicate?.load_from(value);
|
||||
if (can_enable_toast_notifications) {
|
||||
_toast_notifications_enabled.set(((INotificationPredicateBuilder<TRowData>)value).is_toast_enabled);
|
||||
}
|
||||
if (can_enable_toast_notifications)
|
||||
_toast_notifications_enabled.set(_get_is_toast_enabled(value));
|
||||
}
|
||||
|
||||
public void assign_to(TPredicate value) {
|
||||
selected_predicate?.assign_to(value);
|
||||
if (toast_notifications_enabled && value is INotificationPredicateBuilder<TRowData> tp)
|
||||
tp.is_toast_enabled = true;
|
||||
if (can_enable_toast_notifications)
|
||||
_set_is_toast_enabeled(value, toast_notifications_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
class PredicateChildWrapperVM<TPredicate, TChild, TChildKey> : DisposableViewModelBase, IChildPredicateBuilderVM<TPredicate, TChild, TChildKey> where TChildKey : struct where TChild : new() {
|
||||
class ChildImpl<TPredicate, TChild, TChildKey> : DisposableViewModelBase, IChildPredicateVM<TPredicate, TChild, TChildKey> where TChildKey : struct where TChild : new() {
|
||||
readonly Property<ITemplatedPropertyWrapperVM<TChild>> _selected_predicate;
|
||||
readonly Property<TChildKey> _selected_predicate_type;
|
||||
readonly Dictionary<TChildKey, ITemplatedPropertyWrapperVM<TChild>> _children;
|
||||
@@ -139,7 +134,7 @@ namespace mbts.ui.settings {
|
||||
readonly Func<TChild, TChildKey> _key;
|
||||
readonly string _template_key;
|
||||
|
||||
public PredicateChildWrapperVM(Func<TPredicate, TChild> get, Action<TPredicate, TChild> set, Func<TChild, TChildKey> key,
|
||||
public ChildImpl(Func<TPredicate, TChild> get, Action<TPredicate, TChild> set, Func<TChild, TChildKey> key,
|
||||
Dictionary<TChildKey, ITemplatedPropertyWrapperVM<TChild>> oneofs, string template = PredicateTemplateKeys.Recursive) {
|
||||
_get = get;
|
||||
_set = set;
|
||||
@@ -4,7 +4,8 @@
|
||||
<Authors>Blue Trading Systems</Authors>
|
||||
<Company>Blue Trading Systems</Company>
|
||||
<Product>Spark</Product>
|
||||
<Description>The game has changed. Make your Move.</Description>
|
||||
<Description>Advanced Derivatives Trading</Description>
|
||||
<ApplicationManifest>spark.manifest</ApplicationManifest>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Platforms>x64</Platforms>
|
||||
|
||||
@@ -78,11 +78,15 @@ namespace bts.spark {
|
||||
public static SparkCommandParamObserver<T> create<T>(string title, ImageSource icon, ITag<T> tag, IObservable<T> parameter, Func<T, bool> can_execute) =>
|
||||
create(title, icon, tag, parameter, parameter.Select(can_execute));
|
||||
|
||||
public static SparkCommandParamObserver<T> create<T>(string title, ImageSource icon, ITag<T> tag, IObservable<T> parameter, Func<T, bool> can_execute, Func<bool> is_confirmation_affirmed) =>
|
||||
create(title, icon, tag, parameter, parameter.Select(can_execute), is_confirmation_affirmed);
|
||||
|
||||
public static SparkCommandParamObserver<T> create<T, TSource>(string title, ImageSource icon, ITag<T> tag, IObservable<TSource> parameter_source, Func<TSource, bool> parameter_source_where, Func<TSource, T> parameter_selector) =>
|
||||
create(title, icon, tag, parameter_source.Select(parameter_selector), parameter_source.Select(parameter_source_where));
|
||||
|
||||
public static SparkCommandParamObserver<T> create<T>(string title, ImageSource icon, ITag<T> tag, IObservable<T> parameter, IObservable<bool> can_execute) =>
|
||||
new SparkCommandParamObserver<T>(title, icon, tag, parameter, can_execute);
|
||||
public static SparkCommandParamObserver<T> create<T>(string title, ImageSource icon, ITag<T> tag, IObservable<T> parameter, IObservable<bool> can_execute, Func<bool> is_confirmation_affirmed = null) =>
|
||||
new SparkCommandParamObserver<T>(title, icon, tag, parameter, can_execute, is_confirmation_affirmed);
|
||||
|
||||
}
|
||||
|
||||
public static class SparkCommandExtensions {
|
||||
@@ -132,11 +136,15 @@ namespace bts.spark {
|
||||
public SparkCommandParamObserver<T> complete(IObservable<T> value, Func<T, bool> can_execute) =>
|
||||
SparkCommand.create(title, icon, tag, value, can_execute);
|
||||
|
||||
public SparkCommandParamObserver<T> complete(IObservable<T> value, Func<T, bool> can_execute, Func<bool> is_confirmation_affirmed) =>
|
||||
SparkCommand.create(title, icon, tag, value, can_execute, is_confirmation_affirmed);
|
||||
|
||||
public SparkCommandParamObserver<T> complete<TSource>(IObservable<TSource> value_source, Func<TSource, bool> value_source_where, Func<TSource, T> value_selector) =>
|
||||
SparkCommand.create(title, icon, tag, value_source, value_source_where, value_selector);
|
||||
|
||||
public SparkCommandParamObserver<T> complete(IObservable<T> parameter, IObservable<bool> can_execute) =>
|
||||
SparkCommand.create(title, icon, tag, parameter, can_execute);
|
||||
|
||||
}
|
||||
|
||||
public class SparkCommandWrapper : SparkCommand, IDisposable {
|
||||
@@ -222,8 +230,9 @@ namespace bts.spark {
|
||||
}
|
||||
|
||||
public class SparkCommandParamObserver<T> : SparkCommand, IDisposable {
|
||||
public SparkCommandParamObserver(string title, ImageSource icon, ITag<T> tag, IObservable<T> parameter, IObservable<bool> can_execute) : base(title, icon) {
|
||||
public SparkCommandParamObserver(string title, ImageSource icon, ITag<T> tag, IObservable<T> parameter, IObservable<bool> can_execute, Func<bool> is_confirmation_affirmed = null) : base(title, icon) {
|
||||
_tag = tag;
|
||||
_is_confirmation_affirmed = is_confirmation_affirmed;
|
||||
_subs = Disposable.Create(
|
||||
parameter.OnDispatcher().Subscribe(p => _parameter = p),
|
||||
can_execute.OnDispatcher().Subscribe(ce => {
|
||||
@@ -237,10 +246,12 @@ namespace bts.spark {
|
||||
IDisposable _subs;
|
||||
T _parameter;
|
||||
bool _can_execute;
|
||||
Func<bool> _is_confirmation_affirmed;
|
||||
|
||||
|
||||
public override bool canExecute() => _can_execute;
|
||||
public override void execute(IBus bus) {
|
||||
if (_can_execute) {
|
||||
if (_can_execute && (_is_confirmation_affirmed == null || _is_confirmation_affirmed())) {
|
||||
try {
|
||||
bus.post(_tag, _parameter);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace mbts.ui.native
|
||||
[DllImport("libspark")]
|
||||
public static extern void enable_limits();
|
||||
|
||||
[DllImport("libspark")]
|
||||
public static extern uint setup_process_job_object();
|
||||
|
||||
[DllImport("libspark", CharSet = CharSet.Unicode)]
|
||||
public static extern void set_window_app_id(IntPtr hwnd, string stack_id);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,15 @@ namespace mbts.ui.controls {
|
||||
TotalNetPos = "Total Net Pos",
|
||||
TotalPnL = "Total PnL",
|
||||
PnLPrice = "PnL Price",
|
||||
Cancel = "Cancel";
|
||||
Cancel = "Cancel",
|
||||
MarketDescription = "Market Description",
|
||||
ClearedAlias = "Cleared Alias",
|
||||
ProductDescription = "Product Description",
|
||||
HubAlias = "Hub Alias",
|
||||
StripName = "Strip Name",
|
||||
MicCode = "Mic Code",
|
||||
PositionInQueue = "PIQ"
|
||||
;
|
||||
}
|
||||
|
||||
public interface IKeyedColumn<TColKey> {
|
||||
|
||||
@@ -11,26 +11,26 @@ namespace mbts.ui {
|
||||
IReadOnlyList<SoundNotification> sound_notifications { get; }
|
||||
}
|
||||
|
||||
interface IPredicateAnimationsData<T, TPredicateBuilder> where TPredicateBuilder : IPredicateBuilder<T> {
|
||||
TPredicateBuilder predicate_builder { get; }
|
||||
interface IPredicateAnimationsData<T, TPredicateData> {
|
||||
TPredicateData predicate_data { get; }
|
||||
IReadOnlyList<CellAnimation> cell_animations { get; }
|
||||
IReadOnlyList<RowAnimation> row_animations { get; }
|
||||
IReadOnlyList<SoundNotification> sound_notifications { get; }
|
||||
}
|
||||
|
||||
static class PredicateAnimations {
|
||||
public static IPredicateAnimationsData<T, TPredicateBuilder> create_data<T, TPredicateBuilder>(TPredicateBuilder predicate_builder, IReadOnlyList<CellAnimation> cell_animations, IReadOnlyList<RowAnimation> row_animations, IReadOnlyList<SoundNotification> sounds)
|
||||
where TPredicateBuilder : IPredicateBuilder<T> => new PredicateAnimationsData<T, TPredicateBuilder>(predicate_builder, cell_animations, row_animations, sounds);
|
||||
public static IPredicateAnimationsData<T, TPredicateData> create_data<T, TPredicateData>(TPredicateData predicate_data, IReadOnlyList<CellAnimation> cell_animations, IReadOnlyList<RowAnimation> row_animations, IReadOnlyList<SoundNotification> sounds)
|
||||
=> new PredicateAnimationsData<T, TPredicateData>(predicate_data, cell_animations, row_animations, sounds);
|
||||
|
||||
class PredicateAnimationsData<TRowData, TPredicateBuilder> : IPredicateAnimationsData<TRowData, TPredicateBuilder> where TPredicateBuilder : IPredicateBuilder<TRowData> {
|
||||
public PredicateAnimationsData(TPredicateBuilder predicate_builder, IReadOnlyList<CellAnimation> cell_animations, IReadOnlyList<RowAnimation> row_animations, IReadOnlyList<SoundNotification> sound_notifications) {
|
||||
this.predicate_builder = predicate_builder;
|
||||
class PredicateAnimationsData<TRowData, TPredicateData> : IPredicateAnimationsData<TRowData, TPredicateData> {
|
||||
public PredicateAnimationsData(TPredicateData predicate_data, IReadOnlyList<CellAnimation> cell_animations, IReadOnlyList<RowAnimation> row_animations, IReadOnlyList<SoundNotification> sound_notifications) {
|
||||
this.predicate_data = predicate_data;
|
||||
this.cell_animations = cell_animations;
|
||||
this.row_animations = row_animations;
|
||||
this.sound_notifications = sound_notifications;
|
||||
}
|
||||
|
||||
public TPredicateBuilder predicate_builder { get; }
|
||||
public TPredicateData predicate_data { get; }
|
||||
public IReadOnlyList<CellAnimation> cell_animations { get; }
|
||||
public IReadOnlyList<RowAnimation> row_animations { get; }
|
||||
public IReadOnlyList<SoundNotification> sound_notifications { get; }
|
||||
|
||||
@@ -27,15 +27,15 @@ namespace mbts.spark {
|
||||
ImmutableFontWeight
|
||||
}
|
||||
|
||||
partial class GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData> {
|
||||
public interface IColumnVM : ISimpleColumnVM, IValueFactory<(GridColumnSettings settings, ILookup<TPredicateBuilder, CellAnimation> animations)>, IDisposable {
|
||||
partial class GridSettingsVM<TRowData, TPredicateData, TSettingsData> {
|
||||
public interface IColumnVM : ISimpleColumnVM, IValueFactory<(GridColumnSettings settings, ILookup<TPredicateData, CellAnimation> animations)>, IDisposable {
|
||||
ObservableEditableCollection<PredicateCellAnimationVM> predicate_animations { get; }
|
||||
new (GridColumnSettings settings, ILookup<TPredicateBuilder, CellAnimation> animations) create();
|
||||
new void load_from((GridColumnSettings settings, ILookup<TPredicateBuilder, CellAnimation> animations) args);
|
||||
new (GridColumnSettings settings, ILookup<TPredicateData, CellAnimation> animations) create();
|
||||
new void load_from((GridColumnSettings settings, ILookup<TPredicateData, CellAnimation> animations) args);
|
||||
}
|
||||
|
||||
public class ColumnVM : DisposableViewModelBase, IColumnVM {
|
||||
public readonly GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData> owner;
|
||||
public readonly GridSettingsVM<TRowData, TPredicateData, TSettingsData> owner;
|
||||
|
||||
readonly Property<string> _id, _display_name;
|
||||
readonly Property<double> _width;
|
||||
@@ -44,7 +44,7 @@ namespace mbts.spark {
|
||||
readonly Property<FontWeight> _font_weight_override;
|
||||
GridColumnSettings _settings;
|
||||
|
||||
public ColumnVM(GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData> owner) {
|
||||
public ColumnVM(GridSettingsVM<TRowData, TPredicateData, TSettingsData> owner) {
|
||||
this.owner = owner;
|
||||
_id = backing(nameof(id), string.Empty);
|
||||
_display_name = backing(nameof(display_name), string.Empty);
|
||||
@@ -60,7 +60,7 @@ namespace mbts.spark {
|
||||
_font_weight_override = backing(nameof(font_weight_override), FontWeights.Normal);
|
||||
// animations
|
||||
predicate_animations = new ObservableEditableCollection<PredicateCellAnimationVM>(() =>
|
||||
new PredicateCellAnimationVM(id, owner._create_column_predicate_vm(id)), true);
|
||||
new PredicateCellAnimationVM(id, owner._create_column_predicate_vm(id), owner._predicate_data_factory), true);
|
||||
predicate_animations.CollectionChanged += WPFHelper.create_collection_changed_cb(on_items_added: (_, __) => owner.show_cell_predicate_animations = true);
|
||||
_dispose = Disposable.Create(() => predicate_animations.OfType<IDisposable>().DisposeAll());
|
||||
}
|
||||
@@ -81,17 +81,17 @@ namespace mbts.spark {
|
||||
// animations
|
||||
public ObservableEditableCollection<PredicateCellAnimationVM> predicate_animations { get; }
|
||||
|
||||
public (GridColumnSettings settings, ILookup<TPredicateBuilder, CellAnimation> animations) create() {
|
||||
public (GridColumnSettings settings, ILookup<TPredicateData, CellAnimation> animations) create() {
|
||||
var settings = _settings.with(display_name, is_visible, null,
|
||||
is_font_weight_overridden ? new NullableFontWeightProto(font_weight_override) : default,
|
||||
is_font_color_overridden ? new NullableColorProto(font_color_override.color) : default,
|
||||
width,
|
||||
horizontal_alignment);
|
||||
var animations_lookup = predicate_animations.ToFlatLookup(pa => pa.predicate.create_assigned(), pa => pa.animations.Select(a => a.create()));
|
||||
var animations_lookup = predicate_animations.ToFlatLookup(pa => pa.predicate.create_assigned(owner._predicate_data_factory), pa => pa.animations.Select(a => a.create()));
|
||||
return (settings, animations_lookup);
|
||||
}
|
||||
|
||||
public void load_from((GridColumnSettings settings, ILookup<TPredicateBuilder, CellAnimation> animations) value) {
|
||||
public void load_from((GridColumnSettings settings, ILookup<TPredicateData, CellAnimation> animations) value) {
|
||||
_settings = value.settings;
|
||||
_id.set(_settings.id);
|
||||
_display_name.set(_settings.display_name);
|
||||
@@ -107,7 +107,7 @@ namespace mbts.spark {
|
||||
font_color_override.load_from(new SolidColorBrush(_settings.font_color_override.Value));
|
||||
}
|
||||
predicate_animations.SetItems(value.animations.empty_if_null().Select(g => {
|
||||
var vm = new PredicateCellAnimationVM(id, owner._create_column_predicate_vm(id));
|
||||
var vm = new PredicateCellAnimationVM(id, owner._create_column_predicate_vm(id), owner._predicate_data_factory);
|
||||
vm.load_from((g.Key, g));
|
||||
return vm;
|
||||
}));
|
||||
@@ -131,17 +131,19 @@ namespace mbts.spark {
|
||||
create().settings;
|
||||
|
||||
void IValueFactory<GridColumnSettings>.load_from(GridColumnSettings value) =>
|
||||
load_from((value, new Dictionary<TPredicateBuilder, CellAnimation>().ToLookup(kv => kv.Key, kv => kv.Value)));
|
||||
load_from((value, new Dictionary<TPredicateData, CellAnimation>().ToLookup(kv => kv.Key, kv => kv.Value)));
|
||||
}
|
||||
|
||||
public class PredicateCellAnimationVM : DisposableViewModelBase, IValueFactory<(TPredicateBuilder predicate, IEnumerable<CellAnimation> animations)> {
|
||||
public class PredicateCellAnimationVM : DisposableViewModelBase, IValueFactory<(TPredicateData predicate, IEnumerable<CellAnimation> animations)> {
|
||||
//
|
||||
readonly string _col_id;
|
||||
readonly Property<bool> _show_animations;
|
||||
readonly Func<TPredicateData> _predicate_data_factory;
|
||||
|
||||
public PredicateCellAnimationVM(string col_id, IPropertyWrapperVM<TPredicateBuilder> predicate) {
|
||||
public PredicateCellAnimationVM(string col_id, IPropertyWrapperVM<TPredicateData> predicate, Func<TPredicateData> predicate_data_factory) {
|
||||
_col_id = col_id;
|
||||
this.predicate = predicate;
|
||||
_predicate_data_factory = predicate_data_factory;
|
||||
_show_animations = backing(nameof(show_animations), true);
|
||||
animations = new ObservableEditableCollection<CellAnimationVM>(() => {
|
||||
var vm = new CellAnimationVM(col_id);
|
||||
@@ -152,15 +154,15 @@ namespace mbts.spark {
|
||||
_dispose = predicate as IDisposable;
|
||||
}
|
||||
|
||||
public IPropertyWrapperVM<TPredicateBuilder> predicate { get; }
|
||||
public IPropertyWrapperVM<TPredicateData> predicate { get; }
|
||||
public ObservableEditableCollection<CellAnimationVM> animations { get; }
|
||||
public IEnumerable<CellAnimation.AnimationTypeOneofCase> animation_types { get; } = EnumHelper.get_values_except(CellAnimation.AnimationTypeOneofCase.None);
|
||||
public bool show_animations { get => _show_animations.Value; set => _show_animations.set(value); }
|
||||
|
||||
public (TPredicateBuilder predicate, IEnumerable<CellAnimation> animations) create() =>
|
||||
(predicate.create_assigned(), animations.Select(a => a.create()));
|
||||
public (TPredicateData predicate, IEnumerable<CellAnimation> animations) create() =>
|
||||
(predicate.create_assigned(_predicate_data_factory), animations.Select(a => a.create()));
|
||||
|
||||
public void load_from((TPredicateBuilder predicate, IEnumerable<CellAnimation> animations) args) {
|
||||
public void load_from((TPredicateData predicate, IEnumerable<CellAnimation> animations) args) {
|
||||
predicate.load_from(args.predicate);
|
||||
animations.SetItems(args.animations.Select(a => {
|
||||
var vm = new CellAnimationVM(_col_id);
|
||||
|
||||
@@ -5,8 +5,6 @@ using mbts.collections;
|
||||
using mbts.spark;
|
||||
using mbts.ui.settings;
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.spark;
|
||||
using mbts.ui.utility;
|
||||
using mbts.utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -17,16 +15,14 @@ using System.Windows.Media;
|
||||
using static mbts.ui.controls.DIYGrid;
|
||||
|
||||
namespace mbts.ui {
|
||||
class GridSettingsManager<TRow, TRowData, TPredicateBuilderArg, TPredicateBuilder, TSettingsData> :
|
||||
class GridSettingsManager<TRow, TRowData, TPredicateData, TSettingsData> :
|
||||
ViewModelBase, IValueFactory<TSettingsData>, IObserver<TSettingsData>, IDisposable
|
||||
where TRow : IRowVM
|
||||
where TPredicateBuilder : IPredicateBuilder<TRowData, TPredicateBuilderArg>, new()
|
||||
where TSettingsData : class, IGridSettingsWithNotifications<TRowData, TPredicateBuilder> {
|
||||
where TSettingsData : class, IGridSettingsWithNotifications<TRowData, TPredicateData> {
|
||||
//
|
||||
readonly IBus _bus;
|
||||
readonly OrdersModel _orders_model;
|
||||
readonly INotificationService _notification_service;
|
||||
readonly List<IDisposable> _resources, _notification_subs = new List<IDisposable>();
|
||||
readonly List<IDisposable> _notification_subs = new List<IDisposable>();
|
||||
readonly ObservableCollection<ColumnBase> _columns;
|
||||
readonly ObservableCollection<TRow> _rows;
|
||||
readonly Property<GridSettings> _grid_settings;
|
||||
@@ -35,30 +31,45 @@ namespace mbts.ui {
|
||||
readonly DelegateProperty<double> _font_size;
|
||||
readonly DelegateProperty<SolidColorBrush> _font_color, _selection_highlight;
|
||||
readonly SetMap<IPredicate<TRowData>, AnimationDefinitionWrapper<TRow>> _animation_defs = new SetMap<IPredicate<TRowData>, AnimationDefinitionWrapper<TRow>>();
|
||||
readonly TPredicateBuilderArg _arg;
|
||||
readonly Func<IPropertyWrapperVM<TPredicateBuilder>> _create_predicate_vm;
|
||||
readonly Func<string, IPropertyWrapperVM<TPredicateBuilder>> _create_column_predicate_vm;
|
||||
readonly Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>>, TSettingsData> _create_settings_obj;
|
||||
readonly Func<TPredicateData> _predicate_data_factory;
|
||||
readonly Func<TPredicateData, IPredicate<TRowData>> _predicate_factory;
|
||||
readonly Func<TPredicateData, INotificationPredicate<TRowData>> _notification_predicate_factory;
|
||||
readonly Func<IPropertyWrapperVM<TPredicateData>> _create_predicate_vm;
|
||||
readonly Func<string, IPropertyWrapperVM<TPredicateData>> _create_column_predicate_vm;
|
||||
readonly Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>>, TSettingsData> _create_settings_obj;
|
||||
readonly Func<IPredicate<TRowData>, SoundNotification, IDisposable> _link_sound;
|
||||
readonly Func<INotificationPredicate<TRowData>, IDisposable> _link_toast_notification;
|
||||
readonly IReadOnlyDictionary<string, ImmutableColumnSettingStore> _column_flags;
|
||||
IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>> _predicate_animations_data;
|
||||
IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>> _predicate_animations_data;
|
||||
|
||||
public GridSettingsManager(
|
||||
IObservable<string> owner_title, IBus bus, INotificationService notification_service, OrdersModel orders_model,
|
||||
ObservableCollection<TRow> rows, ObservableCollection<ColumnBase> columns,
|
||||
Func<IPropertyWrapperVM<TPredicateBuilder>> create_predicate_vm,
|
||||
Func<string, IPropertyWrapperVM<TPredicateBuilder>> create_column_predicate_vm,
|
||||
Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>>, TSettingsData> create_settings_obj,
|
||||
TPredicateBuilderArg arg, IReadOnlyDictionary<string, GridColumnSettingsFeatureFlags> column_flags = null) {
|
||||
IObservable<string> owner_title,
|
||||
IBus bus,
|
||||
OrdersModel orders_model,
|
||||
ObservableCollection<TRow> rows,
|
||||
ObservableCollection<ColumnBase> columns,
|
||||
Func<TPredicateData> predicate_data_factory,
|
||||
Func<IPropertyWrapperVM<TPredicateData>> create_predicate_vm,
|
||||
Func<string, IPropertyWrapperVM<TPredicateData>> create_column_predicate_vm,
|
||||
Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>>, TSettingsData> create_settings_obj,
|
||||
Func<TPredicateData, IPredicate<TRowData>> predicate_factory,
|
||||
Func<TPredicateData, INotificationPredicate<TRowData>> notification_predicate_factory,
|
||||
Func<IPredicate<TRowData>, SoundNotification, IDisposable> link_sound,
|
||||
Func<INotificationPredicate<TRowData>, IDisposable> link_toast_notification,
|
||||
IReadOnlyDictionary<string, GridColumnSettingsFeatureFlags> column_flags = null) {
|
||||
//
|
||||
_bus = bus;
|
||||
_notification_service = notification_service;
|
||||
_orders_model = orders_model;
|
||||
_rows = rows;
|
||||
_columns = columns;
|
||||
_predicate_data_factory = predicate_data_factory;
|
||||
_predicate_factory = predicate_factory;
|
||||
_notification_predicate_factory = notification_predicate_factory;
|
||||
_create_predicate_vm = create_predicate_vm;
|
||||
_create_column_predicate_vm = create_column_predicate_vm;
|
||||
_create_settings_obj = create_settings_obj;
|
||||
_arg = arg;
|
||||
_link_sound = link_sound;
|
||||
_link_toast_notification = link_toast_notification;
|
||||
_column_flags = column_flags.ToDictionary(kv => kv.Key, kv => ImmutableColumnSettingStore.create(kv.Value));
|
||||
_grid_settings = backing(nameof(grid_settings), GridSettings.Default);
|
||||
_font_family = backing(nameof(font_family), () => new FontFamily(grid_settings.font_family), nameof(grid_settings));
|
||||
@@ -66,32 +77,10 @@ namespace mbts.ui {
|
||||
_font_size = backing(nameof(font_size), () => grid_settings.font_size, nameof(font_size));
|
||||
_font_color = backing(nameof(font_color), () => grid_settings.font_color.rgb_solid_brush().frozen(), nameof(grid_settings));
|
||||
_selection_highlight = backing(nameof(selection_highlight), () => grid_settings.selection_highlight.to_brush().frozen(), nameof(grid_settings));
|
||||
_resources = new List<IDisposable> {
|
||||
(launch_settings_editor = new DialogCommand(create_settings_view))
|
||||
};
|
||||
// local methods
|
||||
Window create_settings_view() {
|
||||
var vm = new GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData>(owner_title, _bus, _orders_model, create_predicate_vm, create_column_predicate_vm, _create_settings_obj);
|
||||
// need to refresh before launching the settings-view bc users can chanve some grid-column-settings properties directly from the grid (e.g. width, is_collapsed, etc.)
|
||||
_grid_settings.set(grid_settings.with(columns.Select(c => c.create())));
|
||||
vm.load(_create_settings_obj(grid_settings, _predicate_animations_data));
|
||||
if (column_flags != null) {
|
||||
foreach (var col in vm.columns) {
|
||||
if (column_flags.TryGetValue(col.id, out GridColumnSettingsFeatureFlags f))
|
||||
col.apply_flags(f);
|
||||
}
|
||||
}
|
||||
var window = new GridSettingsDialog { DataContext = vm };
|
||||
vm.committed += () => load_from(vm.get_result());
|
||||
vm.RequestClose += (s, e) => WindowUtilities.force_close(window);
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Disposable.dispose(_resources);
|
||||
public void Dispose() =>
|
||||
Disposable.dispose(_notification_subs);
|
||||
}
|
||||
|
||||
public GridSettings grid_settings => _grid_settings.Value;
|
||||
public FontFamily font_family => _font_family.Value;
|
||||
@@ -99,10 +88,9 @@ namespace mbts.ui {
|
||||
public double font_size => _font_size.Value;
|
||||
public SolidColorBrush font_color => _font_color.Value;
|
||||
public SolidColorBrush selection_highlight => _selection_highlight.Value;
|
||||
public IDialogCommand launch_settings_editor { get; }
|
||||
|
||||
public GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData> create_vm(GridSettings settings, IObservable<string> title) {
|
||||
var vm = new GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData>(title, _bus, _orders_model, _create_predicate_vm, _create_column_predicate_vm, _create_settings_obj, _column_flags.ToDictionary(kv => kv.Key, kv => kv.Value.flags));
|
||||
public GridSettingsVM<TRowData, TPredicateData, TSettingsData> create_vm(GridSettings settings, IObservable<string> title) {
|
||||
var vm = new GridSettingsVM<TRowData, TPredicateData, TSettingsData>(title, _bus, _orders_model, _predicate_data_factory, _notification_predicate_factory, _create_predicate_vm, _create_column_predicate_vm, _create_settings_obj, _column_flags.ToDictionary(kv => kv.Key, kv => kv.Value.flags));
|
||||
vm.load(_create_settings_obj(settings, _predicate_animations_data));
|
||||
return vm;
|
||||
}
|
||||
@@ -127,16 +115,16 @@ namespace mbts.ui {
|
||||
col.set_fallback_font_params(new FontFamily(grid.font_family), grid.font_size, grid.font_color.rgb_color(), grid.font_weight);
|
||||
_predicate_animations_data = value.predicate_animations;
|
||||
_animation_defs.clear();
|
||||
if (_notification_service != null && _arg != null) {
|
||||
foreach (var pa in _predicate_animations_data) {
|
||||
var predicate = pa.predicate_builder.create_predicate(_arg);
|
||||
foreach (var s in pa.sound_notifications) {
|
||||
_notification_subs.Add(_notification_service.link(predicate, s));
|
||||
}
|
||||
if (pa.predicate_builder is INotificationPredicateBuilder<TRowData, TPredicateBuilderArg> tpb && tpb.is_toast_enabled) {
|
||||
_notification_subs.Add(_notification_service.link(tpb.create_notification_predicate(_arg)));
|
||||
}
|
||||
foreach (var pa in _predicate_animations_data) {
|
||||
var predicate = _predicate_factory(pa.predicate_data);
|
||||
if (predicate == null)
|
||||
continue;
|
||||
foreach (var s in pa.sound_notifications) {
|
||||
_notification_subs.Add(_link_sound(predicate, s));
|
||||
}
|
||||
var notification_predicate = _notification_predicate_factory(pa.predicate_data);
|
||||
if (notification_predicate != null)
|
||||
_notification_subs.Add(_link_toast_notification(notification_predicate));
|
||||
}
|
||||
// ** in the unfortunate event that we botch backwards compatability, and the columns don't bear a 1:1 relationship with the column-settings
|
||||
// don't add insult to injury by crashing **
|
||||
|
||||
@@ -19,38 +19,38 @@ using CellAnimation = mbts.ui.CellAnimation;
|
||||
using FontFamily = System.Windows.Media.FontFamily;
|
||||
|
||||
namespace mbts.spark {
|
||||
interface IGridSettingsWithNotifications<TRowData, TPredicateBuilder> where TPredicateBuilder : IPredicateBuilder<TRowData> {
|
||||
interface IGridSettingsWithNotifications<TRowData, TPredicateData> {
|
||||
GridSettings general { get; }
|
||||
IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>> predicate_animations { get; }
|
||||
IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>> predicate_animations { get; }
|
||||
}
|
||||
|
||||
class GridSettingsWithNotifications<TRowData, TPredicateBuilder> : IEquatable<GridSettingsWithNotifications<TRowData, TPredicateBuilder>> where TPredicateBuilder : IPredicateBuilder<TRowData> {
|
||||
class GridSettingsWithNotifications<TRowData, TPredicateData> : IEquatable<GridSettingsWithNotifications<TRowData, TPredicateData>> {
|
||||
public readonly GridSettings grid;
|
||||
public readonly IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>> predicate_animations_data;
|
||||
public GridSettingsWithNotifications(GridSettings grid, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>> predicate_animations_data) {
|
||||
public readonly IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>> predicate_animations_data;
|
||||
public GridSettingsWithNotifications(GridSettings grid, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>> predicate_animations_data) {
|
||||
this.grid = grid;
|
||||
this.predicate_animations_data = predicate_animations_data;
|
||||
}
|
||||
|
||||
public bool Equals(GridSettingsWithNotifications<TRowData, TPredicateBuilder> other) =>
|
||||
public bool Equals(GridSettingsWithNotifications<TRowData, TPredicateData> other) =>
|
||||
other != null &&
|
||||
EqualityComparer.null_check_equals(grid, other.grid) &&
|
||||
EqualityComparer.safe_sequence_equals(predicate_animations_data, other.predicate_animations_data);
|
||||
|
||||
public override bool Equals(object obj) => Equals(obj as GridSettingsWithNotifications<TRowData, TPredicateBuilder>);
|
||||
public override bool Equals(object obj) => Equals(obj as GridSettingsWithNotifications<TRowData, TPredicateData>);
|
||||
public override int GetHashCode() =>
|
||||
EqualityComparer.aggregate_hash(
|
||||
EqualityComparer.safe_get_hash_code(grid),
|
||||
EqualityComparer.safe_aggregate_hash(predicate_animations_data));
|
||||
}
|
||||
|
||||
partial class GridSettingsVM<TRowData, TPredicateBuilder, TSettingsData> : DisposableViewModelBase, IRequestViewClose, IWindowSettingsVM<TSettingsData>, ITemplateSelectorKey
|
||||
where TPredicateBuilder : IPredicateBuilder<TRowData>, new()
|
||||
where TSettingsData :class, IGridSettingsWithNotifications<TRowData, TPredicateBuilder> {
|
||||
partial class GridSettingsVM<TRowData, TPredicateData, TSettingsData> : DisposableViewModelBase, IRequestViewClose, IWindowSettingsVM<TSettingsData>, ITemplateSelectorKey
|
||||
where TSettingsData :class, IGridSettingsWithNotifications<TRowData, TPredicateData> {
|
||||
//
|
||||
protected readonly Func<IPropertyWrapperVM<TPredicateBuilder>> _create_predicate_vm;
|
||||
protected readonly Func<string, IPropertyWrapperVM<TPredicateBuilder>> _create_column_predicate_vm;
|
||||
readonly Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>>, TSettingsData> _create_settings_obj;
|
||||
protected readonly Func<IPropertyWrapperVM<TPredicateData>> _create_predicate_vm;
|
||||
protected readonly Func<string, IPropertyWrapperVM<TPredicateData>> _create_column_predicate_vm;
|
||||
readonly Func<TPredicateData> _predicate_data_factory;
|
||||
readonly Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>>, TSettingsData> _create_settings_obj;
|
||||
readonly Property<IColumnVM> _current_column;
|
||||
readonly Property<FontFamily> _font_family;
|
||||
readonly Property<FontWeight> _font_weight;
|
||||
@@ -62,14 +62,17 @@ namespace mbts.spark {
|
||||
|
||||
public GridSettingsVM(
|
||||
IObservable<string> owner_title, IBus bus, OrdersModel orders_model,
|
||||
Func<IPropertyWrapperVM<TPredicateBuilder>> create_predicate_vm,
|
||||
Func<string, IPropertyWrapperVM<TPredicateBuilder>> create_column_predicate_vm,
|
||||
Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateBuilder>>, TSettingsData> create_settings_obj,
|
||||
Func<TPredicateData> predicate_data_factory,
|
||||
Func<TPredicateData, INotificationPredicate<TRowData>> notification_predicate_factory,
|
||||
Func<IPropertyWrapperVM<TPredicateData>> create_predicate_vm,
|
||||
Func<string, IPropertyWrapperVM<TPredicateData>> create_column_predicate_vm,
|
||||
Func<GridSettings, IEnumerable<IPredicateAnimationsData<TRowData, TPredicateData>>, TSettingsData> create_settings_obj,
|
||||
IReadOnlyDictionary<string, GridColumnSettingsFeatureFlags> column_flags = null) {
|
||||
//
|
||||
_owner_title = backing(nameof(owner_title), owner_title);
|
||||
this.bus = bus;
|
||||
_orders_model = orders_model;
|
||||
_predicate_data_factory = predicate_data_factory;
|
||||
_create_predicate_vm = create_predicate_vm;
|
||||
_create_column_predicate_vm = create_column_predicate_vm;
|
||||
_create_settings_obj = create_settings_obj;
|
||||
@@ -82,7 +85,7 @@ namespace mbts.spark {
|
||||
_show_cell_predicate_animations = backing(nameof(show_cell_predicate_animations), true);
|
||||
_current_column = backing<IColumnVM>(nameof(current_column));
|
||||
predicate_animations = new ObservableEditableCollection<PredicateRowAnimationVM>(() =>
|
||||
new PredicateRowAnimationVM(_create_predicate_vm()), true);
|
||||
new PredicateRowAnimationVM(_create_predicate_vm(), _predicate_data_factory), true);
|
||||
predicate_animations.CollectionChanged += WPFHelper.create_collection_changed_cb(on_items_added: (_, __) => _show_predicate_animations.set(true));
|
||||
}
|
||||
|
||||
@@ -125,13 +128,13 @@ namespace mbts.spark {
|
||||
foreach (var c in columns) {
|
||||
var (settings, animations) = c.create();
|
||||
col_settings.Add(settings);
|
||||
foreach (IGrouping<TPredicateBuilder, CellAnimation> g in animations)
|
||||
foreach (IGrouping<TPredicateData, CellAnimation> g in animations)
|
||||
animation_map.AddOrUpdate(g.Key, p => animation_tuple(c: g), (p, t) => t.cell_animations.AddRange(g));
|
||||
}
|
||||
return _create_settings_obj(new GridSettings(font_family.name(), font_size, font_weight, font_color.color.rgb_color(), selection_highlight.to_proto(), col_settings),
|
||||
animation_map.Select(kv => PredicateAnimations.create_data<TRowData, TPredicateBuilder>(kv.Key, kv.Value.cell_animations, kv.Value.row_animations, kv.Value.sounds)));
|
||||
animation_map.Select(kv => PredicateAnimations.create_data<TRowData, TPredicateData>(kv.Key, kv.Value.cell_animations, kv.Value.row_animations, kv.Value.sounds)));
|
||||
//
|
||||
(List<RowAnimation> row_animations, List<SoundNotification> sounds, List<CellAnimation> cell_animations) animation_tuple(IEnumerable<RowAnimation> r = null, IEnumerable<SoundNotification> s = null, IGrouping<TPredicateBuilder, CellAnimation> c = null) =>
|
||||
(List<RowAnimation> row_animations, List<SoundNotification> sounds, List<CellAnimation> cell_animations) animation_tuple(IEnumerable<RowAnimation> r = null, IEnumerable<SoundNotification> s = null, IGrouping<TPredicateData, CellAnimation> c = null) =>
|
||||
(r?.ToList() ?? new List<RowAnimation>(), s?.ToList() ?? new List<SoundNotification>(), c?.ToList() ?? new List<CellAnimation>());
|
||||
}
|
||||
|
||||
@@ -141,18 +144,18 @@ namespace mbts.spark {
|
||||
font_color.load_from(sd.general.font_color.rgb_solid_brush());
|
||||
selection_highlight.load_from(sd.general.selection_highlight.to_brush());
|
||||
_font_size.set(sd.general.font_size);
|
||||
var col_animations = new Dictionary<string, Dictionary<TPredicateBuilder, List<CellAnimation>>>();
|
||||
var col_animations = new Dictionary<string, Dictionary<TPredicateData, List<CellAnimation>>>();
|
||||
predicate_animations.Clear();
|
||||
foreach (var pa in sd.predicate_animations) {
|
||||
if (pa.row_animations.Count > 0 || pa.sound_notifications.Count > 0) {
|
||||
var vm = new PredicateRowAnimationVM(_create_predicate_vm());
|
||||
vm.load_from((pa.predicate_builder, pa.row_animations, pa.sound_notifications));
|
||||
var vm = new PredicateRowAnimationVM(_create_predicate_vm(), _predicate_data_factory);
|
||||
vm.load_from((pa.predicate_data, pa.row_animations, pa.sound_notifications));
|
||||
predicate_animations.Add(vm);
|
||||
}
|
||||
foreach (var ca in pa.cell_animations) {
|
||||
col_animations.AddOrUpdate(ca.column_id,
|
||||
col => new Dictionary<TPredicateBuilder, List<CellAnimation>> { { pa.predicate_builder, new List<CellAnimation> { ca } } },
|
||||
(col, d) => d.AddOrUpdate(pa.predicate_builder, p => new List<CellAnimation> { ca }, (p, l) => l.Add(ca)));
|
||||
col => new Dictionary<TPredicateData, List<CellAnimation>> { { pa.predicate_data, new List<CellAnimation> { ca } } },
|
||||
(col, d) => d.AddOrUpdate(pa.predicate_data, p => new List<CellAnimation> { ca }, (p, l) => l.Add(ca)));
|
||||
}
|
||||
}
|
||||
var curr_col_id = current_column?.id;
|
||||
@@ -171,11 +174,13 @@ namespace mbts.spark {
|
||||
_current_column.set(curr_column);
|
||||
}
|
||||
|
||||
public class PredicateRowAnimationVM : DisposableViewModelBase, IValueFactory<(TPredicateBuilder predicate, IEnumerable<RowAnimation> animations, IEnumerable<SoundNotification> sounds)> {
|
||||
public class PredicateRowAnimationVM : DisposableViewModelBase, IValueFactory<(TPredicateData predicate, IEnumerable<RowAnimation> animations, IEnumerable<SoundNotification> sounds)> {
|
||||
readonly Property<bool> _show_animations/*, _play_sound*/;
|
||||
readonly Func<TPredicateData> _predicate_state_factory;
|
||||
|
||||
public PredicateRowAnimationVM(IPropertyWrapperVM<TPredicateBuilder> predicate) {
|
||||
public PredicateRowAnimationVM(IPropertyWrapperVM<TPredicateData> predicate, Func<TPredicateData> predicate_state_factory) {
|
||||
this.predicate = predicate;
|
||||
_predicate_state_factory = predicate_state_factory;
|
||||
_show_animations = backing(nameof(show_animations), true);
|
||||
//_play_sound = backing(nameof(play_sound), true);
|
||||
animations = new ObservableEditableCollection<RowAnimationVM>(() => {
|
||||
@@ -187,20 +192,20 @@ namespace mbts.spark {
|
||||
_dispose = predicate as IDisposable;
|
||||
}
|
||||
|
||||
public IPropertyWrapperVM<TPredicateBuilder> predicate { get; }
|
||||
public IPropertyWrapperVM<TPredicateData> predicate { get; }
|
||||
public ObservableEditableCollection<RowAnimationVM> animations { get; }
|
||||
public IEnumerable<CellAnimation.AnimationTypeOneofCase> animation_types { get; } = EnumHelper.get_values_except(CellAnimation.AnimationTypeOneofCase.None);
|
||||
public bool show_animations { get => _show_animations.Value; set => _show_animations.set(value); }
|
||||
//public bool play_sound { get => _play_sound.Value; set => _play_sound.set(value); }
|
||||
public IPropertyWrapperVM<SoundNotification> sound { get; } = SoundAnimationVM.create_system_sound_vm();
|
||||
|
||||
public (TPredicateBuilder predicate, IEnumerable<RowAnimation> animations, IEnumerable<SoundNotification> sounds) create() =>
|
||||
(predicate.create_assigned(),
|
||||
public (TPredicateData predicate, IEnumerable<RowAnimation> animations, IEnumerable<SoundNotification> sounds) create() =>
|
||||
(predicate.create_assigned(_predicate_state_factory),
|
||||
animations.Select(a => a.create_assigned()),
|
||||
new[] { sound.create_assigned() });
|
||||
//EnumerableExtensions.return_if(play_sound, () => sound.create_assigned()));
|
||||
|
||||
public void load_from((TPredicateBuilder predicate, IEnumerable<RowAnimation> animations, IEnumerable<SoundNotification> sounds) args) {
|
||||
public void load_from((TPredicateData predicate, IEnumerable<RowAnimation> animations, IEnumerable<SoundNotification> sounds) args) {
|
||||
predicate.load_from(args.predicate);
|
||||
animations.SetItems(args.animations.Select(a => {
|
||||
var vm = new RowAnimationVM();
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace mbts.spark.filters {
|
||||
TimeFilter = "TimeFilterTemplate",
|
||||
DiscreteValues = "DiscreteValuesTemplate",
|
||||
EnumValues = "EnumValuesTemplate",
|
||||
Regex = "RegexTemplate";
|
||||
Regex = "RegexTemplate",
|
||||
YesNo = "YesNoTemplate";
|
||||
}
|
||||
}
|
||||
@@ -146,6 +146,27 @@
|
||||
/>
|
||||
</usp:FilterContentControl>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="YesNoTemplate">
|
||||
<usp:FilterContentControl
|
||||
ApplyCommandParameter="{Binding}"
|
||||
ApplyCommand="{x:Static c:DataGridFilterProperties.CommitCommand}"
|
||||
ClearCommandParameter="{Binding}"
|
||||
ClearCommand="{x:Static c:DataGridFilterProperties.ClearCommand}"
|
||||
>
|
||||
<c:ListBoxEx
|
||||
ItemsSource="{Binding items}"
|
||||
Selection="{Binding selected_items}"
|
||||
SelectionMode="Multiple"
|
||||
ItemContainerStyle="{StaticResource ListBoxItemCheckBoxStyle}"
|
||||
>
|
||||
<c:ListBoxEx.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={StaticResource BoolToAffirmativeNameConverter}}"/>
|
||||
</DataTemplate>
|
||||
</c:ListBoxEx.ItemTemplate>
|
||||
</c:ListBoxEx>
|
||||
</usp:FilterContentControl>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="EnumValuesTemplate">
|
||||
<usp:FilterContentControl
|
||||
ApplyCommandParameter="{Binding}"
|
||||
|
||||
@@ -103,10 +103,8 @@ namespace mbts.ui {
|
||||
}
|
||||
|
||||
static void tb_keydown(object sender, KeyEventArgs e) {
|
||||
if (e.Key == Key.Enter) {
|
||||
var binding = BindingOperations.GetBindingExpression(sender as DependencyObject, TextBox.TextProperty);
|
||||
binding.UpdateSource();
|
||||
}
|
||||
if (e.Key == Key.Enter)
|
||||
BindingOperations.GetBindingExpression(sender as DependencyObject, TextBox.TextProperty)?.UpdateSource();
|
||||
}
|
||||
|
||||
public static bool GetCommitOnEnter(DependencyObject obj) => (bool)obj.GetValue(CommitOnEnterProperty);
|
||||
|
||||
@@ -153,37 +153,33 @@ namespace mbts.ui
|
||||
// need to convert them to WPF cooredinates/pixels
|
||||
var transform = get_transform_from_device(window);
|
||||
task_bar_rect = Rect.Transform(task_bar_rect, transform);
|
||||
|
||||
// our source window is already in WPF pixels, so no conversion
|
||||
Rect source_window_rect = new Rect((int)window.Left, (int)window.Top, (int)window.Width, (int)window.Height);
|
||||
|
||||
while (source_window_rect.IntersectsWith(task_bar_rect)) {
|
||||
// our source window is already in WPF pixels, so no conversion
|
||||
Rect source_window_rect = new Rect(window.Left, window.Top, window.ActualWidth, window.ActualHeight);
|
||||
|
||||
// use counter just in case something goes awry (don't risk entering an infinite loop)
|
||||
int counter = 0;
|
||||
while (source_window_rect.IntersectsWith(task_bar_rect) && counter++ < 2) {
|
||||
// we have some kind of intersection, let's figure out what kind
|
||||
var intersection = Rect.Intersect(task_bar_rect, source_window_rect);
|
||||
if (intersection.Height == 0 && intersection.Width == 0 ||
|
||||
intersection.Width == 0 && intersection.Height == window.Height ||
|
||||
intersection.Height == 0 && intersection.Width == window.Width) break;
|
||||
|
||||
const double error_margin = 0.00005;
|
||||
int nudge_direction = 0;
|
||||
if (intersection.Width < window.Width) {
|
||||
if ((source_window_rect.Width - intersection.Width) > error_margin) {
|
||||
// 1 = task bar on left, so nudge right
|
||||
// -1 = task on right, so nuedge left
|
||||
nudge_direction = (task_bar_rect.Left == 0) ? 1 : -1;
|
||||
window.Left = window.Left + nudge_direction * intersection.Width;
|
||||
window.Left = source_window_rect.Left + nudge_direction * intersection.Width;
|
||||
}
|
||||
if (intersection.Height < window.Height) {
|
||||
if ((source_window_rect.Height - intersection.Height) > error_margin) {
|
||||
// 1 = task bar on top, so nudge down
|
||||
// -1 = task on bottom, so nuedge up
|
||||
nudge_direction = (task_bar_rect.Top == 0) ? 1 : -1;
|
||||
window.Top = window.Top + nudge_direction * intersection.Height;
|
||||
|
||||
window.Top = source_window_rect.Top + nudge_direction * intersection.Height;
|
||||
}
|
||||
|
||||
// update the rect w/ the new window position to see if we have to go another round
|
||||
source_window_rect = new Rect((int)window.Left, (int)window.Top, (int)window.Width, (int)window.Height);
|
||||
|
||||
}
|
||||
}
|
||||
source_window_rect = new Rect(window.Left, window.Top, window.ActualWidth, window.ActualHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,4 +83,7 @@
|
||||
<cv:NumericSignBrushConverter x:Key="PositionSignBrushConverter" Zero="{StaticResource IntZero}"/>
|
||||
<cv:NumericSignBrushConverter x:Key="DayChangeSignBrushConverter" Zero="{StaticResource DoubleZero}"/>
|
||||
<cv:QuantityMeasureCaseDisplayTextConverter x:Key="QuantityMeasureCaseDisplayConverter"/>
|
||||
<cv:ValueMap x:Key="BoolToAffirmativeNameConverter" Default="No">
|
||||
<cv:KeyValue Key="{u:True}" Value="Yes"/>
|
||||
</cv:ValueMap>
|
||||
</ResourceDictionary>
|
||||
@@ -94,7 +94,7 @@ namespace mbts.ui.shell {
|
||||
Configuration.initialize();
|
||||
}
|
||||
catch (ApplicationException e) {
|
||||
ErrorMessage = e.Message;
|
||||
ErrorMessage = (e.Message ?? string.Empty) + " " + (App.stunnel_job_error ?? string.Empty);
|
||||
HasFatalError = true;
|
||||
return;
|
||||
}
|
||||
@@ -106,7 +106,13 @@ namespace mbts.ui.shell {
|
||||
var auth = _ctx.locate<AuthService>();
|
||||
var response = await auth.get_users_async(new GetUsersRequest());
|
||||
if (response.success) {
|
||||
Users = response.value.Users.Select(x => new User(x.Login,x.Id)).OrderBy(u => u.name).ToArray();
|
||||
if (!string.IsNullOrEmpty(response.value.Error)) {
|
||||
ErrorMessage = response.value.Error;
|
||||
HasFatalError = true;
|
||||
}
|
||||
else {
|
||||
Users = response.value.Users.Select(x => new User(x.Login,x.Id)).OrderBy(u => u.name).ToArray();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ErrorMessage = "Logon: " + response.error_message;
|
||||
|
||||
@@ -42,7 +42,8 @@ namespace mbts.spark {
|
||||
_ask_vis_tup = new VisualGlyphTuple(),
|
||||
_price_vis_tup = new VisualGlyphTuple(),
|
||||
_last_vis_tup = new VisualGlyphTuple(),
|
||||
_volume_vis_tup = new VisualGlyphTuple();
|
||||
_volume_vis_tup = new VisualGlyphTuple(),
|
||||
_piq_vis_tup = new VisualGlyphTuple();
|
||||
|
||||
readonly RefValueContainer<IEnumerable<VolumeAtPriceLevelImmutable>> _volume_container =
|
||||
new RefValueContainer<IEnumerable<VolumeAtPriceLevelImmutable>>();
|
||||
@@ -92,7 +93,7 @@ namespace mbts.spark {
|
||||
};
|
||||
}
|
||||
|
||||
public enum ColumnType { Order, Bid, Price, Ask, Last, Volume, None }
|
||||
public enum ColumnType { Order, Bid, Price, Ask, Last, Volume, None, PIQ }
|
||||
|
||||
public event Action visible_columns_changed;
|
||||
|
||||
@@ -192,6 +193,18 @@ namespace mbts.spark {
|
||||
set => SetValue(LastColumnWidthProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PIQColumnWidthProperty =
|
||||
WPFHelper.create_dp<uint, LadderGridHost>(
|
||||
nameof(PIQColumnWidth),
|
||||
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
|
||||
(o, oldval, newval) => o._adjust_column_width(o.columns.FirstOrDefault(c => c.column_type == ColumnType.PIQ), (double)newval - (double)oldval),
|
||||
50u);
|
||||
|
||||
public uint PIQColumnWidth {
|
||||
get => (uint)GetValue(PIQColumnWidthProperty);
|
||||
set => SetValue(PIQColumnWidthProperty, value);
|
||||
}
|
||||
|
||||
#region Command
|
||||
public ICommand Command {
|
||||
get => (ICommand)GetValue(CommandProperty);
|
||||
@@ -404,7 +417,8 @@ namespace mbts.spark {
|
||||
double x = 0;
|
||||
var col_list = new List<Column> {
|
||||
new Column(_settings.orders_column, ColumnType.Order, null, x),
|
||||
new Column(_settings.bid_column, ColumnType.Bid, _bid_vis_tup, (x += _settings.orders_column.show ? _settings.orders_column.width : 0)),
|
||||
new Column(_settings.piq_column, ColumnType.PIQ, _piq_vis_tup, (x += _settings.orders_column.show ? _settings.orders_column.width : 0)),
|
||||
new Column(_settings.bid_column, ColumnType.Bid, _bid_vis_tup, (x += _settings.piq_column.show ? _settings.piq_column.width : 0)),
|
||||
(_price_column = new Column(_settings.price_column, ColumnType.Price, _price_vis_tup, (x += _settings.bid_column.show ? _settings.bid_column.width : 0))),
|
||||
new Column(_settings.ask_column, ColumnType.Ask, _ask_vis_tup, (x += _settings.price_column.show ? _settings.price_column.width : 0))
|
||||
};
|
||||
@@ -509,6 +523,8 @@ namespace mbts.spark {
|
||||
if (depth_changed)
|
||||
_refresh_sizes();
|
||||
}
|
||||
// TODO - detect changes in PIQ to selectively redraw
|
||||
_refresh_piq();
|
||||
_refresh_volume_at_price();
|
||||
_last_origin_price = _mkt_break_lines.origin;
|
||||
_price_dirty = false;
|
||||
@@ -545,6 +561,14 @@ namespace mbts.spark {
|
||||
LadderRender.render_last(_last_vis_tup.visual, _last_vis_tup.glyph_context, _last_trade, last_index, _settings.row_height, _settings.last_column);
|
||||
}
|
||||
|
||||
void _refresh_piq() {
|
||||
if (!_settings.piq_column.show)
|
||||
return;
|
||||
int origin_index = LadderRender.index_of(_price_list, _mkt_break_lines.origin, _price_comparer);
|
||||
var piq_list = _vm.price_vs_piq;
|
||||
LadderRender.render_piqs(_piq_vis_tup.visual, _last_vis_tup.glyph_context, origin_index, _price_list, piq_list.ToArray(), _settings.row_height, security.ContractSpec, _settings.piq_column);
|
||||
}
|
||||
|
||||
void _refresh_sizes() {
|
||||
Log.assert_d(_price_list != null);
|
||||
int origin_index = LadderRender.index_of(_price_list, _mkt_break_lines.origin, _price_comparer);
|
||||
@@ -693,6 +717,7 @@ namespace mbts.spark {
|
||||
_ask_vis_tup.glyph_context = glyph_context(s.ask_column);
|
||||
_price_vis_tup.glyph_context = glyph_context(s.price_column);
|
||||
_last_vis_tup.glyph_context = glyph_context(s.last_column);
|
||||
_piq_vis_tup.glyph_context = glyph_context(s.piq_column);
|
||||
_volume_vis_tup.glyph_context = glyph_context(s.volume_column.general);
|
||||
|
||||
GlyphContext glyph_context(LadderColumnSettings cs) =>
|
||||
@@ -720,6 +745,7 @@ namespace mbts.spark {
|
||||
case ColumnType.Price: SetCurrentValue(price_column_widthProperty, col.settings.width); break;
|
||||
case ColumnType.Ask: SetCurrentValue(ask_column_widthProperty, col.settings.width); break;
|
||||
case ColumnType.Last: SetCurrentValue(LastColumnWidthProperty, col.settings.width); break;
|
||||
case ColumnType.PIQ: SetCurrentValue(PIQColumnWidthProperty, col.settings.width); break;
|
||||
case ColumnType.Volume:
|
||||
SetCurrentValue(VolumeColumnWidthProperty, col.settings.width);
|
||||
_volume_container.mark_dirty();
|
||||
|
||||
@@ -46,9 +46,9 @@ namespace mbts.spark {
|
||||
int working_quantity;
|
||||
|
||||
LadderModel model => _parent.model;
|
||||
Dictionary<uint, OrderRecordImmutable> _orders = new Dictionary<uint, OrderRecordImmutable>();
|
||||
Dictionary<uint, (OrderRecordImmutable order, uint? p)> _orders = new Dictionary<uint, (OrderRecordImmutable order, uint? p)>();
|
||||
|
||||
public LadderOrderVM(OrderRecordImmutable o, double real_price, LadderVM parent, IBus bus, IObservable<LadderSettings.BadgeStyle> bs) {
|
||||
public LadderOrderVM((OrderRecordImmutable order, uint? p) op, double real_price, LadderVM parent, IBus bus, IObservable<LadderSettings.BadgeStyle> bs) {
|
||||
_parent = parent;
|
||||
_bus = bus;
|
||||
_bs = bs;
|
||||
@@ -73,7 +73,7 @@ namespace mbts.spark {
|
||||
double get_font_size(LadderSettings s) => s.orders_column.font_size;
|
||||
Brush get_foreground(LadderSettings s) => s.orders_column.foreground.rgb_brush();
|
||||
//
|
||||
add_order(o);
|
||||
add_order(op);
|
||||
|
||||
_dispose = Disposable.Create(
|
||||
_bs.Subscribe(badge => {
|
||||
@@ -109,19 +109,19 @@ namespace mbts.spark {
|
||||
// if this badge only represents a single order, then is_exchange_order and the border (= algo color)
|
||||
// should be set appropriately
|
||||
if (_orders.Count == 1) {
|
||||
var single_order = _orders.Values.First();
|
||||
var single_order = _orders.Values.First().order;
|
||||
var single_order_metadata = _parent.model.order_gateway.factory.get_metadata(single_order);
|
||||
border = single_order_metadata.Color.rgb_brush();
|
||||
is_exchange_order = OrderUtils.is_exchange_order(_orders.Values.First());
|
||||
is_exchange_order = OrderUtils.is_exchange_order(single_order);
|
||||
} else {
|
||||
border = new SolidColorBrush(color);
|
||||
is_exchange_order = false;
|
||||
}
|
||||
has_multiple_orders_at_same_level = _orders.Count > 1;
|
||||
is_hedge_order = _orders.Any(o => o.Value.sub_type() == OrderSubType.HedgingLeg);
|
||||
is_hedge_order = _orders.Any(op => op.Value.order.sub_type() == OrderSubType.HedgingLeg);
|
||||
|
||||
if (_orders.Any()) {
|
||||
summary = _orders.Values.Select(order => order.short_description(_parent.security.ContractSpec)).Aggregate((s1, s2) => $"{s1}{Environment.NewLine}{Environment.NewLine}{s2}");
|
||||
summary = _orders.Values.Select(op => op.order.short_description(_parent.security.ContractSpec)).Aggregate((s1, s2) => $"{s1}{Environment.NewLine}{Environment.NewLine}{s2}");
|
||||
}
|
||||
_set_badge_text();
|
||||
|
||||
@@ -132,8 +132,8 @@ namespace mbts.spark {
|
||||
RaisePropertyChanged(nameof(text_lines));
|
||||
}
|
||||
|
||||
public void add_order(OrderRecordImmutable new_order) {
|
||||
_orders[new_order.Key] = new_order;
|
||||
public void add_order((OrderRecordImmutable order, uint? p) new_op) {
|
||||
_orders[new_op.order.Key] = new_op;
|
||||
}
|
||||
|
||||
public void remove_order(uint order_key) {
|
||||
@@ -149,10 +149,11 @@ namespace mbts.spark {
|
||||
|
||||
public uint security_key => _parent.security.Id;
|
||||
public double price { get => double.IsNaN(_phantom_price) ? _real_price : _phantom_price; }
|
||||
public uint? min_piq => _orders.Select(op => op.Value.p).Where(piq => piq.HasValue).Min();
|
||||
public double real_price => _real_price;
|
||||
public Side side {
|
||||
get {
|
||||
var distinct_sides = _orders.Values.Select(o => o.side()).Distinct();
|
||||
var distinct_sides = _orders.Values.Select(op => op.order.side()).Distinct();
|
||||
if (distinct_sides.Count() > 1) {
|
||||
return Side.Undefined;
|
||||
}
|
||||
@@ -160,11 +161,11 @@ namespace mbts.spark {
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<OrderRecordImmutable> _parent_and_child_not_sharing_slot() => _orders.Values.Where(o => !_orders.ContainsKey(o.ParentKey));
|
||||
IEnumerable<OrderRecordImmutable> _parent_and_child_not_sharing_slot() => _orders.Values.Select(op => op.order).Where(o => !_orders.ContainsKey(o.ParentKey));
|
||||
|
||||
public IReadOnlyList<string> text_lines { get; private set; }
|
||||
|
||||
public bool has_parent => _orders.Values.Any( order => order.has_parent());
|
||||
public bool has_parent => _orders.Values.Any( op => op.order.has_parent());
|
||||
public bool has_phantom_price => !double.IsNaN(_phantom_price);
|
||||
|
||||
public ICommand detach_command => new DelegateCommand(() => _execute_command(_crack_order), () => !has_parent);
|
||||
@@ -191,16 +192,16 @@ namespace mbts.spark {
|
||||
// the setter is public so that the LadderVM can set this field
|
||||
public CustomOrderDefinition.CustomOneofCase parent_algo_type { get => _parent_algo_type.Value; set => _parent_algo_type.Value = value; }
|
||||
|
||||
public IEnumerable<OrderRecordImmutable> orders => _orders.Values;
|
||||
public IEnumerable<OrderRecordImmutable> orders => _orders.Values.Select(o => o.order);
|
||||
|
||||
void _cancel_order() {
|
||||
foreach (var order in _orders.Values) {
|
||||
model.order_gateway.cancel_order(order).ignore();
|
||||
foreach (var op in _orders.Values) {
|
||||
model.order_gateway.cancel_order(op.order).ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void _crack_order() {
|
||||
var distinct_parent_keys = _orders.Values.Where(o => o.has_parent()).Select(x => x.ParentKey).Distinct();
|
||||
var distinct_parent_keys = _orders.Values.Where(op => op.order.has_parent()).Select(x => x.order.ParentKey).Distinct();
|
||||
model.order_gateway.crack_orders(distinct_parent_keys).ignore();
|
||||
}
|
||||
|
||||
@@ -279,7 +280,7 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return $"Price: {this.price} Order Count: {this.orders.Count()}";
|
||||
return $"Price: {this.price} Order Count: {this.orders.Count()} PIQ: {(this.min_piq.HasValue ? this.min_piq.Value.ToString() : "")}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +249,8 @@ namespace mbts.spark {
|
||||
bid_column = LadderColumnSettings.Default,
|
||||
ask_column = LadderColumnSettings.Default,
|
||||
price_column = LadderColumnSettings.Default,
|
||||
last_column = LadderColumnSettings.Default;
|
||||
last_column = LadderColumnSettings.Default,
|
||||
piq_column = LadderColumnSettings.Default;
|
||||
orders_column.background = BTSColors.LadderSpecial.default_column_background;
|
||||
bid_column.foreground = 0xFFFFFF;
|
||||
bid_column.background = BTSColors.MarketData.bid;
|
||||
@@ -257,6 +258,7 @@ namespace mbts.spark {
|
||||
ask_column.background = BTSColors.MarketData.ask;
|
||||
price_column.background = BTSColors.LadderSpecial.default_column_background;
|
||||
last_column.background = 0xFFFFFF;
|
||||
piq_column.background = BTSColors.LadderSpecial.default_column_background;
|
||||
return new LadderSettings {
|
||||
row_height = 20,
|
||||
grid_line_color = 0x535353,
|
||||
@@ -265,6 +267,7 @@ namespace mbts.spark {
|
||||
ask_column = ask_column,
|
||||
price_column = price_column,
|
||||
last_column = last_column,
|
||||
piq_column = piq_column,
|
||||
volume_column = VolumeColumnSettings.Default,
|
||||
calculator_buttons = new[] { 1, 5, 10, 25, 50, 100 },
|
||||
scroll_bar_visible = false,
|
||||
@@ -398,7 +401,7 @@ namespace mbts.spark {
|
||||
public bool clear_visible { get; set; }
|
||||
//
|
||||
[ProtoMember(43), DefaultValue(_default_order_entry_panel_width)]
|
||||
public double order_entry_panel_initial_width { get; set; }
|
||||
public double order_entry_panel_initial_width { get; set; }
|
||||
|
||||
[ProtoMember(44), DefaultValue(true)]
|
||||
public bool use_defaults { get; set; }
|
||||
@@ -417,6 +420,13 @@ namespace mbts.spark {
|
||||
[ProtoMember(48)]
|
||||
public NetChangeTerms net_change { get; set; }
|
||||
|
||||
[ProtoMember(49)]
|
||||
LadderColumnSettings _piq_column;
|
||||
public LadderColumnSettings piq_column {
|
||||
get => _piq_column ?? (_piq_column = LadderSettings.Default.piq_column);
|
||||
set => _piq_column = value;
|
||||
}
|
||||
|
||||
public bool Equals(LadderSettings other) =>
|
||||
other != null &&
|
||||
row_height == other.row_height &&
|
||||
@@ -426,6 +436,7 @@ namespace mbts.spark {
|
||||
ask_column.safe_equals(other.ask_column) &&
|
||||
price_column.safe_equals(other.price_column) &&
|
||||
last_column.safe_equals(other.last_column) &&
|
||||
piq_column.safe_equals(other.piq_column) &&
|
||||
calculator_buttons.safe_equals(other.calculator_buttons, (a, b) => a.SequenceEqual(b)) &&
|
||||
scroll_bar_visible == other.scroll_bar_visible &&
|
||||
default_order_type == other.default_order_type &&
|
||||
@@ -476,6 +487,7 @@ namespace mbts.spark {
|
||||
EqualityComparer.safe_get_hash_code(ask_column),
|
||||
EqualityComparer.safe_get_hash_code(price_column),
|
||||
EqualityComparer.safe_get_hash_code(last_column),
|
||||
EqualityComparer.safe_get_hash_code(piq_column),
|
||||
EqualityComparer.safe_get_hash_code(calculator_buttons),
|
||||
scroll_bar_visible.GetHashCode(),
|
||||
default_order_type.GetHashCode(),
|
||||
@@ -517,12 +529,12 @@ namespace mbts.spark {
|
||||
|
||||
public struct WindowSpecifics {
|
||||
public readonly double order_entry_panel_width, zoom_factor;
|
||||
public readonly uint orders_column_width, bid_column_width, price_column_width, ask_column_width, last_column_width, volume_column_width;
|
||||
public readonly uint orders_column_width, bid_column_width, price_column_width, ask_column_width, last_column_width, volume_column_width, piq_column_width;
|
||||
|
||||
public WindowSpecifics(LadderSettings s)
|
||||
: this(s.order_entry_panel_initial_width, s.orders_column.width, s.bid_column.width, s.price_column.width, s.ask_column.width, s.last_column.width, s.volume_column.general.width, s.zoom_factor) { }
|
||||
: this(s.order_entry_panel_initial_width, s.orders_column.width, s.bid_column.width, s.price_column.width, s.ask_column.width, s.last_column.width, s.volume_column.general.width, s.zoom_factor, s.piq_column.width) { }
|
||||
|
||||
public WindowSpecifics(double order_entry_panel_width, uint orders_column_width, uint bid_column_width, uint price_column_width, uint ask_column_width, uint last_column_width, uint volume_column_width, double zoom_factor) {
|
||||
public WindowSpecifics(double order_entry_panel_width, uint orders_column_width, uint bid_column_width, uint price_column_width, uint ask_column_width, uint last_column_width, uint volume_column_width, double zoom_factor, uint piq_column_width) {
|
||||
this.order_entry_panel_width = order_entry_panel_width;
|
||||
this.orders_column_width = orders_column_width;
|
||||
this.bid_column_width = bid_column_width;
|
||||
@@ -531,6 +543,7 @@ namespace mbts.spark {
|
||||
this.last_column_width = last_column_width;
|
||||
this.volume_column_width = volume_column_width;
|
||||
this.zoom_factor = zoom_factor;
|
||||
this.piq_column_width = piq_column_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -543,6 +556,7 @@ namespace mbts.spark {
|
||||
yield return settings.ask_column;
|
||||
yield return settings.volume_column.general;
|
||||
yield return settings.last_column;
|
||||
yield return settings.piq_column;
|
||||
}
|
||||
|
||||
public static IEnumerable<LadderColumnSettings> visible_columns(this LadderSettings settings) =>
|
||||
@@ -560,6 +574,7 @@ namespace mbts.spark {
|
||||
source.price_column.width = specifics.price_column_width;
|
||||
source.ask_column.width = specifics.ask_column_width;
|
||||
source.last_column.width = specifics.last_column_width;
|
||||
source.piq_column.width = specifics.piq_column_width;
|
||||
source.volume_column.general.width = specifics.volume_column_width;
|
||||
source.zoom_factor = specifics.zoom_factor;
|
||||
return source;
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace mbts.spark {
|
||||
_bid = new LadderColumnSettingsVM("Bid"),
|
||||
_price = new LadderColumnSettingsVM("Price"),
|
||||
_ask = new LadderColumnSettingsVM("Ask"),
|
||||
_last = new LadderColumnSettingsVM("Last", true);
|
||||
_last = new LadderColumnSettingsVM("Last", true),
|
||||
_piq = new LadderColumnSettingsVM("PIQ", true);
|
||||
VolumeColumnVM _volume = new VolumeColumnVM();
|
||||
LadderMarketBreakLineVM
|
||||
_bid_mkt_line = new LadderMarketBreakLineVM("Bid"),
|
||||
@@ -82,6 +83,7 @@ namespace mbts.spark {
|
||||
_price.font_size_changed += on_font_size_changed;
|
||||
_ask.font_size_changed += on_font_size_changed;
|
||||
_last.font_size_changed += on_font_size_changed;
|
||||
_piq.font_size_changed += on_font_size_changed;
|
||||
|
||||
void on_font_size_changed(double oldval, double newval) => _row_height.refresh();
|
||||
}
|
||||
@@ -120,6 +122,7 @@ namespace mbts.spark {
|
||||
if (!is_synthetic) {
|
||||
yield return _volume.general;
|
||||
yield return _last;
|
||||
yield return _piq;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,6 +133,7 @@ namespace mbts.spark {
|
||||
public LadderColumnSettingsVM ask_column => _ask;
|
||||
public LadderColumnSettingsVM volume_column => _volume.general;
|
||||
public LadderColumnSettingsVM last_column => _last;
|
||||
public LadderColumnSettingsVM piq_column => _piq;
|
||||
public VolumeColumnVM volume => _volume;
|
||||
public LadderMarketBreakLineVM session_range_fill => _session_range_fill;
|
||||
public ObservableEditableCollection<IMutableValueWrapperVM<uint>> size_presets { get; }
|
||||
@@ -209,6 +213,7 @@ namespace mbts.spark {
|
||||
_price.assign_from(_current.price_column);
|
||||
_volume.assign_from(_current.volume_column);
|
||||
_last.assign_from(_current.last_column);
|
||||
_piq.assign_from(_current.piq_column);
|
||||
_bid_mkt_line.assign_from(_current.bid_break_line);
|
||||
_ask_mkt_line.assign_from(_current.ask_break_line);
|
||||
_mid_mkt_line.assign_from(_current.mid_break_line);
|
||||
@@ -254,6 +259,7 @@ namespace mbts.spark {
|
||||
clone.ask_column = _ask.get_settings();
|
||||
clone.volume_column = _volume.get_settings();
|
||||
clone.last_column = _last.get_settings();
|
||||
clone.piq_column = _piq.get_settings();
|
||||
clone.bid_break_line = _bid_mkt_line.get_settings();
|
||||
clone.ask_break_line = _ask_mkt_line.get_settings();
|
||||
clone.mid_break_line = _mid_mkt_line.get_settings();
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace mbts.spark {
|
||||
readonly LadderModel _model;
|
||||
readonly Property<double> _high, _low, _change, _open, _settlement, _position, _left_panel_width, _zoom_factor;
|
||||
//readonly Property<double> _window_width, _window_height;
|
||||
readonly Property<uint> _orders_column_width, _bid_column_width, _price_column_width, _ask_column_width, _last_column_width, _volume_column_width;
|
||||
readonly Property<uint> _orders_column_width, _bid_column_width, _price_column_width, _ask_column_width, _last_column_width, _volume_column_width, _piq_column_width;
|
||||
readonly Property<ulong> _volume;
|
||||
readonly Property<bool> _auto_clear, _show_day, _show_high, _show_low, _show_open, _show_settle, _show_volume, _show_account,
|
||||
_show_tif, _show_order_type, _show_account_position, _show_size_preset, _show_auto_clear, _show_clear, _show_cancel_buys,
|
||||
@@ -58,6 +58,7 @@ namespace mbts.spark {
|
||||
_price_column_width = backing(nameof(price_column_width), ws.price_column_width);
|
||||
_ask_column_width = backing(nameof(ask_column_width), ws.ask_column_width);
|
||||
_last_column_width = backing(nameof(last_column_width), ws.last_column_width);
|
||||
_piq_column_width = backing(nameof(piq_column_width), ws.piq_column_width);
|
||||
_volume_column_width = backing(nameof(volume_column_width), ws.volume_column_width);
|
||||
_left_panel_width = backing(nameof(left_panel_width), ws.order_entry_panel_width);
|
||||
_zoom_factor = backing(nameof(zoom_factor), ws.zoom_factor);
|
||||
@@ -132,7 +133,7 @@ namespace mbts.spark {
|
||||
account_positions,
|
||||
size_calculator = new CalculatorLogic(0, _settings_manager.subscribe_current().Select(s => s.calculator_buttons)),
|
||||
bus.subscribe(SparkTags.LogActivity).OnDispatcher().Subscribe(status_update),
|
||||
model.order_gateway.working_orders.OnDispatcher().Subscribe(working => {
|
||||
model.order_gateway.working_orders_with_piq.OnDispatcher().Subscribe(working => {
|
||||
// Here we manage N orders to 1 price slot in the ladder
|
||||
|
||||
Dictionary<double, HashSet<uint>> orders_used_in_this_update = new Dictionary<double, HashSet<uint>>(_equality);
|
||||
@@ -157,9 +158,9 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
if (_slot_price_vs_orders.TryGetValue(slot_price_target, out LadderOrderVM slot_vm)) {
|
||||
slot_vm.add_order(wo);
|
||||
slot_vm.add_order((wo, osec.piq));
|
||||
} else {
|
||||
slot_vm = new LadderOrderVM(wo, slot_price_target, this, _bus, _settings_manager.subscribe_current().Select(s => s.badge_style));
|
||||
slot_vm = new LadderOrderVM((wo, osec.piq), slot_price_target, this, _bus, _settings_manager.subscribe_current().Select(s => s.badge_style));
|
||||
_slot_price_vs_orders[slot_price_target] = slot_vm;
|
||||
}
|
||||
|
||||
@@ -232,6 +233,10 @@ namespace mbts.spark {
|
||||
public event Action on_tick;
|
||||
|
||||
public MDConsumerHandle md => _model.md;
|
||||
// we return only entries who have piqs and whose piqs are not uint.Max
|
||||
// uint.Max happens when the server is restarted but the client is still up
|
||||
// maybe long term we don't show this data while the exchange connection is down
|
||||
public IEnumerable<(double, uint)> price_vs_piq => _slot_price_vs_orders.Values.Where(result => result.min_piq.HasValue && result.min_piq.Value != uint.MaxValue).Select(o => (o.price, o.min_piq.Value));
|
||||
public bool is_synthetic => _model.security.ContractCase == Security.ContractOneofCase.Synthetic;
|
||||
|
||||
Property<string> _status;
|
||||
@@ -306,13 +311,14 @@ namespace mbts.spark {
|
||||
public uint price_column_width { get => _price_column_width.Value; set => _price_column_width.set(value); }
|
||||
public uint ask_column_width { get => _ask_column_width.Value; set => _ask_column_width.set(value); }
|
||||
public uint last_column_width { get => _last_column_width.Value; set => _last_column_width.set(value); }
|
||||
public uint piq_column_width { get => _piq_column_width.Value; set => _piq_column_width.set(value); }
|
||||
public uint volume_column_width { get => _volume_column_width.Value; set => _volume_column_width.set(value); }
|
||||
internal LadderModel model => _model;
|
||||
internal IObservable<LadderSettings> settings => _settings_manager.subscribe_current();
|
||||
|
||||
public LadderSettings get_save_state() {
|
||||
var state = _settings_manager.current_settings();
|
||||
state = state.with_window_specifics(new LadderSettings.WindowSpecifics(left_panel_width, orders_column_width, bid_column_width, price_column_width, ask_column_width, last_column_width, volume_column_width, zoom_factor));
|
||||
state = state.with_window_specifics(new LadderSettings.WindowSpecifics(left_panel_width, orders_column_width, bid_column_width, price_column_width, ask_column_width, last_column_width, volume_column_width, zoom_factor, piq_column_width));
|
||||
state.use_defaults = _settings_manager.instance_settings == null;
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -541,6 +541,7 @@
|
||||
price_column_width="{Binding price_column_width, Mode=TwoWay}"
|
||||
ask_column_width="{Binding ask_column_width, Mode=TwoWay}"
|
||||
LastColumnWidth="{Binding last_column_width, Mode=TwoWay}"
|
||||
PIQColumnWidth="{Binding piq_column_width, Mode=TwoWay}"
|
||||
VolumeColumnWidth="{Binding volume_column_width, Mode=TwoWay}"
|
||||
>
|
||||
<spark:LadderGridHost.Resources>
|
||||
|
||||
@@ -141,6 +141,10 @@ namespace mbts.spark {
|
||||
header = "Last";
|
||||
width_prop = nameof(LadderVM.last_column_width);
|
||||
break;
|
||||
case LadderGridHost.ColumnType.PIQ:
|
||||
header = "PIQ";
|
||||
width_prop = nameof(LadderVM.piq_column_width);
|
||||
break;
|
||||
default: throw ExceptionBuilder.Argument.unexpected_case(type, nameof(type));
|
||||
}
|
||||
return _create(host, header, $"DataContext.{width_prop}");
|
||||
|
||||
@@ -277,6 +277,30 @@ namespace mbts.spark {
|
||||
}
|
||||
}
|
||||
|
||||
// this is basically a copy of redner_sizes up above
|
||||
internal static void render_piqs(DrawingVisual dv, GlyphContext glyph_context, int origin_index, double[] prices, (double price, uint piq)[] piqs, double row_height, ContractSpecificationImmutable spec, LadderColumnSettings settings) {
|
||||
using (var dc = dv.RenderOpen()) {
|
||||
using (_draw_with_clip(dc, settings, row_height, prices.Length)) {
|
||||
if (!prices.within_range(origin_index) || piqs.is_null_or_empty())
|
||||
return;
|
||||
var foreground = settings.foreground.rgb_brush();
|
||||
int curr_index = origin_index;
|
||||
double curr_price = prices[curr_index];
|
||||
for (int i = 0; i < piqs.Length; i++) {
|
||||
double price = piqs[i].price;
|
||||
// prices are in descending order, so get diff from curr_price - price
|
||||
int tick_diff = spec.tickdiff_unchecked(curr_price, price);
|
||||
curr_index += tick_diff;
|
||||
curr_price = price;
|
||||
if (curr_index >= 0 && curr_index < prices.Length) {
|
||||
var gr = format_text(piqs[i].piq.ToString(), curr_index, row_height, settings, glyph_context);
|
||||
dc.DrawGlyphRun(foreground, gr);
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void render_mkt_break(DrawingVisual dv, int index, double row_height, uint color) =>
|
||||
render_single_grid_line(dv, index, row_height, color, 0, SystemParameters.FullPrimaryScreenWidth);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ using mbts.ui.settings;
|
||||
|
||||
namespace mbts.spark {
|
||||
class PAndLVM : DisposableViewModelBase {
|
||||
|
||||
public PAndLVM(IBus bus, PAndLModel model, PAndLStartupData startup_data, IWindowSettingsManager<GridSettings> settings_manager) {
|
||||
_bus = bus;
|
||||
_model = model;
|
||||
@@ -42,6 +43,10 @@ namespace mbts.spark {
|
||||
if (p != null) {
|
||||
PnLCalculator calc = new PnLCalculator(p.state.Values, _selected_pnl_calc_type.Value);
|
||||
var summary_position_rows = calc.get_summary_position();
|
||||
// remove rows for which there is no net pos or no day pos
|
||||
summary_position_rows = summary_position_rows.Where(r =>
|
||||
!(r.start_net_position == 0 && r.day_long_quantity == 0 && r.day_short_quantity == 0)
|
||||
);
|
||||
_pnl_data.sync_with(summary_position_rows);
|
||||
_last_pnl_update_time = DateTime.Now;
|
||||
}
|
||||
@@ -64,6 +69,11 @@ namespace mbts.spark {
|
||||
total_pnl_filter.load_state(fs.total_pnl);
|
||||
pnl_price_filter.load_state(fs.pnl_price);
|
||||
security_type_filter.load_state(fs.security_types);
|
||||
has_day_trades_filter.load_state(fs.has_day_trades);
|
||||
} else {
|
||||
// this is debt that will have to be paid down at some point, similar to the pnl_calc_type thing above
|
||||
// these should come from the default startup_data.
|
||||
security_type_filter.load_state(new[] { SecurityType.Future });
|
||||
}
|
||||
pnl_view.CollectionChanged += Pnl_view_CollectionChanged;
|
||||
|
||||
@@ -77,6 +87,7 @@ namespace mbts.spark {
|
||||
add_col(Columns.DayLong, DefaultColumnHeaders.DayLong, r => r.day_long_quantity.ToString(), nameof(PnLSummaryRow.day_long_quantity), DefaultColumnWidths.PnL_Generic, day_long_quantity_filter, DataGridFilterKnownTemplates.UIntMinMax, HorizontalAlignment.Right);
|
||||
add_col(Columns.DayShort, DefaultColumnHeaders.DayShort, r => r.day_short_quantity.ToString(), nameof(PnLSummaryRow.day_short_quantity), DefaultColumnWidths.PnL_Generic, day_short_quantity_filter, DataGridFilterKnownTemplates.UIntMinMax, HorizontalAlignment.Right);
|
||||
add_col(Columns.DayPNL, DefaultColumnHeaders.DayPnL, r => r.day_pnl_text, nameof(PnLSummaryRow.day_pnl), 90, day_pnl_filter, DataGridFilterKnownTemplates.DoubleMinMax, HorizontalAlignment.Right, r => r.day_pnl_background);
|
||||
add_col(Columns.TradedToday, "Traded Today", r => r.has_day_trades_text, nameof(PnLSummaryRow.has_day_trades), 100, has_day_trades_filter, DataGridFilterKnownTemplates.YesNo, HorizontalAlignment.Center);
|
||||
add_col(Columns.TotalNetPos, DefaultColumnHeaders.TotalNetPos, r => r.total_net_position.ToString(), nameof(PnLSummaryRow.total_net_position), DefaultColumnWidths.Total_Net_Pos, total_net_position_filter, DataGridFilterKnownTemplates.DoubleMinMax, HorizontalAlignment.Right);
|
||||
add_col(Columns.TotalPNL, DefaultColumnHeaders.TotalPnL, r => r.total_pnl_text, nameof(PnLSummaryRow.total_pnl), DefaultColumnWidths.PnL_Generic, total_pnl_filter, DataGridFilterKnownTemplates.DoubleMinMax, HorizontalAlignment.Right, r => r.total_pnl_background);
|
||||
add_col(Columns.PNLPrice, DefaultColumnHeaders.PnLPrice, r => r.pnl_price_text, nameof(PnLSummaryRow.pnl_price), DefaultColumnWidths.PnL_Generic, pnl_price_filter, DataGridFilterKnownTemplates.DoubleMinMax, HorizontalAlignment.Right);
|
||||
@@ -125,7 +136,8 @@ namespace mbts.spark {
|
||||
pnl_price_filter,
|
||||
weighted_average_buy_filter,
|
||||
weighted_average_sell_filter,
|
||||
security_type_filter),
|
||||
security_type_filter,
|
||||
has_day_trades_filter),
|
||||
WorkLoop.Start("PAndL", _UPDATE_PERIOD, _calculate_pnl)
|
||||
);
|
||||
}
|
||||
@@ -245,6 +257,7 @@ namespace mbts.spark {
|
||||
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, 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 IDataGridColumnPersistentFilter<PnLSummaryRow, bool[]> has_day_trades_filter { get; } = DiscreteValuesFilterVM.Create<PnLSummaryRow, bool>(new[] { true, false }, r => r.has_day_trades, nameof(PnLSummaryRow.has_day_trades));
|
||||
|
||||
public FilterStates get_filters_states() => new FilterStates {
|
||||
account_regex = account_filter.get_state(),
|
||||
@@ -259,7 +272,8 @@ 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(),
|
||||
security_types = security_type_filter.get_state()
|
||||
security_types = security_type_filter.get_state(),
|
||||
has_day_trades = has_day_trades_filter.get_state(),
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Windows.Controls;
|
||||
|
||||
namespace mbts.spark {
|
||||
internal partial class PAndLView : UserControl {
|
||||
public enum Columns { Account, Exchange, Symbol, Security, SecurityType, StartNetPos, StartPNL, DayLong, DayShort, DayPNL, TotalNetPos, TotalPNL, PNLPrice }
|
||||
public enum Columns { Account, Exchange, Symbol, Security, SecurityType, StartNetPos, StartPNL, DayLong, DayShort, DayPNL, TotalNetPos, TotalPNL, PNLPrice, TradedToday }
|
||||
|
||||
public PAndLView(PAndLVM vm) {
|
||||
InitializeComponent();
|
||||
|
||||
@@ -184,6 +184,10 @@ namespace mbts.spark {
|
||||
public string weighted_average_buy_text => _weighted_average_buy.text;
|
||||
public double weighted_average_sell => _weighted_average_sell.value;
|
||||
public string weighted_average_sell_text => _weighted_average_sell.text;
|
||||
//
|
||||
public bool has_day_trades => day_long_quantity != 0 || day_short_quantity != 0;
|
||||
public string has_day_trades_text => has_day_trades ? "Yes" : "No";
|
||||
|
||||
|
||||
public void raise_invalidated() => invalidated?.Invoke();
|
||||
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace mbts.co2 {
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 376)]
|
||||
[StructLayout(LayoutKind.Sequential, Size = 704)]
|
||||
internal struct ColdEntry {
|
||||
public int exchange_status;
|
||||
// Last trade
|
||||
|
||||
@@ -110,19 +110,21 @@ namespace bts.api.core {
|
||||
the_update.Clear();
|
||||
try {
|
||||
if (event_type == ApiNativeMethods.EventType.TABLE_UPDATED) {
|
||||
foreach (var change in changes) {
|
||||
switch (change.type) {
|
||||
case ApiNativeMethods.ChangeType.REMOVE:
|
||||
the_update.removed_keys.Add(change.key);
|
||||
break;
|
||||
case ApiNativeMethods.ChangeType.REPLACE:
|
||||
the_update.changed_items.Add(converter(parser.ParseFrom(new UnmanagedMemoryStream(change.buffer, change.buffer_len))));
|
||||
the_update.changed_keys.Add(change.key);
|
||||
break;
|
||||
case ApiNativeMethods.ChangeType.CREATE:
|
||||
the_update.added_items.Add(converter(parser.ParseFrom(new UnmanagedMemoryStream(change.buffer, change.buffer_len))));
|
||||
the_update.added_keys.Add(change.key);
|
||||
break;
|
||||
if (changes != null) {
|
||||
foreach (var change in changes) {
|
||||
switch (change.type) {
|
||||
case ApiNativeMethods.ChangeType.REMOVE:
|
||||
the_update.removed_keys.Add(change.key);
|
||||
break;
|
||||
case ApiNativeMethods.ChangeType.REPLACE:
|
||||
the_update.changed_items.Add(converter(parser.ParseFrom(new UnmanagedMemoryStream(change.buffer, change.buffer_len))));
|
||||
the_update.changed_keys.Add(change.key);
|
||||
break;
|
||||
case ApiNativeMethods.ChangeType.CREATE:
|
||||
the_update.added_items.Add(converter(parser.ParseFrom(new UnmanagedMemoryStream(change.buffer, change.buffer_len))));
|
||||
the_update.added_keys.Add(change.key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
observer.OnNext(the_update);
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace bts.md
|
||||
var sec = lookup(key);
|
||||
if (sec.HasValue)
|
||||
{
|
||||
security_desc = sec.Value.glbx_desc();
|
||||
security_desc = sec.Value.security_desc();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -198,7 +198,7 @@ namespace bts.md
|
||||
public bool lookup_security_key_from_desc(string security_desc, out SecurityKey key)
|
||||
{
|
||||
key = 0;
|
||||
var fnd = find(x => x.glbx_desc() == security_desc).TryFirst();
|
||||
var fnd = find(x => x.security_desc() == security_desc).TryFirst();
|
||||
if (fnd.HasValue)
|
||||
{
|
||||
key = fnd.Value.security.Id;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace bts.api {
|
||||
|
||||
static string _format(SecurityImmutable? security) {
|
||||
switch (security?.ContractCase) {
|
||||
case ContractOneofCase.Future: return format_future(security?.Symbol, security?.glbx_desc(), security.Value.Future);
|
||||
case ContractOneofCase.Future: return format_future(security?.Symbol, security?.security_desc(), security.Value.Future);
|
||||
case ContractOneofCase.Spread:
|
||||
if (security?.HasGlbx == true) {
|
||||
// In case we ever bring it back, pretty printed spread names can be found here:
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace bts.api {
|
||||
foreach (var l in legs) {
|
||||
switch (l.Security.ContractCase) {
|
||||
case ContractOneofCase.Future:
|
||||
yield return new FutureLeg(l.Security.Exchange, l.Security.Symbol, l.Security.glbx_desc(), l.Security.Future, qty * l.SignedQuantity());
|
||||
yield return new FutureLeg(l.Security.Exchange, l.Security.Symbol, l.Security.security_desc(), l.Security.Future, qty * l.SignedQuantity());
|
||||
break;
|
||||
case ContractOneofCase.Spread:
|
||||
foreach (var fl in _get_flat_future_legs(l.Security.Spread.Legs, qty * l.SignedQuantity()))
|
||||
@@ -57,8 +57,18 @@ namespace bts.api {
|
||||
public static string DisplayExchange(this SecurityImmutable security) =>
|
||||
security.ContractCase == ContractOneofCase.Synthetic ? $"[{string.Join(",", get_flat_future_legs(security).Select(flt => flt.exchange.ToString()).Distinct().OrderBy(e => e))}]" : security.Exchange.ToString();
|
||||
|
||||
public static string glbx_desc(this SecurityImmutable security) =>
|
||||
security.HasGlbx ? security.Glbx.SecurityDesc ?? string.Empty : string.Empty;
|
||||
public static string security_desc(this SecurityImmutable security)
|
||||
{
|
||||
if(security.HasGlbx)
|
||||
return security.Glbx.SecurityDesc;
|
||||
else if(security.HasIce)
|
||||
return security.Ice.SecurityDesc;
|
||||
else
|
||||
{
|
||||
Log.assert(false, "security_desc not implemented for exchange");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static class Comparer {
|
||||
|
||||
@@ -51,6 +51,12 @@ namespace mbts.config
|
||||
reset();
|
||||
initialize();
|
||||
}
|
||||
|
||||
public static bool try_initialize(out string error)
|
||||
{
|
||||
reset();
|
||||
return initialize(out error);
|
||||
}
|
||||
|
||||
////////////
|
||||
/// private
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace bts.api.orderman {
|
||||
|
||||
public static class OrderUtilities {
|
||||
public static NativeOrderStateImmutable? native_order_state(this OrderStateImmutable order) {
|
||||
switch(order.CustomCase) {
|
||||
case OrderState.CustomOneofCase.Market:
|
||||
return order.Market.NativeState;
|
||||
case OrderState.CustomOneofCase.Limit:
|
||||
return order.Limit.NativeState;
|
||||
case OrderState.CustomOneofCase.Stop:
|
||||
return order.Stop.NativeState;
|
||||
case OrderState.CustomOneofCase.StopLimit:
|
||||
return order.StopLimit.NativeState;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,14 +1,19 @@
|
||||
using ManyConsole;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CommandLine;
|
||||
|
||||
namespace bts {
|
||||
public class Configcheck : ConsoleCommand {
|
||||
public Configcheck() {
|
||||
IsCommand("configcheck", "Ye olde Configcheck");
|
||||
HasAdditionalArguments(null, " [Keys to check]");
|
||||
}
|
||||
public override int Run(string[] args) {
|
||||
mbts.config.Configuration.configcheck(args.Length, args.ToArray());
|
||||
|
||||
[Verb("configcheck", HelpText="Ye olde Configcheck")]
|
||||
public class ConfigcheckOptions {
|
||||
[Value(0, MetaName="keys", HelpText="Keys to print")]
|
||||
public IEnumerable<string> keys { get; set; }
|
||||
}
|
||||
public class Configcheck {
|
||||
public static int Run(ConfigcheckOptions options) {
|
||||
var keys = options.keys.ToArray();
|
||||
mbts.config.Configuration.configcheck(keys.Length, keys);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ManyConsole {
|
||||
public static class ConsoleCommandEx {
|
||||
public static string get_argument(this ConsoleCommand _, string arg_name) {
|
||||
var arg = Environment.GetCommandLineArgs().FirstOrDefault(str => str.StartsWith("--"+arg_name));
|
||||
if (arg != null) {
|
||||
var parts = arg.Split(new[] { '=' }, 2);
|
||||
if (parts.Length > 1) {
|
||||
return parts[1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,32 +6,33 @@ using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive;
|
||||
using ManyConsole;
|
||||
using System.Linq;
|
||||
using CommandLine;
|
||||
|
||||
namespace sparkcmd {
|
||||
public class ScriptClientCommand : ConsoleCommand {
|
||||
bool _server = false;
|
||||
string _host;
|
||||
string _logfile;
|
||||
[Verb("script", HelpText="Remote control for shell diagnostic host")]
|
||||
public class ScriptClientOptions {
|
||||
[Option('s', "server", HelpText="Run a script server for testing.")]
|
||||
public bool server { get; set; }
|
||||
|
||||
public ScriptClientCommand() {
|
||||
IsCommand("script", "Remote control for shell diagnostic host");
|
||||
HasOption("s|server", "Run a script server for testing.", x => _server = true);
|
||||
HasOption("h|host", "Connect to {host}", h => _host = h);
|
||||
HasOption("f|fromfile", "Read commands from file instead of stdin", f => _logfile = f);
|
||||
}
|
||||
public override int Run(string[] args) {
|
||||
if (_server) {
|
||||
[Option('h', "host", HelpText="Connect to {host}")]
|
||||
public string host { get; set; }
|
||||
|
||||
[Option('f', "fromfile", HelpText="Read commands from file instead of stdin")]
|
||||
public string file { get; set; }
|
||||
|
||||
}
|
||||
public class ScriptClientCommand {
|
||||
public static int Run(ScriptClientOptions o) {
|
||||
if (o.server) {
|
||||
ScriptClient.runserver();
|
||||
}
|
||||
else {
|
||||
var host = string.IsNullOrEmpty(_host) ? args.First() : _host;
|
||||
if (string.IsNullOrEmpty(_logfile) && File.Exists(_logfile)) {
|
||||
ScriptClient.start(host, File.OpenRead(_logfile));
|
||||
if (string.IsNullOrEmpty(o.file) && File.Exists(o.file)) {
|
||||
ScriptClient.start(o.host, File.OpenRead(o.file));
|
||||
}
|
||||
else {
|
||||
ScriptClient.start(host, Console.OpenStandardInput());
|
||||
ScriptClient.start(o.host, Console.OpenStandardInput());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using bts.api.core;
|
||||
using bts.test;
|
||||
using ManyConsole;
|
||||
using CommandLine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -8,26 +8,44 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bts {
|
||||
class TailService : ConsoleCommand {
|
||||
|
||||
enum PrintFormat {
|
||||
ToString,
|
||||
Json
|
||||
}
|
||||
[Verb("tail", HelpText="'console dsqa'")]
|
||||
class TailServiceOptions {
|
||||
[Option('m', "method", Required=true, HelpText = "'[ServiceName].[Method]' to call")]
|
||||
public string method { get;set; }
|
||||
|
||||
[Option('t', "time", HelpText="Include timestamp")]
|
||||
public bool time { get; set; }
|
||||
|
||||
[Option('p', "path", HelpText="Path inside the row to use for display. Ex: 'Id' or 'Name' ")]
|
||||
public string path { get; set; }
|
||||
|
||||
[Option('a', "all", HelpText="Include 'all' rows on every print")]
|
||||
public bool all { get; set; }
|
||||
|
||||
[Option('j', "json", HelpText="Format rows as json")]
|
||||
public bool json { get; set; }
|
||||
}
|
||||
class TailService {
|
||||
static bool _all = false;
|
||||
static PrintFormat _format = PrintFormat.ToString;
|
||||
|
||||
static bool _timestamp = false;
|
||||
public TailService() {
|
||||
void ignore(string _) { }
|
||||
IsCommand("tailservice", "Tail updates to named service api. Ex: tail --method=SyntheticSecurityService.metadata");
|
||||
HasRequiredOption("method", "Service.method to tail", ignore);
|
||||
HasOption("time", "Include timestamp", _ => _timestamp = true);
|
||||
// The following are not implemented. If you need them get to work.
|
||||
HasOption("path", "Path inside the row to use for display. Ex: 'Id' or 'Name' ", ignore);
|
||||
HasOption("all", "Invlude 'all' rows on every print", _ => _all = true);
|
||||
HasAdditionalArguments(null, " [nothing]");
|
||||
}
|
||||
public override int Run(string[] remainingArguments) {
|
||||
var arg = this.get_argument("method");
|
||||
var split = arg.Split('.');
|
||||
public static int Run(TailServiceOptions o) {
|
||||
var split = o.method.Split('.');
|
||||
if (split.Length != 2) {
|
||||
Console.WriteLine("Try --method=[ServiceName].[Method]");
|
||||
Console.WriteLine("Try --method [ServiceName].[Method]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (o.json) {
|
||||
_format = PrintFormat.Json;
|
||||
}
|
||||
|
||||
tail(split[0], split[1]);
|
||||
return 0;
|
||||
}
|
||||
@@ -46,7 +64,17 @@ namespace bts {
|
||||
Console.Write(" ");
|
||||
}
|
||||
if (_all) { }
|
||||
Console.WriteLine(value);
|
||||
|
||||
switch(_format) {
|
||||
case PrintFormat.Json:
|
||||
dynamic dv = value;
|
||||
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { dv.added, dv.removed, dv.changed });
|
||||
Console.WriteLine(json);
|
||||
break;
|
||||
case PrintFormat.ToString:
|
||||
Console.WriteLine(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void tail(string service_name, string method_name) {
|
||||
|
||||
@@ -2,35 +2,74 @@ using bts.api;
|
||||
using bts.api.core;
|
||||
using bts.api.synthetic;
|
||||
using bts.test;
|
||||
using ManyConsole;
|
||||
using bts.md;
|
||||
using CommandLine;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace bts {
|
||||
public class ServiceTest : ConsoleCommand {
|
||||
bool _synthetic;
|
||||
bool _user;
|
||||
bool _admin;
|
||||
|
||||
public ServiceTest() {
|
||||
IsCommand("service", "Put code here for testing during service development");
|
||||
HasOption("synthetic", "Run synthetic test", _ => _synthetic = true);
|
||||
HasOption("user", "user test", _ => _user = true);
|
||||
HasOption("admin", "admin test", _ => _admin = true);
|
||||
}
|
||||
public override int Run(string[] remainingArguments) {
|
||||
if (_synthetic) {
|
||||
public class ServiceTestOptions {
|
||||
[Option(nameof(synthetic))]
|
||||
public bool synthetic { get; set; }
|
||||
[Option(nameof(user))]
|
||||
public bool user { get; set; }
|
||||
[Option(nameof(admin))]
|
||||
public bool admin { get; set; }
|
||||
|
||||
[Option(nameof(mbo))]
|
||||
public bool mbo { get; set; }
|
||||
|
||||
[Option("key")]
|
||||
public UInt32 key { get; set; }
|
||||
|
||||
[Option("side")]
|
||||
public api.Side side { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceTest {
|
||||
public static int Run(ServiceTestOptions o) {
|
||||
if (o.synthetic) {
|
||||
synthetic_test();
|
||||
}
|
||||
if (_user) {
|
||||
if (o.user) {
|
||||
user_test();
|
||||
}
|
||||
if (_admin) {
|
||||
if (o.admin) {
|
||||
admin_test();
|
||||
}
|
||||
if (o.mbo) {
|
||||
mbo_test(o);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static string try_get(string[] args, int index) {
|
||||
if (args.Length < index) {
|
||||
return args[index];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static void mbo_test(ServiceTestOptions o) {
|
||||
var key = o.key;
|
||||
var side = o.side;
|
||||
using (var ctx = new ServiceContext()) {
|
||||
var mbo = ctx.locate<MBOService>();
|
||||
var data = mbo.get_orders_for_security(new MBOSecurityQuery { SecurityId = key });
|
||||
|
||||
Console.WriteLine($"Order data for {data.SecurityId}");
|
||||
var vector = side == api.Side.Buy ? data.Bid : data.Ask;
|
||||
var price = 0.0;
|
||||
foreach(var e in vector) {
|
||||
if (e.Price != price) {
|
||||
price = e.Price;
|
||||
Console.WriteLine("================");
|
||||
}
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void synthetic_test() {
|
||||
using (var ctx = new ServiceContext()) {
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using ManyConsole;
|
||||
using System.Reflection;
|
||||
using CommandLine;
|
||||
|
||||
namespace bts {
|
||||
|
||||
public class SettinsManagerCommand : ConsoleCommand {
|
||||
public SettinsManagerCommand() {
|
||||
IsCommand("SettingsManager", "Copy workspaces around");
|
||||
}
|
||||
[Verb("settingsmanager", HelpText="Copy workspaces around")]
|
||||
public class SettingsManagerOptions { }
|
||||
|
||||
public override int Run(string[] remainingArguments) {
|
||||
public class SettingsManagerCommand {
|
||||
public static int Run(SettingsManagerOptions _) {
|
||||
var asm = Assembly.Load("spark");
|
||||
var type = asm.GetType("bts.settings.SettingsManagerTool");
|
||||
var run = type.GetMethod("run", BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
using bts.test;
|
||||
using ManyConsole;
|
||||
using System;
|
||||
using mbts;
|
||||
using System.Collections.Generic;
|
||||
@@ -8,64 +7,73 @@ using bts.api.test;
|
||||
using System.Threading.Tasks;
|
||||
using mbts.config;
|
||||
using System.Linq;
|
||||
using CommandLine;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace sparkcmd {
|
||||
public class TestCommand : ConsoleCommand {
|
||||
uint _timeout = 0;
|
||||
uint _parallel = 1;
|
||||
bool _list;
|
||||
|
||||
TestType test_type = TestType.Unit;
|
||||
[Verb("test", HelpText="Run Tests")]
|
||||
public class TestCommandOptions {
|
||||
|
||||
bool self_contained = false;
|
||||
[Option('t', "timeout", HelpText="Timeout unit tets", Default=0u)]
|
||||
public uint timeout { get; set; }
|
||||
[Option('l', "list", HelpText="List tests")]
|
||||
public bool list { get; set; }
|
||||
[Option('i', "insular", HelpText="Tests run sparkd and use their own config (if specified)")]
|
||||
public bool self_contained { get; set; }
|
||||
|
||||
public TestCommand() {
|
||||
IsCommand("test", "Run managed unit tests");
|
||||
// i comes thorugh as "t" which seems daft.
|
||||
HasOption("t|timeout", "Timeout unit tests", i => _timeout = 10);
|
||||
HasOption<uint>("n|parallel", "How many tests to run in parallel", i => _parallel = i);
|
||||
HasOption("l|list", "List all tests", _ => _list = true);
|
||||
HasOption("unit","Run unit tests", _ => test_type = TestType.Unit);
|
||||
HasOption("system","Run system tests", _ => test_type = TestType.System);
|
||||
HasOption("shell","Run shell tests", _ => test_type = TestType.Shell);
|
||||
HasOption("i|insular|selfcontained", "Tests run sparkd and use their own config (if specified)", _ => self_contained = true);
|
||||
HasAdditionalArguments(null, " [Test List]");
|
||||
[Option("type", HelpText ="Run all tests of type [Unit|System|Shell]")]
|
||||
public TestType type { get; set; }
|
||||
|
||||
|
||||
[Value(1, MetaName="Tests", HelpText="Test list")]
|
||||
public IEnumerable<string> tests { get; set; }
|
||||
|
||||
}
|
||||
public static class TestCommand {
|
||||
static TestType test_type(string t) {
|
||||
switch(t.ToLower()) {
|
||||
case "unit": return TestType.Unit;
|
||||
case "system": return TestType.System;
|
||||
case "shell": return TestType.Shell;
|
||||
}
|
||||
return TestType.Unit;
|
||||
}
|
||||
|
||||
public override int Run(string[] tests) {
|
||||
if (_list) {
|
||||
list_tests();
|
||||
public static int Run(TestCommandOptions o) {
|
||||
Console.WriteLine(JsonConvert.SerializeObject(o));
|
||||
|
||||
if (o.list) {
|
||||
list_tests((o.type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Configuration.initialize_for_test();
|
||||
|
||||
if (_timeout == 0 && tests.Length == 1 && !self_contained) {
|
||||
if (o.timeout == 0 && o.tests.Count() == 1 && !o.self_contained) {
|
||||
//System.Threading.Thread.Sleep(5000);
|
||||
using (var trr = new TestResultReceiver(true)) {
|
||||
InProcessTestRunner.run_test_synchronously(tests[0], Enumerator, trr.get_reporter());
|
||||
InProcessTestRunner.run_test_synchronously(o.tests.First(), Enumerator, trr.get_reporter());
|
||||
trr.print_summary();
|
||||
return trr.ErrorCount;
|
||||
}
|
||||
}
|
||||
else if (tests.Length > 0) {
|
||||
return run_tests(Enumerator.match(tests));
|
||||
else if (o.tests.Count() > 0) {
|
||||
return run_tests(o, Enumerator.match(o.tests));
|
||||
}
|
||||
else {
|
||||
return run_tests(Enumerator.get_of_type(test_type));
|
||||
return run_tests(o, Enumerator.get_of_type(o.type));
|
||||
}
|
||||
}
|
||||
|
||||
Lazy<TestEnumerator> _enumerator = new Lazy<TestEnumerator>(() => new TestEnumerator("spark_test"));
|
||||
TestEnumerator Enumerator => _enumerator.Value;
|
||||
static Lazy<TestEnumerator> _enumerator = new Lazy<TestEnumerator>(() => new TestEnumerator("spark_test"));
|
||||
static TestEnumerator Enumerator => _enumerator.Value;
|
||||
|
||||
int run_tests(IEnumerable<TestMethod> tests) {
|
||||
static int run_tests(TestCommandOptions o, IEnumerable<TestMethod> tests) {
|
||||
var runner = new TestRunner();
|
||||
// waits for all child processes to exit or time out
|
||||
return runner.run_tests(tests, _timeout, self_contained);
|
||||
return runner.run_tests(tests, o.timeout, o.self_contained);
|
||||
}
|
||||
|
||||
void list_tests() {
|
||||
static void list_tests(TestType test_type) {
|
||||
Console.WriteLine("All tests: ");
|
||||
foreach (var t in Enumerator.get_groups_of_type(test_type)) {
|
||||
ConsoleEx.WriteLine(t.name, ConsoleColor.Green);
|
||||
|
||||
@@ -2,16 +2,58 @@
|
||||
using bts.api.core;
|
||||
using bts.api.synthetic;
|
||||
using bts.api.test;
|
||||
using ManyConsole;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using CommandLine;
|
||||
using bts;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace sparkcmd {
|
||||
class Program {
|
||||
|
||||
static object option<T>(Func<T, int> run) { return run; }
|
||||
static Type argType(object arg) {
|
||||
return arg.GetType().GetGenericArguments().First();
|
||||
}
|
||||
static int Run(Func<IEnumerable<Error>, int> on_error, params Type[] runners) {
|
||||
var run_methods =
|
||||
runners
|
||||
.Select(r => r.GetMethod("Run", BindingFlags.Static | BindingFlags.Public))
|
||||
.ToList();
|
||||
var args =
|
||||
run_methods
|
||||
.Select(m => m.GetParameters().First().GetType());
|
||||
|
||||
var parser = Parser.Default.GetType().GetMethod("ParseArguments", new[] { typeof(IEnumerable<string>) });
|
||||
|
||||
//var types = args.Select(argType).ToArray();
|
||||
//var parse = CommandLine.Parser.Default.GetType().GetMethod("ParseArguments", BindingFlags.Public).MakeGenericMethod(types);
|
||||
return 3;
|
||||
}
|
||||
static int Main(string[] args) {
|
||||
mbts.config.Configuration.initialize();
|
||||
var commands = ConsoleCommandDispatcher.FindCommandsInSameAssemblyAs(typeof(Program));
|
||||
return ConsoleCommandDispatcher.DispatchCommand(commands, args, Console.Out);
|
||||
mbts.utils.BTSNativeMethods.provide_command_line(args, args.Length);
|
||||
|
||||
//return Parser.Default
|
||||
//.ParseArguments<ConfigcheckOptions,ScriptClientOptions,TailServiceOptions,ServiceTestOptions,SettingsManagerOptions,TestCommandOptions>(args)
|
||||
//.MapResult<ConfigcheckOptions,ScriptClientOptions,TailServiceOptions,ServiceTestOptions,SettingsManagerOptions,TestCommandOptions,int>(
|
||||
// Configcheck.Run,
|
||||
// ScriptClientCommand.Run,
|
||||
// TailService.Run,
|
||||
// ServiceTest.Run,
|
||||
// SettingsManagerCommand.Run,
|
||||
// TestCommand.Run,
|
||||
// errors => 1);
|
||||
|
||||
return Run(
|
||||
errors => 1,
|
||||
typeof(Configcheck),
|
||||
typeof(ScriptClientCommand),
|
||||
typeof(TailService),
|
||||
typeof(ServiceTest),
|
||||
typeof(SettingsManagerCommand),
|
||||
typeof(TestCommand));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win7-x64;ubuntu.16.04-x64</RuntimeIdentifiers>
|
||||
<Authors>Blue Trading Systems</Authors>
|
||||
<Company>Blue Trading Systems</Company>
|
||||
<Product>Spark</Product>
|
||||
<Platform>x64</Platform>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<Version>1.0.0</Version>
|
||||
<LangVersion>7.2</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../spark_api/spark_api.csproj" />
|
||||
<!--<ProjectReference Include="..\spark\Spark.csproj" />-->
|
||||
<ProjectReference Include="..\spark_core\spark_core.csproj" />
|
||||
<ProjectReference Include="..\spark_test\spark_test.csproj" />
|
||||
<!--<Proto3 Include="**/*.proto" />-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ManyConsole" Version="1.0.0.4" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win7-x64;ubuntu.16.04-x64</RuntimeIdentifiers>
|
||||
<Authors>Blue Trading Systems</Authors>
|
||||
<Company>Blue Trading Systems</Company>
|
||||
<Product>Spark</Product>
|
||||
<Platform>x64</Platform>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<Version>1.0.0</Version>
|
||||
<LangVersion>7.2</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../spark_api/spark_api.csproj" />
|
||||
<!--<ProjectReference Include="..\spark\Spark.csproj" />-->
|
||||
<ProjectReference Include="..\spark_core\spark_core.csproj" />
|
||||
<ProjectReference Include="..\spark_test\spark_test.csproj" />
|
||||
<!--<Proto3 Include="**/*.proto" />-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.4.3" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1 +1 @@
|
||||
set(sources files/Onixs.BTS.lic;files/cert_secure_logon.txt;files/futures.coconut.xz;files/perf_trace/compiled.css;files/perf_trace/index.html;files/perf_trace/jquery-3.3.1.min.js;files/perf_trace/main.js;files/perf_trace/perf_log.sql;files/perf_trace/perf_trace_analysis.sql;files/perf_trace/plotly-latest.min.js)
|
||||
set(sources files/Onixs.BTS.lic;files/cert_secure_logon.txt;files/futures.coconut.xz;files/onixs_ice/ConnectivityConfiguration.APITest.xml;files/onixs_ice/ConnectivityConfiguration.PerfTest.xml;files/onixs_ice/ConnectivityConfiguration.Production.xml;files/perf_trace/compiled.css;files/perf_trace/index.html;files/perf_trace/jquery-3.3.1.min.js;files/perf_trace/main.js;files/perf_trace/perf_log.sql;files/perf_trace/perf_trace_analysis.sql;files/perf_trace/plotly-latest.min.js)
|
||||
@@ -0,0 +1,659 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This file contains the configuration information for various
|
||||
deployment environments. The TCP and Multicast Group addresses are pre-configured
|
||||
so we can choose a configuration during the launch of the multicast client application
|
||||
|
||||
Within the multicast tag, we have different multicast groups named as "ICE Futures US Agricultures" etc.,
|
||||
Each of these groups, then, have information on the context for which the client might be interested in
|
||||
subscribing to. These are under FullOrderDepth/TOP5PL tags. They, in turn, contain the live and
|
||||
snapshot multicast group addresses.
|
||||
-->
|
||||
<connectivityConfiguration>
|
||||
<!-- TCP Connection Information -->
|
||||
|
||||
<tcp>
|
||||
<server name="default">
|
||||
<ip>63.247.113.163</ip>
|
||||
<port>3000</port>
|
||||
<userName>bluetrd-ps</userName>
|
||||
<password>Starts123</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<server name="endex">
|
||||
<ip>63.247.113.77</ip>
|
||||
<port>3000</port>
|
||||
<userName>Value from ICE Support</userName>
|
||||
<password>Value from ICE Support</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<server name="liffe-eu">
|
||||
<ip>63.247.113.229</ip>
|
||||
<port>3000</port>
|
||||
<userName>bluetrdl-ps</userName>
|
||||
<password>Starts123</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<settings>
|
||||
<reconnectTimeoutInSeconds>16</reconnectTimeoutInSeconds>
|
||||
<maximumNumberOfReconnectAttempts>0</maximumNumberOfReconnectAttempts>
|
||||
</settings>
|
||||
</tcp>
|
||||
|
||||
<!-- Multicast Groups Information -->
|
||||
|
||||
<multicast>
|
||||
|
||||
<group name="ICE Endex">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="20163"/>
|
||||
<snapshot ip="233.156.208.232" port="20162"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="20161"/>
|
||||
<snapshot ip="233.156.208.232" port="20160"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21147"/>
|
||||
<snapshot ip="233.156.208.232" port="21146"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21145"/>
|
||||
<snapshot ip="233.156.208.232" port="21144"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Endex Spot">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21151"/>
|
||||
<snapshot ip="233.156.208.232" port="21150"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21149"/>
|
||||
<snapshot ip="233.156.208.232" port="21148"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Agricultures">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.255" port="20255"/>
|
||||
<snapshot ip="233.156.208.254" port="20254"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.253" port="20253"/>
|
||||
<snapshot ip="233.156.208.252" port="20252"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.215" port="20215"/>
|
||||
<snapshot ip="233.156.208.214" port="20214"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.213" port="20213"/>
|
||||
<snapshot ip="233.156.208.212" port="20212"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Financials">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.251" port="20251"/>
|
||||
<snapshot ip="233.156.208.250" port="20250"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.249" port="20249"/>
|
||||
<snapshot ip="233.156.208.248" port="20248"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Non Oil">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.247" port="20247"/>
|
||||
<snapshot ip="233.156.208.246" port="20246"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.245" port="20245"/>
|
||||
<snapshot ip="233.156.208.244" port="20244"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.211" port="20211"/>
|
||||
<snapshot ip="233.156.208.210" port="20210"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.209" port="20209"/>
|
||||
<snapshot ip="233.156.208.208" port="20208"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE OTC">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.243" port="20243"/>
|
||||
<snapshot ip="233.156.208.242" port="20242"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.241" port="20241"/>
|
||||
<snapshot ip="233.156.208.240" port="20240"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.219" port="20219"/>
|
||||
<snapshot ip="233.156.208.218" port="20218"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.217" port="20217"/>
|
||||
<snapshot ip="233.156.208.216" port="20216"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Canada">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.239" port="20239"/>
|
||||
<snapshot ip="233.156.208.238" port="20238"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.237" port="20237"/>
|
||||
<snapshot ip="233.156.208.236" port="20236"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Brent">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.231" port="20231"/>
|
||||
<snapshot ip="233.156.208.230" port="20230"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.229" port="20229"/>
|
||||
<snapshot ip="233.156.208.228" port="20228"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.207" port="20207"/>
|
||||
<snapshot ip="233.156.208.206" port="20206"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.205" port="20205"/>
|
||||
<snapshot ip="233.156.208.204" port="20204"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures WTI">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.227" port="20227"/>
|
||||
<snapshot ip="233.156.208.226" port="20226"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.225" port="20225"/>
|
||||
<snapshot ip="233.156.208.224" port="20224"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.203" port="20203"/>
|
||||
<snapshot ip="233.156.208.202" port="20202"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.201" port="20201"/>
|
||||
<snapshot ip="233.156.208.200" port="20200"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Oil Others">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.223" port="20223"/>
|
||||
<snapshot ip="233.156.208.222" port="20222"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.221" port="20221"/>
|
||||
<snapshot ip="233.156.208.220" port="20220"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.199" port="20199"/>
|
||||
<snapshot ip="233.156.208.198" port="20198"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.197" port="20197"/>
|
||||
<snapshot ip="233.156.208.196" port="20196"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Singapore">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21163"/>
|
||||
<snapshot ip="233.156.208.232" port="21162"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21161"/>
|
||||
<snapshot ip="233.156.208.232" port="21160"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21159"/>
|
||||
<snapshot ip="233.156.208.232" port="21158"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.197" port="21157"/>
|
||||
<snapshot ip="233.156.208.196" port="21156"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="CDS - SWAP Futures">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21167"/>
|
||||
<snapshot ip="233.156.208.232" port="21166"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21165"/>
|
||||
<snapshot ip="233.156.208.232" port="21164"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Russell Cash Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21171"/>
|
||||
<snapshot ip="233.156.208.232" port="21170"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21169"/>
|
||||
<snapshot ip="233.156.208.232" port="21168"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) STIRS Other">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21255"/>
|
||||
<snapshot ip="233.156.208.232" port="21254"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21253"/>
|
||||
<snapshot ip="233.156.208.232" port="21252"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21223"/>
|
||||
<snapshot ip="233.156.208.232" port="21222"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21221"/>
|
||||
<snapshot ip="233.156.208.232" port="21220"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Equity and Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21243"/>
|
||||
<snapshot ip="233.156.208.232" port="21242"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21241"/>
|
||||
<snapshot ip="233.156.208.232" port="21240"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21211"/>
|
||||
<snapshot ip="233.156.208.232" port="21210"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21209"/>
|
||||
<snapshot ip="233.156.208.232" port="21208"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Medium and Long Term IR">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21247"/>
|
||||
<snapshot ip="233.156.208.232" port="21246"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21245"/>
|
||||
<snapshot ip="233.156.208.232" port="21244"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21215"/>
|
||||
<snapshot ip="233.156.208.232" port="21214"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21213"/>
|
||||
<snapshot ip="233.156.208.232" port="21212"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Agricultural">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21239"/>
|
||||
<snapshot ip="233.156.208.232" port="21238"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21237"/>
|
||||
<snapshot ip="233.156.208.232" port="21236"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21207"/>
|
||||
<snapshot ip="233.156.208.232" port="21206"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21205"/>
|
||||
<snapshot ip="233.156.208.232" port="21204"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) GCF and Eurodollar">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21235"/>
|
||||
<snapshot ip="233.156.208.232" port="21234"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21233"/>
|
||||
<snapshot ip="233.156.208.232" port="21232"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21203"/>
|
||||
<snapshot ip="233.156.208.232" port="21202"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21201"/>
|
||||
<snapshot ip="233.156.208.232" port="21200"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Three Month Euro and EONIA">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21251"/>
|
||||
<snapshot ip="233.156.208.232" port="21250"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21249"/>
|
||||
<snapshot ip="233.156.208.232" port="21248"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21219"/>
|
||||
<snapshot ip="233.156.208.232" port="21218"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21217"/>
|
||||
<snapshot ip="233.156.208.232" port="21216"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="IRS - SWAP Futures">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21155"/>
|
||||
<snapshot ip="233.156.208.232" port="21154"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21153"/>
|
||||
<snapshot ip="233.156.208.232" port="21152"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Metals">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21231"/>
|
||||
<snapshot ip="233.156.208.232" port="21230"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21229"/>
|
||||
<snapshot ip="233.156.208.232" port="21228"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="21199"/>
|
||||
<snapshot ip="233.156.208.232" port="21198"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="21197"/>
|
||||
<snapshot ip="233.156.208.232" port="21196"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Equity Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21227"/>
|
||||
<snapshot ip="233.156.208.232" port="21226"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21225"/>
|
||||
<snapshot ip="233.156.208.232" port="21224"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<!-- Options -->
|
||||
|
||||
<group name="ICE Endex Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="20151"/>
|
||||
<snapshot ip="233.156.208.232" port="20150"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.232" port="20159"/>
|
||||
<snapshot ip="233.156.208.232" port="20158"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="20149"/>
|
||||
<snapshot ip="233.156.208.232" port="20148"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.195" port="20195"/>
|
||||
<snapshot ip="233.156.208.194" port="20194"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Canada Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="20153"/>
|
||||
<snapshot ip="233.156.208.232" port="20152"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.185" port="20185"/>
|
||||
<snapshot ip="233.156.208.184" port="20184"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Agricultures Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="20147"/>
|
||||
<snapshot ip="233.156.208.232" port="20146"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.191" port="20191"/>
|
||||
<snapshot ip="233.156.208.190" port="20190"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Financials Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="20145"/>
|
||||
<snapshot ip="233.156.208.232" port="20144"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.193" port="20193"/>
|
||||
<snapshot ip="233.156.208.192" port="20192"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE OTC Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="20143"/>
|
||||
<snapshot ip="233.156.208.232" port="20142"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.187" port="20187"/>
|
||||
<snapshot ip="233.156.208.186" port="20186"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Financial Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="21183"/>
|
||||
<snapshot ip="233.156.208.232" port="21182"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.232" port="21181"/>
|
||||
<snapshot ip="233.156.208.232" port="21180"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Indices Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="21179"/>
|
||||
<snapshot ip="233.156.208.232" port="21178"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.232" port="21177"/>
|
||||
<snapshot ip="233.156.208.232" port="21176"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Equity Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="21175"/>
|
||||
<snapshot ip="233.156.208.232" port="21174"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.232" port="21173"/>
|
||||
<snapshot ip="233.156.208.232" port="21172"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="21187"/>
|
||||
<snapshot ip="233.156.208.232" port="21186"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.232" port="21185"/>
|
||||
<snapshot ip="233.156.208.232" port="21184"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
</multicast>
|
||||
|
||||
<!--
|
||||
List of all market types with their corresponding multicast groups
|
||||
The multicast group name must match what has been specified in the multicast tag
|
||||
More than one market type may be mapped to a multicast group channel
|
||||
Refer to the spec document, Section Appendix C: Supported Market Types
|
||||
-->
|
||||
|
||||
<allMarketTypes>
|
||||
<marketType code="0" multicastGroup="ICE OTC" optionsMulticastGroup="ICE OTC Options">Financial Gas</marketType>
|
||||
<marketType code="1" multicastGroup="ICE OTC">Financial Power</marketType>
|
||||
<marketType code="2" multicastGroup="ICE OTC">Oil</marketType>
|
||||
<marketType code="3" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">IPE Natural Gas Futures</marketType>
|
||||
<marketType code="4" multicastGroup="ICE Futures Europe Oil Others" optionsMulticastGroup="ICE Futures Europe Options">IPE Gas Oil Futures</marketType>
|
||||
<marketType code="5" multicastGroup="ICE Futures Brent" optionsMulticastGroup="ICE Futures Europe Options">IPE Brent Futures</marketType>
|
||||
<marketType code="7" multicastGroup="ICE Futures Europe Non Oil">IPE UK Electricity Futures Peak</marketType>
|
||||
<marketType code="8" multicastGroup="ICE Futures Europe Non Oil">IPE UK Electricity Futures Base</marketType>
|
||||
<marketType code="9" multicastGroup="ICE Futures WTI" optionsMulticastGroup="ICE Futures Europe Options">ICE WTI Crude Futures</marketType>
|
||||
<marketType code="10" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">gC Newcastle Coal Futures</marketType>
|
||||
<marketType code="11" multicastGroup="ICE Futures Europe Oil Others">ICE Brent-WTI Futures Spread</marketType>
|
||||
<marketType code="12" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">IPE-ECX European Emissions</marketType>
|
||||
<marketType code="13" multicastGroup="ICE Futures Europe Oil Others" optionsMulticastGroup="ICE Futures Europe Options">ICE Heating Oil Futures</marketType>
|
||||
<marketType code="14" multicastGroup="ICE Futures Europe Oil Others">ICE Heating Oil/WTI Futures Crack</marketType>
|
||||
<marketType code="15" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE NYH (RBOB) Gasoline Futures</marketType>
|
||||
<marketType code="16" multicastGroup="ICE Futures Europe Non Oil">ICE NYH (RBOB) Gasoline/WTI Futures Crack</marketType>
|
||||
<marketType code="17" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE Rotterdam Coal Futures</marketType>
|
||||
<marketType code="18" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE Richards Bay Coal Futures</marketType>
|
||||
<marketType code="19" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam/Richards Bay Coal Futures Spread</marketType>
|
||||
<marketType code="20" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Cocoa</marketType>
|
||||
<marketType code="21" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Coffee C</marketType>
|
||||
<marketType code="22" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Cotton No 2</marketType>
|
||||
<marketType code="23" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">FCOJ A</marketType>
|
||||
<marketType code="24" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Sugar No 11</marketType>
|
||||
<marketType code="25" multicastGroup="ICE OTC">Heat Rate Spread</marketType>
|
||||
<marketType code="26" multicastGroup="ICE Futures US Financials" optionsMulticastGroup="ICE Futures US Financials Options">US Dollar Index</marketType>
|
||||
<marketType code="31" multicastGroup="ICE Futures Europe Oil Others">ICE Middle East Sour Crude Futures</marketType>
|
||||
<marketType code="32" multicastGroup="ICE Futures Europe Oil Others">ICE Brent/Middle East Crude Futures Spread</marketType>
|
||||
<marketType code="33" multicastGroup="ICE Futures Europe Oil Others">ICE WTI/Middle East Crude Futures Spread</marketType>
|
||||
<marketType code="36" multicastGroup="ICE Futures Canada" optionsMulticastGroup="ICE Futures Canada Options">Canadian Oilseeds</marketType>
|
||||
<marketType code="37" multicastGroup="ICE Futures Canada" optionsMulticastGroup="ICE Futures Canada Options">Canadian Grains</marketType>
|
||||
<marketType code="38" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE ECX CER Futures</marketType>
|
||||
<marketType code="39" multicastGroup="ICE Futures US Financials">Foreign Exchange</marketType>
|
||||
<marketType code="40" multicastGroup="ICE Futures US Financials">Financial Index Data</marketType>
|
||||
<marketType code="41" multicastGroup="ICE Futures US Agricultures">Sugar No 16</marketType>
|
||||
<marketType code="42" multicastGroup="ICE Futures Europe Non Oil">ECX EUA/CER Futures Spread</marketType>
|
||||
<marketType code="44" multicastGroup="ICE OTC" optionsMulticastGroup="ICE OTC Options">Henry Hub</marketType>
|
||||
<marketType code="48" multicastGroup="ICE Endex" optionsMulticastGroup="ICE Endex Options" tcpServer="endex">Dutch TTF Gas Futures</marketType>
|
||||
<marketType code="50" multicastGroup="ICE Endex" tcpServer="endex">German Natural Gas Futures</marketType>
|
||||
<marketType code="51" multicastGroup="ICE Endex" tcpServer="endex">European Gas Spreads</marketType>
|
||||
<marketType code="53" multicastGroup="ICE OTC">Canadian Financial Gas</marketType>
|
||||
<marketType code="54" multicastGroup="ICE OTC">NGX Canadian Physical Crude</marketType>
|
||||
<marketType code="55" multicastGroup="ICE Futures Europe Non Oil">US Coal Futures</marketType>
|
||||
<marketType code="57" multicastGroup="ICE Futures Europe Non Oil">FOB Indo sub-bit Coal Futures</marketType>
|
||||
<marketType code="58" multicastGroup="ICE Futures Europe Oil Others">Heating Oil/Brent Futures Crack</marketType>
|
||||
<marketType code="59" multicastGroup="ICE Futures Europe Oil Others">NYH (RBOB) Gasoline/Brent Futures Crack</marketType>
|
||||
<marketType code="66" multicastGroup="ICE Futures Europe Non Oil">NYH (RBOB) Gasoline/Heating Oil Spread</marketType>
|
||||
<marketType code="69" multicastGroup="ICE OTC">Physical Environmental</marketType>
|
||||
<marketType code="70" multicastGroup="ICE Futures Europe Oil Others">Heating Oil/LS Gasoil Futures Spread</marketType>
|
||||
<marketType code="71" multicastGroup="ICE Futures Europe Oil Others">LS Gasoil/Brent Futures Crack</marketType>
|
||||
<marketType code="72" multicastGroup="ICE Futures Europe Oil Others">NYH (RBOB) Gasoline/LS Gasoil Futures Spread</marketType>
|
||||
<marketType code="84" multicastGroup="ICE Futures Europe Non Oil">ECX EUAA Futures</marketType>
|
||||
<marketType code="85" multicastGroup="ICE Futures Europe Non Oil">ECX CER/EUAA Futures Spread</marketType>
|
||||
<marketType code="86" multicastGroup="ICE Futures Europe Non Oil">ECX EUAA/EUA Futures Spread</marketType>
|
||||
<marketType code="89" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Soybean</marketType>
|
||||
<marketType code="90" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Wheat</marketType>
|
||||
<marketType code="91" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Corn</marketType>
|
||||
<marketType code="97" multicastGroup="ICE Futures Europe Non Oil">CFR South China Coal Futures</marketType>
|
||||
<marketType code="98" multicastGroup="ICE Endex" tcpServer="endex">Belgian Power Futures</marketType>
|
||||
<marketType code="99" multicastGroup="ICE Endex" tcpServer="endex">Dutch Power Futures</marketType>
|
||||
<marketType code="100" multicastGroup="ICE Futures Europe Non Oil">gC Newcastle/FOB Indo sub-bit Coal Futures Spread</marketType>
|
||||
<marketType code="101" multicastGroup="ICE Futures Europe Non Oil">Richards Bay/gC Newcastle Coal Futures Spread</marketType>
|
||||
<marketType code="104" multicastGroup="CDS - SWAP Futures">CIF US</marketType>
|
||||
<marketType code="109" multicastGroup="ICE OTC">Financial Environmental</marketType>
|
||||
<marketType code="111" multicastGroup="ICE Endex" tcpServer="endex">European Power Spreads</marketType>
|
||||
<marketType code="112" multicastGroup="ICE Endex Spot" tcpServer="endex">TAQA</marketType>
|
||||
<marketType code="113" multicastGroup="ICE Endex Spot" tcpServer="endex">Belgian ZTP Gas Spot</marketType>
|
||||
<marketType code="114" multicastGroup="ICE Endex Spot" tcpServer="endex">Dutch TTF Gas Spot</marketType>
|
||||
<marketType code="115" multicastGroup="ICE Endex Spot" tcpServer="endex">Dutch TTF Gas Storage</marketType>
|
||||
<marketType code="116" multicastGroup="ICE Endex Spot" tcpServer="endex">European Gas Spot Spreads</marketType>
|
||||
<marketType code="117" multicastGroup="ICE Endex" tcpServer="endex">Belgian ZTP Gas Futures</marketType>
|
||||
<marketType code="119" multicastGroup="ICE Endex" tcpServer="endex">Belgian Gas Spreads</marketType>
|
||||
<marketType code="122" multicastGroup="ICE Endex" tcpServer="endex">German Power Futures</marketType>
|
||||
<marketType code="123" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">Atlantic Coal Futures</marketType>
|
||||
<marketType code="124" multicastGroup="ICE OTC">Financial Olefins</marketType>
|
||||
<marketType code="125" multicastGroup="ICE OTC">Financial Monomers</marketType>
|
||||
<marketType code="127" multicastGroup="ICE Endex Spot" tcpServer="endex">Endex Spot Market Indices</marketType>
|
||||
<marketType code="128" multicastGroup="ICE Futures US Russell Cash Indices">Russell Cash Indices</marketType>
|
||||
<marketType code="131" multicastGroup="IRS - SWAP Futures" tcpServer="liffe-eu">Interest Rate Futures</marketType>
|
||||
<marketType code="133" multicastGroup="ICE Futures Singapore">Singapore Energy</marketType>
|
||||
<marketType code="134" multicastGroup="ICE Futures Singapore">Singapore Financials</marketType>
|
||||
<marketType code="135" multicastGroup="ICE Futures Singapore">Singapore Metals</marketType>
|
||||
<marketType code="136" multicastGroup="ICE Endex" tcpServer="endex">Italian Natural Gas Futures</marketType>
|
||||
<marketType code="137" multicastGroup="ICE Endex" tcpServer="endex">Italian Power Futures</marketType>
|
||||
<marketType code="138" multicastGroup="ICE Futures US Agricultures">World Cotton</marketType>
|
||||
<marketType code="160" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam/Newcastle Coal Futures Spread</marketType>
|
||||
<marketType code="172" multicastGroup="ICE Futures US Financials" optionsMulticastGroup="ICE Futures US Financials Options">IFUS ICE Indices</marketType>
|
||||
<marketType code="200" multicastGroup="ICE Futures Europe (Liffe) STIRS Other" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe STIRs</marketType>
|
||||
<marketType code="202" multicastGroup="ICE Futures Europe (Liffe) Medium and Long Term IR" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe Bonds</marketType>
|
||||
<marketType code="203" multicastGroup="ICE Futures Europe (Liffe) Medium and Long Term IR" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe Swapnotes</marketType>
|
||||
<marketType code="205" multicastGroup="ICE Futures Europe (Liffe) Agricultural" optionsMulticastGroup="ICE Futures Europe Options" tcpServer="liffe-eu">Liffe Commodities</marketType>
|
||||
<marketType code="206" multicastGroup="ICE Futures US (Liffe) Metals" optionsMulticastGroup="ICE Futures US (Liffe) Options">Metals</marketType>
|
||||
<marketType code="207" multicastGroup="ICE Futures US (Liffe) Equity Indices" optionsMulticastGroup="ICE Futures US (Liffe) Options">IFUS Equity Indices</marketType>
|
||||
<marketType code="208" multicastGroup="ICE Futures Europe (Liffe) GCF and Eurodollar" tcpServer="liffe-eu">GCF Repo</marketType>
|
||||
<marketType code="209" multicastGroup="ICE Futures Europe (Liffe) Three Month Euro and EONIA" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe Three Month Euro and EONIA</marketType>
|
||||
<marketType code="210" multicastGroup="ICE Futures Europe (Liffe) GCF and Eurodollar" tcpServer="liffe-eu">Eurodollar</marketType>
|
||||
<marketType code="211" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Equity Options" tcpServer="liffe-eu">Liffe Equity Derivatives - Non-US Based</marketType>
|
||||
<marketType code="212" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Equity Options" tcpServer="liffe-eu">Liffe Equity Derivatives - US Based</marketType>
|
||||
<marketType code="213" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Indices Options" tcpServer="liffe-eu">Liffe Index Options</marketType>
|
||||
<marketType code="214" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Indices Options" tcpServer="liffe-eu">Liffe Index Futures - US Restricted</marketType>
|
||||
<marketType code="215" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Indices Options" tcpServer="liffe-eu">Liffe Index Futures - Non-US Restricted</marketType>
|
||||
<marketType code="314" multicastGroup="ICE OTC">NGX Physical Gas</marketType>
|
||||
<marketType code="315" multicastGroup="ICE OTC">NGX Financial Power</marketType>
|
||||
<marketType code="317" multicastGroup="ICE OTC">Financial NGL</marketType>
|
||||
<marketType code="318" multicastGroup="ICE OTC">Olefins/Polymers</marketType>
|
||||
</allMarketTypes>
|
||||
|
||||
</connectivityConfiguration>
|
||||
@@ -0,0 +1,364 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This file contains the configuration information for various
|
||||
deployment environments. The TCP and Multicast Group addresses are pre-configured
|
||||
so we can choose a configuration during the launch of the multicast client application
|
||||
|
||||
Within the multicast tag, we have different multicast groups named as "ICE Futures US Agricultures" etc.,
|
||||
Each of these groups, then, have information on the context for which the client might be interested in
|
||||
subscribing to. These are under FullOrderDepth/TOP5PL tags. They, in turn, contain the live and
|
||||
snapshot multicast group addresses.
|
||||
-->
|
||||
<connectivityConfiguration>
|
||||
|
||||
<!-- TCP Connection Information -->
|
||||
|
||||
<tcp>
|
||||
<server name="default">
|
||||
<ip>63.247.113.214</ip>
|
||||
<port>3000</port>
|
||||
<userName>Value from ICE Support</userName>
|
||||
<password>Value from ICE Support</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<settings>
|
||||
<reconnectTimeoutInSeconds>16</reconnectTimeoutInSeconds>
|
||||
<maximumNumberOfReconnectAttempts>0</maximumNumberOfReconnectAttempts>
|
||||
</settings>
|
||||
</tcp>
|
||||
|
||||
<!-- Multicast Groups Information -->
|
||||
|
||||
<multicast>
|
||||
<group name="ICE Futures US Agricultures">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.255" port="30255"/>
|
||||
<snapshot ip="233.156.208.254" port="30254"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.253" port="30253"/>
|
||||
<snapshot ip="233.156.208.252" port="30252"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.215" port="30215"/>
|
||||
<snapshot ip="233.156.208.214" port="30214"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.213" port="30213"/>
|
||||
<snapshot ip="233.156.208.212" port="30212"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Financials">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.251" port="30251"/>
|
||||
<snapshot ip="233.156.208.250" port="30250"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.249" port="30249"/>
|
||||
<snapshot ip="233.156.208.248" port="30248"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Non Oil">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.247" port="30247"/>
|
||||
<snapshot ip="233.156.208.246" port="30246"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.245" port="30245"/>
|
||||
<snapshot ip="233.156.208.244" port="30244"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE OTC">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.243" port="30243"/>
|
||||
<snapshot ip="233.156.208.242" port="30242"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.241" port="30241"/>
|
||||
<snapshot ip="233.156.208.240" port="30240"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.219" port="30219"/>
|
||||
<snapshot ip="233.156.208.218" port="30218"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.217" port="30217"/>
|
||||
<snapshot ip="233.156.208.216" port="30216"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Canada">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.239" port="30239"/>
|
||||
<snapshot ip="233.156.208.238" port="30238"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.237" port="30237"/>
|
||||
<snapshot ip="233.156.208.236" port="30236"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Brent">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.231" port="30231"/>
|
||||
<snapshot ip="233.156.208.230" port="30230"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.229" port="30229"/>
|
||||
<snapshot ip="233.156.208.228" port="30228"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.207" port="30207"/>
|
||||
<snapshot ip="233.156.208.206" port="30206"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.205" port="30205"/>
|
||||
<snapshot ip="233.156.208.204" port="30204"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures WTI">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.227" port="30227"/>
|
||||
<snapshot ip="233.156.208.226" port="30226"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.225" port="30225"/>
|
||||
<snapshot ip="233.156.208.224" port="30224"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.203" port="30203"/>
|
||||
<snapshot ip="233.156.208.202" port="30202"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.201" port="30201"/>
|
||||
<snapshot ip="233.156.208.200" port="30200"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Oil Others">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.223" port="30223"/>
|
||||
<snapshot ip="233.156.208.222" port="30222"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.221" port="30221"/>
|
||||
<snapshot ip="233.156.208.220" port="30220"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.199" port="30199"/>
|
||||
<snapshot ip="233.156.208.198" port="30198"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.197" port="30197"/>
|
||||
<snapshot ip="233.156.208.196" port="30196"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Agricultural">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="31239"/>
|
||||
<snapshot ip="233.156.208.232" port="31238"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="31237"/>
|
||||
<snapshot ip="233.156.208.232" port="31236"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="31207"/>
|
||||
<snapshot ip="233.156.208.232" port="31206"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="31205"/>
|
||||
<snapshot ip="233.156.208.232" port="31204"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) GCF and Eurodollar">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="31235"/>
|
||||
<snapshot ip="233.156.208.232" port="31234"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="31233"/>
|
||||
<snapshot ip="233.156.208.232" port="31232"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="31203"/>
|
||||
<snapshot ip="233.156.208.232" port="31202"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="31201"/>
|
||||
<snapshot ip="233.156.208.232" port="31200"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Metals">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="31231"/>
|
||||
<snapshot ip="233.156.208.232" port="31230"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="31229"/>
|
||||
<snapshot ip="233.156.208.232" port="31228"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.232" port="31199"/>
|
||||
<snapshot ip="233.156.208.232" port="31198"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.232" port="31197"/>
|
||||
<snapshot ip="233.156.208.232" port="31196"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Equity Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="31227"/>
|
||||
<snapshot ip="233.156.208.232" port="31226"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="31225"/>
|
||||
<snapshot ip="233.156.208.232" port="31224"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<!-- Options -->
|
||||
|
||||
<group name="ICE Futures Europe Options">
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.195" port="30195"/>
|
||||
<snapshot ip="233.156.208.194" port="30194"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Financials Options">
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.193" port="30193"/>
|
||||
<snapshot ip="233.156.208.192" port="30192"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Agricultures Options">
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.191" port="30191"/>
|
||||
<snapshot ip="233.156.208.190" port="30190"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE OTC Options">
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.187" port="30187"/>
|
||||
<snapshot ip="233.156.208.186" port="30186"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.232" port="31187"/>
|
||||
<snapshot ip="233.156.208.232" port="31186"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.232" port="31185"/>
|
||||
<snapshot ip="233.156.208.232" port="31184"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
</multicast>
|
||||
|
||||
<!--
|
||||
List of all market types with their corresponding multicast groups
|
||||
The multicast group name must match what has been specified in the multicast tag
|
||||
More than one market type may be mapped to a multicast group channel
|
||||
Refer to the spec document, Section Appendix C: Supported Market Types
|
||||
-->
|
||||
|
||||
<allMarketTypes>
|
||||
<marketType code="0" multicastGroup="ICE OTC" optionsMulticastGroup="ICE OTC Options">Financial Gas</marketType>
|
||||
<marketType code="1" multicastGroup="ICE OTC">Financial Power</marketType>
|
||||
<marketType code="2" multicastGroup="ICE OTC">Oil</marketType>
|
||||
<marketType code="3" multicastGroup="ICE Futures Europe Non Oil">IPE Natural Gas Futures</marketType>
|
||||
<marketType code="4" multicastGroup="ICE Futures Europe Oil Others">IPE Gas Oil Futures</marketType>
|
||||
<marketType code="5" multicastGroup="ICE Futures Brent">IPE Brent Futures</marketType>
|
||||
<marketType code="7" multicastGroup="ICE Futures Europe Non Oil">IPE UK Electricity Futures Peak</marketType>
|
||||
<marketType code="8" multicastGroup="ICE Futures Europe Non Oil">IPE UK Electricity Futures Base</marketType>
|
||||
<marketType code="9" multicastGroup="ICE Futures WTI">ICE WTI Crude Futures</marketType>
|
||||
<marketType code="10" multicastGroup="ICE Futures Europe Non Oil">gC Newcastle Coal Futures</marketType>
|
||||
<marketType code="11" multicastGroup="ICE Futures Europe Oil Others">ICE Brent-WTI Futures Spread</marketType>
|
||||
<marketType code="12" multicastGroup="ICE Futures Europe Non Oil">IPE-ECX European Emissions</marketType>
|
||||
<marketType code="13" multicastGroup="ICE Futures Europe Oil Others">ICE Heating Oil Futures</marketType>
|
||||
<marketType code="14" multicastGroup="ICE Futures Europe Oil Others">ICE Heating Oil/WTI Futures Crack</marketType>
|
||||
<marketType code="15" multicastGroup="ICE Futures Europe Non Oil">ICE NYH (RBOB) Gasoline Futures</marketType>
|
||||
<marketType code="16" multicastGroup="ICE Futures Europe Non Oil">ICE NYH (RBOB) Gasoline/WTI Futures Crack</marketType>
|
||||
<marketType code="17" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam Coal Futures</marketType>
|
||||
<marketType code="18" multicastGroup="ICE Futures Europe Non Oil">ICE Richards Bay Coal Futures</marketType>
|
||||
<marketType code="19" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam/Richards Bay Coal Futures Spread</marketType>
|
||||
<marketType code="20" multicastGroup="ICE Futures US Agricultures">Cocoa</marketType>
|
||||
<marketType code="21" multicastGroup="ICE Futures US Agricultures">Coffee C</marketType>
|
||||
<marketType code="22" multicastGroup="ICE Futures US Agricultures">Cotton No 2</marketType>
|
||||
<marketType code="23" multicastGroup="ICE Futures US Agricultures">FCOJ A</marketType>
|
||||
<marketType code="24" multicastGroup="ICE Futures US Agricultures">Sugar No 11</marketType>
|
||||
<marketType code="25" multicastGroup="ICE OTC">Heat Rate Spread</marketType>
|
||||
<marketType code="26" multicastGroup="ICE Futures US Financials">US Dollar Index</marketType>
|
||||
<marketType code="31" multicastGroup="ICE Futures Europe Oil Others">ICE Middle East Sour Crude Futures</marketType>
|
||||
<marketType code="32" multicastGroup="ICE Futures Europe Oil Others">ICE Brent/Middle East Crude Futures Spread</marketType>
|
||||
<marketType code="33" multicastGroup="ICE Futures Europe Oil Others">ICE WTI/Middle East Crude Futures Spread</marketType>
|
||||
<marketType code="36" multicastGroup="ICE Futures Canada">Canadian Oilseeds</marketType>
|
||||
<marketType code="37" multicastGroup="ICE Futures Canada">Canadian Grains</marketType>
|
||||
<marketType code="38" multicastGroup="ICE Futures Europe Non Oil">ICE ECX CER Futures</marketType>
|
||||
<marketType code="39" multicastGroup="ICE Futures US Financials">Foreign Exchange</marketType>
|
||||
<marketType code="40" multicastGroup="ICE Futures US Financials">Financial Index Data</marketType>
|
||||
<marketType code="41" multicastGroup="ICE Futures US Agricultures">Sugar No 16</marketType>
|
||||
<marketType code="42" multicastGroup="ICE Futures Europe Non Oil">ECX EUA/CER Futures Spread</marketType>
|
||||
<marketType code="44" multicastGroup="ICE OTC" optionsMulticastGroup="ICE OTC Options">Henry Hub</marketType>
|
||||
<marketType code="53" multicastGroup="ICE OTC">Canadian Financial Gas</marketType>
|
||||
<marketType code="54" multicastGroup="ICE OTC">NGX Canadian Physical Crude</marketType>
|
||||
<marketType code="55" multicastGroup="ICE Futures Europe Non Oil">US Coal Futures</marketType>
|
||||
<marketType code="57" multicastGroup="ICE Futures Europe Non Oil">FOB Indo sub-bit Coal Futures</marketType>
|
||||
<marketType code="58" multicastGroup="ICE Futures Europe Oil Others">Heating Oil/Brent Futures Crack</marketType>
|
||||
<marketType code="59" multicastGroup="ICE Futures Europe Oil Others">NYH (RBOB) Gasoline/Brent Futures Crack</marketType>
|
||||
<marketType code="66" multicastGroup="ICE Futures Europe Non Oil">NYH (RBOB) Gasoline/Heating Oil Spread</marketType>
|
||||
<marketType code="69" multicastGroup="ICE OTC">Physical Environmental</marketType>
|
||||
<marketType code="70" multicastGroup="ICE Futures Europe Oil Others">Heating Oil/LS Gasoil Futures Spread</marketType>
|
||||
<marketType code="71" multicastGroup="ICE Futures Europe Oil Others">LS Gasoil/Brent Futures Crack</marketType>
|
||||
<marketType code="72" multicastGroup="ICE Futures Europe Oil Others">NYH (RBOB) Gasoline/LS Gasoil Futures Spread</marketType>
|
||||
<marketType code="84" multicastGroup="ICE Futures Europe Non Oil">ECX EUAA Futures</marketType>
|
||||
<marketType code="85" multicastGroup="ICE Futures Europe Non Oil">ECX CER/EUAA Futures Spread</marketType>
|
||||
<marketType code="86" multicastGroup="ICE Futures Europe Non Oil">ECX EUAA/EUA Futures Spread</marketType>
|
||||
<marketType code="89" multicastGroup="ICE Futures US Agricultures">Soybean</marketType>
|
||||
<marketType code="90" multicastGroup="ICE Futures US Agricultures">Wheat</marketType>
|
||||
<marketType code="91" multicastGroup="ICE Futures US Agricultures">Corn</marketType>
|
||||
<marketType code="97" multicastGroup="ICE Futures Europe Non Oil">CFR South China Coal Futures</marketType>
|
||||
<marketType code="100" multicastGroup="ICE Futures Europe Non Oil">gC Newcastle/FOB Indo sub-bit Coal Futures Spread</marketType>
|
||||
<marketType code="101" multicastGroup="ICE Futures Europe Non Oil">Richards Bay/gC Newcastle Coal Futures Spread</marketType>
|
||||
<marketType code="109" multicastGroup="ICE OTC">Financial Environmental</marketType>
|
||||
<marketType code="123" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">Atlantic Coal Futures</marketType>
|
||||
<marketType code="124" multicastGroup="ICE OTC">Financial Olefins</marketType>
|
||||
<marketType code="125" multicastGroup="ICE OTC">Financial Monomers</marketType>
|
||||
<marketType code="160" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam/Newcastle Coal Futures Spread</marketType>
|
||||
<marketType code="172" multicastGroup="ICE Futures US Financials">IFUS ICE Indices</marketType>
|
||||
<marketType code="205" multicastGroup="ICE Futures Europe (Liffe) Agricultural">Liffe Commodities</marketType>
|
||||
<marketType code="206" multicastGroup="ICE Futures US (Liffe) Metals" optionsMulticastGroup="ICE Futures US (Liffe) Options">Metals</marketType>
|
||||
<marketType code="207" multicastGroup="ICE Futures US (Liffe) Equity Indices" optionsMulticastGroup="ICE Futures US (Liffe) Options">IFUS Equity Indices</marketType>
|
||||
<marketType code="208" multicastGroup="ICE Futures Europe (Liffe) GCF and Eurodollar">GCF Repo</marketType>
|
||||
<marketType code="210" multicastGroup="ICE Futures Europe (Liffe) GCF and Eurodollar">Eurodollar</marketType>
|
||||
<marketType code="314" multicastGroup="ICE OTC">NGX Physical Gas</marketType>
|
||||
<marketType code="315" multicastGroup="ICE OTC">NGX Financial Power</marketType>
|
||||
<marketType code="317" multicastGroup="ICE OTC">Financial NGL</marketType>
|
||||
<marketType code="318" multicastGroup="ICE OTC">Olefins/Polymers</marketType>
|
||||
</allMarketTypes>
|
||||
|
||||
</connectivityConfiguration>
|
||||
@@ -0,0 +1,677 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file contains the configuration information for various
|
||||
deployment environments. The TCP and Multicast Group addresses
|
||||
are pre-configured so we can choose a configuration during the
|
||||
launch of the multicast client application
|
||||
|
||||
Within the multicast tag, we have different multicast groups named
|
||||
as "ICE Futures US Agricultures" etc., Each of these groups, then,
|
||||
have information on the context for which the client might be interested
|
||||
in subscribing to. These are under FullOrderDepth/TOP5PL tags.
|
||||
They, in turn, contain the live and snapshot multicast group addresses.
|
||||
-->
|
||||
<connectivityConfiguration>
|
||||
|
||||
<!-- TCP Connection Information -->
|
||||
|
||||
<tcp>
|
||||
<server name="default">
|
||||
<ip>63.247.112.185</ip>
|
||||
<port>80</port>
|
||||
<userName>Value from ICE Support</userName>
|
||||
<password>Value from ICE Support</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<server name="endex">
|
||||
<ip>63.247.112.190</ip>
|
||||
<port>80</port>
|
||||
<userName>Value from ICE Support</userName>
|
||||
<password>Value from ICE Support</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<server name="liffe-eu">
|
||||
<ip>63.247.125.185</ip>
|
||||
<port>80</port>
|
||||
<userName>Value from ICE Support</userName>
|
||||
<password>Value from ICE Support</password>
|
||||
<getStripInfoMessages>N</getStripInfoMessages>
|
||||
<strategyPreference>Legacy</strategyPreference>
|
||||
<localNetworkInterface></localNetworkInterface>
|
||||
</server>
|
||||
<settings>
|
||||
<reconnectTimeoutInSeconds>16</reconnectTimeoutInSeconds>
|
||||
<maximumNumberOfReconnectAttempts>0</maximumNumberOfReconnectAttempts>
|
||||
</settings>
|
||||
</tcp>
|
||||
|
||||
<!-- Multicast Groups Information -->
|
||||
|
||||
<multicast>
|
||||
|
||||
<group name="ICE Endex">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.100" port="20100"/>
|
||||
<snapshot ip="233.156.208.101" port="20101"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.102" port="20102"/>
|
||||
<snapshot ip="233.156.208.103" port="20103"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.30" port="20030"/>
|
||||
<snapshot ip="224.0.127.30" port="20030"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.31" port="20031"/>
|
||||
<snapshot ip="224.0.127.31" port="20031"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Endex Spot">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.162" port="20162"/>
|
||||
<snapshot ip="233.156.208.163" port="20163"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.164" port="20164"/>
|
||||
<snapshot ip="233.156.208.165" port="20165"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Agricultures">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.0" port="20000"/>
|
||||
<snapshot ip="233.156.208.1" port="20001"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.2" port="20002"/>
|
||||
<snapshot ip="233.156.208.3" port="20003"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.36" port="20036"/>
|
||||
<snapshot ip="233.156.208.37" port="20037"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.38" port="20038"/>
|
||||
<snapshot ip="233.156.208.39" port="20039"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Financials">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.4" port="20004"/>
|
||||
<snapshot ip="233.156.208.5" port="20005"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.6" port="20006"/>
|
||||
<snapshot ip="233.156.208.7" port="20007"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Brent">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.52" port="20052"/>
|
||||
<snapshot ip="233.156.208.53" port="20053"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.54" port="20054"/>
|
||||
<snapshot ip="233.156.208.55" port="20055"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.64" port="20064"/>
|
||||
<snapshot ip="233.156.208.65" port="20065"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.66" port="20066"/>
|
||||
<snapshot ip="233.156.208.67" port="20067"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures WTI">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.56" port="20056"/>
|
||||
<snapshot ip="233.156.208.57" port="20057"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.58" port="20058"/>
|
||||
<snapshot ip="233.156.208.59" port="20059"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.68" port="20068"/>
|
||||
<snapshot ip="233.156.208.69" port="20069"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.70" port="20070"/>
|
||||
<snapshot ip="233.156.208.71" port="20071"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Oil Others">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.60" port="20060"/>
|
||||
<snapshot ip="233.156.208.61" port="20061"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.62" port="20062"/>
|
||||
<snapshot ip="233.156.208.63" port="20063"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.72" port="20072"/>
|
||||
<snapshot ip="233.156.208.73" port="20073"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.74" port="20074"/>
|
||||
<snapshot ip="233.156.208.75" port="20075"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Non Oil">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.12" port="20012"/>
|
||||
<snapshot ip="233.156.208.13" port="20013"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.14" port="20014"/>
|
||||
<snapshot ip="233.156.208.15" port="20015"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.28" port="20028"/>
|
||||
<snapshot ip="233.156.208.29" port="20029"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.30" port="20030"/>
|
||||
<snapshot ip="233.156.208.31" port="20031"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE OTC">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.16" port="20016"/>
|
||||
<snapshot ip="233.156.208.17" port="20017"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.18" port="20018"/>
|
||||
<snapshot ip="233.156.208.19" port="20019"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.32" port="20032"/>
|
||||
<snapshot ip="233.156.208.33" port="20033"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.34" port="20034"/>
|
||||
<snapshot ip="233.156.208.35" port="20035"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Canada">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.20" port="20020"/>
|
||||
<snapshot ip="233.156.208.21" port="20021"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.22" port="20022"/>
|
||||
<snapshot ip="233.156.208.23" port="20023"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Singapore">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.28" port="20028"/>
|
||||
<snapshot ip="224.0.127.28" port="20028"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.29" port="20029"/>
|
||||
<snapshot ip="224.0.127.29" port="20029"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.26" port="20026"/>
|
||||
<snapshot ip="224.0.127.26" port="20026"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.27" port="20027"/>
|
||||
<snapshot ip="224.0.127.27" port="20027"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="CDS - SWAP Futures">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.24" port="20024"/>
|
||||
<snapshot ip="224.0.127.24" port="20024"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.25" port="20025"/>
|
||||
<snapshot ip="224.0.127.25" port="20025"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Russell Cash Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.8" port="20008"/>
|
||||
<snapshot ip="233.156.208.9" port="20009"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.10" port="20010"/>
|
||||
<snapshot ip="233.156.208.11" port="20011"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) STIRS Other">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.0" port="20000"/>
|
||||
<snapshot ip="224.0.127.0" port="20000"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.1" port="20001"/>
|
||||
<snapshot ip="224.0.127.1" port="20001"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.8" port="20008"/>
|
||||
<snapshot ip="224.0.127.8" port="20008"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.9" port="20009"/>
|
||||
<snapshot ip="224.0.127.9" port="20009"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Equity and Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.6" port="20006"/>
|
||||
<snapshot ip="224.0.127.6" port="20006"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.7" port="20007"/>
|
||||
<snapshot ip="224.0.127.7" port="20007"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.14" port="20014"/>
|
||||
<snapshot ip="224.0.127.14" port="20014"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.15" port="20015"/>
|
||||
<snapshot ip="224.0.127.15" port="20015"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Medium and Long Term IR">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.4" port="20004"/>
|
||||
<snapshot ip="224.0.127.4" port="20004"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.5" port="20005"/>
|
||||
<snapshot ip="224.0.127.5" port="20005"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.12" port="20012"/>
|
||||
<snapshot ip="224.0.127.12" port="20012"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.13" port="20013"/>
|
||||
<snapshot ip="224.0.127.13" port="20013"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Equity and Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.232" port="21243"/>
|
||||
<snapshot ip="233.156.208.232" port="21242"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.232" port="21241"/>
|
||||
<snapshot ip="233.156.208.232" port="21240"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.14" port="20014"/>
|
||||
<snapshot ip="224.0.127.14" port="20014"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.15" port="20015"/>
|
||||
<snapshot ip="224.0.127.15" port="20015"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Agricultural">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.138" port="20138"/>
|
||||
<snapshot ip="233.156.208.139" port="20139"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.140" port="20138"/>
|
||||
<snapshot ip="233.156.208.141" port="20139"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.146" port="20146"/>
|
||||
<snapshot ip="233.156.208.147" port="20147"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.148" port="20148"/>
|
||||
<snapshot ip="233.156.208.149" port="20149"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) GCF and Eurodollar">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.142" port="20142"/>
|
||||
<snapshot ip="233.156.208.143" port="20143"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.144" port="20144"/>
|
||||
<snapshot ip="233.156.208.145" port="20145"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.150" port="20150"/>
|
||||
<snapshot ip="233.156.208.151" port="20151"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.152" port="20152"/>
|
||||
<snapshot ip="233.156.208.153" port="20153"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Three Month Euro and EONIA">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.2" port="20002"/>
|
||||
<snapshot ip="224.0.127.2" port="20002"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.3" port="20003"/>
|
||||
<snapshot ip="224.0.127.3" port="20003"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="224.0.126.10" port="20010"/>
|
||||
<snapshot ip="224.0.127.10" port="20010"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="224.0.126.11" port="20011"/>
|
||||
<snapshot ip="224.0.127.11" port="20011"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="IRS - SWAP Futures">
|
||||
<fullOrderDepth>
|
||||
<live ip="224.0.126.22" port="20022"/>
|
||||
<snapshot ip="224.0.127.22" port="20022"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="224.0.126.23" port="20023"/>
|
||||
<snapshot ip="224.0.127.23" port="20023"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Metals">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.118" port="20118"/>
|
||||
<snapshot ip="233.156.208.119" port="20119"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.120" port="20120"/>
|
||||
<snapshot ip="233.156.208.121" port="20121"/>
|
||||
</top5pl>
|
||||
|
||||
<fullOrderDepth implied="true">
|
||||
<live ip="233.156.208.126" port="20126"/>
|
||||
<snapshot ip="233.156.208.127" port="20127"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl implied="true">
|
||||
<live ip="233.156.208.128" port="20128"/>
|
||||
<snapshot ip="233.156.208.129" port="20129"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Equity Indices">
|
||||
<fullOrderDepth>
|
||||
<live ip="233.156.208.122" port="20122"/>
|
||||
<snapshot ip="233.156.208.123" port="20123"/>
|
||||
</fullOrderDepth>
|
||||
<top5pl>
|
||||
<live ip="233.156.208.124" port="20124"/>
|
||||
<snapshot ip="233.156.208.125" port="20125"/>
|
||||
</top5pl>
|
||||
</group>
|
||||
|
||||
<!-- Options -->
|
||||
|
||||
<group name="ICE Endex Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.116" port="20116"/>
|
||||
<snapshot ip="233.156.208.117" port="20117"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.104" port="20104"/>
|
||||
<snapshot ip="233.156.208.105" port="20105"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.110" port="20110"/>
|
||||
<snapshot ip="233.156.208.111" port="20111"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.40" port="20040"/>
|
||||
<snapshot ip="233.156.208.41" port="20041"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Canada Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.112" port="20112"/>
|
||||
<snapshot ip="233.156.208.113" port="20113"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.46" port="20046"/>
|
||||
<snapshot ip="233.156.208.47" port="20046"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Agricultures Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.106" port="20106"/>
|
||||
<snapshot ip="233.156.208.107" port="20107"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.42" port="20042"/>
|
||||
<snapshot ip="233.156.208.43" port="20043"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US Financials Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.108" port="20108"/>
|
||||
<snapshot ip="233.156.208.109" port="20109"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.44" port="20044"/>
|
||||
<snapshot ip="233.156.208.45" port="20045"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE OTC Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.114" port="20114"/>
|
||||
<snapshot ip="233.156.208.115" port="20115"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.78" port="20078"/>
|
||||
<snapshot ip="233.156.208.79" port="20079"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Financial Options">
|
||||
<top10pl>
|
||||
<live ip="224.0.126.17" port="20017"/>
|
||||
<snapshot ip="224.0.127.17" port="20017"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="224.0.126.16" port="20016"/>
|
||||
<snapshot ip="224.0.127.16" port="20016"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Index Options">
|
||||
<top10pl>
|
||||
<live ip="224.0.126.19" port="20019"/>
|
||||
<snapshot ip="224.0.127.19" port="20019"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="224.0.126.18" port="20018"/>
|
||||
<snapshot ip="224.0.127.18" port="20018"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures Europe (Liffe) Equity Options">
|
||||
<top10pl>
|
||||
<live ip="224.0.126.21" port="20021"/>
|
||||
<snapshot ip="224.0.127.21" port="20021"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="224.0.126.20" port="20020"/>
|
||||
<snapshot ip="224.0.127.20" port="20020"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
<group name="ICE Futures US (Liffe) Options">
|
||||
<top10pl>
|
||||
<live ip="233.156.208.134" port="20134"/>
|
||||
<snapshot ip="233.156.208.135" port="20135"/>
|
||||
</top10pl>
|
||||
<topOfBook>
|
||||
<live ip="233.156.208.136" port="20136"/>
|
||||
<snapshot ip="233.156.208.137" port="20137"/>
|
||||
</topOfBook>
|
||||
</group>
|
||||
|
||||
</multicast>
|
||||
|
||||
<!--
|
||||
List of all market types with their corresponding multicast groups
|
||||
The multicast group name must match what has been specified in the multicast tag
|
||||
More than one market type may be mapped to a multicast group channel
|
||||
Refer to the spec document, Section Appendix C: Supported Market Types
|
||||
-->
|
||||
|
||||
<allMarketTypes>
|
||||
<marketType code="0" multicastGroup="ICE OTC" optionsMulticastGroup="ICE OTC Options">Financial Gas</marketType>
|
||||
<marketType code="1" multicastGroup="ICE OTC">Financial Power</marketType>
|
||||
<marketType code="2" multicastGroup="ICE OTC">Oil</marketType>
|
||||
<marketType code="3" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">IPE Natural Gas Futures</marketType>
|
||||
<marketType code="4" multicastGroup="ICE Futures Europe Oil Others" optionsMulticastGroup="ICE Futures Europe Options">IPE Gas Oil Futures</marketType>
|
||||
<marketType code="5" multicastGroup="ICE Futures Brent" optionsMulticastGroup="ICE Futures Europe Options">IPE Brent Futures</marketType>
|
||||
<marketType code="7" multicastGroup="ICE Futures Europe Non Oil">IPE UK Electricity Futures Peak</marketType>
|
||||
<marketType code="8" multicastGroup="ICE Futures Europe Non Oil">IPE UK Electricity Futures Base</marketType>
|
||||
<marketType code="9" multicastGroup="ICE Futures WTI" optionsMulticastGroup="ICE Futures Europe Options">ICE WTI Crude Futures</marketType>
|
||||
<marketType code="10" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">gC Newcastle Coal Futures</marketType>
|
||||
<marketType code="11" multicastGroup="ICE Futures Europe Oil Others">ICE Brent-WTI Futures Spread</marketType>
|
||||
<marketType code="12" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">IPE-ECX European Emissions</marketType>
|
||||
<marketType code="13" multicastGroup="ICE Futures Europe Oil Others" optionsMulticastGroup="ICE Futures Europe Options">ICE Heating Oil Futures</marketType>
|
||||
<marketType code="14" multicastGroup="ICE Futures Europe Oil Others">ICE Heating Oil/WTI Futures Crack</marketType>
|
||||
<marketType code="15" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE NYH (RBOB) Gasoline Futures</marketType>
|
||||
<marketType code="16" multicastGroup="ICE Futures Europe Non Oil">ICE NYH (RBOB) Gasoline/WTI Futures Crack</marketType>
|
||||
<marketType code="17" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE Rotterdam Coal Futures</marketType>
|
||||
<marketType code="18" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE Richards Bay Coal Futures</marketType>
|
||||
<marketType code="19" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam/Richards Bay Coal Futures Spread</marketType>
|
||||
<marketType code="20" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Cocoa</marketType>
|
||||
<marketType code="21" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Coffee C</marketType>
|
||||
<marketType code="22" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Cotton No 2</marketType>
|
||||
<marketType code="23" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">FCOJ A</marketType>
|
||||
<marketType code="24" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Sugar No 11</marketType>
|
||||
<marketType code="25" multicastGroup="ICE OTC">Heat Rate Spread</marketType>
|
||||
<marketType code="26" multicastGroup="ICE Futures US Financials" optionsMulticastGroup="ICE Futures US Financials Options">US Dollar Index</marketType>
|
||||
<marketType code="31" multicastGroup="ICE Futures Europe Oil Others">ICE Middle East Sour Crude Futures</marketType>
|
||||
<marketType code="32" multicastGroup="ICE Futures Europe Oil Others">ICE Brent/Middle East Crude Futures Spread</marketType>
|
||||
<marketType code="33" multicastGroup="ICE Futures Europe Oil Others">ICE WTI/Middle East Crude Futures Spread</marketType>
|
||||
<marketType code="36" multicastGroup="ICE Futures Canada" optionsMulticastGroup="ICE Futures Canada Options">Canadian Oilseeds</marketType>
|
||||
<marketType code="37" multicastGroup="ICE Futures Canada" optionsMulticastGroup="ICE Futures Canada Options">Canadian Grains</marketType>
|
||||
<marketType code="38" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">ICE ECX CER Futures</marketType>
|
||||
<marketType code="39" multicastGroup="ICE Futures US Financials">Foreign Exchange</marketType>
|
||||
<marketType code="40" multicastGroup="ICE Futures US Financials">Financial Index Data</marketType>
|
||||
<marketType code="41" multicastGroup="ICE Futures US Agricultures">Sugar No 16</marketType>
|
||||
<marketType code="42" multicastGroup="ICE Futures Europe Non Oil">ECX EUA/CER Futures Spread</marketType>
|
||||
<marketType code="44" multicastGroup="ICE OTC" optionsMulticastGroup="ICE OTC Options">Henry Hub</marketType>
|
||||
<marketType code="48" multicastGroup="ICE Endex" optionsMulticastGroup="ICE Endex Options" tcpServer="endex">Dutch TTF Gas Futures</marketType>
|
||||
<marketType code="50" multicastGroup="ICE Endex" tcpServer="endex">German Natural Gas Futures</marketType>
|
||||
<marketType code="51" multicastGroup="ICE Endex" tcpServer="endex">European Gas Spreads</marketType>
|
||||
<marketType code="53" multicastGroup="ICE OTC">Canadian Financial Gas</marketType>
|
||||
<marketType code="54" multicastGroup="ICE OTC">NGX Canadian Physical Crude</marketType>
|
||||
<marketType code="55" multicastGroup="ICE Futures Europe Non Oil">US Coal Futures</marketType>
|
||||
<marketType code="57" multicastGroup="ICE Futures Europe Non Oil">FOB Indo sub-bit Coal Futures</marketType>
|
||||
<marketType code="58" multicastGroup="ICE Futures Europe Oil Others">Heating Oil/Brent Futures Crack</marketType>
|
||||
<marketType code="59" multicastGroup="ICE Futures Europe Oil Others">NYH (RBOB) Gasoline/Brent Futures Crack</marketType>
|
||||
<marketType code="66" multicastGroup="ICE Futures Europe Non Oil">NYH (RBOB) Gasoline/Heating Oil Spread</marketType>
|
||||
<marketType code="69" multicastGroup="ICE OTC">Physical Environmental</marketType>
|
||||
<marketType code="70" multicastGroup="ICE Futures Europe Oil Others">Heating Oil/LS Gasoil Futures Spread</marketType>
|
||||
<marketType code="71" multicastGroup="ICE Futures Europe Oil Others">LS Gasoil/Brent Futures Crack</marketType>
|
||||
<marketType code="72" multicastGroup="ICE Futures Europe Oil Others">NYH (RBOB) Gasoline/LS Gasoil Futures Spread</marketType>
|
||||
<marketType code="84" multicastGroup="ICE Futures Europe Non Oil">ECX EUAA Futures</marketType>
|
||||
<marketType code="85" multicastGroup="ICE Futures Europe Non Oil">ECX CER/EUAA Futures Spread</marketType>
|
||||
<marketType code="86" multicastGroup="ICE Futures Europe Non Oil">ECX EUAA/EUA Futures Spread</marketType>
|
||||
<marketType code="89" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Soybean</marketType>
|
||||
<marketType code="90" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Wheat</marketType>
|
||||
<marketType code="91" multicastGroup="ICE Futures US Agricultures" optionsMulticastGroup="ICE Futures US Agricultures Options">Corn</marketType>
|
||||
<marketType code="97" multicastGroup="ICE Futures Europe Non Oil">CFR South China Coal Futures</marketType>
|
||||
<marketType code="98" multicastGroup="ICE Endex" tcpServer="endex">Belgian Power Futures</marketType>
|
||||
<marketType code="99" multicastGroup="ICE Endex" tcpServer="endex">Dutch Power Futures</marketType>
|
||||
<marketType code="100" multicastGroup="ICE Futures Europe Non Oil">gC Newcastle/FOB Indo sub-bit Coal Futures Spread</marketType>
|
||||
<marketType code="101" multicastGroup="ICE Futures Europe Non Oil">Richards Bay/gC Newcastle Coal Futures Spread</marketType>
|
||||
<marketType code="104" multicastGroup="CDS - SWAP Futures">CIF US</marketType>
|
||||
<marketType code="109" multicastGroup="ICE OTC">Financial Environmental</marketType>
|
||||
<marketType code="111" multicastGroup="ICE Endex" tcpServer="endex">European Power Spreads</marketType>
|
||||
<marketType code="112" multicastGroup="ICE Endex Spot" tcpServer="endex">TAQA</marketType>
|
||||
<marketType code="113" multicastGroup="ICE Endex Spot" tcpServer="endex">Belgian ZTP Gas Spot</marketType>
|
||||
<marketType code="114" multicastGroup="ICE Endex Spot" tcpServer="endex">Dutch TTF Gas Spot</marketType>
|
||||
<marketType code="115" multicastGroup="ICE Endex Spot" tcpServer="endex">Dutch TTF Gas Storage</marketType>
|
||||
<marketType code="116" multicastGroup="ICE Endex Spot" tcpServer="endex">European Gas Spot Spreads</marketType>
|
||||
<marketType code="117" multicastGroup="ICE Endex" tcpServer="endex">Belgian ZTP Gas Futures</marketType>
|
||||
<marketType code="119" multicastGroup="ICE Endex" tcpServer="endex">Belgian Gas Spreads</marketType>
|
||||
<marketType code="122" multicastGroup="ICE Endex" tcpServer="endex">German Power Futures</marketType>
|
||||
<marketType code="123" multicastGroup="ICE Futures Europe Non Oil" optionsMulticastGroup="ICE Futures Europe Options">Atlantic Coal Futures</marketType>
|
||||
<marketType code="124" multicastGroup="ICE OTC">Financial Olefins</marketType>
|
||||
<marketType code="125" multicastGroup="ICE OTC">Financial Monomers</marketType>
|
||||
<marketType code="128" multicastGroup="ICE Futures US Russell Cash Indices">Russell Cash Indices</marketType>
|
||||
<marketType code="131" multicastGroup="IRS - SWAP Futures" tcpServer="liffe-eu">Interest Rate Futures</marketType>
|
||||
<marketType code="136" multicastGroup="ICE Endex" tcpServer="endex">Italian Natural Gas Futures</marketType>
|
||||
<marketType code="137" multicastGroup="ICE Endex" tcpServer="endex">Italian Power Futures</marketType>
|
||||
<marketType code="160" multicastGroup="ICE Futures Europe Non Oil">ICE Rotterdam/Newcastle Coal Futures Spread</marketType>
|
||||
<marketType code="172" multicastGroup="ICE Futures US Financials" optionsMulticastGroup="ICE Futures US Financials Options">IFUS ICE Indices</marketType>
|
||||
<marketType code="200" multicastGroup="ICE Futures Europe (Liffe) STIRS Other" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe STIRs</marketType>
|
||||
<marketType code="202" multicastGroup="ICE Futures Europe (Liffe) Medium and Long Term IR" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe Bonds</marketType>
|
||||
<marketType code="203" multicastGroup="ICE Futures Europe (Liffe) Medium and Long Term IR" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe Swapnotes</marketType>
|
||||
<marketType code="205" multicastGroup="ICE Futures Europe (Liffe) Agricultural" optionsMulticastGroup="ICE Futures Europe Options" tcpServer="liffe-eu">Liffe Commodities</marketType>
|
||||
<marketType code="206" multicastGroup="ICE Futures US (Liffe) Metals" optionsMulticastGroup="ICE Futures US (Liffe) Options">Metals</marketType>
|
||||
<marketType code="207" multicastGroup="ICE Futures US (Liffe) Equity Indices" optionsMulticastGroup="ICE Futures US (Liffe) Options">IFUS Equity Indices</marketType>
|
||||
<marketType code="208" multicastGroup="ICE Futures Europe (Liffe) GCF and Eurodollar" tcpServer="liffe-eu">GCF Repo</marketType>
|
||||
<marketType code="209" multicastGroup="ICE Futures Europe (Liffe) Three Month Euro and EONIA" optionsMulticastGroup="ICE Futures Europe (Liffe) Financial Options" tcpServer="liffe-eu">Liffe Three Month Euro and EONIA</marketType>
|
||||
<marketType code="210" multicastGroup="ICE Futures Europe (Liffe) GCF and Eurodollar" tcpServer="liffe-eu">Eurodollar</marketType>
|
||||
<marketType code="211" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Equity Options" tcpServer="liffe-eu">Liffe Equity Derivatives - Non-US Based</marketType>
|
||||
<marketType code="212" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Equity Options" tcpServer="liffe-eu">Liffe Equity Derivatives - US Based</marketType>
|
||||
<marketType code="213" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" optionsMulticastGroup="ICE Futures Europe (Liffe) Index Options" tcpServer="liffe-eu">Liffe Index Options</marketType>
|
||||
<marketType code="214" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" tcpServer="liffe-eu">Liffe Index Futures - US Restricted</marketType>
|
||||
<marketType code="215" multicastGroup="ICE Futures Europe (Liffe) Equity and Indices" tcpServer="liffe-eu">Liffe Index Futures - Non-US Restricted</marketType>
|
||||
<marketType code="314" multicastGroup="ICE OTC">NGX Physical Gas</marketType>
|
||||
<marketType code="315" multicastGroup="ICE OTC">NGX Financial Power</marketType>
|
||||
<marketType code="317" multicastGroup="ICE OTC">Financial NGL</marketType>
|
||||
<marketType code="318" multicastGroup="ICE OTC">Olefins/Polymers</marketType>
|
||||
</allMarketTypes>
|
||||
|
||||
</connectivityConfiguration>
|
||||
@@ -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/service_helpers/AlgoServiceUtils.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.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/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/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.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/jetfix.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.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/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityOracle.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;oLine 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/service_helpers/AlgoServiceUtils.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.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/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/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.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/jetfix.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.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/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.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/PrLine truncated
|
||||
@@ -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/service_helpers/AlgoServiceUtils.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.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/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/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.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/jetfix.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.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/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityOracle.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/AuthToken.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/tests/AuthTokenTests.cpp;utils/thread_manager.cpp)
|
||||
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/service_helpers/AlgoServiceUtils.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.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/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/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.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/jetfix.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.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/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.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/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.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/AuthToken.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/tests/AuthTokenTests.cpp;utils/thread_manager.cpp)
|
||||
@@ -141,4 +141,4 @@ if (WIN32)
|
||||
include(${CMAKE_SOURCE_DIR}/tools/vs_filters.cmake)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ void safe_call_subscription_callback(raw_subscription_callback cb, EventType typ
|
||||
if (updates.size() > 0)
|
||||
cb(type, &updates[0], updates.size(), extra);
|
||||
else
|
||||
cb(type, nullptr, updates.size(), extra);
|
||||
cb(type, nullptr, 0, extra);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "ApiException.h"
|
||||
#include "RawUpdate.h"
|
||||
#include "ServiceContext.h"
|
||||
#include "lib/logging/logging.h"
|
||||
|
||||
#include <rxcpp/rx.hpp>
|
||||
#include <functional>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
|
||||
@@ -12,6 +14,17 @@
|
||||
namespace bts {
|
||||
namespace api {
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> deserialize(const char* buffer, size_t length) {
|
||||
google::protobuf::io::ArrayInputStream stream(buffer, length);
|
||||
auto item = std::make_shared<T>();
|
||||
if (item->ParseFromZeroCopyStream(&stream)) {
|
||||
return item;
|
||||
}
|
||||
LOG(Api,Error,"Failed to deserialize proto from api stream. This is likely fatal.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class ClientChannel
|
||||
{
|
||||
int _id;
|
||||
@@ -80,29 +93,29 @@ public:
|
||||
}
|
||||
else {
|
||||
bool first_update = true;
|
||||
auto cb = [observer, first_update](EventType event_type, const StreamUpdate* changes, int change_count) mutable {
|
||||
auto cb = [observer, first_update, method, qualifier](EventType event_type, const StreamUpdate* changes, int change_count) mutable {
|
||||
if (event_type == EventType::TABLE_UPDATED) {
|
||||
std::vector<std::shared_ptr<const T>> added_items;
|
||||
std::vector<std::shared_ptr<const T>> added_items, changed_items;
|
||||
std::vector<int> added_keys,
|
||||
removed_keys;
|
||||
changed_keys,
|
||||
removed_keys;
|
||||
for (size_t x = 0; x < change_count; ++x) {
|
||||
const StreamUpdate& change = changes[x];
|
||||
if (change.type != StreamUpdate::REMOVE) {
|
||||
added_keys.reserve(change_count);
|
||||
added_items.reserve(change_count);
|
||||
added_keys.push_back(change.key);
|
||||
google::protobuf::io::ArrayInputStream stream(change.buffer, change.buffer_len);
|
||||
auto item = std::make_shared<T>();
|
||||
if (item->ParseFromZeroCopyStream(&stream)) {
|
||||
added_items.push_back(move(item));
|
||||
}
|
||||
}
|
||||
if (change.type != StreamUpdate::CREATE) {
|
||||
removed_keys.reserve(change_count);
|
||||
removed_keys.push_back(change.key);
|
||||
switch(change.type) {
|
||||
case StreamUpdate::REMOVE:
|
||||
removed_keys.push_back(change.key);
|
||||
break;
|
||||
case StreamUpdate::REPLACE:
|
||||
changed_items.push_back(deserialize<T>(change.buffer, change.buffer_len));
|
||||
changed_keys.push_back(change.key);
|
||||
break;
|
||||
case StreamUpdate::CREATE:
|
||||
added_items.push_back(deserialize<T>(change.buffer, change.buffer_len));
|
||||
added_keys.push_back(change.key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
observer.on_next(RawUpdate<std::shared_ptr<const T>>(added_items, added_keys, removed_keys));
|
||||
observer.on_next(RawUpdate<std::shared_ptr<const T>>(added_items, added_keys, changed_items, changed_keys, removed_keys));
|
||||
}
|
||||
else if (event_type == EventType::TABLE_CREATED) {
|
||||
if (!first_update) {
|
||||
|
||||
Loaded 100 of 185 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user