hedgequantx 1.2.33 → 1.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/app.js +121 -9
- package/src/services/rithmic/connection.js +203 -0
- package/src/services/rithmic/constants.js +156 -0
- package/src/services/rithmic/index.js +487 -0
- package/src/services/rithmic/proto/account_pnl_position_update.proto +59 -0
- package/src/services/rithmic/proto/base.proto +7 -0
- package/src/services/rithmic/proto/best_bid_offer.proto +39 -0
- package/src/services/rithmic/proto/exchange_order_notification.proto +140 -0
- package/src/services/rithmic/proto/instrument_pnl_position_update.proto +50 -0
- package/src/services/rithmic/proto/last_trade.proto +53 -0
- package/src/services/rithmic/proto/request_account_list.proto +20 -0
- package/src/services/rithmic/proto/request_cancel_all_orders.proto +15 -0
- package/src/services/rithmic/proto/request_heartbeat.proto +13 -0
- package/src/services/rithmic/proto/request_login.proto +28 -0
- package/src/services/rithmic/proto/request_login_info.proto +10 -0
- package/src/services/rithmic/proto/request_logout.proto +10 -0
- package/src/services/rithmic/proto/request_market_data_update.proto +42 -0
- package/src/services/rithmic/proto/request_new_order.proto +84 -0
- package/src/services/rithmic/proto/request_pnl_position_snapshot.proto +14 -0
- package/src/services/rithmic/proto/request_pnl_position_updates.proto +20 -0
- package/src/services/rithmic/proto/request_rithmic_system_info.proto +8 -0
- package/src/services/rithmic/proto/request_show_order_history.proto +16 -0
- package/src/services/rithmic/proto/request_show_order_history_dates.proto +10 -0
- package/src/services/rithmic/proto/request_show_order_history_summary.proto +14 -0
- package/src/services/rithmic/proto/request_show_orders.proto +14 -0
- package/src/services/rithmic/proto/request_subscribe_for_order_updates.proto +14 -0
- package/src/services/rithmic/proto/request_tick_bar_replay.proto +48 -0
- package/src/services/rithmic/proto/request_trade_routes.proto +11 -0
- package/src/services/rithmic/proto/response_account_list.proto +18 -0
- package/src/services/rithmic/proto/response_heartbeat.proto +14 -0
- package/src/services/rithmic/proto/response_login.proto +18 -0
- package/src/services/rithmic/proto/response_login_info.proto +24 -0
- package/src/services/rithmic/proto/response_logout.proto +11 -0
- package/src/services/rithmic/proto/response_market_data_update.proto +9 -0
- package/src/services/rithmic/proto/response_new_order.proto +18 -0
- package/src/services/rithmic/proto/response_pnl_position_snapshot.proto +11 -0
- package/src/services/rithmic/proto/response_pnl_position_updates.proto +11 -0
- package/src/services/rithmic/proto/response_rithmic_system_info.proto +12 -0
- package/src/services/rithmic/proto/response_show_order_history.proto +11 -0
- package/src/services/rithmic/proto/response_show_order_history_dates.proto +13 -0
- package/src/services/rithmic/proto/response_show_order_history_summary.proto +11 -0
- package/src/services/rithmic/proto/response_show_orders.proto +11 -0
- package/src/services/rithmic/proto/response_subscribe_for_order_updates.proto +11 -0
- package/src/services/rithmic/proto/response_tick_bar_replay.proto +40 -0
- package/src/services/rithmic/proto/response_trade_routes.proto +19 -0
- package/src/services/rithmic/proto/rithmic_order_notification.proto +124 -0
- package/src/services/rithmic/protobuf.js +259 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseAccountList
|
|
5
|
+
{
|
|
6
|
+
required int32 template_id = 154467;
|
|
7
|
+
repeated string user_msg = 132760;
|
|
8
|
+
repeated string rq_handler_rp_code = 132764;
|
|
9
|
+
repeated string rp_code = 132766;
|
|
10
|
+
|
|
11
|
+
optional string fcm_id = 154013;
|
|
12
|
+
optional string ib_id = 154014;
|
|
13
|
+
optional string account_id = 154008;
|
|
14
|
+
optional string account_name = 154002;
|
|
15
|
+
optional string account_currency = 154383;
|
|
16
|
+
optional string account_auto_liquidate = 131035;
|
|
17
|
+
optional string auto_liq_threshold_current_value = 131040;
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseHeartbeat
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
|
|
12
|
+
optional int32 ssboe = 150100; // PB_OFFSET + MNM_SECONDS_SINCE_BOE
|
|
13
|
+
optional int32 usecs = 150101; // PB_OFFSET + MNM_USECS
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseLogin
|
|
5
|
+
{
|
|
6
|
+
required int32 template_id = 154467;
|
|
7
|
+
optional string template_version = 153634;
|
|
8
|
+
repeated string user_msg = 132760;
|
|
9
|
+
repeated string rp_code = 132766;
|
|
10
|
+
|
|
11
|
+
optional string fcm_id = 154013;
|
|
12
|
+
optional string ib_id = 154014;
|
|
13
|
+
optional string country_code = 154712;
|
|
14
|
+
optional string state_code = 154713;
|
|
15
|
+
|
|
16
|
+
optional string unique_user_id = 153428;
|
|
17
|
+
optional double heartbeat_interval = 153633;
|
|
18
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseLoginInfo
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
enum UserType {
|
|
9
|
+
USER_TYPE_ADMIN = 0;
|
|
10
|
+
USER_TYPE_FCM = 1;
|
|
11
|
+
USER_TYPE_IB = 2;
|
|
12
|
+
USER_TYPE_TRADER = 3;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
16
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
17
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
18
|
+
|
|
19
|
+
optional string fcm_id = 154013; // PB_OFFSET + MNM_FCM_ID
|
|
20
|
+
optional string ib_id = 154014; // PB_OFFSET + MNM_IB_ID
|
|
21
|
+
optional string first_name = 154216; // PB_OFFSET + MNM_FIRST_NAME
|
|
22
|
+
optional string last_name = 154217; // PB_OFFSET + MNM_LAST_NAME
|
|
23
|
+
optional UserType user_type = 154036; // PB_OFFSET + MNM_USER_TYPE
|
|
24
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseLogout
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000 , is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseNewOrder
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
optional string user_tag = 154119; // PB_OFFSET + MNM_USER_ORIGIN
|
|
11
|
+
repeated string rq_handler_rp_code = 132764; // PB_OFFSET + MNM_REQUEST_HANDLER_RESPONSE_CODE
|
|
12
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
13
|
+
|
|
14
|
+
optional string basket_id = 110300; // PB_OFFSET + MNM_BASKET_ID
|
|
15
|
+
|
|
16
|
+
optional int32 ssboe = 150100; // PB_OFFSET + MNM_SECONDS_SINCE_BOE
|
|
17
|
+
optional int32 usecs = 150101; // PB_OFFSET + MNM_USECS
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponsePnLPositionSnapshot
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponsePnLPositionUpdates
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseRithmicSystemInfo
|
|
5
|
+
{
|
|
6
|
+
required int32 template_id = 154467;
|
|
7
|
+
repeated string user_msg = 132760;
|
|
8
|
+
repeated string rp_code = 132766;
|
|
9
|
+
|
|
10
|
+
repeated string system_name = 153628;
|
|
11
|
+
repeated bool has_aggregated_quotes = 153649;
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseShowOrderHistory
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseShowOrderHistoryDates
|
|
5
|
+
{
|
|
6
|
+
// CORRECT field IDs from rundef/async_rithmic (verified Dec 2025)
|
|
7
|
+
// PB_OFFSET = 100000
|
|
8
|
+
optional int32 template_id = 154467;
|
|
9
|
+
repeated string user_msg = 132760;
|
|
10
|
+
repeated string rq_handler_rp_code = 132764;
|
|
11
|
+
repeated string rp_code = 132766;
|
|
12
|
+
repeated string date = 110615; // Available dates (YYYYMMDD)
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseShowOrderHistorySummary
|
|
5
|
+
{
|
|
6
|
+
// Based on async_rithmic proto definitions
|
|
7
|
+
optional int32 template_id = 156580;
|
|
8
|
+
repeated string user_msg = 142744;
|
|
9
|
+
repeated string rp_code = 142750;
|
|
10
|
+
optional int32 fills_collected = 156569;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseShowOrders
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseSubscribeForOrderUpdates
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
11
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseTickBarReplay
|
|
5
|
+
{
|
|
6
|
+
enum BarType {
|
|
7
|
+
TICK_BAR = 1;
|
|
8
|
+
RANGE_BAR = 2;
|
|
9
|
+
VOLUME_BAR = 3;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
enum BarSubType {
|
|
13
|
+
REGULAR = 1;
|
|
14
|
+
CUSTOM = 2;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
required int32 template_id = 154467;
|
|
18
|
+
optional string request_key = 132758;
|
|
19
|
+
repeated string user_msg = 132760;
|
|
20
|
+
repeated string rq_handler_rp_code = 132764;
|
|
21
|
+
repeated string rp_code = 132766;
|
|
22
|
+
|
|
23
|
+
optional string symbol = 110100;
|
|
24
|
+
optional string exchange = 110101;
|
|
25
|
+
|
|
26
|
+
optional BarType type = 119200;
|
|
27
|
+
optional BarSubType sub_type = 119208;
|
|
28
|
+
optional string type_specifier = 148162;
|
|
29
|
+
optional uint64 num_trades = 119204;
|
|
30
|
+
optional uint64 volume = 119205;
|
|
31
|
+
optional uint64 bid_volume = 119213;
|
|
32
|
+
optional uint64 ask_volume = 119214;
|
|
33
|
+
optional double open_price = 100019;
|
|
34
|
+
optional double close_price = 100021;
|
|
35
|
+
optional double high_price = 100012;
|
|
36
|
+
optional double low_price = 100013;
|
|
37
|
+
optional int32 custom_session_open_ssm = 119209;
|
|
38
|
+
repeated int32 data_bar_ssboe = 119202;
|
|
39
|
+
repeated int32 data_bar_usecs = 119203;
|
|
40
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message ResponseTradeRoutes
|
|
5
|
+
{
|
|
6
|
+
// PB_OFFSET = 100000, is the offset added for each MNM field id
|
|
7
|
+
|
|
8
|
+
required int32 template_id = 154467; // PB_OFFSET + MNM_TEMPLATE_ID
|
|
9
|
+
repeated string user_msg = 132760; // PB_OFFSET + MNM_USER_MSG
|
|
10
|
+
repeated string rq_handler_rp_code = 132764; // PB_OFFSET + MNM_REQUEST_HANDLER_RESPONSE_CODE
|
|
11
|
+
repeated string rp_code = 132766; // PB_OFFSET + MNM_RESPONSE_CODE
|
|
12
|
+
|
|
13
|
+
optional string fcm_id = 154013; // PB_OFFSET + MNM_FCM_ID
|
|
14
|
+
optional string ib_id = 154014; // PB_OFFSET + MNM_IB_ID
|
|
15
|
+
optional string exchange = 110101; // PB_OFFSET + MNM_EXCHANGE
|
|
16
|
+
optional string trade_route = 112016; // PB_OFFSET + MNM_TRADE_ROUTE
|
|
17
|
+
optional string status = 131407; // PB_OFFSET + MNM_SERVICE_STATE
|
|
18
|
+
optional bool is_default = 154689; // PB_OFFSET + MNM_DEFAULT_ROUTE
|
|
19
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
|
|
2
|
+
package rti;
|
|
3
|
+
|
|
4
|
+
message RithmicOrderNotification
|
|
5
|
+
{
|
|
6
|
+
enum NotifyType {
|
|
7
|
+
ORDER_RCVD_FROM_CLNT = 1;
|
|
8
|
+
MODIFY_RCVD_FROM_CLNT = 2;
|
|
9
|
+
CANCEL_RCVD_FROM_CLNT = 3;
|
|
10
|
+
OPEN_PENDING = 4;
|
|
11
|
+
MODIFY_PENDING = 5;
|
|
12
|
+
CANCEL_PENDING = 6;
|
|
13
|
+
ORDER_RCVD_BY_EXCH_GTWY = 7;
|
|
14
|
+
MODIFY_RCVD_BY_EXCH_GTWY = 8;
|
|
15
|
+
CANCEL_RCVD_BY_EXCH_GTWY = 9;
|
|
16
|
+
ORDER_SENT_TO_EXCH = 10;
|
|
17
|
+
MODIFY_SENT_TO_EXCH = 11;
|
|
18
|
+
CANCEL_SENT_TO_EXCH = 12;
|
|
19
|
+
OPEN = 13;
|
|
20
|
+
MODIFIED = 14;
|
|
21
|
+
COMPLETE = 15;
|
|
22
|
+
MODIFICATION_FAILED = 16;
|
|
23
|
+
CANCELLATION_FAILED = 17;
|
|
24
|
+
TRIGGER_PENDING = 18;
|
|
25
|
+
GENERIC = 19;
|
|
26
|
+
LINK_ORDERS_FAILED = 20;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
enum TransactionType {
|
|
30
|
+
BUY = 1;
|
|
31
|
+
SELL = 2;
|
|
32
|
+
SS = 3;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
enum Duration {
|
|
36
|
+
DAY = 1;
|
|
37
|
+
GTC = 2;
|
|
38
|
+
IOC = 3;
|
|
39
|
+
FOK = 4;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
enum PriceType {
|
|
43
|
+
LIMIT = 1;
|
|
44
|
+
MARKET = 2;
|
|
45
|
+
STOP_LIMIT = 3;
|
|
46
|
+
STOP_MARKET = 4;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
enum BracketType {
|
|
50
|
+
STOP_ONLY = 1;
|
|
51
|
+
TARGET_ONLY = 2;
|
|
52
|
+
TARGET_AND_STOP = 3;
|
|
53
|
+
STOP_ONLY_STATIC = 4;
|
|
54
|
+
TARGET_ONLY_STATIC = 5;
|
|
55
|
+
TARGET_AND_STOP_STATIC = 6;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
enum OrderPlacement {
|
|
59
|
+
MANUAL = 1;
|
|
60
|
+
AUTO = 2;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
required int32 template_id = 154467;
|
|
64
|
+
optional string user_tag = 154119;
|
|
65
|
+
|
|
66
|
+
optional NotifyType notify_type = 153625;
|
|
67
|
+
optional bool is_snapshot = 110121;
|
|
68
|
+
|
|
69
|
+
optional string status = 110303;
|
|
70
|
+
optional string basket_id = 110300;
|
|
71
|
+
optional string original_basket_id = 154497;
|
|
72
|
+
optional string linked_basket_ids = 110358;
|
|
73
|
+
|
|
74
|
+
optional string fcm_id = 154013;
|
|
75
|
+
optional string ib_id = 154014;
|
|
76
|
+
optional string user_id = 131003;
|
|
77
|
+
optional string account_id = 154008;
|
|
78
|
+
|
|
79
|
+
optional string symbol = 110100;
|
|
80
|
+
optional string exchange = 110101;
|
|
81
|
+
optional string trade_exchange = 112021;
|
|
82
|
+
optional string trade_route = 112016;
|
|
83
|
+
optional string exchange_order_id = 149238;
|
|
84
|
+
optional string instrument_type = 110116;
|
|
85
|
+
optional string completion_reason = 149273;
|
|
86
|
+
|
|
87
|
+
optional int32 quantity = 112004;
|
|
88
|
+
optional int32 quan_release_pending = 112027;
|
|
89
|
+
optional double price = 110306;
|
|
90
|
+
optional double trigger_price = 149247;
|
|
91
|
+
|
|
92
|
+
optional TransactionType transaction_type = 112003;
|
|
93
|
+
optional Duration duration = 112005;
|
|
94
|
+
optional PriceType price_type = 112008;
|
|
95
|
+
optional PriceType orig_price_type = 154770;
|
|
96
|
+
optional OrderPlacement manual_or_auto = 154710;
|
|
97
|
+
optional BracketType bracket_type = 157087;
|
|
98
|
+
|
|
99
|
+
optional double avg_fill_price = 110322;
|
|
100
|
+
|
|
101
|
+
optional int32 total_fill_size = 154111;
|
|
102
|
+
optional int32 total_unfilled_size = 154112;
|
|
103
|
+
|
|
104
|
+
optional string sequence_number = 112002;
|
|
105
|
+
optional string orig_sequence_number = 149263;
|
|
106
|
+
optional string cor_sequence_number = 149264;
|
|
107
|
+
|
|
108
|
+
optional string currency = 154382;
|
|
109
|
+
optional string country_code = 154172;
|
|
110
|
+
|
|
111
|
+
optional string text = 120008;
|
|
112
|
+
optional string report_text = 120028;
|
|
113
|
+
optional string remarks = 154806;
|
|
114
|
+
|
|
115
|
+
optional string window_name = 154629;
|
|
116
|
+
optional string originator_window_name = 154671;
|
|
117
|
+
|
|
118
|
+
optional int32 cancel_at_ssboe = 157085;
|
|
119
|
+
optional int32 cancel_at_usecs = 157086;
|
|
120
|
+
optional int32 cancel_after_secs = 154488;
|
|
121
|
+
|
|
122
|
+
optional int32 ssboe = 150100;
|
|
123
|
+
optional int32 usecs = 150101;
|
|
124
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rithmic Protobuf Handler
|
|
3
|
+
* Handles encoding/decoding of Rithmic protobuf messages
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const protobuf = require('protobufjs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const { PROTO_FILES } = require('./constants');
|
|
9
|
+
|
|
10
|
+
// PnL field IDs (Rithmic uses very large field IDs)
|
|
11
|
+
const PNL_FIELDS = {
|
|
12
|
+
TEMPLATE_ID: 154467,
|
|
13
|
+
IS_SNAPSHOT: 110121,
|
|
14
|
+
FCM_ID: 154013,
|
|
15
|
+
IB_ID: 154014,
|
|
16
|
+
ACCOUNT_ID: 154008,
|
|
17
|
+
ACCOUNT_BALANCE: 156970,
|
|
18
|
+
CASH_ON_HAND: 156971,
|
|
19
|
+
MARGIN_BALANCE: 156977,
|
|
20
|
+
MIN_ACCOUNT_BALANCE: 156968,
|
|
21
|
+
OPEN_POSITION_PNL: 156961,
|
|
22
|
+
CLOSED_POSITION_PNL: 156963,
|
|
23
|
+
DAY_PNL: 157956,
|
|
24
|
+
DAY_OPEN_PNL: 157954,
|
|
25
|
+
DAY_CLOSED_PNL: 157955,
|
|
26
|
+
AVAILABLE_BUYING_POWER: 157015,
|
|
27
|
+
SSBOE: 150100,
|
|
28
|
+
USECS: 150101,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Read a varint from buffer
|
|
33
|
+
*/
|
|
34
|
+
function readVarint(buffer, offset) {
|
|
35
|
+
let result = BigInt(0);
|
|
36
|
+
let shift = BigInt(0);
|
|
37
|
+
let pos = offset;
|
|
38
|
+
|
|
39
|
+
while (pos < buffer.length) {
|
|
40
|
+
const byte = buffer[pos++];
|
|
41
|
+
result |= BigInt(byte & 0x7f) << shift;
|
|
42
|
+
if ((byte & 0x80) === 0) {
|
|
43
|
+
return [Number(result), pos];
|
|
44
|
+
}
|
|
45
|
+
shift += BigInt(7);
|
|
46
|
+
if (shift > BigInt(63)) {
|
|
47
|
+
throw new Error('Varint too large');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
throw new Error('Incomplete varint');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Read a length-delimited field (string/bytes)
|
|
55
|
+
*/
|
|
56
|
+
function readLengthDelimited(buffer, offset) {
|
|
57
|
+
const [length, newOffset] = readVarint(buffer, offset);
|
|
58
|
+
const value = buffer.slice(newOffset, newOffset + length).toString('utf8');
|
|
59
|
+
return [value, newOffset + length];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Skip a field based on wire type
|
|
64
|
+
*/
|
|
65
|
+
function skipField(buffer, offset, wireType) {
|
|
66
|
+
switch (wireType) {
|
|
67
|
+
case 0: // Varint
|
|
68
|
+
const [, newOffset] = readVarint(buffer, offset);
|
|
69
|
+
return newOffset;
|
|
70
|
+
case 1: // 64-bit
|
|
71
|
+
return offset + 8;
|
|
72
|
+
case 2: // Length-delimited
|
|
73
|
+
const [length, lenOffset] = readVarint(buffer, offset);
|
|
74
|
+
return lenOffset + length;
|
|
75
|
+
case 5: // 32-bit
|
|
76
|
+
return offset + 4;
|
|
77
|
+
default:
|
|
78
|
+
throw new Error(`Unknown wire type: ${wireType}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Manually decode AccountPnL from raw bytes
|
|
84
|
+
*/
|
|
85
|
+
function decodeAccountPnL(buffer) {
|
|
86
|
+
const result = {};
|
|
87
|
+
let offset = 0;
|
|
88
|
+
|
|
89
|
+
while (offset < buffer.length) {
|
|
90
|
+
try {
|
|
91
|
+
const [tag, tagOffset] = readVarint(buffer, offset);
|
|
92
|
+
const wireType = tag & 0x7;
|
|
93
|
+
const fieldNumber = tag >>> 3;
|
|
94
|
+
offset = tagOffset;
|
|
95
|
+
|
|
96
|
+
switch (fieldNumber) {
|
|
97
|
+
case PNL_FIELDS.TEMPLATE_ID:
|
|
98
|
+
[result.templateId, offset] = readVarint(buffer, offset);
|
|
99
|
+
break;
|
|
100
|
+
case PNL_FIELDS.IS_SNAPSHOT:
|
|
101
|
+
const [isSnap, snapOffset] = readVarint(buffer, offset);
|
|
102
|
+
result.isSnapshot = isSnap !== 0;
|
|
103
|
+
offset = snapOffset;
|
|
104
|
+
break;
|
|
105
|
+
case PNL_FIELDS.FCM_ID:
|
|
106
|
+
[result.fcmId, offset] = readLengthDelimited(buffer, offset);
|
|
107
|
+
break;
|
|
108
|
+
case PNL_FIELDS.IB_ID:
|
|
109
|
+
[result.ibId, offset] = readLengthDelimited(buffer, offset);
|
|
110
|
+
break;
|
|
111
|
+
case PNL_FIELDS.ACCOUNT_ID:
|
|
112
|
+
[result.accountId, offset] = readLengthDelimited(buffer, offset);
|
|
113
|
+
break;
|
|
114
|
+
case PNL_FIELDS.ACCOUNT_BALANCE:
|
|
115
|
+
[result.accountBalance, offset] = readLengthDelimited(buffer, offset);
|
|
116
|
+
break;
|
|
117
|
+
case PNL_FIELDS.CASH_ON_HAND:
|
|
118
|
+
[result.cashOnHand, offset] = readLengthDelimited(buffer, offset);
|
|
119
|
+
break;
|
|
120
|
+
case PNL_FIELDS.MARGIN_BALANCE:
|
|
121
|
+
[result.marginBalance, offset] = readLengthDelimited(buffer, offset);
|
|
122
|
+
break;
|
|
123
|
+
case PNL_FIELDS.MIN_ACCOUNT_BALANCE:
|
|
124
|
+
[result.minAccountBalance, offset] = readLengthDelimited(buffer, offset);
|
|
125
|
+
break;
|
|
126
|
+
case PNL_FIELDS.OPEN_POSITION_PNL:
|
|
127
|
+
[result.openPositionPnl, offset] = readLengthDelimited(buffer, offset);
|
|
128
|
+
break;
|
|
129
|
+
case PNL_FIELDS.CLOSED_POSITION_PNL:
|
|
130
|
+
[result.closedPositionPnl, offset] = readLengthDelimited(buffer, offset);
|
|
131
|
+
break;
|
|
132
|
+
case PNL_FIELDS.DAY_PNL:
|
|
133
|
+
[result.dayPnl, offset] = readLengthDelimited(buffer, offset);
|
|
134
|
+
break;
|
|
135
|
+
case PNL_FIELDS.DAY_OPEN_PNL:
|
|
136
|
+
[result.dayOpenPnl, offset] = readLengthDelimited(buffer, offset);
|
|
137
|
+
break;
|
|
138
|
+
case PNL_FIELDS.DAY_CLOSED_PNL:
|
|
139
|
+
[result.dayClosedPnl, offset] = readLengthDelimited(buffer, offset);
|
|
140
|
+
break;
|
|
141
|
+
case PNL_FIELDS.AVAILABLE_BUYING_POWER:
|
|
142
|
+
[result.availableBuyingPower, offset] = readLengthDelimited(buffer, offset);
|
|
143
|
+
break;
|
|
144
|
+
case PNL_FIELDS.SSBOE:
|
|
145
|
+
[result.ssboe, offset] = readVarint(buffer, offset);
|
|
146
|
+
break;
|
|
147
|
+
case PNL_FIELDS.USECS:
|
|
148
|
+
[result.usecs, offset] = readVarint(buffer, offset);
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
offset = skipField(buffer, offset, wireType);
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Protobuf Handler class
|
|
163
|
+
*/
|
|
164
|
+
class ProtobufHandler {
|
|
165
|
+
constructor() {
|
|
166
|
+
this.root = null;
|
|
167
|
+
this.loaded = false;
|
|
168
|
+
this.protoPath = path.join(__dirname, 'proto');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Load all proto files
|
|
173
|
+
*/
|
|
174
|
+
async load() {
|
|
175
|
+
if (this.loaded) return;
|
|
176
|
+
|
|
177
|
+
this.root = new protobuf.Root();
|
|
178
|
+
|
|
179
|
+
for (const file of PROTO_FILES) {
|
|
180
|
+
try {
|
|
181
|
+
await this.root.load(path.join(this.protoPath, file));
|
|
182
|
+
} catch (e) {
|
|
183
|
+
// Some files may not exist, that's ok
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.loaded = true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Encode a message to Buffer
|
|
192
|
+
*/
|
|
193
|
+
encode(typeName, data) {
|
|
194
|
+
if (!this.root) throw new Error('Proto not loaded');
|
|
195
|
+
|
|
196
|
+
const Type = this.root.lookupType(typeName);
|
|
197
|
+
const msg = Type.create(data);
|
|
198
|
+
return Buffer.from(Type.encode(msg).finish());
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Decode a Buffer to object
|
|
203
|
+
*/
|
|
204
|
+
decode(typeName, buffer) {
|
|
205
|
+
if (!this.root) throw new Error('Proto not loaded');
|
|
206
|
+
|
|
207
|
+
const Type = this.root.lookupType(typeName);
|
|
208
|
+
return Type.decode(buffer);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get template ID from buffer (manual decode for large field IDs)
|
|
213
|
+
*/
|
|
214
|
+
getTemplateId(buffer) {
|
|
215
|
+
const TEMPLATE_ID_FIELD = 154467;
|
|
216
|
+
|
|
217
|
+
let offset = 0;
|
|
218
|
+
while (offset < buffer.length) {
|
|
219
|
+
try {
|
|
220
|
+
const [tag, newOffset] = readVarint(buffer, offset);
|
|
221
|
+
const fieldNumber = tag >>> 3;
|
|
222
|
+
const wireType = tag & 0x7;
|
|
223
|
+
offset = newOffset;
|
|
224
|
+
|
|
225
|
+
if (fieldNumber === TEMPLATE_ID_FIELD && wireType === 0) {
|
|
226
|
+
const [templateId] = readVarint(buffer, offset);
|
|
227
|
+
return templateId;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
offset = skipField(buffer, offset, wireType);
|
|
231
|
+
} catch (e) {
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Fallback
|
|
237
|
+
if (this.root) {
|
|
238
|
+
try {
|
|
239
|
+
const Base = this.root.lookupType('Base');
|
|
240
|
+
const base = Base.decode(buffer);
|
|
241
|
+
return base.templateId;
|
|
242
|
+
} catch (e) {
|
|
243
|
+
return -1;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return -1;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Singleton
|
|
251
|
+
const proto = new ProtobufHandler();
|
|
252
|
+
|
|
253
|
+
module.exports = {
|
|
254
|
+
proto,
|
|
255
|
+
decodeAccountPnL,
|
|
256
|
+
readVarint,
|
|
257
|
+
readLengthDelimited,
|
|
258
|
+
skipField,
|
|
259
|
+
};
|