Compare commits

..
90 Commits
Author SHA1 Message Date
Pedro Pinto f871dfe142 Merged. 2019-04-01 14:48:40 -04:00
Pedro Pinto d44de204ee Merge remote-tracking branch 'origin/ice_md' 2019-04-01 14:34:32 -04:00
Pedro Pinto 04beea61eb Updated release notes. 2019-04-01 14:34:03 -04:00
Pedro Pinto 2181b92970 Merged 2019-04-01 14:25:48 -04:00
Pedro Pinto 693c730f51 Update release notes. 2019-04-01 14:24:44 -04:00
Kevin Darby 0ccba5bb0b Merged in fix_sim (pull request #202)
RTM: Fix ladder highlighting and aggressor marking in sim

Approved-by: Pedro Pinto <pedro.pinto+atlassian@bluetradesys.com>
2019-04-01 18:24:09 +00:00
Pedro Pinto 3458be59d7 Merge branch 'master' of bitbucket.org:bluetradesys/spark 2019-04-01 14:17:52 -04:00
Pedro Pinto 7dc9aa0710 Uppdate release notes. 2019-04-01 14:17:02 -04:00
Pedro Pinto 88d6dd0f00 Merge remote-tracking branch 'origin/SPARK-2162-notificationservice-cleanup' 2019-04-01 14:11:34 -04:00
Eric Harding ce4c46da04 Add some logging to spark shell shutdown sequence 2019-04-01 14:03:09 -04:00
Pedro Pinto 59c1f6a511 Updated release notes 2019-04-01 12:58:44 -04:00
Pedro Pinto 938caf9a4f Updated release notes. 2019-04-01 12:55:51 -04:00
Pedro Pinto df4f061b6c Merged 2019-04-01 12:47:38 -04:00
Jake Norbut 8afee21df7 hooking up the yes/no filter to the column 2019-04-01 11:21:02 -05:00
Pedro Pinto f34014eb25 Merged SPARK-2198 again 2019-04-01 12:11:58 -04:00
Jake Norbut b07eec08b4 Yes No formatting in row 2019-04-01 10:36:25 -05:00
Pedro Pinto 964274f5c4 Updated release notes. 2019-04-01 10:02:45 -04:00
Pedro Pinto c16941977c Merge remote-tracking branch 'origin/SPARK-2189' 2019-04-01 09:55:38 -04:00
Pedro Pinto 6b19119ab2 Updated release notes 2019-04-01 09:54:11 -04:00
Pedro Pinto ea42086e96 Merge branch 'SPARK-2198' of bitbucket.org:bluetradesys/spark 2019-04-01 09:39:05 -04:00
Pedro Pinto 292873b189 Update release notes. 2019-04-01 09:37:01 -04:00
Pedro Pinto 8545a5ef38 Merge branch 'SPARK-2150' 2019-04-01 09:30:03 -04:00
Pedro Pinto 6a52fff3d5 Updated release notes. 2019-04-01 09:28:33 -04:00
John Colvin 4ec6fafbc2 Merged in SPARK-2160-shell-windows-offscreen (pull request #195)
RTM: SPARK-2160 shell windows come up off screen sometimes

Approved-by: Jake Norbut <jake.norbut@bluetradesys.com>
2019-04-01 13:11:20 +00:00
Pedro Pinto b08e2c2ee6 Updated release notes. 2019-04-01 09:08:58 -04:00
Pedro Pinto 8bdd033501 Merge branch 'Documentation' 2019-04-01 09:04:51 -04:00
Taha Afzal 76466e83f0 changing hedger addiiton log from error to info 2019-03-29 17:26:36 -04:00
Kevin Darby 2540dc0510 ops notes 2019-03-29 15:20:35 -04:00
Kevin Darby f0132c84b6 Merge branch 'master' of bitbucket.org:bluetradesys/spark into fix_sim 2019-03-29 12:57:37 -04:00
Jake Norbut 57ca9596c8 changing column name 2019-03-29 11:05:15 -05:00
Jake Norbut bf4953f6dc adding TradedToday column to pnl 2019-03-29 09:45:32 -05:00
Jake Norbut c277fcd503 adding has_day_trades property 2019-03-29 09:44:55 -05:00
Jake Norbut dff57a43dd Adding TradedToday to Column enum 2019-03-29 09:43:53 -05:00
Jake Norbut 39c71d0c16 adding has day trades field to pnl's FilterState proto 2019-03-29 09:39:21 -05:00
Jake Norbut 009e72953c adding SecurityType default fitler; technical_debt++ 2019-03-28 15:31:56 -05:00
Jake Norbut 635163c895 hiding exch, start pnl, total net pos, and total net pnl by default 2019-03-28 15:03:54 -05:00
Jake Norbut 95e96a6afc remove pnl rows from which there is no net pos or day pos 2019-03-28 13:52:29 -05:00
Kevin Darby c7f0e2dd58 Merge branch 'master' of bitbucket.org:bluetradesys/spark into ice_md 2019-03-26 18:43:38 -04:00
Jake Norbut f5e79a65a3 relocating comment after PR edit 2019-03-26 11:17:37 -05:00
Jake Norbut c958f4bf1a PR suggestion - making row_vm -> communication a bit more flexibile 2019-03-26 11:15:15 -05:00
Eric Harding 95939a5534 SPARK-2087 add GE to default symbol list 2019-03-25 10:22:52 -04:00
Kevin Darby 9a7164b42b Merge branch 'ice_md' of bitbucket.org:bluetradesys/spark into ice_md 2019-03-25 10:10:04 -04:00
Kevin Darby f347fda47f PR details 2019-03-25 10:09:37 -04:00
Kevin Darby d75ab3a63f default to no ice symbols 2019-03-22 23:12:24 -04:00
Kevin Darby b30f59227e note to reference jetfix on the precision 2019-03-22 23:11:01 -04:00
Kevin Darby ef60d4200a Fix ladder highlighting and aggressor marking in sim 2019-03-22 17:56:19 -04:00
Jake Norbut ed6f0b8bdb Merge branch 'master' of bitbucket.org:bluetradesys/spark into SPARK-2150 2019-03-22 15:17:21 -05:00
Jake Norbut 766116eac4 adding confirmation to OB cancel buys and cancel sells 2019-03-22 09:33:49 -05:00
Jake Norbut 8d49de3f61 simplying boolean comparison 2019-03-21 14:31:59 -05:00
Jake Norbut 16cf4554c5 refactoring into a much simpler implementation 2019-03-21 14:24:32 -05:00
Jake Norbut 6b17efee60 Converting cancel all command to new SparkConfirmationCommandParamObserver 2019-03-21 13:44:17 -05:00
Jake Norbut 5d64213455 Adding new SparkConfirmationCommandParamObserver, which adds a confirmation func to SparkCommandParamObserver 2019-03-21 13:40:21 -05:00
John Colvin 0ef44e92aa SPARK-2160 pr edit: refer to 'source_window_rect' for width/height params instead of window (easy way to avoid extra dp lookups) 2019-03-20 10:46:47 -05:00
Kevin Darby ee2f76553b tests pass 2019-03-19 17:54:37 -04:00
Kevin Darby c1887b9786 launch.json 2019-03-19 15:28:11 -04:00
Kevin Darby 1fd5e51b9e reenabled cme, now we can get both ice and cme 2019-03-19 15:23:40 -04:00
John Colvin 56d3a27e7f SPARK-2162 / SPARK-2164 INotificationService - remove fake strongly typed 'link<T>' extension method 2019-03-19 13:12:04 -05:00
John Colvin 1c65b1d87a rename generic type arg 'TPredicateBuilder' -> 'TPredicateData' 2019-03-19 13:00:25 -05:00
John Colvin 693910f093 SPARK-2162 / SPARK-2163 GridSettingsManager/VM - replace IPredicateBuilder dependency with predicate-data factory(delegate) 2019-03-19 12:58:02 -05:00
Kevin Darby 498b38ebcb Merge branch 'master' of bitbucket.org:bluetradesys/spark into ice_md 2019-03-18 16:00:59 -04:00
John Colvin fb91206e0f pr edit: get window dimensions with window.ActualWidth/Height 2019-03-18 13:56:17 -05:00
John Colvin 91f4de00f8 pr edit: should not have changed while-loop to if-condition 2019-03-18 13:54:01 -05:00
John Colvin 28980f10ae SPARK-2160 shell windows come up off screen sometimes 2019-03-18 13:41:29 -05:00
Michael Harding 04e006b812 Add new Spreader and Algo studio videos to the manual 2019-03-15 10:44:58 -04:00
Jake Norbut 5b959ca5bd OB window command update when selected row's row vm changes 2019-03-12 14:39:25 -05:00
Kevin Darby 7ac54242e0 Merge branch 'master' of bitbucket.org:bluetradesys/spark into ice_md 2019-03-08 16:19:04 -05:00
Kevin Darby 1ebf8219c2 ice descriptions in mview 2019-03-08 16:17:53 -05:00
Kevin Darby f0b14cb8dc forgot to init new string fields 2019-03-08 16:10:02 -05:00
Kevin Darby 7259f81ab5 forgot to init new string fields 2019-03-08 16:03:49 -05:00
Kevin Darby 3b902b61dd ice spreads 2019-03-08 15:55:10 -05:00
Kevin Darby 6cfef51e3d subrepo 2019-03-07 18:12:39 -05:00
Kevin Darby 76edb94905 ticks.... 2019-03-07 18:10:11 -05:00
Kevin Darby e4bf9fc747 ice market data 2019-03-07 17:56:28 -05:00
Kevin Darby d488ff23ba I misunderstood how onixs wants to do the ice threading. fixed 2019-03-07 11:38:38 -05:00
Kevin Darby 6b6fd9c40a more ice 2019-03-06 14:58:09 -05:00
Kevin Darby f7265740e7 ICE securities, from the actual ICE 2019-03-05 18:08:20 -05:00
Kevin Darby 724da31316 adding data files 2019-02-28 17:50:46 -05:00
Kevin Darby 2ae5b50445 ice builds with .so 2019-02-28 15:01:35 -05:00
Kevin Darby dfcf38289f move externals up for ice .so 2019-02-28 14:44:13 -05:00
Kevin Darby 1c54b0140b ready to test, but we need to solve a link issue 2019-02-27 16:41:38 -05:00
Kevin Darby e034fd2623 Merge branch 'master' of bitbucket.org:bluetradesys/spark into ice_md 2019-02-26 18:23:23 -05:00
Kevin Darby a3b8d579a1 hooked up all ice callbacks except books 2019-02-26 18:20:22 -05:00
Kevin Darby 9d2cdb702d getting somewhere 2019-02-26 16:00:26 -05:00
Kevin Darby d0784feddd more ice 2019-02-25 10:34:58 -05:00
Kevin Darby 4a64e45d36 translated onixs::Handler settings to our config. 2019-02-15 18:08:26 -05:00
Kevin Darby 97f09768bb got the boilerplate up, now just need to get the right ice handlers and options in there 2019-02-14 17:55:34 -05:00
Kevin Darby 2b4add85a2 kinda copy / pastey stuff from cme 2019-02-12 13:00:47 -05:00
Kevin Darby 4c798f6db4 initial push 2019-02-11 16:14:41 -05:00
Kevin Darby b2e275124f update externals with onixs ice docs 2019-02-11 13:35:14 -05:00
Kevin Darby 36e4f62a53 moved externals pointer forward to capture onixs ice addition 2019-02-11 12:38:00 -05:00
106 changed files with 5670 additions and 451 deletions

No files matched your search

+9 -3
View File
@@ -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",
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
"args": ["test", "[md]"],
"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",
+2
View File
@@ -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"
@@ -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.
+20
View File
@@ -4,6 +4,26 @@ weight = 3
sort_by = "weight"
insert_anchor_links = "right"
+++
## 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
+5
View File
@@ -54,3 +54,8 @@ img {
background: #ccc;
border: 1px solid #aaa;
}
iframe {
width:560px;
height:315px;
}
+3
View File
@@ -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
View File
@@ -66,6 +66,7 @@ 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);
@@ -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.link_to_order,
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 working 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 working 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 working 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,8 +48,8 @@ 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) =>
@@ -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;
@@ -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 -20
View File
@@ -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
@@ -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;
+15 -4
View File
@@ -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) {
@@ -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"
;
}
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}"
@@ -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>
+16 -2
View File
@@ -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();
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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
View File
@@ -1 +1 @@
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/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
View File
@@ -1 +1 @@
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/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/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/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;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)
+1 -1
View File
@@ -141,4 +141,4 @@ if (WIN32)
include(${CMAKE_SOURCE_DIR}/tools/vs_filters.cmake)
endif()
+1 -1
View File
@@ -40,7 +40,7 @@
#include "lib/config_proto_files.h"
#include "lib/config_defaults.h"
using namespace std;
using namespace std;
namespace bts {
namespace config {
+31 -1
View File
@@ -12,6 +12,7 @@ MarketDataConfig {
PlatformMap {
value {
glbx_platform: "PLATFORM_MDP3ONIXS"
ice_platform: "PLATFORM_ICEONIXS"
}
}
@@ -37,6 +38,35 @@ CMEOptions {
}
}
ICEPublisherOptions {
value {
network_interface: "eth1"
}
}
#to make this work in dev clone the operations repo
#go here: c:\\code\\bts\\operations\\ice\\ICE_iMpactMulticastFeed_GettingStarted-1_1_36\\bin\\easyTunnel>
#modify the easyTunnelProxy.properties file to replace
#tunnel.multicast.interface=10.96.18.37 with your local ip
#run easyTunnelProxy.bat BRENT-FI for Brent Full implied
#you should see ice data
ICEOptions {
value {
channel {
name: "oil" #these names are arbitrary and are for debugging
market_type: 5 #ICE Futures Brent, IPE Brent Futures
market_type: 9 #ICE Futures WTI, ICE WTI Crude Futures
#udp_buffer_size: 33554432 #32mb
}
channel {
name: "juice"
market_type: 23 #ICE Futures US Agricultures, FCOJ A
}
ice_config_file: "ConnectivityConfiguration.APITest.xml"
}
}
MDBootDelayWindow {
rule: "DeploymentType.type == 'dev'"
value {
@@ -56,4 +86,4 @@ MDBootDelayWindow {
end: "14:10"
}
}
}
}
+53 -34
View File
@@ -1,37 +1,52 @@
SymbolList {
value {
symbol: "HE"
symbol: "LE"
symbol: "CL"
symbol: "RB"
symbol: "HO"
symbol: "BZ"
symbol: "NG"
symbol: "GC"
symbol: "SI"
symbol: "HG"
symbol: "ZW"
symbol: "ZC"
symbol: "ZS"
symbol: "ZM"
symbol: "ZL"
symbol: "ZO"
symbol: "ZR"
symbol: "ZB"
symbol: "ZN"
symbol: "ZF"
symbol: "ZT"
symbol: "UB"
}
SymbolLists
{
value
{
list
{
key: "ICE"
# symbol: "BRN"
# symbol: "WBS"
# symbol: "OJ"
}
list
{
key: "GLBX"
symbol: "HE"
symbol: "LE"
symbol: "CL"
symbol: "RB"
symbol: "HO"
symbol: "BZ"
symbol: "NG"
symbol: "GC"
symbol: "SI"
symbol: "HG"
symbol: "ZW"
symbol: "ZC"
symbol: "ZS"
symbol: "ZM"
symbol: "ZL"
symbol: "ZO"
symbol: "ZR"
symbol: "ZB"
symbol: "ZN"
symbol: "ZF"
symbol: "ZT"
symbol: "UB"
symbol: "GE"
}
}
}
Symbols {
rule: "DeploymentType.type == 'DEMO' and System.platform == 'windows'"
value {
sim {
future: @SymbolList.symbol
spread: @SymbolList.symbol
future: @SymbolLists.list[GLBX].symbol
spread: @SymbolLists.list[GLBX].symbol
}
}
}
@@ -40,8 +55,8 @@ Symbols {
rule: "DeploymentType.type == 'PROD' and System.platform == 'windows'"
value {
glbx {
future: @SymbolList.symbol
spread: @SymbolList.symbol
future: @SymbolLists.list[GLBX].symbol
spread: @SymbolLists.list[GLBX].symbol
}
}
}
@@ -49,12 +64,16 @@ Symbols {
Symbols {
value {
glbx {
future: @SymbolList.symbol
spread: @SymbolList.symbol
future: @SymbolLists.list[GLBX].symbol
spread: @SymbolLists.list[GLBX].symbol
}
sim {
future: @SymbolList.symbol
spread: @SymbolList.symbol
future: @SymbolLists.list[GLBX].symbol
spread: @SymbolLists.list[GLBX].symbol
}
ice {
future: @SymbolLists.list[ICE].symbol
spread: @SymbolLists.list[ICE].symbol
}
}
}
+53
View File
@@ -13,6 +13,8 @@ message PlatformMap
{
// PLATFORM_MDP3ONIXS
optional string glbx_platform = 1 [default = "PLATFORM_SIM"];
// PLATFORM_ICEONIXS
optional string ice_platform = 2 [default = "PLATFORM_ICEONIXS"];
}
// LOCAL TIME
@@ -52,6 +54,14 @@ message PublisherOptions
optional bool skip_options = 13 [default = true];
}
message ICEPublisherOptions
{
optional string network_interface = 3 [default = "0.0.0.0"];
// Supply either network_interface -or- network_interface_[a,b]
optional string network_interface_a = 30;
optional string network_interface_b = 31;
}
message PlatformConfig
{
required string platform = 1;
@@ -125,6 +135,49 @@ message CMEOptions
optional bool verbose_ticker = 7 [default=false];
}
//
// ICE Options
//
message ICEOptions
{
enum OnixSLogMode {
Fatal = 0;
Error = 1;
Warning = 2;
Info = 3;
Trace = 4;
Debug = 5;
}
//A channel is one onixs-ice thread
message ICEChannel {
required string name = 1;
repeated uint32 market_type = 2;
optional uint32 udp_buffer_size = 3 [default = 4194304]; //4mb
optional uint32 heartbeat_interval = 4 [default = 36000];
optional uint32 sequence_gap_margin = 5 [default = 10000];
optional uint32 gap_timeout_in_ms = 6 [default = 10000];
optional int32 snapshot_recovery_timeout_in_ms = 10 [default = -1];
optional int32 maximum_number_of_snapshot_recovery_attempts = 11 [default = -1];
optional int32 maximum_size_of_snapshot_message_queue = 12 [default = -1];
optional int32 maximum_size_of_live_message_queue = 13 [default = 200000];
optional string processing_thread_affinity = 20 [default = ""];
optional bool track_top_of_the_book_only = 30 [default = false];
optional bool receive_product_definitions_only = 31 [default = false];
optional uint32 max_multicast_message_block_size = 32 [default = 1400];
optional string product_definition_cache_directory = 35 [default = ""];
optional OnixSLogMode onixs_log_mode = 40 [default = Warning];
optional bool load_security_db = 41 [default = true];
}
optional string onixs_license = 1 [default = "{default}"];
optional string ice_config_file = 2 [default = "ConnectivityConfiguration.Production.xml"];
repeated ICEChannel channel = 3;
}
message RecordOptions {
// optional string output_path = 2 [default = "/home/bts/md/today"];
optional bool enable_depth = 3 [default = false];
+1
View File
@@ -19,4 +19,5 @@ message SecurityExchangeList {
message Symbols {
optional SecurityExchangeList glbx = 10;
optional SecurityExchangeList sim = 20;
optional SecurityExchangeList ice = 30;
}
+2
View File
@@ -24,6 +24,8 @@ std::string descriptor(api::Security const&sec)
{
if (sec.has_glbx())
return sec.glbx().security_desc();
else if (sec.has_ice())
return sec.ice().security_desc();
else
return "No descriptor for non glbx exchange";
}
+11
View File
@@ -101,6 +101,17 @@ message CBOECFEExchangeData {
int32 class_key = 30;
}
message ICEExchangeData {
int64 exchange_id = 10;
string security_desc = 15; //contractSymbol
int32 deal_display_factor = 20;
int32 settle_display_factor = 30;
string market_description = 100;
string cleared_alias = 110;
string product_name = 120;
string hub_alias = 130;
string strip_name = 140;
string mic_code = 150;
}
message FutureContract {
+7
View File
@@ -90,6 +90,13 @@ string dump_security(const FixedSecurity& security) {
res << "'low_tick': " << security.low_tick << ", ";
res << "'high_tick': " << security.high_tick << ", ";
res << "'cpp': " << security.cash_per_point << ", ";
res << "'market_description ': " << security.ice_market_description() << ", ";
res << "'cleared_alias ': " << security.ice_cleared_alias() << ", ";
res << "'product_description ': " << security.ice_product_name() << ", ";
res << "'hub_alias ': " << security.ice_hub_alias() << ", ";
res << "'strip_name': " << security.ice_strip_name() << ", ";
res << "'mic_code': " << security.mic_code() << ", ";
switch(security.type) {
case SECURITYTYPE_STOCK: break;
+36 -6
View File
@@ -61,6 +61,10 @@ void PlatformLoader::run() {
switch (_platform) {
case PLATFORM_MDP3ONIXS:
break;
case PLATFORM_MDP3EMUMBA:
break;
case PLATFORM_ICEONIXS:
break;
default:
bts_assert(false);
break;
@@ -86,8 +90,7 @@ void add_symbols_to_result(
size_t get_system_md_symbols(api::Venue exchange, SecurityType type,
std::set<UserSymbol> &result) {
bts_assert(config::system_symbols::Symbols::descriptor()->field_count() ==
2);
bts_assert(config::system_symbols::Symbols::descriptor()->field_count() == 3);
{
auto const &e = config::get<config::system_symbols::Symbols>().glbx();
if (exchange == api::VENUE_UNSET || exchange == api::VENUE_GLBX) {
@@ -118,6 +121,28 @@ size_t get_system_md_symbols(api::Venue exchange, SecurityType type,
}
}
}
{
auto const &e = config::get<config::system_symbols::Symbols>().ice();
if (exchange == api::VENUE_UNSET || exchange == api::VENUE_ICE)
{
if (type == api::SECURITYTYPE_FUTURE || type == api::SECURITYTYPE_UNSET)
add_symbols_to_result(e.future(), api::VENUE_ICE, api::SECURITYTYPE_FUTURE, &result);
if (type == api::SECURITYTYPE_OPTION || type == api::SECURITYTYPE_UNSET)
add_symbols_to_result(e.option(), api::VENUE_ICE, api::SECURITYTYPE_OPTION, &result);
if (type == api::SECURITYTYPE_SPREAD || type == api::SECURITYTYPE_UNSET)
add_symbols_to_result(e.spread(), api::VENUE_ICE, api::SECURITYTYPE_SPREAD, &result);
}
if (exchange == api::VENUE_BTS || exchange == api::VENUE_UNSET)
{
std::set<std::string> all_symbols;
all_symbols.insert(e.future().begin(), e.future().end());
all_symbols.insert(e.option().begin(), e.option().end());
all_symbols.insert(e.spread().begin(), e.spread().end());
for (const auto &symbol : all_symbols)
result.insert(UserSymbol(symbol, api::VENUE_BTS, api::SECURITYTYPE_SYNTHETIC));
}
}
{
auto const &e = config::get<config::system_symbols::Symbols>().sim();
@@ -181,10 +206,15 @@ std::set<UserSymbol> get_system_md_symbols() {
extern "C" BTS_EXPORT Platform platform_for_exchange(Venue v) {
const auto &pmap = config::get<PlatformMap>();
co2::Platform platform;
if (v == VENUE_SIM) return PLATFORM_SIM;
if (co2::Platform_Parse(pmap.glbx_platform(), &platform)) {
return platform;
}
if (v == VENUE_SIM)
return PLATFORM_SIM;
if (v == VENUE_ICE && co2::Platform_Parse(pmap.ice_platform(), &platform))
return platform;
//md2_tests.cpp depends on this fall through to yield SIM as the GLBX platform
if (co2::Platform_Parse(pmap.glbx_platform(), &platform))
return platform;
return PLATFORM_UNSET;
}
+35 -2
View File
@@ -31,6 +31,8 @@ FixedSecurity::FixedSecurity() :
cme_main_fraction(0),
cme_sub_fraction(0),
cme_price_display_format(0),
ice_deal_display_factor(0),
ice_settle_display_factor(0),
_symbol(),
_cfi_code(),
_security_desc(),
@@ -41,6 +43,13 @@ FixedSecurity::FixedSecurity() :
memset(_cfi_code, 0, BTS_ARRAYSIZE(_cfi_code));
memset(_security_desc, 0, BTS_ARRAYSIZE(_security_desc));
memset(_platform_id, 0, BTS_ARRAYSIZE(_platform_id));
memset(_ice_market_description, 0, BTS_ARRAYSIZE(_ice_market_description));
memset(_ice_cleared_alias, 0, BTS_ARRAYSIZE(_ice_cleared_alias));
memset(_ice_product_name, 0, BTS_ARRAYSIZE(_ice_product_name));
memset(_ice_hub_alias, 0, BTS_ARRAYSIZE(_ice_hub_alias));
memset(_ice_strip_name, 0, BTS_ARRAYSIZE(_ice_strip_name));
memset(_mic_code, 0, BTS_ARRAYSIZE(_mic_code));
}
FixedSecurity::~FixedSecurity(){}
@@ -169,6 +178,19 @@ void convert_security(const FixedSecurity& source, Security* presult) {
dest.mutable_glbx()->set_cme_symbol(source.alt_symbol());
if (source.cme_market_segment_id != 0) dest.mutable_glbx()->set_market_segment_id(source.cme_market_segment_id);
break;
case Venue::VENUE_ICE:
dest.mutable_ice()->set_exchange_id(source.numeric_id);
dest.mutable_ice()->set_security_desc(source.security_desc());
dest.mutable_ice()->set_deal_display_factor(source.ice_deal_display_factor);
dest.mutable_ice()->set_settle_display_factor(source.ice_settle_display_factor);
dest.mutable_ice()->set_market_description(source.ice_market_description());
dest.mutable_ice()->set_cleared_alias(source.ice_cleared_alias());
dest.mutable_ice()->set_product_name(source.ice_product_name());
dest.mutable_ice()->set_hub_alias(source.ice_hub_alias());
dest.mutable_ice()->set_strip_name(source.ice_strip_name());
dest.mutable_ice()->set_mic_code(source.mic_code());
break;
case Venue::VENUE_BTS:
break;
default:
@@ -257,7 +279,7 @@ uint64_t exchange_id(const Security& security) {
case Security::ExchangeDataCase::kCboe: return security.cboe().exchange_id();
case Security::ExchangeDataCase::kGlbx: return security.glbx().exchange_id();
case Security::ExchangeDataCase::kCfe: return security.cfe().exchange_id();
case Security::ExchangeDataCase::kIce: bts_assert(false);
case Security::ExchangeDataCase::kIce: return security.ice().exchange_id();
// Debatable whether this should be an error or not.
// If is possible that we might create a spread with no exchange in the future
// and if we did this would be a runtime error.
@@ -288,7 +310,18 @@ void convert_security(const Security& src, FixedSecurity& dest, bool set_securit
dest.cboe_class_key = src.cfe().class_key();
break;
case Security::ExchangeDataCase::kIce:
bts_assert_d(false);
dest.numeric_id = src.ice().exchange_id();
dest.security_desc(src.ice().security_desc());
dest.ice_deal_display_factor = src.ice().deal_display_factor();
dest.ice_settle_display_factor = src.ice().settle_display_factor();
dest.ice_market_description(src.ice().market_description());
dest.ice_cleared_alias(src.ice().cleared_alias());
dest.ice_product_name(src.ice().product_name());
dest.ice_hub_alias(src.ice().hub_alias());
dest.ice_strip_name(src.ice().strip_name());
dest.mic_code(src.ice().mic_code());
break;
case Security::ExchangeDataCase::EXCHANGEDATA_NOT_SET:
break;
}
+18 -1
View File
@@ -59,13 +59,29 @@ public:
uint8_t cme_main_fraction;
uint8_t cme_sub_fraction;
uint8_t cme_price_display_format;
int8_t ice_deal_display_factor;
int8_t ice_settle_display_factor;
STRING_PROPERTY(ice_market_description);
STRING_PROPERTY(ice_cleared_alias);
STRING_PROPERTY(ice_product_name);
STRING_PROPERTY(ice_hub_alias);
STRING_PROPERTY(ice_strip_name);
STRING_PROPERTY(mic_code);
private:
char _symbol[16]; // CME defines this as a char[6] but I'm padding
char _cfi_code[8]; // CME defines this as char[6]
char _security_desc[32]; // cme security desc FIX=107
char _security_desc[32]; // cme security desc FIX=107 //ice wants this to be 35
char _alt_symbol[16]; // "cme symbol" or alternate symbol
char _platform_id[64];
char _ice_market_description[120];
char _ice_cleared_alias[15];
char _ice_product_name[62];
char _ice_hub_alias[80];
char _ice_strip_name[39];
char _mic_code[4];
};
class FixedStockSecurity : public FixedSecurity {
@@ -171,6 +187,7 @@ private:
};
// Stack allocate a FixedSpreadSecurity with a high number of legs then memcpy the right size to shared memory
typedef FixedSpreadSecurity<2> FixedSpreadSecurityXS;
typedef FixedSpreadSecurity<16> FixedSpreadSecurityS;
typedef FixedSpreadSecurity<128> FixedSpreadSecurityL;
typedef FixedSpreadSecurity<512> FixedSpreadSecurityXL;
+1 -1
View File
@@ -163,5 +163,5 @@ const vector<CMEChannel> parse_channels(const vector<UserSymbol>& symbols) {
return result;
}
}}//namespace
}} //namespace
#endif
@@ -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>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.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>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.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>
+126
View File
@@ -0,0 +1,126 @@
#ifndef _WIN32
#include "ICEUtils.h"
#include "lib/config/config.h"
#include "lib/utils/datetime.h"
#include "lib/utils/bts_chrono.h"
#include "lib/utils/download.h"
#include "lib/logging/logging.h"
#include "lib/md/get_symbols.h"
#include "lib/config/protos/MarketData.pb.h"
#include "lib/config/protos/system.pb.h"
#include <boost/filesystem.hpp>
#include <pugixml/pugixml.hpp>
using namespace std;
using namespace bts::api;
namespace bts {
namespace md {
namespace ice {
std::string ICEChannel::to_string() const
{
std::string mt = name;
for(const auto& x : market_types)
mt += " " + x;
return mt;
}
//We are sort of punting on symbols here because there is no symbol -> channel mapping supplied by ice
//therefore we must 1) enumerate the channels we want in config, and smash them together with the list of
//symbols we care about. This has the unfortunate side effect of not knowing what channel should heartbeat what symbol
//but Eric says this is ok
const vector<ICEChannel> parse_ice_channels(const vector<UserSymbol>& symbols)
{
vector<ICEChannel> result;
const auto& ice_options = config::get<bts::md::ICEOptions>();
for(const auto& x : ice_options.channel())
{
md::ice::ICEChannel chan;
chan.name = x.name();
chan.symbols.insert(symbols.begin(), symbols.end());
for(const auto& xx : x.market_type())
chan.market_types.push_back(xx);
result.push_back(chan);
}
return result;
}
string ice_data_path() {
auto p = config::get<config::System>().data_path() + "onixs_ice/";
#ifdef _WIN32
// OnixS requires win32 paths to look like Win32 paths - everyone else in the world is ok with '/'
os::normalize_path(p, '\\');
#else
os::normalize_path(p);
#endif
return p;
}
const string ice_config_file() { return config::get<bts::md::ICEOptions>().ice_config_file(); }
const string ice_config_path() { return ice_data_path() + "/" + ice_config_file(); }
const std::string ice_log_path() {return log:: log_path().string() + "/onix_ice";}
bool ice_check_file_exists_with_instructions(const string& filename, const string& url, bool log) {
// if (!boost::filesystem::exists(filename)) {
// download_file(url.c_str(), filename.c_str());
// }
if (!boost::filesystem::exists(filename)) {
if (log) {
LOG(md,Error,
"File {} is not present on this system. "
"Please download it from the ICE web site. "
"I will wait until the file is present.\n$ curl {} > {} ",
filename, url, filename);
}
return false;
}
return true;
}
// For exponential backoff on logging this return true if x is a power of 2 or 0
bool is_pow_two_or_0(uint32_t x) { return (x & (~x + 1)) == x; }
void await_ice_config() {
std::string config_url;
if (config::get<config::DeploymentType>().type() != "dev") {
config_url = "https://drive.google.com/open?id=13_eyF2pKtn3F7chgsa_75ftUdf7emMbp";
}
else {
config_url = "https://community.theice.com/docs/DOC-19989";
}
boost::filesystem::create_directories(ice_data_path());
boost::filesystem::create_directories(ice_log_path());
// Check config is present and give instructions for downloading it if not
// If the file is not present log an error and wait a second. Continue to log the error ever power of 2 seconds until the file appears or the process is killed.
auto configpath = ice_config_path();
uint32_t count = 0;
while(!ice_check_file_exists_with_instructions(configpath, config_url, is_pow_two_or_0(count))) {
++count;
std::this_thread::sleep_for(1s);
}
// If we waited for someone to download the file give it a second to be finished downloading
if (count > 0) {
std::this_thread::sleep_for(1s);
}
}
const std::vector<ICEChannel> get_configured_ice_channels() {
std::vector<UserSymbol> symbols;
// Get all ice symbols
get_system_md_symbols(api::VENUE_ICE, api::SECURITYTYPE_UNSET, &symbols);
return parse_ice_channels(symbols);
}
}}} //namespace
#endif
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include "lib/md/coconut2.h"
#include <string>
#include <set>
#include <vector>
namespace bts {
namespace md {
namespace ice {
struct ICEChannel
{
std::string name;
std::vector<uint32_t> market_types;
std::set<UserSymbol> symbols;
std::string to_string() const;
};
void await_ice_config();
const std::vector<ICEChannel> get_configured_ice_channels();
const std::vector<ICEChannel> parse_ice_channels(const std::vector<UserSymbol>& symbols);
const std::string ice_config_path();
const std::string ice_log_path();
}}} //namespace
+1
View File
@@ -11,6 +11,7 @@ enum Platform {
PLATFORM_MDP3ONIXS = 10;
PLATFORM_CELOXICA = 13;
PLATFORM_MDP3EMUMBA = 14;
PLATFORM_ICEONIXS = 15;
}
enum TradingStatus {
+8
View File
@@ -376,6 +376,14 @@ public:
google::protobuf::MapPair<uint32_t,std::string> v(h.handle.key(), security.glbx().security_desc());
x->insert(v);
}
else if (security.ExchangeData_case() == Security::kIce) {
google::protobuf::MapPair<uint32_t,std::string> v(h.handle.key(), security.ice().security_desc());
x->insert(v);
}
else
{
LOG(md,Error, "Invalid ExchangeData_case {}", security.ExchangeData_case());
}
}
}
}
@@ -33,7 +33,7 @@ public:
for (auto& h : _hedgers)
if(h.is_free())
return h;
LOG(OrderMan, Error, "HedgerManager::get_hedger allocating new hedger {} ",
LOG(OrderMan, Info, "HedgerManager::get_hedger allocating new hedger {} ",
_hedgers.size());
_hedgers.emplace_back(_spreader_manager,
_leg_property_data,
+1
View File
@@ -17,6 +17,7 @@ void init_spark_lib()
void finit_spark_lib()
{
LOG(Gen, Info, "finit_spark_lib");
if (poller) {
delete poller;
}
+1 -1
View File
@@ -1 +1 @@
set(sources algo/AlgoDefinitionServiceServer.cpp;algo/AlgoServiceServer.cpp;cmds/AdminReport.cpp;cmds/AutoCert.cpp;cmds/Benchmark.cpp;cmds/CmdRegistry.cpp;cmds/ConfigCheck.cpp;cmds/Help.cpp;cmds/Md.cpp;cmds/PrintHedgeOrders.cpp;cmds/QuickTest.cpp;cmds/Run.cpp;cmds/RunSim.cpp;cmds/Span.cpp;cmds/Test.cpp;cmds/TestCeloxica.cpp;cmds/Web.cpp;dspark/mirage/quick_queue/quick_queue.cpp;exchange_sim/ExchangeSim.cpp;exchange_sim/ExchangeSimApplication.cpp;exchange_sim/book/Book.cpp;exchange_sim/book/ExchangeSim.proto;exchange_sim/book/Order.cpp;exchange_sim/book/OrderMatcher.cpp;exchange_sim/book/book_transform.cpp;exchange_sim/tests/test_book_transform.cpp;http/ApiGateway.cpp;http/WebServer.cpp;main.cpp;md/ChannelVolume.cpp;md/MarketDataAuxiliaryServiceServer.cpp;md/VolumeAtPriceState.cpp;md/platforms/celoxica/CXListener.cpp;md/platforms/celoxica/CXMain.cpp;md/platforms/celoxica/tests/cx_tests.cpp;md/platforms/mdp3_onixs/MDP3Listener.cpp;md/platforms/mdp3_onixs/MDP3Main.cpp;md/platforms/mdp3_onixs/tests/mdp3_tests.cpp;md/run_md.cpp;position/IMarginObserver.cpp;position/IPositionObserver.cpp;position/MarginServiceCore.cpp;position/PositionServiceCore.cpp;position/PositionServiceServer.cpp;position/tests/PositionTests.cpp;support/ErrorReportService.cpp;support/ShellLatencyServer.cpp;user/AdminServiceServer.cpp;user/AuthServiceServer.cpp;user/tests/admin_service_tests.cpp)
set(sources algo/AlgoDefinitionServiceServer.cpp;algo/AlgoServiceServer.cpp;cmds/AdminReport.cpp;cmds/AutoCert.cpp;cmds/Benchmark.cpp;cmds/CmdRegistry.cpp;cmds/ConfigCheck.cpp;cmds/Help.cpp;cmds/Md.cpp;cmds/PrintHedgeOrders.cpp;cmds/QuickTest.cpp;cmds/Run.cpp;cmds/RunSim.cpp;cmds/Span.cpp;cmds/Test.cpp;cmds/TestCeloxica.cpp;cmds/Web.cpp;dspark/mirage/quick_queue/quick_queue.cpp;exchange_sim/ExchangeSim.cpp;exchange_sim/ExchangeSimApplication.cpp;exchange_sim/book/Book.cpp;exchange_sim/book/ExchangeSim.proto;exchange_sim/book/Order.cpp;exchange_sim/book/OrderMatcher.cpp;exchange_sim/book/book_transform.cpp;exchange_sim/tests/test_book_transform.cpp;http/ApiGateway.cpp;http/WebServer.cpp;main.cpp;md/ChannelVolume.cpp;md/MarketDataAuxiliaryServiceServer.cpp;md/VolumeAtPriceState.cpp;md/platforms/IMDPlatform.cpp;md/platforms/celoxica/CXListener.cpp;md/platforms/celoxica/CXMain.cpp;md/platforms/celoxica/tests/cx_tests.cpp;md/platforms/ice_onixs/ICEListener.cpp;md/platforms/ice_onixs/ICEMain.cpp;md/platforms/ice_onixs/tests/ice_tests.cpp;md/platforms/mdp3_onixs/MDP3Listener.cpp;md/platforms/mdp3_onixs/MDP3Main.cpp;md/platforms/mdp3_onixs/tests/mdp3_tests.cpp;md/run_md.cpp;position/IMarginObserver.cpp;position/IPositionObserver.cpp;position/MarginServiceCore.cpp;position/PositionServiceCore.cpp;position/PositionServiceServer.cpp;position/tests/PositionTests.cpp;support/ErrorReportService.cpp;support/ShellLatencyServer.cpp;user/AdminServiceServer.cpp;user/AuthServiceServer.cpp;user/tests/admin_service_tests.cpp)
+2
View File
@@ -26,6 +26,8 @@ target_link_libraries( sparkd
cryptopp
tbb
onixs-cmemdh-all-4.8.0
OnixS.IceImpactMulticastPriceFeedHandlerCpp
ACE
quickfix
benchmark
lttng-ust
@@ -107,11 +107,14 @@ struct MDPlayer : md::IRelayWriter
obs.on_depth(*sec_ptr, bids, asks, nullptr, nullptr);
}
if (cr.has_misc()) {
if (cr.misc().has_settlement()) {
const auto& s = cr.misc().settlement();
obs.on_settlement(*sec_ptr, { s.mantissa(), (int8_t)s.exponent() });
}
if (cr.has_misc()) {
const auto& s = cr.misc();
obs.on_high(*sec_ptr, s.session_high());
obs.on_low(*sec_ptr, s.session_low());
obs.on_open(*sec_ptr, s.open_price());
obs.on_close(*sec_ptr, s.close_price());
if (cr.misc().has_settlement())
obs.on_settlement(*sec_ptr, { s.settlement().mantissa(), (int8_t)s.settlement().exponent() });
}
}
}
@@ -483,10 +483,11 @@ void ExchangeSimApplication::update_md(std::string const &sec_desc) {
for (auto &t : new_trades)
handle.add_trade(
utils::TimeStamp::now(),
md::PriceSize_from_double<7>(t.price.value() * price_factor,
t.quantity.value()),
md::PriceSize_from_double<ex_sim::precision>(t.price.value() * price_factor,t.quantity.value()),
datetime::ll_now(),
co2::AGGRESSOR_SIDE_NONE);
t.bid_aggressor ? co2::AGGRESSOR_SIDE_BUY
: ( t.ask_aggressor ? co2::AGGRESSOR_SIDE_SELL
: co2::AGGRESSOR_SIDE_NONE) );
}
}
@@ -540,6 +541,42 @@ void ExchangeSimApplication::on_settlement(md::Security const& sec, md::IntPrice
}
}
void ExchangeSimApplication::on_high(md::Security const& sec, md::Price price) {
auto sec_desc = get_sim_sec_desc(sec);
auto iter = me->md_producer_handles.find(sec_desc);
if (iter != me->md_producer_handles.end()) {
auto &handle = iter->second;
handle.update_session_high(utils::TimeStamp::now(), price);
}
}
void ExchangeSimApplication::on_low(md::Security const& sec, md::Price price) {
auto sec_desc = get_sim_sec_desc(sec);
auto iter = me->md_producer_handles.find(sec_desc);
if (iter != me->md_producer_handles.end()) {
auto &handle = iter->second;
handle.update_session_low(utils::TimeStamp::now(), price);
}
}
void ExchangeSimApplication::on_open(md::Security const& sec, md::Price price) {
auto sec_desc = get_sim_sec_desc(sec);
auto iter = me->md_producer_handles.find(sec_desc);
if (iter != me->md_producer_handles.end()) {
auto &handle = iter->second;
handle.update_opening(utils::TimeStamp::now(), price, datetime::today());
}
}
void ExchangeSimApplication::on_close(md::Security const& sec, md::Price price) {
auto sec_desc = get_sim_sec_desc(sec);
auto iter = me->md_producer_handles.find(sec_desc);
if (iter != me->md_producer_handles.end()) {
auto &handle = iter->second;
handle.update_closing(utils::TimeStamp::now(), price, datetime::today());
}
}
void ExchangeSimApplication::on_depth(
md::Security const &sec,
md::PriceSize bids[md::COCONUT_MAX_DEPTH],
@@ -100,7 +100,11 @@ public:
void persist_book(OrderBook const &b);
void on_new_security(md::Security const&) override;
void on_settlement(md::Security const&, md::IntPrice) override;
void on_high(md::Security const& sec, md::Price price) override;
void on_low(md::Security const& sec, md::Price price) override;
void on_open(md::Security const& sec, md::Price price) override;
void on_close(md::Security const& sec, md::Price price) override;
void on_settlement(md::Security const&, md::IntPrice) override;
void on_depth(md::Security const&s,
md::PriceSize bids[md::COCONUT_MAX_DEPTH],
md::PriceSize asks[md::COCONUT_MAX_DEPTH],
@@ -9,7 +9,11 @@ namespace sim {
struct IMDPlayerObserver {
virtual void on_new_security(md::Security const&) = 0;
virtual void on_settlement(const md::Security&, md::IntPrice) = 0;
virtual void on_high(const md::Security&, md::Price) = 0;
virtual void on_low(const md::Security&, md::Price) = 0;
virtual void on_open(const md::Security&, md::Price) = 0;
virtual void on_close(const md::Security&, md::Price) = 0;
virtual void on_settlement(const md::Security&, md::IntPrice) = 0;
virtual void on_depth(md::Security const&s,
md::PriceSize bids[md::COCONUT_MAX_DEPTH],
md::PriceSize asks[md::COCONUT_MAX_DEPTH],
@@ -195,12 +195,18 @@ void OrderMatcher::match(std::vector<Order> *out) {
void OrderMatcher::match(Order *bid, Order *ask) {
Price price(0);
bool bid_aggressor = false, ask_aggressor = false;
if (utils::pb::greater(bid->last_update_time(), ask->last_update_time()))
{
price = Price(ask->price());
bid_aggressor = true;
}
else
{
price = Price(bid->price());
if(utils::pb::smaller(bid->last_update_time(), ask->last_update_time()))
ask_aggressor = true;
}
Quantity quantity;
if (bid->open_quantity() > ask->open_quantity())
@@ -208,7 +214,7 @@ void OrderMatcher::match(Order *bid, Order *ask) {
else
quantity = Quantity(bid->open_quantity());
me->pending_trades.push_back(Trade{price, quantity});
me->pending_trades.push_back(Trade{price, quantity, bid_aggressor, ask_aggressor});
execute(bid, price, quantity);
execute(ask, price, quantity);
}
@@ -38,7 +38,8 @@ class OrderMatcher {
struct Trade {
Price price;
Quantity quantity;
Quantity quantity;
bool bid_aggressor, ask_aggressor;
};
std::vector<Trade> get_new_trades();
std::tuple<size_t,size_t,size_t> size() const;
@@ -0,0 +1,8 @@
#include "IMDPlatform.h"
namespace bts {
namespace md {
void IMDPlatform::send_heartbeats() {}
}}
@@ -0,0 +1,12 @@
#pragma once
namespace bts {
namespace md {
class IMDPlatform
{
public:
virtual void send_heartbeats();
};
}}
@@ -0,0 +1,393 @@
#include "ICEListener.h"
#include "lib/utils/datetime.h"
#include <vector>
#include "lib/utils/helper_macros.h"
#include "lib/config/protos/MarketData.pb.h"
#include "lib/md/protos/co2.pb.h"
using namespace std;
using namespace bts::co2;
using namespace bts::md::ice;
namespace bts {
namespace md {
namespace ice {
template <>
double double_of_price<onixs_ice::Rational>(const onixs_ice::Rational& price, int8_t display_factor)
{
UNUSED(display_factor);
double dbl = price.convertTo<double>();
return dbl;
}
ICEListener::ICEListener(ICESecurityIndex& index, MDProducer& producer, const std::vector<MDProducerChannel> channels) :
_index(index),
_producer(producer),
_symbol_filter(),
_channels(channels),
_concurrency_monitor(0)
{
}
ICEListener::~ICEListener() {}
std::string ICEListener::parse_contract_symbol(const std::string& sym)
{
const auto&& res = sym.substr(0, sym.find(' '));
return res;
}
//
//State change
void ICEListener::onHandlerStateChange(const onixs_ice::HandlerStateChange& )
{
//TODO
}
void ICEListener::onMarketStateChange(const onixs_ice::MarketStateChange& , const onixs_ice::MessageInfo& )
{
//TODO
}
//
// Warnings/Errors
void ICEListener::onError(const onixs_ice::Error& error)
{
std::string error_desc(error.description());
tracepoint (bts_trace,trace_order,(char*) "onError", 0, (uint16_t) 0, 0);
LOG(md,Warn, "OnixS ICE Error: {} - {}", error.toString(), error_desc );
}
void ICEListener::onFeedError(onixs_ice::FeedId feedid, onixs_ice::ErrorCode code, const std::string& desc)
{
tracepoint (bts_trace,trace_order,(char*) "onFeedError", 0, (uint16_t) 0, 0);
LOG(md,Warn, "OnixS ICE FeedError: {} - {}", feedid, desc, code);
}
void ICEListener::onWarning(const onixs_ice::Warning& warning)
{
tracepoint (bts_trace,trace_order,(char*) "onWarning", 0, (uint16_t) 0, 0);
LOG(md,Warn, "OnixS ICE Warn: {} - {}", warning.toString(), std::string(warning.description()) );
}
//
// Security discovery
void ICEListener::onFuturesProductDefinition(const onixs_ice::FuturesProductDefinition& msg, bool& is_interested)
{
tracepoint (bts_trace,trace_order,(char*) "onFuturesProductDefinition", 0, (uint16_t) 0, 0);
if(msg.isSpread)
on_future_strip(msg, is_interested);
else
on_future(msg, is_interested);
}
void ICEListener::onNewExpiry(const onixs_ice::NewExpiry& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onNewExpiry", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
on_future(msg, is_interested);
}
void ICEListener::onFuturesStrategyDefinition(const onixs_ice::FuturesStrategyDefinition& def, bool& is_interested)
{
tracepoint (bts_trace,trace_order,(char*) "onFuturesStrategyDefinition", 0, (uint16_t) 0, 0);
//TODO need to find out how to produce data for testing
//on_uds_future_spread(def, is_interested);
UNUSED(def);
UNUSED(is_interested);
}
//This is only for UDS
void ICEListener::onNewFuturesStrategyDefinition(const onixs_ice::NewFuturesStrategyDefinition& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onFuturesStrategyDefinition", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
//TODO need to find out how to produce data for testing
//on_uds_future_spread(msg, is_interested);
UNUSED(msg);
UNUSED(is_interested);
}
void ICEListener::onOptionsProductDefinition(const onixs_ice::OptionsProductDefinition& msg, bool& is_interested)
{
UNUSED(msg);
UNUSED(is_interested);
}
void ICEListener::onNewOptionsMarketDefinition(const onixs_ice::NewOptionsMarketDefinition& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info)
{
UNUSED(msg);
UNUSED(is_interested);
UNUSED(msg_info);
}
void ICEListener::onOptionsStrategyDefinition(const onixs_ice::OptionsStrategyDefinition& msg, bool& is_interested)
{
UNUSED(msg);
UNUSED(is_interested);
}
void ICEListener::onNewOptionsStrategyDefinition(const onixs_ice::NewOptionsStrategyDefinition& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info)
{
UNUSED(msg);
UNUSED(is_interested);
UNUSED(msg_info);
}
//
// Gap Recovery -- This is not necessary if we subscribe to the onOrderBookUpdated callback, they handle the breaks transparently
void ICEListener::onMarketSnapshot(const onixs_ice::MarketSnapshot& msg, const onixs_ice::MessageInfo& msg_info)
{
UNUSED(msg);
UNUSED(msg_info);
}
void ICEListener::onMarketSnapshotOrder(const onixs_ice::MarketSnapshotOrder& msg, const onixs_ice::MessageInfo& msg_info)
{
UNUSED(msg);
UNUSED(msg_info);
}
void ICEListener::onMarketSnapshotPriceLevel(const onixs_ice::MarketSnapshotPriceLevel& msg, const onixs_ice::MessageInfo& msg_info)
{
UNUSED(msg);
UNUSED(msg_info);
}
//
// Book
void ICEListener::onOrderBookUpdated(const onixs_ice::OrderBook& onixs_book, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onBookUpdate", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto data = _index.get_security(onixs_book.marketId());
if (data == nullptr)
return;
bts_assert(data->id == onixs_book.marketId());
auto display_factor = data->handle.security().display_factor;
// Overwrite all entries every time
size_t bids_size = onixs_book.bids().size();
size_t asks_size = onixs_book.offers().size();
if (!data->handle.has_depth())
{
bids_size = std::min(bids_size, size_t { 1 });
asks_size = std::min(asks_size, size_t { 1 });
}
std::array<PriceSize,COCONUT_MAX_DEPTH> dbids; dbids.fill(NO_MARKET);
std::array<PriceSize,COCONUT_MAX_IMPLIED_DEPTH> ibids; ibids.fill(NO_MARKET);
std::array<PriceSize,COCONUT_MAX_DEPTH> dasks; dasks.fill(NO_MARKET);
std::array<PriceSize,COCONUT_MAX_IMPLIED_DEPTH> iasks; iasks.fill(NO_MARKET);
for (size_t x = 0; x < bids_size; ++x)
{
auto& bid = onixs_book.bids()[x];
if(x < COCONUT_MAX_DEPTH)
dbids[x] = pricesize_of_price_size(bid.price, display_factor, bid.quantity - bid.impliedQuantity);
if(x < COCONUT_MAX_IMPLIED_DEPTH)
ibids[x] = pricesize_of_price_size(bid.price, display_factor, bid.impliedQuantity);
}
for (size_t x = 0; x < asks_size; ++x)
{
auto& ask = onixs_book.offers()[x];
if(x < COCONUT_MAX_DEPTH)
dasks[x] = pricesize_of_price_size(ask.price, display_factor, ask.quantity - ask.impliedQuantity);
if(x < COCONUT_MAX_IMPLIED_DEPTH)
iasks[x] = pricesize_of_price_size(ask.price, display_factor, ask.impliedQuantity);
}
data->handle.update_books(TimeStamp::now(), dbids, dasks, ibids, iasks, (uint32_t) msg_info.sequenceNumber);
}
//
// Trades
AggressorSide map_aggressor(onixs_ice::AggressorSide::Enum agside)
{
switch(agside) {
default:
case onixs_ice::AggressorSide::NoAggressor:
return AGGRESSOR_SIDE_NONE;
case onixs_ice::AggressorSide::Buy:
return AGGRESSOR_SIDE_BUY;
case onixs_ice::AggressorSide::Sell:
return AGGRESSOR_SIDE_SELL;
}
}
void on_trade(ICESecurityData* data, const onixs_ice::Price& price, int size, onixs_ice::AggressorSide::Enum agside, const onixs_ice::DateTime& onixs_date)
{
auto ts = utils::TimeStamp::now();
PriceSize ps = pricesize_of_price_size(price, data->handle.security().display_factor, size);
auto date = ll_of_timestamp(onixs_date);
data->handle.add_trade(ts, ps, date, map_aggressor(agside), size);
}
void ICEListener::onTrade(const onixs_ice::Trade& msg, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onTrade", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto* data = _index.get_security(msg.marketId);
if (data != NULL)
{
bts_assert(data->id == msg.marketId);
auto size = msg.quantity;
auto price = msg.price;
onixs_ice::AggressorSide::Enum agside = msg.aggressorSide;
on_trade(data, price, size, agside, msg.transactDateTime);
}
}
//
// RFQ
void ICEListener::onRfq(const onixs_ice::Rfq& msg, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onRfq", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto* data = _index.get_security(msg.marketId);
if (data != nullptr)
{
bts_assert(data->id == msg.marketId);
auto ts = utils::TimeStamp::now();
co2::QuoteRequestMessage message;
message.set_key(data->handle.key());
auto time = ll_of_timestamp(msg.messageTimestamp);
message.set_time(time);
long long rfqid = msg.rfqSystemId;
message.set_request_id(std::to_string(rfqid));
//https://ref.onixs.biz/cpp-ice-impact-handler-guide/struct_onix_s_1_1_i_c_e_1_1i_mpact_1_1_market_data_1_1_side.html#a8150b7776c2a1749101acf22e868d091
switch(msg.side)
{
case ' ':
message.set_side(co2::QuoteRequestMessage::UNDEFINED);
break;
case '1':
message.set_side(co2::QuoteRequestMessage::BUY);
break;
case '2':
message.set_side(co2::QuoteRequestMessage::SELL);
break;
}
message.set_size(msg.quantity);
data->handle.add_rfq(ts, message);
}
}
//
// Misc
void ICEListener::onSettlementPrice(const onixs_ice::SettlementPrice& msg, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onSettlementPrice", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto* data = _index.get_security(msg.marketId);
if (data != nullptr)
{
bts_assert(data->id == msg.marketId);
onixs_ice::Price price = msg.settlementPrice;
onixs_ice::DateTime time = msg.dateTime;
auto display_factor = data->handle.security().display_factor;
data->handle.update_settlement(utils::TimeStamp::now(), convert_price(price, display_factor), date_of_timestamp(time));
}
}
void ICEListener::onOpenInterest(const onixs_ice::OpenInterest &msg, const onixs_ice::MessageInfo &msg_info)
{
UNUSED(msg);
UNUSED(msg_info);
}
void ICEListener::onOpenPrice(const onixs_ice::OpenPrice& msg, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onOpenPrice", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto* data = _index.get_security(msg.marketId);
if (data != nullptr)
{
bts_assert(data->id == msg.marketId);
onixs_ice::Price price = msg.openPrice;
onixs_ice::DateTime time = msg.dateTime;
auto display_factor = data->handle.security().display_factor;
data->handle.update_opening( utils::TimeStamp::now(), double_of_price(price, display_factor), date_of_timestamp(time));
}
}
void ICEListener::onClosePrice(const onixs_ice::ClosePrice& msg, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onClosePrice", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto* data = _index.get_security(msg.marketId);
if (data != nullptr)
{
bts_assert(data->id == msg.marketId);
onixs_ice::Price price = msg.closePrice;
onixs_ice::DateTime time = msg.dateTime;
auto display_factor = data->handle.security().display_factor;
data->handle.update_closing( utils::TimeStamp::now(), double_of_price(price, display_factor), date_of_timestamp(time));
}
}
void ICEListener::onEndOfDayMarketSummary(const onixs_ice::EndOfDayMarketSummary& msg, const onixs_ice::MessageInfo& msg_info)
{
tracepoint (bts_trace,trace_order,(char*) "onEndOfDayMarketSummary", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
auto* data = _index.get_security(msg.marketId);
if (data != nullptr)
{
bts_assert(data->id == msg.marketId);
onixs_ice::DateTime time = msg.dateTime;
auto display_factor = data->handle.security().display_factor;
data->handle.update_opening( utils::TimeStamp::now(), double_of_price(msg.openingPrice, display_factor), date_of_timestamp(time) );
data->handle.update_session_high( utils::TimeStamp::now(), double_of_price(msg.high, display_factor) );
data->handle.update_session_low( utils::TimeStamp::now(), double_of_price(msg.low, display_factor) );
data->handle.update_settlement( utils::TimeStamp::now(), convert_price(msg.settlementPrice, display_factor), date_of_timestamp(time) );
}
}
//
// Feed
void ICEListener::onMulticastMessageBlockBegin(onixs_ice::FeedId feedId, const onixs_ice::MessageInfo& msg_info)
{
UNUSED(feedId);
tracepoint (bts_trace,trace_order,(char*) "onMulticastMessageBlockBegin", (uint32_t)msg_info.sequenceNumber, (uint16_t) msg_info.sequenceNumber, 0);
}
void ICEListener::onMulticastMessageBlockEnd(onixs_ice::FeedId feedId, const onixs_ice::MarketIds& marketIds)
{
UNUSED(feedId);
UNUSED(marketIds);
tracepoint (bts_trace,trace_order,(char*) "onMulticastMessageBlockEnd.begin", 0, (uint16_t) 0, 0);
tracepoint (bts_trace,trace_order,(char*) "onMulticastMessageBlockEnd.end", 0, (uint16_t) 0, 0);
}
void ICEListener::onFeedStarted(onixs_ice::FeedId, const onixs_ice::MarketIds&)
{}
void ICEListener::onFeedStopped(onixs_ice::FeedId)
{}
void ICEListener::onSessionNumberChange(onixs_ice::FeedId , short , short )
{}
//
// Non-onixs calls
void ICEListener::add_filter_symbol(const std::string& symbol)
{
_symbol_filter.insert(symbol);
}
void ICEListener::heartbeat()
{
for (auto& c : _channels) { c.heartbeat(); }
}
//
// Private functions
void ICEListener::add_security(const FixedSecurity& security)
{
// Set up the shared memory for this security
auto handle = _producer.add_security(security);
bts_assert(security.numeric_id != 0);
// Add it to the index so it can receive messages
_index.add_security(security.numeric_id, handle);
}
void ICEListener::update_all_status(CoconutSecurityStatus status)
{
_index.walk_security_list([=](ICESecurityData& data)
{
data.handle.set_status(status);
});
}
}}} //namespace
@@ -0,0 +1,239 @@
#pragma once
#include "lib/utils/bts_no_copy.h"
#include "lib/md/coconut2.h"
#include "ICESecurityIndex.h"
#include "lib/tracing/bts_trace.h"
#include "ICEListenerHelpers.h"
#include "onixs.h"
#include <tbb/concurrent_queue.h>
#include <vector>
#include <atomic>
#include <array>
#include <utility>
namespace bts {
namespace md {
namespace ice {
class ICEListener :
public onixs_ice::ExchangeListener, //One Thread
public onixs_ice::HandlerStateChangeListener, //One thread
public onixs_ice::OrderBookUpdateListener, //One thread //TODO?
public onixs_ice::FeedListener, //Multi thread
public onixs_ice::ErrorListener, //Multi thread
public onixs_ice::WarningListener //Multi thread
{
typedef uint32_t BookType;
static constexpr BookType book_type_direct=1;
static constexpr BookType book_type_implied=2;
static constexpr BookType book_type_both=(book_type_direct|book_type_implied);
public:
ICEListener(ICESecurityIndex& index, MDProducer&, const std::vector<MDProducerChannel>);
virtual ~ICEListener();
//
//State change
void onHandlerStateChange(const onixs_ice::HandlerStateChange& change) override;
void onMarketStateChange(const onixs_ice::MarketStateChange& msg, const onixs_ice::MessageInfo& msgInfo) override;
// Warnings/Errors/Info
void onError(const onixs_ice::Error&) override;
void onFeedError(onixs_ice::FeedId feedid, onixs_ice::ErrorCode code, const std::string& desc) override;
void onWarning(const onixs_ice::Warning& warning) override;
//
// Security discovery
void onFuturesProductDefinition(const onixs_ice::FuturesProductDefinition& def, bool& is_interested) override;
void process_strip(int stripid);
void onNewExpiry(const onixs_ice::NewExpiry& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info) override;
void onFuturesStrategyDefinition(const onixs_ice::FuturesStrategyDefinition& def, bool& is_interested) override;
void onNewFuturesStrategyDefinition(const onixs_ice::NewFuturesStrategyDefinition& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info) override;
void onOptionsProductDefinition(const onixs_ice::OptionsProductDefinition& def, bool& is_interested) override;
void onNewOptionsMarketDefinition(const onixs_ice::NewOptionsMarketDefinition& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info) override;
void onOptionsStrategyDefinition(const onixs_ice::OptionsStrategyDefinition& def, bool& is_interested) override;
void onNewOptionsStrategyDefinition(const onixs_ice::NewOptionsStrategyDefinition& msg, bool& is_interested, const onixs_ice::MessageInfo& msg_info) override;
//
// Gap Recovery
void onMarketSnapshot(const onixs_ice::MarketSnapshot& msg, const onixs_ice::MessageInfo& msgInfo) override;
void onMarketSnapshotOrder(const onixs_ice::MarketSnapshotOrder& msg, const onixs_ice::MessageInfo& msgInfo) override;
void onMarketSnapshotPriceLevel(const onixs_ice::MarketSnapshotPriceLevel& msg, const onixs_ice::MessageInfo& msgInfo) override;
//
// Book
void onOrderBookUpdated(const onixs_ice::OrderBook& book, const onixs_ice::MessageInfo& msgInfo) override;
//
// Trades
void onTrade (const onixs_ice::Trade& msg, const onixs_ice::MessageInfo& msgInfo) override;
//
// RFQ
void onRfq (const onixs_ice::Rfq& msg, const onixs_ice::MessageInfo& msgInfo) override;
//
// Misc
void onSettlementPrice(const onixs_ice::SettlementPrice& msg, const onixs_ice::MessageInfo& msgInfo) override;
void onOpenInterest(const onixs_ice::OpenInterest &msg, const onixs_ice::MessageInfo &msgInfo) override;
void onOpenPrice(const onixs_ice::OpenPrice& msg, const onixs_ice::MessageInfo& msgInfo) override;
void onClosePrice(const onixs_ice::ClosePrice& msg, const onixs_ice::MessageInfo& msgInfo) override;
void onEndOfDayMarketSummary(const onixs_ice::EndOfDayMarketSummary& msg, const onixs_ice::MessageInfo& msgInfo) override;
// Feed
void onMulticastMessageBlockBegin(onixs_ice::FeedId feedId, const onixs_ice::MessageInfo& msgInfo) override;
void onMulticastMessageBlockEnd(onixs_ice::FeedId feedId, const onixs_ice::MarketIds& marketIds) override;
void onFeedStarted(onixs_ice::FeedId feedId, const onixs_ice::MarketIds& ids) override;
void onFeedStopped(onixs_ice::FeedId feedId) override;
void onSessionNumberChange(onixs_ice::FeedId feedId, short oldSessionNumber, short newSessionNumber) override;
//
// Discover securities
void add_filter_symbol(const std::string& symbol);
void heartbeat();
// Add a new security to the index
void add_security(const FixedSecurity& security);
private:
template<typename Definition>
void set_security_common(const Definition& def, FixedSecurity& fsec);
template<typename Definition>
void on_future(const Definition& def, bool& is_interested);
template<typename Definition>
void on_uds_future_spread(const Definition& def, bool& is_interested);
template<typename Definition>
void on_future_strip(const Definition& def, bool& is_interested);
template <size_t MAX_DEPTH, typename TBook>
void on_book(const TBook& onixs_book, BookType booktype);
private:
enum SecurityFilterAction { ADD, SKIP, DELETE };
std::string parse_contract_symbol(const std::string& sym);
template<typename Definition>
SecurityFilterAction filter_security(int exchange_id, const Definition& def)
{
if (_index.has_security(exchange_id))
return SKIP;
// if(_symbol_filter.count("*") > 0)
// return ADD;
return _symbol_filter.count( parse_contract_symbol(def.contractSymbol) ) > 0 ? ADD : SKIP;
}
void flush_books();
void update_all_status(co2::CoconutSecurityStatus status);
ICESecurityIndex& _index;
MDProducer& _producer;
std::set<std::string> _symbol_filter;
std::vector<MDProducerChannel> _channels;
std::atomic<int> _concurrency_monitor;
};
template<typename Definition>
void ICEListener::set_security_common(const Definition& def, FixedSecurity& fsec)
{
fsec.numeric_id = def.marketId;
std::string sym = parse_contract_symbol(def.contractSymbol);
fsec.symbol( sym );
//fsec.security_desc(def.marketDesc);
fsec.security_desc(def.contractSymbol);
fsec.exchange = api::Venue::VENUE_ICE;
fsec.display_factor = (int8_t)(def.orderPriceDenominator - '0');
fsec.ice_deal_display_factor = (int8_t)(def.dealPriceDenominator - '0');
fsec.ice_settle_display_factor = (int8_t)(def.settlePriceDenominator - '0');
double min_tick = double_of_price(def.incrementPrice, fsec.display_factor);
fsec.low_tick = fsec.high_tick = min_tick;
fsec.price_break = 0.;
fsec.ice_market_description(def.marketDesc);
fsec.ice_cleared_alias(def.clearedAlias);
fsec.ice_product_name(def.productName);
fsec.ice_hub_alias(def.hubAlias);
fsec.ice_strip_name(def.stripName);
fsec.mic_code(def.micCode);
}
template<typename Definition>
void ICEListener::on_future(const Definition& def, bool& is_interested)
{
is_interested = false;
auto exchange_id = def.marketId;
if (filter_security(exchange_id, def) != ADD) return;
FixedFutureSecurity fsec;
set_security_common(def, fsec);
//fsec.cash_per_point = double_of_price(def.tickValue, fsec.display_factor);
fsec.expiration_year = def.maturityYear;
fsec.expiration_month = def.maturityMonth;
fsec.expiration_day = def.maturityDay;
add_security(fsec);
is_interested = true;
}
template<typename Definition>
void ICEListener::on_uds_future_spread(const Definition& def, bool& is_interested)
{
is_interested = false;
auto exchange_id = def.marketId;
if (filter_security(exchange_id, def) != ADD) return;
// // Filter out any already expired spreads
// auto expiration = date_of_maturity(sec);
// if (expiration < datetime::today()) return;
FixedSpreadSecurityL fsec;
set_security_common(def, fsec);
fsec.alt_symbol(def.strategySymbol);
const auto& legs = def.legs;
fsec.set_leg_count(legs.size());
for(size_t x = 0; x < fsec.leg_count(); ++x)
{
const auto& leg = legs[x];
if(leg.ratioPriceNumerator)
fsec.legs[x].leg_price = double_of_price(leg.ratioPriceNumerator.value(), leg.ratioPriceDenominator.value());
if(leg.ratioQtyNumerator && leg.ratioQtyDenominator)
fsec.legs[x].leg_delta = double_of_price(leg.ratioQtyNumerator.value(), leg.ratioQtyDenominator.value());
fsec.legs[x].leg_quantity = leg.ratio;
fsec.legs[x].leg_side = leg.side == onixs_ice::Side::Bid ? api::SIDE_BUY : api::SIDE_SELL;
fsec.legs[x].exchange_key = ExchangeKey(leg.marketId);
fsec.legs[x].key = invalid_security_key;
}
add_security(fsec);
is_interested = true;
}
template<typename FutureDefinition>
void ICEListener::on_future_strip(const FutureDefinition& def, bool& is_interested)
{
is_interested = false;
auto exchange_id = def.marketId;
if (filter_security(exchange_id, def) != ADD) return;
FixedSpreadSecurityXS fsec;
set_security_common(def, fsec);
fsec.alt_symbol(def.stripName);
fsec.set_leg_count(2);
for(size_t x = 0; x < fsec.leg_count(); ++x)
{
fsec.legs[x].leg_quantity = 1.0;
fsec.legs[x].leg_side = (x == 0) ? api::SIDE_BUY : api::SIDE_SELL;
fsec.legs[x].exchange_key = ExchangeKey((x == 0) ? def.primaryMarketId : def.secondaryMarketId);
fsec.legs[x].key = invalid_security_key;
}
add_security(fsec);
is_interested = true;
}
}}} //namespace
@@ -0,0 +1,55 @@
#pragma once
#include "lib/utils/bts_assert.h"
#include "lib/utils/helper_macros.h"
#include "lib/md/ice/ICEUtils.h"
#include "lib/md/coconut2.h"
#include "onixs.h"
#include <vector>
#include <atomic>
#include <array>
namespace bts {
namespace md {
namespace ice {
template <typename OnixPrice>
double double_of_price(const OnixPrice& price, int8_t display_factor)
{
double dbl = price / pow10(display_factor);
return dbl;
}
template <typename OnixsPrice>
IntPrice convert_price(const OnixsPrice& price, int8_t display_factor)
{
double dbl = double_of_price<OnixsPrice>(price, display_factor);
const int PRECISION = 7; //TODO config::get<bts::JetFIX>().connection() case ICE
auto intpx = md::IntPrice_from_double<PRECISION>(dbl);
return intpx;
}
template <typename OnixsPrice>
inline PriceSize pricesize_of_price_size(const OnixsPrice& price, int8_t display_factor, Size size)
{
auto intpx = convert_price<OnixsPrice>(price, display_factor);
PriceSize result({intpx.mantissa(), (int8_t)(intpx.exponent())}, size);
return result;
}
inline datetime::LLDateTime ll_of_timestamp(const onixs_ice::DateTime& dt)
{
return datetime::ll_from_unix_epoch_ms(dt);
}
inline datetime::Date date_of_timestamp(const onixs_ice::DateTime& dt)
{
auto ll = ll_of_timestamp(dt);
return datetime::ll_to_date(ll);
}
}}} //namespace
@@ -0,0 +1,237 @@
#include "ICEMain.h"
#include "lib/md/ice/ICEUtils.h"
#include "lib/config/config.h"
#include "lib/md/coconut2.h"
#include "lib/md/SecurityDB.h"
#include "lib/os/os.h"
#include "lib/utils/helper_macros.h"
#include "lib/utils/Dispatcher.h"
#include "lib/utils/proto_helper.h"
#include "lib/utils/bts_chrono.h"
#include "lib/md/protos/co2.pb.h"
#include "lib/config/protos/MarketData.pb.h"
#include "lib/config/protos/system.pb.h"
#include "lib/utils/thread_manager.h"
#include <memory>
#include <boost/filesystem.hpp>
#include <set>
void recursive_copy(const boost::filesystem::path &src, const boost::filesystem::path &dst)
{
if (boost::filesystem::exists(dst))
throw std::runtime_error(dst.generic_string() + " exists");
if (boost::filesystem::is_directory(src))
{
boost::filesystem::create_directories(dst);
for (boost::filesystem::directory_entry& item : boost::filesystem::directory_iterator(src))
recursive_copy(item.path(), dst/item.path().filename());
}
else if (boost::filesystem::is_regular_file(src))
boost::filesystem::copy(src, dst);
else
throw std::runtime_error(dst.generic_string() + " not dir or file");
}
using namespace std;
using namespace bts::co2;
using std::size_t;
namespace bts {
namespace md {
namespace ice {
ICEMain::ICEMain() :
_index(),
_recorder ({ utils::Dispatcher::current(), [=](ExchangeKey k) { return SecurityKey(_index.get_key(k.value())); } }),
_producer(PLATFORM_ICEONIXS, _recorder ),
_handlers(),
_listeners()
{
}
ICEMain::~ICEMain() {}
const ICEOptions::ICEChannel channel_settings_for(const ICEChannel& channel)
{
const auto& config = config::get<ICEOptions>();
for (const auto& ch : config.channel())
{
if(ch.name() == channel.name)
return ch;
}
return ICEOptions::ICEChannel();
}
onixs_ice::MarketSubscriptions market_subcription_for_channel(const ICEChannel& chan)
{
onixs_ice::MarketSubscriptions subs;
for(const auto& x : chan.market_types)
{
//onixs_ice::MarketSubType::NonImplied
onixs_ice::MarketSubscription futures(x, onixs_ice::MarketSubType::FullImplied, onixs_ice::SecurityType::Futures, onixs_ice::BookDepth::FOD);
onixs_ice::MarketSubscription spreads(x, onixs_ice::MarketSubType::FullImplied, onixs_ice::SecurityType::UdsFuturesMarkets, onixs_ice::BookDepth::FOD);
subs.push_back(futures);
subs.push_back(spreads);
}
return subs;
}
void ICEMain::start(std::vector<UserSymbol>& symbols)
{
// License path and config file
auto license_location = os::bts_data_path() + "/licenses/";
if (!boost::filesystem::is_directory(license_location))
{
auto license_path =os::sparkd_wd() + "/data_files/Onixs.BTS.lic" ;
boost::filesystem::create_directories(license_location);
boost::filesystem::copy_file(license_path,license_location+"/Onixs.BTS.lic");
}
auto ice_conf_location = os::bts_data_path() + "/onixs_ice/";
if (!boost::filesystem::is_directory(ice_conf_location))
{
auto conf_path = os::sparkd_wd() + "/data_files/onixs_ice/" ;
recursive_copy(boost::filesystem::path(conf_path), boost::filesystem::path(ice_conf_location));
}
await_ice_config();
const auto& channels = parse_ice_channels(symbols);
for (const auto& channel : channels)
{
unique_ptr<onixs_ice::Handler> phandler = prepare_handler(channel);
_listeners.push_back(prepare_listener(*phandler, channel));
_handlers.push_back(std::make_pair(channel, move(phandler)));
std::stringstream symstr;
for (const auto& sym : channel.symbols)
symstr << sym.symbol() << "-" << SecurityType_Name(sym.type()) << " ";
LOG(md,Info, "ICE: Initialized channel {} ({})", channel.to_string(), symstr.str());
}
for (auto& pair : _handlers)
{
LOG(md,Info, "ICE: Init Handler {}", pair.first.to_string());
sleep_for(16s);
onixs_ice::MarketSubscriptions subs = market_subcription_for_channel(pair.first);
pair.second->start(subs);
}
LOG(md,Info, "** ICE Publisher started **");
}
void ICEMain::send_heartbeats()
{
for (const auto& listener: _listeners)
listener->heartbeat();
}
// //
// Initialize HandlerSettings and allocate the channel Handler
unique_ptr<onixs_ice::Handler> ICEMain::prepare_handler(const ICEChannel& channel)
{
const auto& ice_options = config::get<ICEOptions>();
auto license = ice_options.onixs_license();
if (license == "{default}")
license = os::bts_data_path() + "/licenses/";
const auto& options = channel_settings_for(channel);
LOG(md,Info,"Loaded channel options for channel {}:\n{}", channel.to_string(), options.DebugString());
onixs_ice::HandlerSettings settings;
settings.licenseDirectory = license;
//
// Logging
settings.logLevel = (onixs_ice::LogLevels::Enum) options.onixs_log_mode();
settings.logDirectory = ice_log_path();
//
// Config file
settings.connectivityConfiguration = ice_config_path();
//
// Network settings
const auto& pub_options = config::get<ICEPublisherOptions>();
if (pub_options.has_network_interface())
settings.networkInterface = pub_options.network_interface();
else
{
std::string inter;
if (pub_options.has_network_interface_a() && !pub_options.has_network_interface_b())
inter = pub_options.network_interface_a();
if (!pub_options.has_network_interface_a() && pub_options.has_network_interface_b())
inter = pub_options.network_interface_b();
if (pub_options.has_network_interface_a() && pub_options.has_network_interface_b())
inter = pub_options.network_interface_b() + ":" + pub_options.network_interface_b();
settings.networkInterface = inter;
}
settings.udpBufferSize = options.udp_buffer_size();
settings.heartbeatInterval = options.heartbeat_interval();
settings.sequenceGapMargin = options.sequence_gap_margin();
settings.gapTimeoutInMilliseconds = options.gap_timeout_in_ms();
//
// Snapshot recovery options
settings.snapshotRecoveryOptions.snapshotRecoveryTimeoutInMilliseconds = options.snapshot_recovery_timeout_in_ms();
settings.snapshotRecoveryOptions.maximumNumberOfSnaphotRecoveryAttempts = options.maximum_number_of_snapshot_recovery_attempts();
settings.snapshotRecoveryOptions.maximumSizeOfSnapshotMessageQueue = options.maximum_size_of_snapshot_message_queue();
settings.snapshotRecoveryOptions.maximumSizeOfLiveMessageQueue = options.maximum_size_of_live_message_queue();
//
// Misc settings
if(options.processing_thread_affinity() != "" )
settings.processingThreadAffinity = onixs_ice::ThreadAffinity::deserialize(options.processing_thread_affinity());
// if(options.has_track_top_of_the_book_only()
// settings.trackTopOfTheBookOnly = options.track_top_of_the_book_only();
if(options.has_receive_product_definitions_only())
settings.receiveProductDefinitionsOnly = options.receive_product_definitions_only();
if(options.has_max_multicast_message_block_size() && options.max_multicast_message_block_size() > 0)
settings.maxMulticastMessageBlockSize = options.max_multicast_message_block_size();
if(options.product_definition_cache_directory() != "" )
settings.productDefinitionCacheDirectory = options.product_definition_cache_directory();
//
// return feed handler
try
{
auto handler = unique_ptr<onixs_ice::Handler>(new onixs_ice::Handler(settings));
return handler;
}
catch (std::exception& e) {
LOG(md,Error,"ONIXSERROR{}", std::string(e.what()));
throw;
}
}
//
// Create a listener for this channel and register callbacks
unique_ptr<ICEListener> ICEMain::prepare_listener(onixs_ice::Handler& handler, const ICEChannel& channel)
{
// We need to get a handler to the producer channels so we can produce heartbeats
vector<MDProducerChannel> producer_channels;
for (auto& symbol : channel.symbols)
{
producer_channels.push_back(_producer.get_channel(symbol.symbol().c_str(), symbol.type(), symbol.exchange()));
}
const auto& options = channel_settings_for(channel);
unique_ptr<ICEListener> listener(new ICEListener(_index, _producer, /*_settlement_recorder,*/ producer_channels));
for (auto& symbol : channel.symbols)
listener->add_filter_symbol(symbol.symbol());
handler.registerExchangeListener(listener.get());
handler.registerFeedListener(listener.get());
handler.registerOrderBookUpdateListener(listener.get());
handler.registerErrorListener(listener.get());
handler.registerWarningListener(listener.get());
handler.registerHandlerStateChangeListener(listener.get());
return listener;
}
}}} //namespace
@@ -0,0 +1,51 @@
#pragma once
#include "lib/utils/bts_no_copy.h"
#include "lib/md/coconut2.h"
#include "ICEListener.h"
#include "ICESecurityIndex.h"
#include "server/sparkd/md/platforms/IMDPlatform.h"
#include "onixs.h"
#include <memory>
#include <vector>
#include <map>
namespace bts {
namespace md {
namespace ice {
// void run_onixs_ice_server(UserSymbol* sym, size_t symcount);
struct ICEChannel;
/*
* The ICE provider is very simple
* Control starts in ICEMain which gets a list of all the symbols we need and starts the onixs handlers
* There is a single listener for all callbacks which maps the exchange id to the MDProducerHandle and writes
* the data to it.
*/
class ICEMain : public IMDPlatform
{
public:
ICEMain();
~ICEMain();
void start(std::vector<UserSymbol>&);
void send_heartbeats() override;
std::unique_ptr<onixs_ice::Handler> prepare_handler(const ICEChannel& channel);
std::unique_ptr<ICEListener> prepare_listener(onixs_ice::Handler& handler, const ICEChannel& channel);
private:
BTS_NO_COPY(ICEMain);
ICESecurityIndex _index;
SecurityIDRecorder _recorder;
MDProducer _producer;
std::vector< std::pair<ICEChannel, std::unique_ptr<onixs_ice::Handler>> > _handlers;
std::vector< std::unique_ptr<ICEListener> > _listeners;
};
}}} //namespace
Loaded 100 of 106 files, more files were not shown because too many files have changed in this diff. Show more