Compare commits

..
4 Commits
Author SHA1 Message Date
Taha Afzal 6e0a92fd65 Adding logs to CME MD 2026-06-15 00:38:02 -04:00
Taha a9c4173b02 Position cols in TC2 work again now 2026-05-06 14:32:36 -04:00
Taha Afzal 7c99fe90de Sim execution works with live cme md now 2026-04-23 03:43:12 +00:00
Taha Afzal feff24bf10 Sim execution works with live cme md now 2026-04-23 03:41:42 +00:00
123 changed files with 5597 additions and 17177 deletions

No files matched your search

+2 -4
View File
@@ -81,8 +81,6 @@ services:
limits:
memory: "${SPARKD__MEMORY:-4gb}"
sparkd-multicast:
environment:
- TZ=America/Chicago
volumes:
- ${SPARKD__DATA_DIR:-sparkd_data}:/home/bts/.local/share/bts/sparkd/data
- ${SPARKD__MD_RECORDING_DIR:-md_recording}:/md_recording
@@ -95,7 +93,7 @@ services:
- CONFIG_DIR=${SPARKD__CONFIG_DIR}
- PYTHON_REQUIREMENTS=${SPARKD__PYTHON_REQUIREMENTS}
- SPARKD_ENTRYPOINT=${SPARKD__SPARKD_ENTRYPOINT}
shm_size: "${SPARKD__SHM_SIZE:-8192mb}"
shm_size: "${SPARKD__SHM_SIZE:-2048mb}"
env_file:
- .env
- ${SPARKD__CONFIG_DIR}/.env
@@ -107,7 +105,7 @@ services:
delay: 3s
resources:
limits:
memory: "${SPARKD__MEMORY:-16gb}"
memory: "${SPARKD__MEMORY:-4gb}"
sparkd-tail:
image: bluetradingsystems/linux_dotnet8
volumes:
@@ -19,11 +19,6 @@ RUN add-apt-repository ppa:ubuntu-toolchain-r/test \
RUN apt-get update \
&& apt-get install -y dotnet8
RUN apt-get update && apt-get install -y gdb
RUN apt-get update && apt-get install -y fish
RUN apt-get update && apt-get install -y vim
RUN apt-get update && apt-get install -y less
RUN locale-gen en_US.UTF-8
ARG docker_user="bts"
Submodule
+1
Submodule docker/linux added at 6537812262.
+1
Submodule docker/windows added at de7d40c09d.
@@ -0,0 +1 @@
r=TimeSeriesStream(ReplayFutureLiveBBOStream("ES"))
@@ -0,0 +1,3 @@
x,y,z,id
123,1.001,abc,1
123,1.001,abc,0
1 x y z id
2 123 1.001 abc 1
3 123 1.001 abc 0
@@ -0,0 +1,3 @@
x,y,z,id
123,1.001,abc,1
123,1.001,abc,0
1 x y z id
2 123 1.001 abc 1
3 123 1.001 abc 0
@@ -0,0 +1,78 @@
id,ts_event,contract,bid_price,bid_size,ask_price,ask_size,timestamp
76,2026-03-13T05:57:25.177965500Z,ESU5,6363.75,51,6364,63,3/13/2026 5:57:25 AM
75,2026-03-13T05:57:25.068062900Z,ESU5,6363.75,52,6364,63,3/13/2026 5:57:25 AM
74,2026-03-13T05:57:24.963428500Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
73,2026-03-13T05:57:24.781215700Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
72,2026-03-13T05:57:24.676290100Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
71,2026-03-13T05:57:24.566898400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
70,2026-03-13T05:57:24.430800400Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
69,2026-03-13T05:57:24.273683400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
68,2026-03-13T05:57:24.167656100Z,ESU5,6363.75,56,6364,64,3/13/2026 5:57:24 AM
67,2026-03-13T05:57:23.995720100Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:23 AM
66,2026-03-13T05:57:23.894029100Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
65,2026-03-13T05:57:23.728897300Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
64,2026-03-13T05:57:23.614316800Z,ESU5,6363.75,52,6364,68,3/13/2026 5:57:23 AM
63,2026-03-13T05:57:23.503752700Z,ESU5,6363.75,51,6364,68,3/13/2026 5:57:23 AM
62,2026-03-13T05:57:23.289108200Z,ESU5,6363.75,50,6364,68,3/13/2026 5:57:23 AM
61,2026-03-13T05:57:23.155673400Z,ESU5,6363.75,49,6364,68,3/13/2026 5:57:23 AM
60,2026-03-13T05:57:23.028898400Z,ESU5,6363.75,48,6364,68,3/13/2026 5:57:23 AM
59,2026-03-13T05:57:22.887132700Z,ESU5,6363.75,46,6364,68,3/13/2026 5:57:22 AM
58,2026-03-13T05:57:22.676916300Z,ESU5,6363.75,44,6364,68,3/13/2026 5:57:22 AM
57,2026-03-13T05:57:22.520328000Z,ESU5,6363.75,43,6364,68,3/13/2026 5:57:22 AM
56,2026-03-13T05:57:22.405244600Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:22 AM
55,2026-03-13T05:57:22.294674100Z,ESU5,6363.75,41,6364,69,3/13/2026 5:57:22 AM
54,2026-03-13T05:57:22.163467900Z,ESU5,6363.75,38,6364,69,3/13/2026 5:57:22 AM
53,2026-03-13T05:57:21.992443000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
52,2026-03-13T05:57:21.872338400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
51,2026-03-13T05:57:21.742801800Z,ESU5,6363.75,37,6364,71,3/13/2026 5:57:21 AM
50,2026-03-13T05:57:21.557711100Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
49,2026-03-13T05:57:21.434977000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
48,2026-03-13T05:57:21.285751600Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
47,2026-03-13T05:57:21.184392000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
46,2026-03-13T05:57:21.076843800Z,ESU5,6363.75,34,6364,73,3/13/2026 5:57:21 AM
45,2026-03-13T05:57:20.894131800Z,ESU5,6363.75,32,6364,73,3/13/2026 5:57:20 AM
44,2026-03-13T05:57:20.759550000Z,ESU5,6363.75,30,6364,73,3/13/2026 5:57:20 AM
43,2026-03-13T05:57:20.641547900Z,ESU5,6363.75,28,6364,73,3/13/2026 5:57:20 AM
42,2026-03-13T05:57:20.540293200Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
41,2026-03-13T05:57:20.439034600Z,ESU5,6363.75,27,6364,74,3/13/2026 5:57:20 AM
40,2026-03-13T05:57:20.337795000Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
39,2026-03-13T05:57:20.236606600Z,ESU5,6363.75,27,6364,72,3/13/2026 5:57:20 AM
38,2026-03-13T05:57:20.135417700Z,ESU5,6363.75,30,6364,72,3/13/2026 5:57:20 AM
37,2026-03-13T05:57:20.034272700Z,ESU5,6363.75,32,6364,72,3/13/2026 5:57:20 AM
36,2026-03-13T05:57:19.933096800Z,ESU5,6363.75,34,6364,72,3/13/2026 5:57:19 AM
35,2026-03-13T05:57:19.832012600Z,ESU5,6363.75,36,6364,72,3/13/2026 5:57:19 AM
34,2026-03-13T05:57:19.730878500Z,ESU5,6363.75,38,6364,72,3/13/2026 5:57:19 AM
33,2026-03-13T05:57:19.629787400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
32,2026-03-13T05:57:19.528697000Z,ESU5,6363.75,38,6364,70,3/13/2026 5:57:19 AM
31,2026-03-13T05:57:19.427077000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
30,2026-03-13T05:57:19.326450300Z,ESU5,6363.75,39,6364,71,3/13/2026 5:57:19 AM
29,2026-03-13T05:57:19.225427900Z,ESU5,6363.75,39,6364,70,3/13/2026 5:57:19 AM
28,2026-03-13T05:57:19.123339800Z,ESU5,6363.75,40,6364,70,3/13/2026 5:57:19 AM
27,2026-03-13T05:57:19.021936500Z,ESU5,6363.75,41,6364,70,3/13/2026 5:57:19 AM
26,2026-03-13T05:57:18.920859200Z,ESU5,6363.75,45,6364,70,3/13/2026 5:57:18 AM
25,2026-03-13T05:57:18.820148400Z,ESU5,6363.75,46,6364,70,3/13/2026 5:57:18 AM
24,2026-03-13T05:57:18.718988100Z,ESU5,6363.75,46,6364,69,3/13/2026 5:57:18 AM
23,2026-03-13T05:57:18.618299700Z,ESU5,6363.75,49,6364,69,3/13/2026 5:57:18 AM
22,2026-03-13T05:57:18.517138100Z,ESU5,6363.75,52,6364,69,3/13/2026 5:57:18 AM
21,2026-03-13T05:57:18.416335200Z,ESU5,6363.75,53,6364,69,3/13/2026 5:57:18 AM
20,2026-03-13T05:57:18.315335900Z,ESU5,6363.75,55,6364,69,3/13/2026 5:57:18 AM
19,2026-03-13T05:57:18.214368600Z,ESU5,6363.75,57,6364,69,3/13/2026 5:57:18 AM
18,2026-03-13T05:57:18.113754700Z,ESU5,6363.75,57,6364,65,3/13/2026 5:57:18 AM
17,2026-03-13T05:57:18.012706500Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:18 AM
16,2026-03-13T05:57:17.911672600Z,ESU5,6363.75,54,6364,65,3/13/2026 5:57:17 AM
15,2026-03-13T05:57:17.810879900Z,ESU5,6363.75,52,6364,65,3/13/2026 5:57:17 AM
14,2026-03-13T05:57:17.710089700Z,ESU5,6363.75,49,6364,65,3/13/2026 5:57:17 AM
13,2026-03-13T05:57:17.609388300Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
12,2026-03-13T05:57:17.508697400Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
11,2026-03-13T05:57:17.408027000Z,ESU5,6363.75,53,6364,67,3/13/2026 5:57:17 AM
10,2026-03-13T05:57:17.307406200Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
9,2026-03-13T05:57:17.206714300Z,ESU5,6363.75,49,6364,71,3/13/2026 5:57:17 AM
8,2026-03-13T05:57:17.105530300Z,ESU5,6363.75,48,6364,71,3/13/2026 5:57:17 AM
7,2026-03-13T05:57:17.004796800Z,ESU5,6363.75,47,6364,71,3/13/2026 5:57:17 AM
6,2026-03-13T05:57:16.904113900Z,ESU5,6363.75,46,6364,71,3/13/2026 5:57:16 AM
5,2026-03-13T05:57:16.803381900Z,ESU5,6363.75,43,6364,71,3/13/2026 5:57:16 AM
4,2026-03-13T05:57:16.701969600Z,ESU5,6363.75,43,6364,72,3/13/2026 5:57:16 AM
3,2026-03-13T05:57:16.600765600Z,ESU5,6363.75,43,6364,73,3/13/2026 5:57:16 AM
2,2026-03-13T05:57:16.499986300Z,ESU5,6363.75,43,6364,74,3/13/2026 5:57:16 AM
1,2026-03-13T05:57:16.399241700Z,ESU5,6363.75,43,6364,75,3/13/2026 5:57:16 AM
0,2026-03-13T05:57:16.264038000Z,ESU5,6363.75,43,6364,76,3/13/2026 5:57:16 AM
1 id ts_event contract bid_price bid_size ask_price ask_size timestamp
2 76 2026-03-13T05:57:25.177965500Z ESU5 6363.75 51 6364 63 3/13/2026 5:57:25 AM
3 75 2026-03-13T05:57:25.068062900Z ESU5 6363.75 52 6364 63 3/13/2026 5:57:25 AM
4 74 2026-03-13T05:57:24.963428500Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
5 73 2026-03-13T05:57:24.781215700Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
6 72 2026-03-13T05:57:24.676290100Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
7 71 2026-03-13T05:57:24.566898400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
8 70 2026-03-13T05:57:24.430800400Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
9 69 2026-03-13T05:57:24.273683400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
10 68 2026-03-13T05:57:24.167656100Z ESU5 6363.75 56 6364 64 3/13/2026 5:57:24 AM
11 67 2026-03-13T05:57:23.995720100Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:23 AM
12 66 2026-03-13T05:57:23.894029100Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
13 65 2026-03-13T05:57:23.728897300Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
14 64 2026-03-13T05:57:23.614316800Z ESU5 6363.75 52 6364 68 3/13/2026 5:57:23 AM
15 63 2026-03-13T05:57:23.503752700Z ESU5 6363.75 51 6364 68 3/13/2026 5:57:23 AM
16 62 2026-03-13T05:57:23.289108200Z ESU5 6363.75 50 6364 68 3/13/2026 5:57:23 AM
17 61 2026-03-13T05:57:23.155673400Z ESU5 6363.75 49 6364 68 3/13/2026 5:57:23 AM
18 60 2026-03-13T05:57:23.028898400Z ESU5 6363.75 48 6364 68 3/13/2026 5:57:23 AM
19 59 2026-03-13T05:57:22.887132700Z ESU5 6363.75 46 6364 68 3/13/2026 5:57:22 AM
20 58 2026-03-13T05:57:22.676916300Z ESU5 6363.75 44 6364 68 3/13/2026 5:57:22 AM
21 57 2026-03-13T05:57:22.520328000Z ESU5 6363.75 43 6364 68 3/13/2026 5:57:22 AM
22 56 2026-03-13T05:57:22.405244600Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:22 AM
23 55 2026-03-13T05:57:22.294674100Z ESU5 6363.75 41 6364 69 3/13/2026 5:57:22 AM
24 54 2026-03-13T05:57:22.163467900Z ESU5 6363.75 38 6364 69 3/13/2026 5:57:22 AM
25 53 2026-03-13T05:57:21.992443000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
26 52 2026-03-13T05:57:21.872338400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
27 51 2026-03-13T05:57:21.742801800Z ESU5 6363.75 37 6364 71 3/13/2026 5:57:21 AM
28 50 2026-03-13T05:57:21.557711100Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
29 49 2026-03-13T05:57:21.434977000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
30 48 2026-03-13T05:57:21.285751600Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
31 47 2026-03-13T05:57:21.184392000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
32 46 2026-03-13T05:57:21.076843800Z ESU5 6363.75 34 6364 73 3/13/2026 5:57:21 AM
33 45 2026-03-13T05:57:20.894131800Z ESU5 6363.75 32 6364 73 3/13/2026 5:57:20 AM
34 44 2026-03-13T05:57:20.759550000Z ESU5 6363.75 30 6364 73 3/13/2026 5:57:20 AM
35 43 2026-03-13T05:57:20.641547900Z ESU5 6363.75 28 6364 73 3/13/2026 5:57:20 AM
36 42 2026-03-13T05:57:20.540293200Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
37 41 2026-03-13T05:57:20.439034600Z ESU5 6363.75 27 6364 74 3/13/2026 5:57:20 AM
38 40 2026-03-13T05:57:20.337795000Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
39 39 2026-03-13T05:57:20.236606600Z ESU5 6363.75 27 6364 72 3/13/2026 5:57:20 AM
40 38 2026-03-13T05:57:20.135417700Z ESU5 6363.75 30 6364 72 3/13/2026 5:57:20 AM
41 37 2026-03-13T05:57:20.034272700Z ESU5 6363.75 32 6364 72 3/13/2026 5:57:20 AM
42 36 2026-03-13T05:57:19.933096800Z ESU5 6363.75 34 6364 72 3/13/2026 5:57:19 AM
43 35 2026-03-13T05:57:19.832012600Z ESU5 6363.75 36 6364 72 3/13/2026 5:57:19 AM
44 34 2026-03-13T05:57:19.730878500Z ESU5 6363.75 38 6364 72 3/13/2026 5:57:19 AM
45 33 2026-03-13T05:57:19.629787400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
46 32 2026-03-13T05:57:19.528697000Z ESU5 6363.75 38 6364 70 3/13/2026 5:57:19 AM
47 31 2026-03-13T05:57:19.427077000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
48 30 2026-03-13T05:57:19.326450300Z ESU5 6363.75 39 6364 71 3/13/2026 5:57:19 AM
49 29 2026-03-13T05:57:19.225427900Z ESU5 6363.75 39 6364 70 3/13/2026 5:57:19 AM
50 28 2026-03-13T05:57:19.123339800Z ESU5 6363.75 40 6364 70 3/13/2026 5:57:19 AM
51 27 2026-03-13T05:57:19.021936500Z ESU5 6363.75 41 6364 70 3/13/2026 5:57:19 AM
52 26 2026-03-13T05:57:18.920859200Z ESU5 6363.75 45 6364 70 3/13/2026 5:57:18 AM
53 25 2026-03-13T05:57:18.820148400Z ESU5 6363.75 46 6364 70 3/13/2026 5:57:18 AM
54 24 2026-03-13T05:57:18.718988100Z ESU5 6363.75 46 6364 69 3/13/2026 5:57:18 AM
55 23 2026-03-13T05:57:18.618299700Z ESU5 6363.75 49 6364 69 3/13/2026 5:57:18 AM
56 22 2026-03-13T05:57:18.517138100Z ESU5 6363.75 52 6364 69 3/13/2026 5:57:18 AM
57 21 2026-03-13T05:57:18.416335200Z ESU5 6363.75 53 6364 69 3/13/2026 5:57:18 AM
58 20 2026-03-13T05:57:18.315335900Z ESU5 6363.75 55 6364 69 3/13/2026 5:57:18 AM
59 19 2026-03-13T05:57:18.214368600Z ESU5 6363.75 57 6364 69 3/13/2026 5:57:18 AM
60 18 2026-03-13T05:57:18.113754700Z ESU5 6363.75 57 6364 65 3/13/2026 5:57:18 AM
61 17 2026-03-13T05:57:18.012706500Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:18 AM
62 16 2026-03-13T05:57:17.911672600Z ESU5 6363.75 54 6364 65 3/13/2026 5:57:17 AM
63 15 2026-03-13T05:57:17.810879900Z ESU5 6363.75 52 6364 65 3/13/2026 5:57:17 AM
64 14 2026-03-13T05:57:17.710089700Z ESU5 6363.75 49 6364 65 3/13/2026 5:57:17 AM
65 13 2026-03-13T05:57:17.609388300Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
66 12 2026-03-13T05:57:17.508697400Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
67 11 2026-03-13T05:57:17.408027000Z ESU5 6363.75 53 6364 67 3/13/2026 5:57:17 AM
68 10 2026-03-13T05:57:17.307406200Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
69 9 2026-03-13T05:57:17.206714300Z ESU5 6363.75 49 6364 71 3/13/2026 5:57:17 AM
70 8 2026-03-13T05:57:17.105530300Z ESU5 6363.75 48 6364 71 3/13/2026 5:57:17 AM
71 7 2026-03-13T05:57:17.004796800Z ESU5 6363.75 47 6364 71 3/13/2026 5:57:17 AM
72 6 2026-03-13T05:57:16.904113900Z ESU5 6363.75 46 6364 71 3/13/2026 5:57:16 AM
73 5 2026-03-13T05:57:16.803381900Z ESU5 6363.75 43 6364 71 3/13/2026 5:57:16 AM
74 4 2026-03-13T05:57:16.701969600Z ESU5 6363.75 43 6364 72 3/13/2026 5:57:16 AM
75 3 2026-03-13T05:57:16.600765600Z ESU5 6363.75 43 6364 73 3/13/2026 5:57:16 AM
76 2 2026-03-13T05:57:16.499986300Z ESU5 6363.75 43 6364 74 3/13/2026 5:57:16 AM
77 1 2026-03-13T05:57:16.399241700Z ESU5 6363.75 43 6364 75 3/13/2026 5:57:16 AM
78 0 2026-03-13T05:57:16.264038000Z ESU5 6363.75 43 6364 76 3/13/2026 5:57:16 AM
@@ -0,0 +1,91 @@
id,ts_event,contract,bid_price,bid_size,ask_price,ask_size,timestamp
89,2026-03-13T05:57:26.904401600Z,ESU5,6363.75,43,6364,67,3/13/2026 5:57:26 AM
88,2026-03-13T05:57:26.778037200Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:26 AM
87,2026-03-13T05:57:26.597038500Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:26 AM
86,2026-03-13T05:57:26.438768300Z,ESU5,6363.75,43,6364,68,3/13/2026 5:57:26 AM
85,2026-03-13T05:57:26.328259100Z,ESU5,6363.75,43,6364,67,3/13/2026 5:57:26 AM
84,2026-03-13T05:57:26.216211200Z,ESU5,6363.75,44,6364,67,3/13/2026 5:57:26 AM
83,2026-03-13T05:57:26.099281200Z,ESU5,6363.75,46,6364,67,3/13/2026 5:57:26 AM
82,2026-03-13T05:57:25.979814900Z,ESU5,6363.75,48,6364,67,3/13/2026 5:57:25 AM
81,2026-03-13T05:57:25.852317700Z,ESU5,6363.75,48,6364,66,3/13/2026 5:57:25 AM
80,2026-03-13T05:57:25.684323100Z,ESU5,6363.75,48,6364,65,3/13/2026 5:57:25 AM
79,2026-03-13T05:57:25.539436900Z,ESU5,6363.75,48,6364,64,3/13/2026 5:57:25 AM
78,2026-03-13T05:57:25.425439200Z,ESU5,6363.75,49,6364,64,3/13/2026 5:57:25 AM
77,2026-03-13T05:57:25.298054100Z,ESU5,6363.75,51,6364,64,3/13/2026 5:57:25 AM
76,2026-03-13T05:57:25.177965500Z,ESU5,6363.75,51,6364,63,3/13/2026 5:57:25 AM
75,2026-03-13T05:57:25.068062900Z,ESU5,6363.75,52,6364,63,3/13/2026 5:57:25 AM
74,2026-03-13T05:57:24.963428500Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
73,2026-03-13T05:57:24.781215700Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
72,2026-03-13T05:57:24.676290100Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
71,2026-03-13T05:57:24.566898400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
70,2026-03-13T05:57:24.430800400Z,ESU5,6363.75,57,6364,63,3/13/2026 5:57:24 AM
69,2026-03-13T05:57:24.273683400Z,ESU5,6363.75,56,6364,63,3/13/2026 5:57:24 AM
68,2026-03-13T05:57:24.167656100Z,ESU5,6363.75,56,6364,64,3/13/2026 5:57:24 AM
67,2026-03-13T05:57:23.995720100Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:23 AM
66,2026-03-13T05:57:23.894029100Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
65,2026-03-13T05:57:23.728897300Z,ESU5,6363.75,56,6364,68,3/13/2026 5:57:23 AM
64,2026-03-13T05:57:23.614316800Z,ESU5,6363.75,52,6364,68,3/13/2026 5:57:23 AM
63,2026-03-13T05:57:23.503752700Z,ESU5,6363.75,51,6364,68,3/13/2026 5:57:23 AM
62,2026-03-13T05:57:23.289108200Z,ESU5,6363.75,50,6364,68,3/13/2026 5:57:23 AM
61,2026-03-13T05:57:23.155673400Z,ESU5,6363.75,49,6364,68,3/13/2026 5:57:23 AM
60,2026-03-13T05:57:23.028898400Z,ESU5,6363.75,48,6364,68,3/13/2026 5:57:23 AM
59,2026-03-13T05:57:22.887132700Z,ESU5,6363.75,46,6364,68,3/13/2026 5:57:22 AM
58,2026-03-13T05:57:22.676916300Z,ESU5,6363.75,44,6364,68,3/13/2026 5:57:22 AM
57,2026-03-13T05:57:22.520328000Z,ESU5,6363.75,43,6364,68,3/13/2026 5:57:22 AM
56,2026-03-13T05:57:22.405244600Z,ESU5,6363.75,43,6364,69,3/13/2026 5:57:22 AM
55,2026-03-13T05:57:22.294674100Z,ESU5,6363.75,41,6364,69,3/13/2026 5:57:22 AM
54,2026-03-13T05:57:22.163467900Z,ESU5,6363.75,38,6364,69,3/13/2026 5:57:22 AM
53,2026-03-13T05:57:21.992443000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
52,2026-03-13T05:57:21.872338400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:21 AM
51,2026-03-13T05:57:21.742801800Z,ESU5,6363.75,37,6364,71,3/13/2026 5:57:21 AM
50,2026-03-13T05:57:21.557711100Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
49,2026-03-13T05:57:21.434977000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
48,2026-03-13T05:57:21.285751600Z,ESU5,6363.75,37,6364,72,3/13/2026 5:57:21 AM
47,2026-03-13T05:57:21.184392000Z,ESU5,6363.75,37,6364,73,3/13/2026 5:57:21 AM
46,2026-03-13T05:57:21.076843800Z,ESU5,6363.75,34,6364,73,3/13/2026 5:57:21 AM
45,2026-03-13T05:57:20.894131800Z,ESU5,6363.75,32,6364,73,3/13/2026 5:57:20 AM
44,2026-03-13T05:57:20.759550000Z,ESU5,6363.75,30,6364,73,3/13/2026 5:57:20 AM
43,2026-03-13T05:57:20.641547900Z,ESU5,6363.75,28,6364,73,3/13/2026 5:57:20 AM
42,2026-03-13T05:57:20.540293200Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
41,2026-03-13T05:57:20.439034600Z,ESU5,6363.75,27,6364,74,3/13/2026 5:57:20 AM
40,2026-03-13T05:57:20.337795000Z,ESU5,6363.75,27,6364,73,3/13/2026 5:57:20 AM
39,2026-03-13T05:57:20.236606600Z,ESU5,6363.75,27,6364,72,3/13/2026 5:57:20 AM
38,2026-03-13T05:57:20.135417700Z,ESU5,6363.75,30,6364,72,3/13/2026 5:57:20 AM
37,2026-03-13T05:57:20.034272700Z,ESU5,6363.75,32,6364,72,3/13/2026 5:57:20 AM
36,2026-03-13T05:57:19.933096800Z,ESU5,6363.75,34,6364,72,3/13/2026 5:57:19 AM
35,2026-03-13T05:57:19.832012600Z,ESU5,6363.75,36,6364,72,3/13/2026 5:57:19 AM
34,2026-03-13T05:57:19.730878500Z,ESU5,6363.75,38,6364,72,3/13/2026 5:57:19 AM
33,2026-03-13T05:57:19.629787400Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
32,2026-03-13T05:57:19.528697000Z,ESU5,6363.75,38,6364,70,3/13/2026 5:57:19 AM
31,2026-03-13T05:57:19.427077000Z,ESU5,6363.75,38,6364,71,3/13/2026 5:57:19 AM
30,2026-03-13T05:57:19.326450300Z,ESU5,6363.75,39,6364,71,3/13/2026 5:57:19 AM
29,2026-03-13T05:57:19.225427900Z,ESU5,6363.75,39,6364,70,3/13/2026 5:57:19 AM
28,2026-03-13T05:57:19.123339800Z,ESU5,6363.75,40,6364,70,3/13/2026 5:57:19 AM
27,2026-03-13T05:57:19.021936500Z,ESU5,6363.75,41,6364,70,3/13/2026 5:57:19 AM
26,2026-03-13T05:57:18.920859200Z,ESU5,6363.75,45,6364,70,3/13/2026 5:57:18 AM
25,2026-03-13T05:57:18.820148400Z,ESU5,6363.75,46,6364,70,3/13/2026 5:57:18 AM
24,2026-03-13T05:57:18.718988100Z,ESU5,6363.75,46,6364,69,3/13/2026 5:57:18 AM
23,2026-03-13T05:57:18.618299700Z,ESU5,6363.75,49,6364,69,3/13/2026 5:57:18 AM
22,2026-03-13T05:57:18.517138100Z,ESU5,6363.75,52,6364,69,3/13/2026 5:57:18 AM
21,2026-03-13T05:57:18.416335200Z,ESU5,6363.75,53,6364,69,3/13/2026 5:57:18 AM
20,2026-03-13T05:57:18.315335900Z,ESU5,6363.75,55,6364,69,3/13/2026 5:57:18 AM
19,2026-03-13T05:57:18.214368600Z,ESU5,6363.75,57,6364,69,3/13/2026 5:57:18 AM
18,2026-03-13T05:57:18.113754700Z,ESU5,6363.75,57,6364,65,3/13/2026 5:57:18 AM
17,2026-03-13T05:57:18.012706500Z,ESU5,6363.75,56,6364,65,3/13/2026 5:57:18 AM
16,2026-03-13T05:57:17.911672600Z,ESU5,6363.75,54,6364,65,3/13/2026 5:57:17 AM
15,2026-03-13T05:57:17.810879900Z,ESU5,6363.75,52,6364,65,3/13/2026 5:57:17 AM
14,2026-03-13T05:57:17.710089700Z,ESU5,6363.75,49,6364,65,3/13/2026 5:57:17 AM
13,2026-03-13T05:57:17.609388300Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
12,2026-03-13T05:57:17.508697400Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
11,2026-03-13T05:57:17.408027000Z,ESU5,6363.75,53,6364,67,3/13/2026 5:57:17 AM
10,2026-03-13T05:57:17.307406200Z,ESU5,6363.75,49,6364,67,3/13/2026 5:57:17 AM
9,2026-03-13T05:57:17.206714300Z,ESU5,6363.75,49,6364,71,3/13/2026 5:57:17 AM
8,2026-03-13T05:57:17.105530300Z,ESU5,6363.75,48,6364,71,3/13/2026 5:57:17 AM
7,2026-03-13T05:57:17.004796800Z,ESU5,6363.75,47,6364,71,3/13/2026 5:57:17 AM
6,2026-03-13T05:57:16.904113900Z,ESU5,6363.75,46,6364,71,3/13/2026 5:57:16 AM
5,2026-03-13T05:57:16.803381900Z,ESU5,6363.75,43,6364,71,3/13/2026 5:57:16 AM
4,2026-03-13T05:57:16.701969600Z,ESU5,6363.75,43,6364,72,3/13/2026 5:57:16 AM
3,2026-03-13T05:57:16.600765600Z,ESU5,6363.75,43,6364,73,3/13/2026 5:57:16 AM
2,2026-03-13T05:57:16.499986300Z,ESU5,6363.75,43,6364,74,3/13/2026 5:57:16 AM
1,2026-03-13T05:57:16.399241700Z,ESU5,6363.75,43,6364,75,3/13/2026 5:57:16 AM
0,2026-03-13T05:57:16.264038000Z,ESU5,6363.75,43,6364,76,3/13/2026 5:57:16 AM
1 id ts_event contract bid_price bid_size ask_price ask_size timestamp
2 89 2026-03-13T05:57:26.904401600Z ESU5 6363.75 43 6364 67 3/13/2026 5:57:26 AM
3 88 2026-03-13T05:57:26.778037200Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:26 AM
4 87 2026-03-13T05:57:26.597038500Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:26 AM
5 86 2026-03-13T05:57:26.438768300Z ESU5 6363.75 43 6364 68 3/13/2026 5:57:26 AM
6 85 2026-03-13T05:57:26.328259100Z ESU5 6363.75 43 6364 67 3/13/2026 5:57:26 AM
7 84 2026-03-13T05:57:26.216211200Z ESU5 6363.75 44 6364 67 3/13/2026 5:57:26 AM
8 83 2026-03-13T05:57:26.099281200Z ESU5 6363.75 46 6364 67 3/13/2026 5:57:26 AM
9 82 2026-03-13T05:57:25.979814900Z ESU5 6363.75 48 6364 67 3/13/2026 5:57:25 AM
10 81 2026-03-13T05:57:25.852317700Z ESU5 6363.75 48 6364 66 3/13/2026 5:57:25 AM
11 80 2026-03-13T05:57:25.684323100Z ESU5 6363.75 48 6364 65 3/13/2026 5:57:25 AM
12 79 2026-03-13T05:57:25.539436900Z ESU5 6363.75 48 6364 64 3/13/2026 5:57:25 AM
13 78 2026-03-13T05:57:25.425439200Z ESU5 6363.75 49 6364 64 3/13/2026 5:57:25 AM
14 77 2026-03-13T05:57:25.298054100Z ESU5 6363.75 51 6364 64 3/13/2026 5:57:25 AM
15 76 2026-03-13T05:57:25.177965500Z ESU5 6363.75 51 6364 63 3/13/2026 5:57:25 AM
16 75 2026-03-13T05:57:25.068062900Z ESU5 6363.75 52 6364 63 3/13/2026 5:57:25 AM
17 74 2026-03-13T05:57:24.963428500Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
18 73 2026-03-13T05:57:24.781215700Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
19 72 2026-03-13T05:57:24.676290100Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
20 71 2026-03-13T05:57:24.566898400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
21 70 2026-03-13T05:57:24.430800400Z ESU5 6363.75 57 6364 63 3/13/2026 5:57:24 AM
22 69 2026-03-13T05:57:24.273683400Z ESU5 6363.75 56 6364 63 3/13/2026 5:57:24 AM
23 68 2026-03-13T05:57:24.167656100Z ESU5 6363.75 56 6364 64 3/13/2026 5:57:24 AM
24 67 2026-03-13T05:57:23.995720100Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:23 AM
25 66 2026-03-13T05:57:23.894029100Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
26 65 2026-03-13T05:57:23.728897300Z ESU5 6363.75 56 6364 68 3/13/2026 5:57:23 AM
27 64 2026-03-13T05:57:23.614316800Z ESU5 6363.75 52 6364 68 3/13/2026 5:57:23 AM
28 63 2026-03-13T05:57:23.503752700Z ESU5 6363.75 51 6364 68 3/13/2026 5:57:23 AM
29 62 2026-03-13T05:57:23.289108200Z ESU5 6363.75 50 6364 68 3/13/2026 5:57:23 AM
30 61 2026-03-13T05:57:23.155673400Z ESU5 6363.75 49 6364 68 3/13/2026 5:57:23 AM
31 60 2026-03-13T05:57:23.028898400Z ESU5 6363.75 48 6364 68 3/13/2026 5:57:23 AM
32 59 2026-03-13T05:57:22.887132700Z ESU5 6363.75 46 6364 68 3/13/2026 5:57:22 AM
33 58 2026-03-13T05:57:22.676916300Z ESU5 6363.75 44 6364 68 3/13/2026 5:57:22 AM
34 57 2026-03-13T05:57:22.520328000Z ESU5 6363.75 43 6364 68 3/13/2026 5:57:22 AM
35 56 2026-03-13T05:57:22.405244600Z ESU5 6363.75 43 6364 69 3/13/2026 5:57:22 AM
36 55 2026-03-13T05:57:22.294674100Z ESU5 6363.75 41 6364 69 3/13/2026 5:57:22 AM
37 54 2026-03-13T05:57:22.163467900Z ESU5 6363.75 38 6364 69 3/13/2026 5:57:22 AM
38 53 2026-03-13T05:57:21.992443000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
39 52 2026-03-13T05:57:21.872338400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:21 AM
40 51 2026-03-13T05:57:21.742801800Z ESU5 6363.75 37 6364 71 3/13/2026 5:57:21 AM
41 50 2026-03-13T05:57:21.557711100Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
42 49 2026-03-13T05:57:21.434977000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
43 48 2026-03-13T05:57:21.285751600Z ESU5 6363.75 37 6364 72 3/13/2026 5:57:21 AM
44 47 2026-03-13T05:57:21.184392000Z ESU5 6363.75 37 6364 73 3/13/2026 5:57:21 AM
45 46 2026-03-13T05:57:21.076843800Z ESU5 6363.75 34 6364 73 3/13/2026 5:57:21 AM
46 45 2026-03-13T05:57:20.894131800Z ESU5 6363.75 32 6364 73 3/13/2026 5:57:20 AM
47 44 2026-03-13T05:57:20.759550000Z ESU5 6363.75 30 6364 73 3/13/2026 5:57:20 AM
48 43 2026-03-13T05:57:20.641547900Z ESU5 6363.75 28 6364 73 3/13/2026 5:57:20 AM
49 42 2026-03-13T05:57:20.540293200Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
50 41 2026-03-13T05:57:20.439034600Z ESU5 6363.75 27 6364 74 3/13/2026 5:57:20 AM
51 40 2026-03-13T05:57:20.337795000Z ESU5 6363.75 27 6364 73 3/13/2026 5:57:20 AM
52 39 2026-03-13T05:57:20.236606600Z ESU5 6363.75 27 6364 72 3/13/2026 5:57:20 AM
53 38 2026-03-13T05:57:20.135417700Z ESU5 6363.75 30 6364 72 3/13/2026 5:57:20 AM
54 37 2026-03-13T05:57:20.034272700Z ESU5 6363.75 32 6364 72 3/13/2026 5:57:20 AM
55 36 2026-03-13T05:57:19.933096800Z ESU5 6363.75 34 6364 72 3/13/2026 5:57:19 AM
56 35 2026-03-13T05:57:19.832012600Z ESU5 6363.75 36 6364 72 3/13/2026 5:57:19 AM
57 34 2026-03-13T05:57:19.730878500Z ESU5 6363.75 38 6364 72 3/13/2026 5:57:19 AM
58 33 2026-03-13T05:57:19.629787400Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
59 32 2026-03-13T05:57:19.528697000Z ESU5 6363.75 38 6364 70 3/13/2026 5:57:19 AM
60 31 2026-03-13T05:57:19.427077000Z ESU5 6363.75 38 6364 71 3/13/2026 5:57:19 AM
61 30 2026-03-13T05:57:19.326450300Z ESU5 6363.75 39 6364 71 3/13/2026 5:57:19 AM
62 29 2026-03-13T05:57:19.225427900Z ESU5 6363.75 39 6364 70 3/13/2026 5:57:19 AM
63 28 2026-03-13T05:57:19.123339800Z ESU5 6363.75 40 6364 70 3/13/2026 5:57:19 AM
64 27 2026-03-13T05:57:19.021936500Z ESU5 6363.75 41 6364 70 3/13/2026 5:57:19 AM
65 26 2026-03-13T05:57:18.920859200Z ESU5 6363.75 45 6364 70 3/13/2026 5:57:18 AM
66 25 2026-03-13T05:57:18.820148400Z ESU5 6363.75 46 6364 70 3/13/2026 5:57:18 AM
67 24 2026-03-13T05:57:18.718988100Z ESU5 6363.75 46 6364 69 3/13/2026 5:57:18 AM
68 23 2026-03-13T05:57:18.618299700Z ESU5 6363.75 49 6364 69 3/13/2026 5:57:18 AM
69 22 2026-03-13T05:57:18.517138100Z ESU5 6363.75 52 6364 69 3/13/2026 5:57:18 AM
70 21 2026-03-13T05:57:18.416335200Z ESU5 6363.75 53 6364 69 3/13/2026 5:57:18 AM
71 20 2026-03-13T05:57:18.315335900Z ESU5 6363.75 55 6364 69 3/13/2026 5:57:18 AM
72 19 2026-03-13T05:57:18.214368600Z ESU5 6363.75 57 6364 69 3/13/2026 5:57:18 AM
73 18 2026-03-13T05:57:18.113754700Z ESU5 6363.75 57 6364 65 3/13/2026 5:57:18 AM
74 17 2026-03-13T05:57:18.012706500Z ESU5 6363.75 56 6364 65 3/13/2026 5:57:18 AM
75 16 2026-03-13T05:57:17.911672600Z ESU5 6363.75 54 6364 65 3/13/2026 5:57:17 AM
76 15 2026-03-13T05:57:17.810879900Z ESU5 6363.75 52 6364 65 3/13/2026 5:57:17 AM
77 14 2026-03-13T05:57:17.710089700Z ESU5 6363.75 49 6364 65 3/13/2026 5:57:17 AM
78 13 2026-03-13T05:57:17.609388300Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
79 12 2026-03-13T05:57:17.508697400Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
80 11 2026-03-13T05:57:17.408027000Z ESU5 6363.75 53 6364 67 3/13/2026 5:57:17 AM
81 10 2026-03-13T05:57:17.307406200Z ESU5 6363.75 49 6364 67 3/13/2026 5:57:17 AM
82 9 2026-03-13T05:57:17.206714300Z ESU5 6363.75 49 6364 71 3/13/2026 5:57:17 AM
83 8 2026-03-13T05:57:17.105530300Z ESU5 6363.75 48 6364 71 3/13/2026 5:57:17 AM
84 7 2026-03-13T05:57:17.004796800Z ESU5 6363.75 47 6364 71 3/13/2026 5:57:17 AM
85 6 2026-03-13T05:57:16.904113900Z ESU5 6363.75 46 6364 71 3/13/2026 5:57:16 AM
86 5 2026-03-13T05:57:16.803381900Z ESU5 6363.75 43 6364 71 3/13/2026 5:57:16 AM
87 4 2026-03-13T05:57:16.701969600Z ESU5 6363.75 43 6364 72 3/13/2026 5:57:16 AM
88 3 2026-03-13T05:57:16.600765600Z ESU5 6363.75 43 6364 73 3/13/2026 5:57:16 AM
89 2 2026-03-13T05:57:16.499986300Z ESU5 6363.75 43 6364 74 3/13/2026 5:57:16 AM
90 1 2026-03-13T05:57:16.399241700Z ESU5 6363.75 43 6364 75 3/13/2026 5:57:16 AM
91 0 2026-03-13T05:57:16.264038000Z ESU5 6363.75 43 6364 76 3/13/2026 5:57:16 AM
+187
View File
@@ -0,0 +1,187 @@
from __future__ import annotations
from dataclasses import dataclass
import json
import os
import subprocess
import threading
from typing import Any, Callable, Dict, List, Optional
@dataclass
class DataPacket:
state: List[Any]
deleted_ids: List[int]
added_ids: List[int]
@dataclass
class DslResponse:
data_packet: DataPacket | None
req_id: str | None
error: str | None
def _resolve_interop_exe() -> str:
env_path = os.environ.get("BLUEORB_DSL_INTEROP")
if env_path and os.path.isfile(env_path):
return env_path
candidates = [
"/workspaces/spark/build/Debug/bin/net8.0/BlueOrbDSLInteropServer",
"/workspaces/spark/build/Release/bin/net8.0/BlueOrbDSLInteropServer",
]
for path in candidates:
if os.path.isfile(path):
return path
raise FileNotFoundError(
"BlueOrbDSLInterop executable not found. "
"Set BLUEORB_DSL_INTEROP to the full path."
)
_interop_proc: Optional[subprocess.Popen] = None
_reader_thread: Optional[threading.Thread] = None
_callbacks: Dict[str, Callable[[DslResponse], None]] = {}
_first_response_events: Dict[str, threading.Event] = {}
_first_responses: Dict[str, DslResponse] = {}
_state_lock = threading.Lock()
def start_interop() -> None:
"""
Start the BlueOrbDSLInteropServer process if it's not already running.
"""
global _interop_proc
if _interop_proc is not None and _interop_proc.poll() is None:
return
exe = _resolve_interop_exe()
_interop_proc = subprocess.Popen(
[exe],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
_start_reader_thread()
def stop_interop() -> None:
"""
Stop the BlueOrbDSLInteropServer process if it's running.
"""
global _interop_proc
if _interop_proc is None:
return
if _interop_proc.poll() is None and _interop_proc.stdin is not None:
_interop_proc.stdin.write(":exit\n")
_interop_proc.stdin.flush()
_interop_proc.stdin.close()
_interop_proc.wait(timeout=5)
global _reader_thread
if _reader_thread is not None:
_reader_thread.join(timeout=1)
_reader_thread = None
with _state_lock:
_callbacks.clear()
_first_response_events.clear()
_first_responses.clear()
_interop_proc = None
def get_interop_status() -> tuple[bool, int | None]:
"""
Returns current interop process status as (is_running, exit_code).
exit_code is None when process was never started or is still running.
"""
proc = _interop_proc
if proc is None:
return (False, None)
rc = proc.poll()
return (rc is None, rc)
def get_dsl(dsl: str, req_id: str, callback: Callable[[DslResponse], None]) -> DslResponse:
"""
Sends the DSL to BlueOrbDSLInteropServer and returns the first response for this req_id.
Subsequent streaming updates for the same req_id are delivered via callback.
Requires start_interop() to be called first.
"""
assert _interop_proc is not None and _interop_proc.poll() is None, (
"Interop process is not running. Call start_interop() first."
)
assert _interop_proc.stdin is not None
payload = {"dsl": dsl, "req_id": req_id}
first_event = threading.Event()
with _state_lock:
_callbacks[req_id] = callback
_first_response_events[req_id] = first_event
_first_responses.pop(req_id, None)
_interop_proc.stdin.write(json.dumps(payload) + "\n")
_interop_proc.stdin.flush()
if not first_event.wait(timeout=10):
with _state_lock:
_first_response_events.pop(req_id, None)
_callbacks.pop(req_id, None)
raise TimeoutError(f"No response received for req_id '{req_id}' from BlueOrbDSLInterop.")
with _state_lock:
response = _first_responses.pop(req_id, None)
_first_response_events.pop(req_id, None)
if response is None:
raise RuntimeError(f"Missing first response for req_id '{req_id}'.")
return response
def _start_reader_thread() -> None:
global _reader_thread
if _reader_thread is not None and _reader_thread.is_alive():
return
_reader_thread = threading.Thread(target=_reader_loop, daemon=True)
_reader_thread.start()
def _reader_loop() -> None:
while True:
proc = _interop_proc
if proc is None or proc.poll() is not None:
return
assert proc.stdout is not None
raw = proc.stdout.readline()
if raw == "":
return
line = raw.strip()
if not line:
continue
try:
payload = json.loads(line)
except json.JSONDecodeError:
continue
response = DslResponse(
data_packet=DataPacket(state=[payload.get("data_packet")], deleted_ids=[], added_ids=[]),
req_id=payload.get("req_id"),
error=payload.get("error"),
)
req_id = response.req_id
if not req_id:
continue
callback: Optional[Callable[[DslResponse], None]]
event: Optional[threading.Event]
with _state_lock:
callback = _callbacks.get(req_id)
event = _first_response_events.get(req_id)
if event is not None and req_id not in _first_responses:
_first_responses[req_id] = response
event.set()
if callback is not None:
try:
callback(response)
except Exception:
# Keep the reader alive if callback logic fails.
pass
@@ -0,0 +1,33 @@
import os
import sys
import uuid
_here = os.path.dirname(os.path.abspath(__file__))
_parent = os.path.dirname(_here)
if _parent not in sys.path:
sys.path.insert(0, _parent)
from BlueOrbDSL import get_dsl, start_interop, stop_interop, DslResponse
def on_packet(response: DslResponse) -> None:
print("callback from DSL Server, DslResponse:", response)
def main() -> None:
start_interop()
try:
while True:
dsl = input("Enter DSL (or 'quit'): ").strip()
if dsl.lower() == "quit":
break
if not dsl:
continue
response = get_dsl(dsl, str(uuid.uuid4()), on_packet)
print("return:", response)
finally:
stop_interop()
if __name__ == "__main__":
main()
+844
View File
@@ -0,0 +1,844 @@
from __future__ import annotations
import csv
import time
import os
import sys
import threading
import uuid
from collections import deque
from datetime import datetime
from typing import Any
from rich.text import Text
from rich.style import Style
from textual import events
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Container, Horizontal, Vertical
from textual.widgets.text_area import TextAreaTheme
from textual.widgets import Button, DataTable, Input, Static, TabbedContent, TabPane, TextArea, Tree
_here = os.path.dirname(os.path.abspath(__file__))
_parent = os.path.dirname(_here)
if _parent not in sys.path:
sys.path.insert(0, _parent)
from BlueOrbDSL import DslResponse, get_dsl, get_interop_status, start_interop, stop_interop
class DSQALiveConsole(App):
DEFAULT_QUERY = (
'FROM market.ticks\n'
'WHERE symbol IN ("BTCUSD", "ETHUSD")\n'
"SELECT symbol, price, change, time"
)
LAST_QUERY_PATH = os.path.join(_here, "DSQA_LAST_EXECUTED_QUERY.txt")
DSL_HIGHLIGHT_QUERY = r"""
; comments
(comment) @comment
; assignment vars: lhs in x = SomeStream(...)
(assignment_expression
left: (identifier) @variable)
; stream operators (function names ending with Stream)
(call_expression
function: (identifier) @function
(#match? @function "^[A-Za-z_][A-Za-z0-9_]*Stream$"))
; normal function calls
(call_expression
function: (identifier) @function.method)
; arguments and literals
(arguments (identifier) @parameter)
(string) @string
(number) @number
(true) @constant.builtin
(false) @constant.builtin
(null) @constant.builtin
"""
BINDINGS = [
Binding("ctrl+r", "execute", "Execute"),
Binding("f11", "execute", show=False),
Binding("alt+enter", "execute", show=False),
# Override Textual's default Ctrl+Q quit to avoid accidental VS Code close.
Binding("ctrl+q", "noop", show=False),
Binding("ctrl+x", "quit", "Quit"),
]
CSS = """
Screen {
background: #060a1c;
color: #d8dff4;
}
#window_close_button {
width: 3;
min-width: 3;
height: 1;
margin: 0;
border: none;
background: #3a1015;
color: #ff9ca8;
text-style: bold;
}
#window_close_button:hover,
#window_close_button:focus {
background: #5a1620;
color: #ffd6db;
}
#root {
padding: 0 1 0 1;
height: 1fr;
}
#query_panel {
background: #070d27;
height: 33%;
margin-top: 1;
}
#query_header_row {
height: 1;
border-bottom: solid #596285;
}
#query_header {
width: auto;
color: #9eb0d4;
content-align: left middle;
}
#query_header_spacer {
width: 1fr;
}
#query_input {
border: solid #697597;
background: #050b22;
color: #cfd7eb;
height: 1fr;
padding-left: 1;
}
#results_panel {
background: #070d27;
height: 1fr;
margin-top: 1;
}
#results_toolbar {
height: 3;
padding: 0 1;
}
#results_left {
width: auto;
height: 3;
margin-top: 0;
}
#stream_toggle_button {
width: auto;
min-width: 11;
margin-top: 0;
margin-left: 1;
border: none;
background: #070d27;
color: #79afe7;
}
#stream_toggle_button:hover,
#stream_toggle_button:focus {
background: #111a3f;
color: #9bc9f6;
}
#execute_button {
width: 5;
min-width: 5;
margin-top: 0;
margin-left: 1;
border: none;
background: #10341f;
color: #7ef1ac;
text-style: bold;
}
#execute_button:hover,
#execute_button:focus {
background: #1a4f30;
color: #b3ffd0;
}
#results_actions {
width: auto;
height: 3;
margin-top: 0;
}
#results_spacer {
width: 1fr;
}
#results_search {
width: 30;
min-width: 24;
margin-right: 1;
border: none;
background: #060d28;
color: #d5def3;
padding: 0 1;
}
#search_button,
#copy_button,
#export_button {
width: auto;
min-width: 11;
margin-left: 1;
border: none;
background: #070d27;
color: #79afe7;
}
#search_button:hover,
#copy_button:hover,
#export_button:hover,
#search_button:focus,
#copy_button:focus,
#export_button:focus {
background: #111a3f;
color: #9bc9f6;
}
#results_table {
border: solid #697597;
background: #050b22;
height: 1fr;
}
#results_table .datatable--header,
#results_table .datatable--header-hover,
#results_table .datatable--header-cursor {
background: #0c1535;
color: #6ea6df;
text-style: bold;
}
#results_table .datatable--even-row {
background: #050b22;
}
#results_table .datatable--odd-row {
background: #07102a;
}
#results_table .datatable--cursor {
background: #19335b;
color: #dbe8ff;
}
#results_table .datatable--fixed-cursor {
background: #132949;
color: #c8dbff;
}
#results_table.error .datatable--odd-row,
#results_table.error .datatable--even-row,
#results_table.error .datatable--cursor,
#results_table.error .datatable--fixed-cursor {
color: #f17486;
text-style: bold;
}
#results_panel.paused {
background: #150f1f;
}
#results_table.paused {
background: #130f18;
}
#results_table.paused .datatable--header,
#results_table.paused .datatable--header-hover,
#results_table.paused .datatable--header-cursor {
background: #262338;
color: #8b90a1;
text-style: bold;
}
#results_tabs {
height: 1fr;
background: #070d27;
}
#data_tab,
#tree_tab {
padding: 0;
}
#ops_tree {
border: solid #697597;
background: #050b22;
color: #cfd7eb;
height: 1fr;
}
#bottom_status_bar {
border-top: solid #596285;
background: #070d27;
height: 2;
margin: 0;
padding: 0 1;
}
#status_right_wrap {
width: 1fr;
}
#status_row {
height: 1;
margin-top: 0;
width: 1fr;
}
#live_status {
width: 1fr;
color: #b3bed9;
content-align: right middle;
}
"""
def compose(self) -> ComposeResult:
with Container(id="root"):
with Vertical(id="query_panel"):
with Horizontal(id="query_header_row"):
yield Static("DSL Query", id="query_header")
yield Static("", id="query_header_spacer")
yield Button("✕", id="window_close_button")
yield TextArea(
text=self._load_last_query(),
id="query_input",
language="javascript",
theme="vscode_dark",
show_line_numbers=True,
)
with Vertical(id="results_panel"):
with Horizontal(id="results_toolbar"):
with Horizontal(id="results_left"):
yield Button("▶", id="execute_button")
yield Button("⏸ Pause", id="stream_toggle_button")
yield Static("", id="results_spacer")
with Horizontal(id="results_actions"):
yield Input(placeholder="Search: col:value", id="results_search")
yield Button("⌕ Search", id="search_button")
yield Button("⧉ Copy", id="copy_button")
yield Button("⇩ Export", id="export_button")
with TabbedContent(initial="data_tab", id="results_tabs"):
with TabPane("Data", id="data_tab"):
table = DataTable(id="results_table")
table.cursor_type = "cell"
table.show_cursor = True
table.zebra_stripes = True
yield table
with TabPane("Operators", id="tree_tab"):
tree = Tree("Assemblies", id="ops_tree")
tree.show_root = False
yield tree
with Horizontal(id="bottom_status_bar"):
with Horizontal(id="status_right_wrap"):
with Horizontal(id="status_row"):
yield Static(
"Rows: 0 | Rate: 0.0/s | Total Updates: 0 | Uptime: 00:00:00 | Last Update: --:--:--",
id="live_status",
)
def on_mount(self) -> None:
self._update_timestamps: deque[float] = deque()
self._last_update_at: datetime | None = None
self._stream_started_at: float | None = None
self._total_updates = 0
self._last_row_count = 0
self._current_col_names: list[str] = []
self._current_rows: list[dict[str, Any]] = []
self._column_width_cache: dict[str, int] = {}
self._ops_catalog_rows: list[dict[str, Any]] = []
self._ops_catalog_error: str | None = None
self._ops_catalog_loaded = False
self._ops_catalog_loading = False
self._interop_is_running = False
self._interop_exit_code: int | None = None
self._grid_updates_enabled = True
self._paused_latest_response: DslResponse | None = None
self._ensure_interop_started()
self._refresh_ops_tree()
self._refresh_ops_tree_async()
self._configure_query_highlighting()
self._set_pause_visuals()
self.set_interval(0.5, self._refresh_status)
def _configure_query_highlighting(self) -> None:
query_input = self.query_one("#query_input", TextArea)
query_input.language = "javascript"
dsl_theme = TextAreaTheme(
"dsqa_ide",
base_style=Style.parse("#d7deee on #171a22"),
gutter_style=Style.parse("#8a93a8 on #1c212b"),
cursor_style=Style.parse("#ffffff on #2b3242"),
cursor_line_style=Style.parse("on #202534"),
cursor_line_gutter_style=Style.parse("#a6afc4 on #202534"),
selection_style=Style.parse("on #2a3f67"),
bracket_matching_style=Style.parse("bold #7fd9ff"),
syntax_styles={
"comment": Style.parse("italic #6f778a"),
"variable": Style.parse("bold #4ec9b0"),
"function": Style.parse("bold #4fc1ff"),
"function.method": Style.parse("bold #70d4ff"),
"parameter": Style.parse("#c6d4f8"),
"string": Style.parse("#d7ba7d"),
"number": Style.parse("#b5cea8"),
"constant.builtin": Style.parse("bold #569cd6"),
},
)
query_input.register_theme(dsl_theme)
query_input.theme = "dsqa_ide"
try:
query_input.update_highlight_query(self.DSL_HIGHLIGHT_QUERY)
except Exception:
pass
def on_shutdown(self) -> None:
stop_interop()
@staticmethod
def _ensure_interop_started() -> None:
try:
start_interop()
except Exception:
pass
def action_execute(self) -> None:
tabs = self.query_one("#results_tabs", TabbedContent)
tabs.active = "data_tab"
self._grid_updates_enabled = True
self._set_stream_toggle_label()
self._set_pause_visuals()
self._execute_query_async()
def action_noop(self) -> None:
pass
def on_button_pressed(self, event: Button.Pressed) -> None:
button_id = event.button.id
if button_id == "search_button":
self._search_results()
elif button_id == "copy_button":
self._copy_selected_cell()
elif button_id == "export_button":
self._export_results_csv()
elif button_id == "execute_button":
self.action_execute()
elif button_id == "window_close_button":
self.exit()
elif button_id == "stream_toggle_button":
self._toggle_stream_painting()
def on_input_submitted(self, event: Input.Submitted) -> None:
if event.input.id == "results_search":
self._search_results()
def on_click(self, event: events.Click) -> None:
if getattr(event.widget, "id", None) != "ops_tree":
return
line = event.style.meta.get("line")
if line is None:
return
tree = self.query_one("#ops_tree", Tree)
node = tree.get_node_at_line(line)
if node is None:
return
node_data = node.data
if not isinstance(node_data, dict) or node_data.get("kind") != "constructor":
return
self._append_operator_to_query(self._stringify(node_data.get("op", "")).strip())
def _append_operator_to_query(self, op_name: str) -> None:
if not op_name:
return
query_input = self.query_one("#query_input", TextArea)
existing = query_input.text
if existing.strip():
separator = "" if existing.endswith("\n") else "\n"
query_input.text = f"{existing}{separator}{op_name}"
else:
query_input.text = op_name
query_input.focus()
def _execute_query_async(self) -> None:
self._ensure_interop_started()
query = self.query_one(TextArea).text.strip()
if not query:
return
self._column_width_cache.clear()
self._save_last_query(query)
self._update_timestamps.clear()
self._last_update_at = None
self._stream_started_at = time.monotonic()
self._total_updates = 0
self._last_row_count = 0
self._paused_latest_response = None
self._refresh_status()
req_id = str(uuid.uuid4())
def _run() -> None:
try:
def _on_response(resp: DslResponse) -> None:
self.call_from_thread(self._render_response, resp)
get_dsl(query, req_id, _on_response)
except Exception as exc:
error_resp = DslResponse(data_packet=None, req_id=req_id, error=str(exc))
self.call_from_thread(self._render_response, error_resp)
threading.Thread(target=_run, daemon=True).start()
def _render_response(self, response: DslResponse) -> None:
if not self._grid_updates_enabled:
self._paused_latest_response = response
return
self._render_response_internal(response)
def _render_response_internal(self, response: DslResponse) -> None:
self._record_update()
table = self.query_one(DataTable)
table.remove_class("error")
prev_scroll_x = table.scroll_offset.x
prev_scroll_y = table.scroll_offset.y
table.clear(columns=True)
if response.error:
table.add_class("error")
error_text = self._stringify(response.error)
error_lines = error_text.splitlines() or [error_text]
self._current_col_names = []
self._current_rows = []
self._last_row_count = len(error_lines)
self._refresh_ops_tree()
table.add_columns("error")
for line in error_lines:
table.add_row(Text(line, style="bold #f17486"))
return
if response.data_packet is None or not response.data_packet.state:
self._current_col_names = []
self._current_rows = []
self._last_row_count = 0
self._refresh_ops_tree()
table.add_columns("empty")
table.add_row("no data")
return
data_packet = response.data_packet.state[0]
columns = data_packet.get("columns", [])
rows = data_packet.get("all", [])
if not isinstance(rows, list):
rows = []
col_names = [c.get("name", "") for c in columns]
if not col_names:
col_names = list(rows[0].keys()) if rows else ["empty"]
self._current_col_names = col_names
self._current_rows = rows
self._last_row_count = len(rows)
self._refresh_ops_tree()
for col_name in col_names:
width = self._column_width_cache.get(col_name, len(col_name))
for row in rows:
if not isinstance(row, dict):
continue
cell_text = self._stringify(row.get(col_name, ""))
width = max(width, len(cell_text))
self._column_width_cache[col_name] = width
table.add_column(col_name, width=width)
for row in rows:
table.add_row(*[self._format_cell(c, row.get(c, "")) for c in col_names])
# Preserve user's viewport during streaming refreshes.
table.scroll_to(
x=min(prev_scroll_x, table.max_scroll_x),
y=min(prev_scroll_y, table.max_scroll_y),
animate=False,
)
@staticmethod
def _stringify(value: Any) -> str:
return "" if value is None else str(value)
@staticmethod
def _format_cell(column_name: str, value: Any) -> str | Text:
text = DSQALiveConsole._stringify(value)
lowered = column_name.lower()
if lowered == "id":
return Text(text, style="bold #9eb1d8")
if lowered == "symbol":
return Text(text, style="bold #dce6ff")
if lowered == "price":
return Text(text, style="bold #d4ddf2")
if lowered == "time":
return Text(text, style="#aab5d0")
if lowered == "change":
cleaned = text.strip()
if cleaned.startswith("-"):
return Text(text, style="bold #f17486")
if cleaned.startswith("+"):
return Text(text, style="bold #92d67e")
return Text(text, style="bold #c7d3ef")
if lowered == "bid":
return Text(text, style="bold #8cf3c0 on #123526")
if lowered == "ask":
return Text(text, style="bold #ffd5d9 on #3b1b25")
return text
def _record_update(self) -> None:
now = time.monotonic()
self._update_timestamps.append(now)
self._total_updates += 1
if self._stream_started_at is None:
self._stream_started_at = now
self._last_update_at = datetime.now()
self._refresh_status()
def _refresh_status(self) -> None:
self._refresh_interop_heartbeat()
now = time.monotonic()
cutoff = now - 1.0
while self._update_timestamps and self._update_timestamps[0] < cutoff:
self._update_timestamps.popleft()
rate = float(len(self._update_timestamps))
if self._stream_started_at is not None:
uptime_seconds = max(0, int(now - self._stream_started_at))
uptime = self._format_duration(uptime_seconds)
else:
uptime = "--:--:--"
last_update = self._last_update_at.strftime("%H:%M:%S") if self._last_update_at else "--:--:--"
status = Text()
if self._interop_is_running:
status.append("Interop: ● UP", style="bold #92d67e")
elif self._interop_exit_code is not None:
status.append(f"Interop: ● DOWN({self._interop_exit_code})", style="bold #f17486")
else:
status.append("Interop: ● DOWN", style="bold #8b90a1")
status.append(" | ")
status.append(f"Rows: {self._last_row_count} | Rate: {rate:.1f}/s | ")
status.append(f"Total Updates: {self._total_updates}", style="bold #79afe7")
status.append(f" | Uptime: {uptime} | ")
status.append(f"Last Update: {last_update}", style="bold #79afe7")
self.query_one("#live_status", Static).update(status)
def _refresh_interop_heartbeat(self) -> None:
is_running, exit_code = get_interop_status()
self._interop_is_running = is_running
self._interop_exit_code = exit_code
@staticmethod
def _format_duration(total_seconds: int) -> str:
hours = total_seconds // 3600
minutes = (total_seconds % 3600) // 60
seconds = total_seconds % 60
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
def _search_results(self) -> None:
raw = self.query_one("#results_search", Input).value.strip()
if ":" not in raw:
return
col_part, value_part = raw.split(":", 1)
target_col = col_part.strip()
target_value = value_part.strip()
if not target_col:
return
lookup = {name.lower(): idx for idx, name in enumerate(self._current_col_names)}
col_idx = lookup.get(target_col.lower())
if col_idx is None:
return
col_name = self._current_col_names[col_idx]
needle = target_value.lower()
for row_idx, row in enumerate(self._current_rows):
if not isinstance(row, dict):
continue
cell_value = self._stringify(row.get(col_name, ""))
if needle in cell_value.lower():
table = self.query_one("#results_table", DataTable)
table.move_cursor(row=row_idx, column=col_idx)
table.focus()
return
def _copy_selected_cell(self) -> None:
table = self.query_one("#results_table", DataTable)
if table.row_count == 0 or not self._current_col_names:
return
coordinate = table.cursor_coordinate
try:
cell = table.get_cell_at(coordinate)
except Exception:
return
if isinstance(cell, Text):
value = cell.plain
else:
value = self._stringify(cell)
self.copy_to_clipboard(value)
def _export_results_csv(self) -> None:
if not self._current_col_names:
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
export_path = os.path.join(_here, f"DSQA_RESULTS_EXPORT_{timestamp}.csv")
with open(export_path, "w", newline="", encoding="utf-8") as csv_file:
writer = csv.writer(csv_file)
writer.writerow(self._current_col_names)
for row in self._current_rows:
if isinstance(row, dict):
writer.writerow([self._stringify(row.get(col, "")) for col in self._current_col_names])
def _refresh_ops_tree(self) -> None:
tree = self.query_one("#ops_tree", Tree)
root = tree.root
root.remove_children()
if self._ops_catalog_error:
root.add(Text(self._ops_catalog_error, style="bold #f17486"))
root.expand()
return
grouped: dict[str, dict[str, dict[str, set[str]]]] = {}
for row in self._ops_catalog_rows:
if not isinstance(row, dict):
continue
row_lookup = {self._stringify(k).lower(): v for k, v in row.items()}
assembly_name = self._stringify(row_lookup.get("assembly_name", "")).strip() or "(unknown assembly)"
namespace = self._stringify(row_lookup.get("namespace", "")).strip() or "(global)"
op = self._stringify(row_lookup.get("op", "")).strip() or "(unknown op)"
constructor = self._stringify(row_lookup.get("constructor", "")).strip() or "(none)"
grouped.setdefault(assembly_name, {}).setdefault(namespace, {}).setdefault(op, set()).add(constructor)
if not grouped:
root.add(Text("No operator metadata available", style="#8ea0c6"))
root.expand()
return
for assembly_name in sorted(grouped.keys(), key=str.lower):
assembly_node = root.add(Text(assembly_name, style="bold #79afe7"))
for namespace in sorted(grouped[assembly_name].keys(), key=str.lower):
namespace_node = assembly_node.add(Text(namespace, style="#cfd7eb"))
for op in sorted(grouped[assembly_name][namespace].keys(), key=str.lower):
op_node = namespace_node.add(
Text(op, style="#b8c8e7"),
data={"kind": "op", "op": op},
)
for constructor in sorted(grouped[assembly_name][namespace][op], key=str.lower):
op_node.add(
Text(constructor, style="#9eb0d4"),
data={"kind": "constructor", "op": op, "constructor": constructor},
)
op_node.expand()
namespace_node.expand()
assembly_node.expand()
root.expand()
def _refresh_ops_tree_async(self) -> None:
if self._ops_catalog_loaded or self._ops_catalog_loading:
return
self._ensure_interop_started()
self._ops_catalog_loading = True
req_id = str(uuid.uuid4())
def _run() -> None:
try:
def _on_response(resp: DslResponse) -> None:
self.call_from_thread(self._update_ops_catalog, resp)
get_dsl("OpsStream()", req_id, _on_response)
except Exception as exc:
error_resp = DslResponse(data_packet=None, req_id=req_id, error=str(exc))
self.call_from_thread(self._update_ops_catalog, error_resp)
threading.Thread(target=_run, daemon=True).start()
def _update_ops_catalog(self, response: DslResponse) -> None:
self._ops_catalog_loading = False
if response.error:
self._ops_catalog_rows = []
self._ops_catalog_error = self._stringify(response.error)
self._refresh_ops_tree()
return
if response.data_packet is None or not response.data_packet.state:
self._ops_catalog_rows = []
self._ops_catalog_error = "OpsStream() returned no data"
self._refresh_ops_tree()
return
data_packet = response.data_packet.state[0]
rows = data_packet.get("all", [])
if not isinstance(rows, list):
rows = []
normalized_rows: list[dict[str, Any]] = []
for row in rows:
if isinstance(row, dict):
normalized_rows.append(row)
self._ops_catalog_rows = normalized_rows
self._ops_catalog_error = None
self._ops_catalog_loaded = True
self._refresh_ops_tree()
def _toggle_stream_painting(self) -> None:
self._grid_updates_enabled = not self._grid_updates_enabled
self._set_stream_toggle_label()
self._set_pause_visuals()
if self._grid_updates_enabled and self._paused_latest_response is not None:
latest = self._paused_latest_response
self._paused_latest_response = None
self._render_response_internal(latest)
def _set_stream_toggle_label(self) -> None:
button = self.query_one("#stream_toggle_button", Button)
button.label = "⏸ Pause" if self._grid_updates_enabled else "▶ Play"
def _set_pause_visuals(self) -> None:
table = self.query_one("#results_table", DataTable)
panel = self.query_one("#results_panel", Vertical)
if self._grid_updates_enabled:
table.remove_class("paused")
panel.remove_class("paused")
else:
table.add_class("paused")
panel.add_class("paused")
def _load_last_query(self) -> str:
try:
with open(self.LAST_QUERY_PATH, "r", encoding="utf-8") as file:
text = file.read().strip()
return text if text else self.DEFAULT_QUERY
except FileNotFoundError:
return self.DEFAULT_QUERY
except OSError:
return self.DEFAULT_QUERY
def _save_last_query(self, query: str) -> None:
try:
with open(self.LAST_QUERY_PATH, "w", encoding="utf-8") as file:
file.write(query)
except OSError:
pass
if __name__ == "__main__":
DSQALiveConsole().run()
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>BlueOrbDSLInteropServer</AssemblyName>
<RootNamespace>BlueOrbDSLInteropServer</RootNamespace>
</PropertyGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\..\cs\Bts.Spark.Api\Bts.Spark.Api.csproj" />
<ProjectReference Include="..\DataStream\DataStream.csproj" />
<ProjectReference Include="..\PubSub\PubSub.csproj" />
<ProjectReference Include="..\BlueOrbOperatorStreams\BlueOrbOperatorStreams.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="Bts.Spark.Api" Version="$(SparkVersion)" />
<PackageReference Include="DataStream" Version="$(SparkVersion)" />
<PackageReference Include="PubSub" Version="$(SparkVersion)" />
<PackageReference Include="BlueOrbOperatorStreams" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
</Project>
@@ -0,0 +1,122 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using BCG;
using bts.BlueOrb;
using Bts.DataStream;
using Bts.DataStreamCore;
using Bts.DataStreamExpressions;
using Bts.PubSub;
using MathNet.Numerics.Statistics;
namespace BlueOrbDSLInteropServer {
// BlueOrbDSLInteropServer reads DSL lines from stdin, validates them,
// and writes one DataPacket JSON line to stdout per input.
internal static class Program {
private const string ExitSignal = ":exit";
private static SyncQueue<DslRequest> _work_queue = new SyncQueue<DslRequest>();
private static JsonSerializerOptions response_json_options = new JsonSerializerOptions {
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
};
private static string _current_req_id;
// Request from Python
private sealed class DslRequest {
public string? dsl { get; set; }
public string? req_id { get; set; }
}
// Response envelope for Python: includes DataPacket, request id, and optional error.
private sealed class DslResponse {
public DataPacket? data_packet { get; set; }
public string? req_id { get; set; }
public string? error { get; set; }
}
private static void Main(string[] args) {
//System.Threading.Thread.Sleep(20000);
System.Threading.Thread thread = new Thread(_worker_loop);
thread.IsBackground = true;
thread.Start();
response_json_options.Converters.Add(new DataPacketJsonConverter {
IncludeCurrent = true,
UseObjectRows = true,
});
string? line;
while ((line = Console.ReadLine()) != null) {
line = line.Trim();
if (line.Length == 0) {
continue;
}
if (string.Equals(line, ExitSignal, StringComparison.OrdinalIgnoreCase)) {
break;
}
try {
DslRequest req = JsonSerializer.Deserialize<DslRequest>(line);
_work_queue.enqueue(req);
} catch (Exception ex) {
bts.Log.assert(false, ex.ToString());
}
}
}
private static void _worker_loop() {
Dictionary<string, ViewStream> req_map = new Dictionary<string, ViewStream>();
while (true) {
System.Threading.Thread.Sleep(100);
ViewStreamDatabase.instance.doWork();
var new_reqs = _work_queue.dequeue_all();
if (new_reqs == null || new_reqs.Count == 0) {
continue;
}
// ubsubscribing to previous stream(s)
foreach (var kv in req_map) {
kv.Value.onChange -= dp_obj => _on_dp(kv.Key, dp_obj);
}
foreach (var r in new_reqs) {
var req_id = string.IsNullOrWhiteSpace(r.req_id) ? Guid.NewGuid().ToString() : r.req_id;
_current_req_id = req_id;
try {
DSLStream dsl_str = new DSLStream(r.dsl);
req_map[req_id] = dsl_str;
dsl_str.onChange += dp_obj => _on_dp(req_id, dp_obj);
} catch (Exception ex) {
_write_error(req_id, ex.StackTrace);
}
}
}
}
private static void _on_dp(string req_id, object dp_obj) {
// eventhough we unsubscribe to all the other streams except the currrent one,
// sometimes the onLastSub is not implemented and we still get updates, this masks them
if (req_id != _current_req_id)
return;
DataPacket dp = dp_obj as DataPacket;
DslResponse response = new DslResponse() {
data_packet = dp,
req_id = req_id,
error = ""
};
var json = JsonSerializer.Serialize(response, response_json_options);
Console.WriteLine(json);
}
private static void _write_error(string req_id, string error) {
DslResponse response = new DslResponse() {
data_packet = null,
req_id = req_id,
error = error
};
var json = JsonSerializer.Serialize(response, response_json_options);
Console.WriteLine(json);
}
}
}
@@ -0,0 +1,514 @@
// namespace BlueOrb.Operators.Signal;
// using BCG;
// using bts;
// using System;
// using System.Collections.Generic;
// using System.Globalization;
// using System.Linq;
// [DataStreamUserRespresentation("BarBuilderStream")]
// public class BarBuilderStream : ViewStream
// {
// enum BarType
// {
// TIME,
// TICK,
// VOLUME,
// DOLLAR,
// }
// enum PriceSource
// {
// trade_price,
// mid,
// bid,
// ask,
// }
// enum VolumeSource
// {
// trade_size,
// none,
// }
// enum SessionReset
// {
// NONE,
// DAY,
// RTH,
// ETH,
// }
// sealed class BarState
// {
// public string Contract = string.Empty;
// public DateTime StartTs;
// public DateTime EndTs;
// public double Open;
// public double High;
// public double Low;
// public double Close;
// public double Volume;
// public int TradeCount;
// public double SumPriceSize;
// public double SumSize;
// public double DollarNotional;
// public bool HasData;
// public DateTime SessionDay;
// public bool InitialSnapshotEmitted;
// }
// readonly ViewStream _priceStream;
// readonly BarType _barType;
// readonly int _barSize;
// readonly PriceSource _priceSource;
// readonly VolumeSource _volumeSource;
// readonly string _timestampCol;
// readonly bool _emitForming;
// readonly bool _emitInitialSnapshot;
// readonly SessionReset _sessionReset;
// readonly Dictionary<string, BarState> _stateByContract = new(StringComparer.Ordinal);
// readonly Dictionary<string, bool> _validCols = new(StringComparer.OrdinalIgnoreCase);
// bool _validated;
// int _nextId;
// readonly BlueTable _outTable;
// readonly IBlueTableSchema _outSchema;
// public BarBuilderStream(
// ViewStream price_stream,
// string bar_type,
// int bar_size,
// string price_source,
// string volume_source,
// string timestamp_col = "ts_event",
// int emit_forming_i = 0,
// string session_reset = "NONE",
// int emit_initial_snapshot_i = 0
// )
// {
// _priceStream = price_stream;
// _barType = ParseBarType(bar_type);
// _barSize = bar_size;
// _priceSource = ParsePriceSource(price_source);
// _volumeSource = ParseVolumeSource(volume_source);
// _timestampCol = timestamp_col;
// _emitForming = emit_forming_i == 1;
// _emitInitialSnapshot = emit_initial_snapshot_i == 1;
// _sessionReset = ParseSessionReset(session_reset);
// if (_barSize <= 0)
// {
// throw new ArgumentException("bar_size must be > 0");
// }
// _outSchema = BlueDataUtility.form_schema(
// "BarBuilder",
// Tuple.Create("id", TypeCode.Int32),
// Tuple.Create("ts_event", TypeCode.String),
// Tuple.Create("bar_start_ts", TypeCode.String),
// Tuple.Create("bar_end_ts", TypeCode.String),
// Tuple.Create("contract", TypeCode.String),
// Tuple.Create("open", TypeCode.Double),
// Tuple.Create("high", TypeCode.Double),
// Tuple.Create("low", TypeCode.Double),
// Tuple.Create("close", TypeCode.Double),
// Tuple.Create("volume", TypeCode.Double),
// Tuple.Create("trade_count", TypeCode.Int32),
// Tuple.Create("vwap", TypeCode.Double),
// Tuple.Create("is_forming", TypeCode.Boolean)
// );
// _outTable = new BlueTable(_outSchema);
// }
// protected override void myOnFirstSubscriber()
// {
// _priceStream.onChange += _on_price_change;
// }
// protected override void myOnLastSubscriber()
// {
// _priceStream.onChange -= _on_price_change;
// }
// void _on_price_change(object newValue)
// {
// var dp = newValue as IDataPacket;
// if (dp is null)
// {
// return;
// }
// if (!_validated)
// {
// ValidateInputSchema(dp.newRows.schema);
// _validated = true;
// }
// var emitted = new List<IBlueRow>();
// foreach (IBlueRow row in dp.addedRows)
// {
// ProcessEvent(row, emitted);
// }
// if (emitted.Count == 0)
// {
// return;
// }
// foreach (var r in emitted)
// {
// _outTable.addRow(r);
// }
// var outDp = BlueDataUtility.build_dp_inc(_outTable, myLastValue as IDataPacket);
// myFireEvent(outDp);
// }
// void ValidateInputSchema(IBlueTableSchema schema)
// {
// _validCols.Clear();
// foreach (var name in schema.columnNames)
// {
// _validCols[name] = true;
// }
// if (!_validCols.ContainsKey(_timestampCol))
// {
// throw new ArgumentException($"Missing required column: {_timestampCol}");
// }
// switch (_priceSource)
// {
// case PriceSource.trade_price:
// RequireCol("trade_price");
// break;
// case PriceSource.mid:
// RequireCol("bid_price");
// RequireCol("ask_price");
// break;
// case PriceSource.bid:
// RequireCol("bid_price");
// break;
// case PriceSource.ask:
// RequireCol("ask_price");
// break;
// }
// if (_barType is BarType.VOLUME or BarType.DOLLAR)
// {
// if (_volumeSource == VolumeSource.none || !_validCols.ContainsKey("trade_size"))
// {
// throw new ArgumentException("VOLUME/DOLLAR require executed trade volume; invalid for BBO-only streams.");
// }
// }
// else if (_volumeSource == VolumeSource.trade_size)
// {
// RequireCol("trade_size");
// }
// }
// void RequireCol(string name)
// {
// if (!_validCols.ContainsKey(name))
// {
// throw new ArgumentException($"Missing required column for selected source: {name}");
// }
// }
// void ProcessEvent(IBlueRow row, List<IBlueRow> emitted)
// {
// var ts = ParseTimestamp(row);
// var contract = ResolveContract(row);
// var price = ResolvePrice(row);
// var size = ResolveSize(row);
// var state = GetOrCreateState(contract);
// if (state.HasData && _sessionReset != SessionReset.NONE && ts.Date != state.SessionDay.Date)
// {
// emitted.Add(ToBarRow(state, ts_event: state.EndTs, isForming: false));
// state.HasData = false;
// }
// switch (_barType)
// {
// case BarType.TIME:
// ProcessTimeBar(state, ts, price, size, emitted);
// break;
// case BarType.TICK:
// ProcessThresholdBar(state, ts, price, size, emitted, state.TradeCount + 1 >= _barSize);
// break;
// case BarType.VOLUME:
// ProcessThresholdBar(state, ts, price, size, emitted, state.Volume + size >= _barSize);
// break;
// case BarType.DOLLAR:
// ProcessThresholdBar(state, ts, price, size, emitted, state.DollarNotional + (price * size) >= _barSize);
// break;
// }
// }
// void ProcessTimeBar(BarState state, DateTime ts, double price, double size, List<IBlueRow> emitted)
// {
// var bucketStart = AlignTimeBucket(ts, _barSize);
// var bucketEnd = bucketStart.AddSeconds(_barSize);
// if (!state.HasData)
// {
// StartBar(state, ts, bucketStart, bucketEnd, price, size);
// MaybeEmitInitialSnapshot(state, ts, emitted);
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// return;
// }
// if (bucketStart < state.StartTs)
// {
// Log.Gen.error(
// $"BarBuilderStream ignored out-of-order event. contract={state.Contract} ts={ToIso(ts)} " +
// $"current_bar_start={ToIso(state.StartTs)}");
// return;
// }
// if (bucketStart > state.StartTs)
// {
// emitted.Add(ToBarRow(state, state.EndTs, isForming: false));
// StartBar(state, ts, bucketStart, bucketEnd, price, size);
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// return;
// }
// Accumulate(state, price, size);
// state.EndTs = bucketEnd;
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// }
// void ProcessThresholdBar(
// BarState state,
// DateTime ts,
// double price,
// double size,
// List<IBlueRow> emitted,
// bool shouldClose
// )
// {
// if (!state.HasData)
// {
// StartBar(state, ts, ts, ts, price, size);
// MaybeEmitInitialSnapshot(state, ts, emitted);
// }
// else
// {
// Accumulate(state, price, size);
// }
// state.EndTs = ts;
// if (_emitForming)
// {
// emitted.Add(ToBarRow(state, ts, isForming: true));
// }
// if (shouldClose)
// {
// emitted.Add(ToBarRow(state, ts, isForming: false));
// state.HasData = false;
// }
// }
// static DateTime AlignTimeBucket(DateTime ts, int seconds)
// {
// var utc = ts.ToUniversalTime();
// long bucketTicks = TimeSpan.FromSeconds(seconds).Ticks;
// long aligned = (utc.Ticks / bucketTicks) * bucketTicks;
// return new DateTime(aligned, DateTimeKind.Utc);
// }
// void MaybeEmitInitialSnapshot(BarState state, DateTime ts, List<IBlueRow> emitted)
// {
// if (!_emitInitialSnapshot || state.InitialSnapshotEmitted)
// {
// return;
// }
// emitted.Add(ToBarRow(state, ts, isForming: false));
// state.InitialSnapshotEmitted = true;
// }
// void StartBar(
// BarState state,
// DateTime ts,
// DateTime barStart,
// DateTime barEnd,
// double price,
// double size
// )
// {
// state.StartTs = barStart;
// state.EndTs = barEnd;
// state.Open = price;
// state.High = price;
// state.Low = price;
// state.Close = price;
// state.Volume = 0;
// state.TradeCount = 0;
// state.SumPriceSize = 0;
// state.SumSize = 0;
// state.DollarNotional = 0;
// state.SessionDay = ts.Date;
// state.HasData = true;
// Accumulate(state, price, size);
// }
// static void Accumulate(BarState state, double price, double size)
// {
// state.High = Math.Max(state.High, price);
// state.Low = Math.Min(state.Low, price);
// state.Close = price;
// state.TradeCount++;
// if (size > 0)
// {
// state.Volume += size;
// state.SumSize += size;
// state.SumPriceSize += price * size;
// state.DollarNotional += price * size;
// }
// }
// IBlueRow ToBarRow(BarState state, DateTime ts_event, bool isForming)
// {
// double vwap = state.SumSize > 0 ? state.SumPriceSize / state.SumSize : state.Close;
// var row = new MutableBlueRow(_outSchema);
// row.setValue("id", _nextId++);
// row.setValue("ts_event", ToIso(ts_event));
// row.setValue("bar_start_ts", ToIso(state.StartTs));
// row.setValue("bar_end_ts", ToIso(state.EndTs));
// row.setValue("contract", state.Contract);
// row.setValue("open", state.Open);
// row.setValue("high", state.High);
// row.setValue("low", state.Low);
// row.setValue("close", state.Close);
// row.setValue("volume", _volumeSource == VolumeSource.none ? 0.0 : state.Volume);
// row.setValue("trade_count", state.TradeCount);
// row.setValue("vwap", vwap);
// row.setValue("is_forming", isForming);
// return row;
// }
// BarState GetOrCreateState(string contract)
// {
// if (_stateByContract.TryGetValue(contract, out var existing))
// {
// return existing;
// }
// var created = new BarState { Contract = contract };
// _stateByContract[contract] = created;
// return created;
// }
// DateTime ParseTimestamp(IBlueRow row)
// {
// object? raw = row[_timestampCol];
// if (raw is DateTime dt)
// {
// return dt;
// }
// if (raw is string s && DateTime.TryParse(s, null, DateTimeStyles.RoundtripKind, out dt))
// {
// return dt;
// }
// throw new ArgumentException($"Invalid timestamp value in column '{_timestampCol}'.");
// }
// string ResolveContract(IBlueRow row)
// {
// if (_validCols.ContainsKey("contract"))
// {
// return (row["contract"]?.ToString() ?? string.Empty).Trim();
// }
// if (_validCols.ContainsKey("symbol"))
// {
// return (row["symbol"]?.ToString() ?? string.Empty).Trim();
// }
// return string.Empty;
// }
// double ResolvePrice(IBlueRow row)
// {
// return _priceSource switch
// {
// PriceSource.trade_price => ToDouble(row["trade_price"], "trade_price"),
// PriceSource.mid => (ToDouble(row["bid_price"], "bid_price") + ToDouble(row["ask_price"], "ask_price")) / 2.0,
// PriceSource.bid => ToDouble(row["bid_price"], "bid_price"),
// PriceSource.ask => ToDouble(row["ask_price"], "ask_price"),
// _ => throw new ArgumentOutOfRangeException()
// };
// }
// double ResolveSize(IBlueRow row)
// {
// if (_volumeSource == VolumeSource.none)
// {
// return 0;
// }
// return ToDouble(row["trade_size"], "trade_size");
// }
// static double ToDouble(object? value, string colName)
// {
// var d = BlueDataUtility.GetDouble(value!);
// if (!d.HasValue)
// {
// throw new ArgumentException($"Column '{colName}' must be numeric.");
// }
// return d.Value;
// }
// static string ToIso(DateTime dt) =>
// dt.ToUniversalTime().ToString("O");
// static BarType ParseBarType(string value)
// {
// if (Enum.TryParse<BarType>(value, true, out var parsed))
// {
// return parsed;
// }
// throw new ArgumentException("bar_type must be one of: TIME | TICK | VOLUME | DOLLAR");
// }
// static PriceSource ParsePriceSource(string value)
// {
// if (Enum.TryParse<PriceSource>(value, true, out var parsed))
// {
// return parsed;
// }
// throw new ArgumentException("price_source must be one of: trade_price | mid | bid | ask");
// }
// static VolumeSource ParseVolumeSource(string value)
// {
// if (Enum.TryParse<VolumeSource>(value, true, out var parsed))
// {
// return parsed;
// }
// throw new ArgumentException("volume_source must be one of: trade_size | none");
// }
// static SessionReset ParseSessionReset(string value)
// {
// if (!Enum.TryParse<SessionReset>(value, true, out var parsed))
// {
// throw new ArgumentException("session_reset must be one of: NONE | DAY | RTH | ETH");
// }
// // TODO: differentiate RTH/ETH session boundaries; currently treated as DAY.
// if (parsed is SessionReset.RTH or SessionReset.ETH)
// {
// return SessionReset.DAY;
// }
// return parsed;
// }
// }
@@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="OpenAI" Version="2.0.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>
<Choose>
<When Condition="'$(UseProjectRefs)' == 'true'">
<ItemGroup>
<ProjectReference Include="..\..\cs\Bts.Spark.Api\Bts.Spark.Api.csproj" />
<ProjectReference Include="..\DataStreamCore\DataStreamCore.csproj" />
<ProjectReference Include="..\DataStream\DataStream.csproj" />
<ProjectReference Include="..\PubSub\PubSub.csproj" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="Bts.Spark.Api" Version="$(SparkVersion)" />
<PackageReference Include="DataStream" Version="$(SparkVersion)" />
<PackageReference Include="PubSub" Version="$(SparkVersion)" />
</ItemGroup>
</Otherwise>
</Choose>
<!-- <ItemGroup>
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubHeartbeatSchema.json" TypeName="PubSubHeartbeatRow" TableName="PubSubHeartbeat" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubRouteSchema.json" TypeName="PubSubRouteRow" TableName="PubSubRoute" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubServerStateSchema.json" TypeName="PubSubServerStateRow" TableName="PubSubServerState" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\PubSubServerTagStatsSchema.json" TypeName="PubSubServerTagStatsRow" TableName="PubSubServerTagStats" />
<RowType Include="RowTemplates\RefTypeRow.tt" SchemaJson="RowTemplates\TableMetadataSchema.json" TypeName="TableMetadataRow" TableName="TableMetadata" />
</ItemGroup> -->
</Project>
@@ -0,0 +1,294 @@
namespace BlueOrb.Internal
{
using bts;
//using bts.api;
//using bts.spark;
using System;
using System.Diagnostics.CodeAnalysis;
public static class ContractUtils
{
public record FutureTradableContract(
string Symbol,
DateTime Expiration,
Exchange Exchange,
string? ContractText);
public class FutureSpreadContract
{
public List<Tuple<double, FutureTradableContract>> legs = new(2);
public string Symbol
{
get
{
return legs == null || legs.Count == 0 ? string.Empty : legs.ElementAt(0).Item2.Symbol;
}
}
public string? ContractText;
}
public record FutureContinousContract(string Symbol, Exchange Exchange);
// this is for all future conytracts belonging to a symbol
public record FutureWildcardContract(string Symbol, Exchange Exchange);
public class FutureContract
{
public FutureWildcardContract? wildcard_contract;
public FutureTradableContract? future_tradable_contract;
public FutureSpreadContract? spread_tradable_contract;
public FutureContinousContract? continous_constract;
public FutureContract(string txt)
{
wildcard_contract = parse_wildcard_contract(txt);
if (wildcard_contract != null)
return;
var fc = parse_future_contract(txt);
if (fc != null)
{
future_tradable_contract = fc;
return;
}
var sc = parse_future_spread_contract(txt);
if (sc != null)
{
spread_tradable_contract = sc;
return;
}
// this is not totally true, since ParseFutureSpreadContract does not
// parse ICS spreads
continous_constract = new(txt, Exchange.CME);
}
[MemberNotNullWhen(true, nameof(continous_constract))]
public bool is_continous_contract => continous_constract != null;
[MemberNotNullWhen(true, nameof(wildcard_contract))]
public bool is_wildcard_contract => wildcard_contract != null;
[MemberNotNullWhen(true, nameof(future_tradable_contract))]
public bool is_future_tradable_contract => future_tradable_contract != null;
[MemberNotNullWhen(true, nameof(spread_tradable_contract))]
public bool is_spread_tradable_contract => spread_tradable_contract != null;
public string symbol()
{
if (wildcard_contract != null)
return wildcard_contract.Symbol;
if (continous_constract != null)
{
return continous_constract.Symbol;
}
else if (future_tradable_contract != null)
{
return future_tradable_contract.Symbol;
}
else if (spread_tradable_contract != null)
{
return spread_tradable_contract.Symbol;
}
Log.assert(false);
return string.Empty;
}
public string? contract_text
{
get
{
if (future_tradable_contract != null)
return future_tradable_contract.ContractText;
if (spread_tradable_contract != null)
return spread_tradable_contract.ContractText;
return null;
}
}
}
#region Parsing
public static FutureWildcardContract? parse_wildcard_contract(string contract_txt, Exchange exchange = Exchange.CME)
{
if (contract_txt.EndsWith("*"))
{
contract_txt = contract_txt.Replace("*", string.Empty);
return new FutureWildcardContract(contract_txt, exchange);
}
return null;
}
public static FutureTradableContract? parse_future_contract(string contract_txt, Exchange exchange = Exchange.CME)
{
// Validate the future string length
if (!contract_txt.All(c => char.IsLetterOrDigit(c)))
return null;
if (contract_txt.Length < 4)
{
return null;
}
// Extract the symbol and the expiration month/year codes
string symbol = contract_txt.Substring(0, contract_txt.Length - 2);
char monthCode = contract_txt[contract_txt.Length - 2];
char yearCode = contract_txt[contract_txt.Length - 1];
// Map month code to month, return null if the month code is invalid
int month = monthCode switch
{
'F' => 1, // January
'G' => 2, // February
'H' => 3, // March
'J' => 4, // April
'K' => 5, // May
'M' => 6, // June
'N' => 7, // July
'Q' => 8, // August
'U' => 9, // September
'V' => 10, // October
'X' => 11, // November
'Z' => 12, // December
_ => 0 // Return 0 for invalid month code
};
if (month == 0)
{
return null; // Invalid month code
}
// Calculate the year based on the current decade
int currentYear = DateTime.Now.Year;
int decadeStart = currentYear / 10 * 10;
int year = decadeStart + (yearCode - '0');
// If the year is in the past, assume the next decade
if (year < currentYear)
{
year += 10;
}
// Create the FutureContract instance and set its properties
DateTime expiration = new DateTime(year, month, 1);
return new(symbol, expiration, exchange, contract_txt);
}
// Method to parse a futures spread, e.g. "CLX4-CLZ4"
public static FutureSpreadContract? parse_future_spread_contract(string contract_txt, Exchange exchange = Exchange.CME)
{
// Split the string by '-' to handle each leg
var spreadParts = contract_txt.Split('-');
if (spreadParts.Length < 2)
{
return null; // Not a valid spread format
}
var spreadContract = new FutureSpreadContract { legs = new List<Tuple<double, FutureTradableContract>>() };
foreach (var part in spreadParts)
{
// Split each leg by '*', assuming the format is weight*future or just future
string[] legParts = part.Split('*');
double weight = 1.0;
string futurePart;
if (legParts.Length == 2)
{
if (!double.TryParse(legParts[0], out weight))
{
return null; // Invalid weight, parsing failed
}
futurePart = legParts[1];
}
else if (legParts.Length == 1)
{
futurePart = legParts[0];
}
else
{
return null; // Invalid format, too many '*' parts
}
// Parse the future contract
var futureContract = parse_future_contract(futurePart, exchange);
if (futureContract == null)
{
return null; // Failed to parse the future part
}
// Add the leg to the spread contract
spreadContract.legs.Add(new Tuple<double, FutureTradableContract>(weight, futureContract));
}
return spreadContract;
}
// public static ContractType DetermineFutureOrSpread(string contract) {
// if (contract.Contains("-")) {
// return ContractType.FutureSpread;
// } else {
// return ContractType.Future;
// }
// }
#endregion
public static ContractType get_type(string contract_txt)
{
var fc = parse_future_contract(contract_txt);
if (fc != null)
{
return ContractType.Future;
}
var sc = parse_future_spread_contract(contract_txt);
if (sc != null)
{
return ContractType.FutureSpread;
}
// tehre are some non calendar spreads we cant parse
//Log.assert(false);
return ContractType.FutureSpread;
}
public static ContractCategory get_category(string symbol)
{
var tp = get_symbol_category(symbol);
return tp.Item1;
}
public static Tuple<ContractCategory, string> get_symbol_category(string symbol)
{
var fc = parse_future_contract(symbol);
if (fc != null)
{
return Tuple.Create(ContractCategory.FutureString, fc.Symbol);
}
var sc = parse_future_spread_contract(symbol);
if (sc != null)
{
return Tuple.Create(ContractCategory.FutureString, sc.Symbol);
}
return Tuple.Create(ContractCategory.Symbol, symbol);
}
public enum ContractType
{
Spot,
Option,
Future,
FutureSpread,
OptionSpread
}
public enum ContractCategory
{
Symbol = 0,
FutureString,
SpreadString
}
public enum CallPut
{
Call,
Put
}
public enum Exchange
{
CME
}
}
}
@@ -0,0 +1,99 @@
namespace BlueOrb.Operators.Data {
using BCG;
using bts;
using Spark.Core.Diagnostics;
using BlueOrb.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
[DataStreamUserRespresentation("ReplayFutureLiveBBOStream")]
public class ReplayFutureLiveBBOStream : ViewStream, BCG.Utilities.General.IWorker {
private class LastFireTime {
public DateTime last_fireitme_file = DateTime.MinValue;
public DateTime last_firetime_clock = DateTime.MinValue;
}
private class RowsWithPointer {
public List<IBlueRow>? rows;
public int pointer;
}
readonly ViewStreamDatabase? _vsd;
readonly ContractUtils.FutureContinousContract? _fcc;
private readonly LastFireTime _last_fire_time = new LastFireTime();
private RowsWithPointer _rows = new RowsWithPointer();
public ReplayFutureLiveBBOStream(string continous_contract) {
Func<string> iso_8601_now = () => {
DateTime utc_now = DateTime.UtcNow;
long ticks = utc_now.Ticks; // 1 tick = 100 ns
long nanoseconds = ticks % TimeSpan.TicksPerSecond * 100;
string formatted = utc_now.ToString("yyyy-MM-ddTHH:mm:ss");
formatted += $".{nanoseconds:D9}Z";
return formatted;
};
ViewStream rs = new ReplayFutureLiveBBOStream(continous_contract, true);
IBlueTableSchema schema_out = BlueDataUtility.form_schema("BBO",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("ts_event", TypeCode.String),
Tuple.Create("contract", TypeCode.String),
Tuple.Create("bid_price", TypeCode.Double),
Tuple.Create("bid_size", TypeCode.Int32),
Tuple.Create("ask_price", TypeCode.Double),
Tuple.Create("ask_size", TypeCode.Int32));
rs = new MapStream(rs, s => schema_out,
r =>
new BlueRow(schema_out, r["id"], /*r.get<string>("ts_event")*/iso_8601_now(), r.get<string>("symbol"),
r.get<double>("bid_px_00"), r.get<int>("bid_sz_00"),
r.get<double>("ask_px_00"), r.get<int>("ask_sz_00")));
mySetRealSource(rs);
}
private ReplayFutureLiveBBOStream(string continous_contract, bool noop)
: this(ViewStreamDatabase.instance, new ContractUtils.FutureContract(continous_contract)) { }
public ReplayFutureLiveBBOStream(ViewStreamDatabase vsd, ContractUtils.FutureContract fc) {
var fcc = fc.continous_constract;
Log.assert(fcc != null);
_vsd = vsd;
_fcc = fcc;
}
protected override void myOnFirstSubscriber() {
Log.notnull(_fcc);
var file_path = Path.Combine(SQLiteHelper.location, $"mbp1_{_fcc.Symbol}_small.csv".ToLower());
var rows = BCG.CSVReaderStream.LoadFile(file_path);
_rows.rows = new(rows.Count);
_rows.rows.AddRange(rows.OfType<IBlueRow>().OrderBy(r => r.get<string>("ts_event")));
_rows.pointer = 0;
ExceptionAssert.NotNull(_vsd).addWorker(this);
}
protected override void myOnLastSubscriber() {
ExceptionAssert.NotNull(_vsd).removeWorker(this);
}
public void doWork() {
var rows = ExceptionAssert.NotNull(_rows.rows);
IBlueRow cand_row = rows[_rows.pointer];
string cand_ts_event = cand_row.get<string>("ts_event");
DateTime cand_ts_event_dt = DateTime.Parse(cand_ts_event, null, System.Globalization.DateTimeStyles.RoundtripKind);
TimeSpan cand_ts_span_file = cand_ts_event_dt - _last_fire_time.last_fireitme_file;
TimeSpan ts_clock = DateTime.Now - _last_fire_time.last_firetime_clock;
if (ts_clock >= cand_ts_span_file) {
_rows.pointer++;
_last_fire_time.last_firetime_clock = DateTime.Now;
_last_fire_time.last_fireitme_file = cand_ts_event_dt;
BlueTable bt_out = new BlueTable(cand_row.schema);
bt_out.addRow(cand_row);
var dp_out = BlueDataUtility.build_dp(bt_out, myLastValue as IDataPacket);
myFireEvent(dp_out);
}
}
}
}
@@ -0,0 +1,111 @@
namespace Blueorb.Operators.Data
{
using BCG;
using Spark.Core.Diagnostics;
using BlueOrb.Internal;
using bts;
using BlueOrb.Operators.Core;
using System;
using System.Collections.Generic;
using System.Linq;
[DataStreamUserRespresentation("ReplayFutureLiveTradeStream")]
public class ReplayFutureLiveTradeStream : ViewStream, BCG.Utilities.General.IWorker
{
private class LastFireTime
{
public DateTime last_fireitme_file = DateTime.MinValue;
public DateTime last_firetime_clock = DateTime.MinValue;
}
private class RowsWithPointer
{
public List<IBlueRow>? rows;
public int pointer;
}
readonly ViewStreamDatabase? _vsd;
readonly ContractUtils.FutureContinousContract? _fcc;
private readonly LastFireTime _last_fire_time = new LastFireTime();
readonly RowsWithPointer _rows = new();
public ReplayFutureLiveTradeStream(string continous_contract)
{
Func<string> iso_8601_now = () =>
{
DateTime utc_now = DateTime.UtcNow;
long ticks = utc_now.Ticks; // 1 tick = 100 ns
long nanoseconds = ticks % TimeSpan.TicksPerSecond * 100;
string formatted = utc_now.ToString("yyyy-MM-ddTHH:mm:ss");
formatted += $".{nanoseconds:D9}Z";
return formatted;
};
ViewStream rs = new ReplayFutureLiveTradeStream(continous_contract, true);
IBlueTableSchema schema_out = BlueDataUtility.form_schema("BBO",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("ts_event", TypeCode.String),
Tuple.Create("contract", TypeCode.String),
Tuple.Create("trade_size", TypeCode.Double),
Tuple.Create("trade_price", TypeCode.Int32),
Tuple.Create("aggressor_side", TypeCode.String));
rs = new MapStream(rs, s => schema_out,
r =>
new BlueRow(schema_out, r["id"], /*r.get<string>("ts_event")*/iso_8601_now(), r.get<string>("symbol"),
r.get<double>("size"), r.get<double>("price"),
r.get<string>("side").StartsWith("B") ? "BUY" : (r.get<string>("side").StartsWith("A") ? "SELL" : "NONE")));
rs = new TimeSeriesStream(rs);
mySetRealSource(rs);
}
private ReplayFutureLiveTradeStream(string continous_contract, bool noop)
: this(ViewStreamDatabase.instance, new ContractUtils.FutureContract(continous_contract)) { }
public ReplayFutureLiveTradeStream(ViewStreamDatabase vsd, ContractUtils.FutureContract fc)
{
var fcc = fc.continous_constract;
Log.assert(fcc != null);
_vsd = vsd;
_fcc = fcc;
}
protected override void myOnFirstSubscriber()
{
Log.notnull(_vsd);
Log.notnull(_fcc);
var file_path = Path.Combine(SQLiteHelper.location, $"trades_{_fcc.Symbol}.csv");
var csv_rd = new BlueOrb.Operators.Core.CSVReaderStream(file_path, false);
var rows = BCG.CSVReaderStream.LoadFile(file_path);
_rows.rows = new(rows.Count);
_rows.rows.AddRange(rows.OfType<IBlueRow>().OrderBy(r => r.get<string>("ts_event")));
_rows.pointer = 0;
ExceptionAssert.NotNull(_vsd).addWorker(this);
}
protected override void myOnLastSubscriber()
{
ExceptionAssert.NotNull(_vsd).removeWorker(this);
}
public void doWork()
{
var rows = ExceptionAssert.NotNull(_rows.rows);
IBlueRow cand_row = rows[_rows.pointer];
string cand_ts_event = cand_row.get<string>("ts_event");
DateTime cand_ts_event_dt = DateTime.Parse(cand_ts_event, null, System.Globalization.DateTimeStyles.RoundtripKind);
TimeSpan cand_ts_span_file = cand_ts_event_dt - _last_fire_time.last_fireitme_file;
TimeSpan ts_clock = DateTime.Now - _last_fire_time.last_firetime_clock;
if (ts_clock >= cand_ts_span_file)
{
_rows.pointer++;
_last_fire_time.last_firetime_clock = DateTime.Now;
_last_fire_time.last_fireitme_file = cand_ts_event_dt;
BlueTable bt_out = new BlueTable(cand_row.schema);
bt_out.addRow(cand_row);
var dp_out = BlueDataUtility.build_dp(bt_out, myLastValue as IDataPacket);
myFireEvent(dp_out);
}
}
}
}
@@ -0,0 +1,144 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Runtime.InteropServices;
namespace BlueOrb.Internal
{
public static class SQLiteHelper
{
public static string location = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? "C:\\BlueOrb_Data\\"
: Path.Combine(Environment.GetEnvironmentVariable("HOME") ?? string.Empty, "BlueOrb_Data");
public static string db_name = "stream_data.db";
public static DataTable execute_select_query(string connection_string, string query)
{
// Create a new DataTable to store the results
DataTable dataTable = new DataTable();
// Create and open a SQLite connection using the provided connection string
using (SQLiteConnection connection = new SQLiteConnection(connection_string))
{
try
{
connection.Open();
// Create a SQLite command with the provided query
using (SQLiteCommand command = new SQLiteCommand(query, connection))
{
// Use SQLiteDataAdapter to fill the DataTable
using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(command))
{
adapter.Fill(dataTable);
}
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
// Return the populated DataTable
return dataTable;
}
public static List<Dictionary<string, object>> ExecuteBulkRead(string connectionString, string query)
{
var result = new List<Dictionary<string, object>>();
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
// Begin a transaction to optimize read speed
using (var transaction = connection.BeginTransaction())
using (var command = new SQLiteCommand(query, connection, transaction))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = columnValue;
}
result.Add(row);
}
// Commit the transaction
transaction.Commit();
}
}
return result;
}
public static List<Dictionary<string, object>> get_table(string connectionString, string query)
{
var result = new List<Dictionary<string, object>>();
using (var connection = new SQLiteConnection(connectionString))
{
try
{
connection.Open();
using (var command = new SQLiteCommand(query, connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = columnValue;
}
result.Add(row);
}
}
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
}
return result;
}
public static IEnumerable<Dictionary<string, object>> get_table_2(string connectionString, string query)
{
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
using (var command = new SQLiteCommand(query, connection))
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var row = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.IsDBNull(i) ? null : reader.GetValue(i);
row[columnName] = columnValue;
}
yield return row;
}
}
}
}
}
}
@@ -0,0 +1,43 @@
namespace BlueOrb.Internal
{
using bts;
using System;
using BCG;
using System.Collections.Generic;
using Bts.DataStreamExpressions;
using System.Xml;
// All this does is take in a dsl expression, parse it and fire the data that come out of running it.
// So for example, if an expresison is passed
[DataStreamUserRespresentation("dsl")]
public class DSLStream : ViewStream
{
private readonly string _dsl;
public DSLStream(string dsl)
{
Log.Gen.info($"DSLStream.cons dsl: {dsl}");
// Remove all colons
string sanitizedDsl = dsl.Replace(":", "COLON");
_dsl = dsl;
ViewStream rs = build_stream(dsl) ?? new LiteralStream("error", $"msg:invalid dsl");
mySetRealSource(rs);
}
static ViewStream? build_stream(string stream_expression)
{
try
{
var exp = DataStreamExpressionsInterpreter.Evaluate(stream_expression);
var rv = exp.getView(new Dictionary<string, StatementExpression>(0));
return rv;
}
catch (Exception ex)
{
//send to blueorb
Log.Gen.error($"Could not build stream: {stream_expression} ex: {ex}");
return null;
}
}
}
}
@@ -0,0 +1,103 @@
using System;
using BCG.Utilities.General;
using BCG;
using bts;
namespace BlueOrb.Internal
{
[DataStreamUserRespresentation("MillisecondStream")]
public class MillisecondStream : ViewStream, IWorker
{
private DateTime _last_fire_time = DateTime.MinValue;
private readonly TimeSpan _period;
private readonly int _size;
private readonly ViewStreamDatabase _vsd;
private IBlueTableSchema _schema;
private bts.CircularBufferTable _table;
public MillisecondStream(int interval_msecs, int size)
: this(ViewStreamDatabase.instance, interval_msecs, size)
{
}
public MillisecondStream(ViewStreamDatabase vsd, int interval_msecs, int size)
{
_vsd = vsd;
_period = TimeSpan.FromMilliseconds(interval_msecs);
_size = size;
_schema = BlueDataUtility.form_schema("Milliseconds",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("time", TypeCode.DateTime),
Tuple.Create("display_time", TypeCode.String));
_table = new CircularBufferTable(_schema, _size);
}
protected override void myOnFirstSubscriber()
{
_vsd.addWorker(this);
}
protected override void myOnLastSubscriber()
{
_vsd.removeWorker(this);
}
private int _id = 0;
public void doWork()
{
if (DateTime.Now - _last_fire_time >= _period)
{
_last_fire_time = DateTime.Now;
IBlueRow nr = new BlueRow(_schema, _id++, _last_fire_time,
_last_fire_time.ToString("yyyy-MM-dd HH:mm:ss.fff"));
_table.add_row(nr);
var dp = BlueDataUtility.build_dp_inc(_table, myLastValue as DataPacket);
myFireEvent(dp);
}
}
}
internal class MSecondStream : TimeUnitStream
{
public MSecondStream(int intervalInms, int size)
: base(DateTime.Now, new TimeSpan(0, 0, 0, 0, intervalInms), size, ViewStreamDatabase.instance) { }
protected override DateTime myRoundTime(DateTime dt) { return dt; }
}
internal class DisplayableMillisecondStream : ViewStream, IStreamMapper
{
private IBlueTableSchema mySchema = new BlueTableSchema("ms",
new ColumnInfo("id", 0, typeof(int)),
new ColumnInfo("time", 1, typeof(string)));
public DisplayableMillisecondStream(int intervalInMs, int sz)
{
mySetRealSource(new MapStream(new MSecondStream(intervalInMs, sz), this));
}
#region IStreamMapper Members
public IBlueTableSchema getOutputSchema(IBlueTableSchema inputSchema)
{
return mySchema;
}
#endregion
#region IDynamicStreamMapper Members
public IBlueRow map(IBlueRow row)
{
DateTime time = row.get_datetime("time");
var time_txt = time.ToString("yyyy-MM-dd HH:mm:ss.fff");
return new BlueRow(mySchema, row["id"], time_txt);
}
#endregion
private string myToString(DateTime dt)
{
string sep = ":";
return dt.Hour + sep + dt.Minute + sep + dt.Second + sep + dt.Millisecond;
}
}
}
@@ -0,0 +1,348 @@
namespace BlueOrb.Operators.Signal
{
using System;
using System.Collections.Concurrent;
using System.IO.MemoryMappedFiles;
using BCG;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Data;
public enum BarType
{
TIME,
TICK,
VOLUME,
DOLLAR,
}
public class BarBuilderSchemaInfo
{
[JsonPropertyName("price_col")]
public string price_col { get; set; } = "trade_price";
[JsonPropertyName("volume_col")]
public string volume_col { get; set; } = "trade_size";
[JsonPropertyName("timestamp_col")]
public string timestamp_col { get; set; } = "ts_event";
}
public class SingleBar : IBlueRow
{
private BarBuilderStream _parent_str;
private IBlueTableSchema _schema;
private MutableBlueRow _row;
public SingleBar(BarBuilderStream parent_str)
{
_parent_str = parent_str;
_schema = BlueDataUtility.form_schema(
"bar_builder_single_bar",
Tuple.Create("id", TypeCode.Int32),
Tuple.Create("ts_event", TypeCode.DateTime),
Tuple.Create("bar_start_ts", TypeCode.DateTime),
Tuple.Create("bar_end_ts", TypeCode.DateTime),
Tuple.Create("open", TypeCode.Double),
Tuple.Create("high", TypeCode.Double),
Tuple.Create("low", TypeCode.Double),
Tuple.Create("close", TypeCode.Double),
Tuple.Create("volume", TypeCode.Double),
Tuple.Create("notional", TypeCode.Double),
Tuple.Create("trade_count", TypeCode.Int32),
Tuple.Create("n_events", TypeCode.Int32),
Tuple.Create("vwap", TypeCode.Double),
Tuple.Create("is_active", TypeCode.Boolean)
);
_row = new MutableBlueRow(_schema);
}
public IBlueTableSchema schema => _row.schema;
public object this[int index] => _row[index];
public object this[string col_name] => _row[col_name];
public IBlueRow add_event(IBlueRow r)
{
// initiaizes _row
void reset_new_bar()
{
_row = new MutableBlueRow(_schema);
_row.setValue("id", _parent_str.get_new_id());
_row.setValue("volume", 0.0);
_row.setValue("notional", 0.0);
_row.setValue("trade_count", 0);
_row.setValue("n_events", 0);
_row.setValue("is_active", true);
}
void absorb_into_row(IBlueRow input_row)
{
var ts = input_row.get_datetime(_parent_str._schema_info.timestamp_col, DateTime.UtcNow).ToUniversalTime();
var price = input_row.get<double>(_parent_str._schema_info.price_col, 0.0);
var volume = input_row.get<double>(_parent_str._schema_info.volume_col, 0.0);
var notional = price * volume;
if (_row.is_null("bar_start_ts"))
{
DateTime bar_start_ts;
DateTime bar_end_ts;
if (_parent_str._bar_type == BarType.TIME)
{
var bucket_ticks = (long)(Math.Max(1.0, _parent_str._bar_size) * TimeSpan.TicksPerSecond);
var start_ticks = (ts.Ticks / bucket_ticks) * bucket_ticks;
bar_start_ts = new DateTime(start_ticks, DateTimeKind.Utc);
bar_end_ts = bar_start_ts.AddTicks(bucket_ticks);
}
else
{
bar_start_ts = ts;
bar_end_ts = ts;
}
_row.setValue("bar_start_ts", bar_start_ts);
_row.setValue("bar_end_ts", bar_end_ts);
_row.setValue("open", price);
_row.setValue("high", price);
_row.setValue("low", price);
}
else
{
var high = _row.get<double>("high", price);
var low = _row.get<double>("low", price);
_row.setValue("high", Math.Max(high, price));
_row.setValue("low", Math.Min(low, price));
}
_row.setValue("ts_event", ts);
_row.setValue("close", price);
_row.setValue("volume", _row.get<double>("volume", 0.0) + volume);
_row.setValue("notional", _row.get<double>("notional", 0.0) + notional);
_row.setValue("trade_count", _row.get<int>("trade_count", 0) + 1);
_row.setValue("n_events", _row.get<int>("n_events", 0) + 1);
var running_volume = _row.get<double>("volume", 0.0);
var running_notional = _row.get<double>("notional", 0.0);
_row.setValue("vwap", running_volume > 0.0 ? running_notional / running_volume : price);
}
bool is_closed()
{
bool closed;
if (_parent_str._bar_type == BarType.TIME)
{
var ts = _row.get_datetime("ts_event", DateTime.MinValue);
var bar_end_ts = _row.get_datetime("bar_end_ts", DateTime.MaxValue);
closed = ts >= bar_end_ts;
}
else if (_parent_str._bar_type == BarType.TICK)
{
closed = _row.get<int>("n_events", 0) >= _parent_str._bar_size;
}
else if (_parent_str._bar_type == BarType.VOLUME)
{
closed = _row.get<double>("volume", 0.0) >= _parent_str._bar_size;
}
else
{
closed = _row.get<double>("notional", 0.0) >= _parent_str._bar_size;
}
_row.setValue("is_active", !closed);
return closed;
}
if (_row == null)
{
reset_new_bar();
}
absorb_into_row(r);
if (is_closed())
{
IBlueRow closed_row = new BlueRow(_row);
reset_new_bar();
return closed_row;
}
return null;
}
}
public class BarState : IBlueRowCollection
{
private SingleBar _curr_row;
private BlueTable _state;
public BarState(BarBuilderStream parent_str)
{
_curr_row = new SingleBar(parent_str);
_state = new BlueTable(_curr_row.schema);
}
public bool add_event(IBlueRow r)
{
var closed_bar = _curr_row.add_event(r);
if (closed_bar is not null)
{
// curr bar is closed, only then its added
// when bars are evolving we dont add it
_state.addRow(closed_bar);
return true;
}
return false;
}
public IBlueRow this[int id] => _state[id];
public IBlueTableSchema schema => _state.schema;
public bool containsID(int id) => _state.containsID(id);
public int Count => _state.Count;
public System.Collections.IEnumerator GetEnumerator() => _state.GetEnumerator();
}
[DataStreamUserRespresentation("BarBuilderStream")]
public class BarBuilderStream : ViewStream
{
readonly ViewStream _price_stream;
internal readonly BarType _bar_type;
internal readonly double _bar_size;
internal readonly bool _show_open_bars;
internal readonly BarBuilderSchemaInfo _schema_info;
private BarState _state;
public BarBuilderStream(ViewStream price_stream,
BarType bar_type,
double bar_size,
bool show_open_bars,
BarBuilderSchemaInfo schema_info)
{
_price_stream = price_stream;
_bar_type = bar_type;
_bar_size = bar_size;
_show_open_bars = show_open_bars;
_schema_info = schema_info;
_state = new BarState(this);
}
int _id = 0;
internal int get_new_id()
{
return _id++;
}
public BarBuilderStream(ViewStream price_stream,
string bar_type,
double bar_size,
string schema_info_json)
:
this(price_stream,
Enum.Parse<BarType>(bar_type),
bar_size,
true,
_parse_and_validate_schema_info_json(schema_info_json))
{
}
public BarBuilderStream(ViewStream price_stream,
string bar_type,
double bar_size,
string price_col,
string volume_col,
string timestamp_col)
:
this(price_stream,
Enum.Parse<BarType>(bar_type),
bar_size,
true,
_create_and_validate_schema_info(price_col, volume_col, timestamp_col))
{
}
protected override void myOnFirstSubscriber()
{
_price_stream.onChange += _on_price_stream_change;
}
protected override void myOnLastSubscriber()
{
_price_stream.onChange -= _on_price_stream_change;
}
void _on_price_stream_change(object dp_obj)
{
DataPacket dp = dp_obj as DataPacket;
var sz_0 = _state.Count;
foreach (IBlueRow r in dp.addedRows)
{
_state.add_event(r);
}
if (_state.Count != sz_0)
// we will check for _show_open_bars here
{
var dp_out = BlueDataUtility.build_dp_inc(_state, myLastValue as DataPacket, false);
myFireEvent(dp_out);
}
}
static BarBuilderSchemaInfo _parse_and_validate_schema_info_json(string schema_info_json)
{
if (string.IsNullOrWhiteSpace(schema_info_json))
{
throw new ArgumentException("schema_info_json cannot be null or empty.", nameof(schema_info_json));
}
var schema_info = JsonSerializer.Deserialize<BarBuilderSchemaInfo>(schema_info_json);
_validate_schema_info(schema_info);
return schema_info!;
}
static BarBuilderSchemaInfo _create_and_validate_schema_info(
string price_col,
string volume_col,
string timestamp_col)
{
var schema_info = new BarBuilderSchemaInfo
{
price_col = price_col,
volume_col = volume_col,
timestamp_col = timestamp_col,
};
_validate_schema_info(schema_info);
return schema_info;
}
static void _validate_schema_info(BarBuilderSchemaInfo? schema_info)
{
if (schema_info is null)
{
throw new ArgumentException("schema_info_json did not deserialize into BarBuilderSchemaInfo.");
}
if (string.IsNullOrWhiteSpace(schema_info.price_col))
{
throw new ArgumentException("BarBuilderSchemaInfo.PriceCol cannot be null or empty.");
}
if (string.IsNullOrWhiteSpace(schema_info.volume_col))
{
throw new ArgumentException("BarBuilderSchemaInfo.VolumeCol cannot be null or empty.");
}
if (string.IsNullOrWhiteSpace(schema_info.timestamp_col))
{
throw new ArgumentException("BarBuilderSchemaInfo.TimestampCol cannot be null or empty.");
}
if (schema_info.price_col.Equals(schema_info.volume_col, StringComparison.OrdinalIgnoreCase) ||
schema_info.price_col.Equals(schema_info.timestamp_col, StringComparison.OrdinalIgnoreCase) ||
schema_info.volume_col.Equals(schema_info.timestamp_col, StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("BarBuilderSchemaInfo columns must be distinct.");
}
}
}
}
@@ -0,0 +1,58 @@
namespace BlueOrb.Internal;
using BCG;
using System;
using System.Linq;
[DataStreamUserRespresentation("TestStream")]
public class TestStream : ViewStream {
public TestStream() {
var rs = new BlueOrb.Operators.Core.LiteralStream("table1", "x:123, y:1.001, z:abc;x:123, y:1.001, z:abc");
mySetRealSource(rs);
}
}
[DataStreamUserRespresentation("OpsStream")]
public class OpsStream : ViewStream {
public OpsStream() {
}
protected override void myOnFirstSubscriber() {
IBlueTableSchema schema = new BlueTableSchema("Ops");
schema = schema.add_column(System.TypeCode.Int32, "id");
schema = schema.add_column(System.TypeCode.String, "op");
schema = schema.add_column(System.TypeCode.String, "namespace");
schema = schema.add_column(System.TypeCode.String, "assembly_name");
schema = schema.add_column(System.TypeCode.String, "constructor");
var loaded_streams = PrimitiveManager.instance.get_loaded_streams();
BlueTable rv = new BlueTable(schema);
foreach (var kv in loaded_streams.OrderBy(kv => kv.Key, StringComparer.OrdinalIgnoreCase)) {
string sn = kv.Key;
Type t = kv.Value;
string ns = t.Namespace ?? string.Empty;
string assembly_name = t.Assembly.GetName().Name ?? string.Empty;
var constructors = t.GetConstructors()
.OrderBy(c => c.GetParameters().Length)
.ThenBy(c => c.ToString());
if (!constructors.Any()) {
IBlueRow r = new BlueRow(schema, rv.Count, sn, ns, assembly_name, "(no public constructor)");
rv.addRow(r);
continue;
}
foreach (var ctor in constructors) {
var parameters = ctor.GetParameters();
string constructor = $"{t.Name}({string.Join(", ", parameters.Select(p => p.ParameterType.Name))})";
IBlueRow r = new BlueRow(schema, rv.Count, sn, ns, assembly_name, constructor);
rv.addRow(r);
}
}
myFireEvent(new DataPacket(rv, rv, new BlueTable(schema)));
}
protected override void myOnLastSubscriber() {
base.myOnLastSubscriber();
}
}
@@ -0,0 +1,218 @@
// namespace Bts.DataStreamTests;
// using BCG;
// using BlueOrb.Operators.Core;
// [TestFixture]
// public class BarBuilderStreamTests {
// static readonly DateTime T0 = new(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc);
// [Test]
// public void TimeBars_FromTrades_AcrossBoundary() {
// var schema = TradeSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "TIME", 60, "trade_price", "trade_size");
// var rows = CaptureAddedRows(bars);
// var sent = new List<IBlueRow>();
// sent.Add(TradeRow(schema, 1, T0.AddSeconds(10), "BTCUSD", 100, 2));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 2, T0.AddSeconds(20), "BTCUSD", 101, 3));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 3, T0.AddMinutes(1).AddSeconds(5), "BTCUSD", 99, 1));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 4, T0.AddMinutes(2), "BTCUSD", 102, 1));
// driver.Reset(sent);
// Assert.That(rows.Count, Is.EqualTo(2));
// AssertBar(rows[0], 100, 101, 100, 101, 5, 2, 100.6, false);
// AssertBar(rows[1], 99, 99, 99, 99, 1, 1, 99, false);
// }
// [Test]
// public void TimeBars_FromBboMid_VolumeIsZero() {
// var schema = BboSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "TIME", 60, "mid", "none");
// var rows = CaptureAddedRows(bars);
// var sent = new List<IBlueRow>();
// sent.Add(BboRow(schema, 1, T0.AddSeconds(0), "ETHUSD", 99, 101));
// driver.Reset(sent);
// sent.Add(BboRow(schema, 2, T0.AddSeconds(30), "ETHUSD", 101, 103));
// driver.Reset(sent);
// sent.Add(BboRow(schema, 3, T0.AddMinutes(1).AddSeconds(1), "ETHUSD", 100, 104));
// driver.Reset(sent);
// sent.Add(BboRow(schema, 4, T0.AddMinutes(2), "ETHUSD", 100, 102));
// driver.Reset(sent);
// Assert.That(rows.Count, Is.EqualTo(2));
// AssertBar(rows[0], 100, 102, 100, 102, 0, 2, 102, false);
// AssertBar(rows[1], 102, 102, 102, 102, 0, 1, 102, false);
// }
// [Test]
// public void TickBars_CloseExactlyOnNEvents() {
// var schema = TradeSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "TICK", 3, "trade_price", "trade_size");
// var rows = CaptureAddedRows(bars);
// var sent = new List<IBlueRow>();
// sent.Add(TradeRow(schema, 1, T0, "NQ", 10, 1));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 2, T0.AddSeconds(1), "NQ", 11, 1));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 3, T0.AddSeconds(2), "NQ", 9, 1));
// driver.Reset(sent);
// Assert.That(rows.Count, Is.EqualTo(1));
// AssertBar(rows[0], 10, 11, 9, 9, 3, 3, 10, false);
// }
// [Test]
// public void VolumeBars_CloseOnThreshold() {
// var schema = TradeSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "VOLUME", 10, "trade_price", "trade_size");
// var rows = CaptureAddedRows(bars);
// var sent = new List<IBlueRow>();
// sent.Add(TradeRow(schema, 1, T0, "ES", 100, 3));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 2, T0.AddSeconds(1), "ES", 120, 4));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 3, T0.AddSeconds(2), "ES", 110, 5));
// driver.Reset(sent);
// Assert.That(rows.Count, Is.EqualTo(1));
// AssertBar(rows[0], 100, 120, 100, 110, 12, 3, (100 * 3 + 120 * 4 + 110 * 5) / 12.0, false);
// }
// [Test]
// public void DollarBars_CloseOnThreshold() {
// var schema = TradeSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "DOLLAR", 1000, "trade_price", "trade_size");
// var rows = CaptureAddedRows(bars);
// var sent = new List<IBlueRow>();
// sent.Add(TradeRow(schema, 1, T0, "CL", 100, 3));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 2, T0.AddSeconds(1), "CL", 120, 4));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 3, T0.AddSeconds(2), "CL", 110, 3));
// driver.Reset(sent);
// Assert.That(rows.Count, Is.EqualTo(1));
// AssertBar(rows[0], 100, 120, 100, 110, 10, 3, 111, false);
// }
// [Test]
// public void Validation_VolumeOnBboOnly_Throws() {
// var schema = BboSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "VOLUME", 10, "mid", "trade_size");
// var row = BboRow(schema, 1, T0, "BTCUSD", 99, 101);
// Assert.Throws<ArgumentException>(() => {
// using var _ = SubscribeNoOp(bars);
// driver.Reset(row);
// });
// }
// [Test]
// public void EmitForming_EmitsFormingAndFinal() {
// var schema = TradeSchema();
// var driver = new TestDriverStream(schema);
// var bars = new BarBuilderStream(driver, "TICK", 2, "trade_price", "trade_size", emit_forming: true);
// var rows = CaptureAddedRows(bars);
// var sent = new List<IBlueRow>();
// sent.Add(TradeRow(schema, 1, T0, "MNQ", 10, 1));
// driver.Reset(sent);
// sent.Add(TradeRow(schema, 2, T0.AddSeconds(1), "MNQ", 12, 1));
// driver.Reset(sent);
// Assert.That(rows.Count, Is.EqualTo(3));
// Assert.That(rows[0].get<bool>("is_forming"), Is.True);
// Assert.That(rows[1].get<bool>("is_forming"), Is.True);
// Assert.That(rows[2].get<bool>("is_forming"), Is.False);
// AssertBar(rows[2], 10, 12, 10, 12, 2, 2, 11, false);
// }
// static IDisposable SubscribeNoOp(ViewStream stream) {
// DataStream.ChangeDelegate d = _ => { };
// stream.onChange += d;
// return new Subscription(() => stream.onChange -= d);
// }
// static List<IBlueRow> CaptureAddedRows(ViewStream stream) {
// var rows = new List<IBlueRow>();
// stream.onChange += o => {
// var dp = (IDataPacket)o;
// foreach (IBlueRow r in dp.addedRows) {
// rows.Add(new BlueRow(r));
// }
// };
// return rows;
// }
// static BlueTableSchema TradeSchema() =>
// new(
// new[] {
// new ColumnInfo("id", 0, typeof(int)),
// new ColumnInfo("ts_event", 1, typeof(string)),
// new ColumnInfo("contract", 2, typeof(string)),
// new ColumnInfo("trade_price", 3, typeof(double)),
// new ColumnInfo("trade_size", 4, typeof(double)),
// },
// "trade_events"
// );
// static BlueTableSchema BboSchema() =>
// new(
// new[] {
// new ColumnInfo("id", 0, typeof(int)),
// new ColumnInfo("ts_event", 1, typeof(string)),
// new ColumnInfo("contract", 2, typeof(string)),
// new ColumnInfo("bid_price", 3, typeof(double)),
// new ColumnInfo("ask_price", 4, typeof(double)),
// },
// "bbo_events"
// );
// static IBlueRow TradeRow(IBlueTableSchema schema, int id, DateTime ts, string contract, double px, double sz) =>
// new BlueRow(schema, id, ts.ToString("O"), contract, px, sz);
// static IBlueRow BboRow(IBlueTableSchema schema, int id, DateTime ts, string contract, double bid, double ask) =>
// new BlueRow(schema, id, ts.ToString("O"), contract, bid, ask);
// static void AssertBar(
// IBlueRow r,
// double open,
// double high,
// double low,
// double close,
// double volume,
// int tradeCount,
// double vwap,
// bool isForming
// ) {
// Assert.That(r.get<double>("open"), Is.EqualTo(open).Within(1e-9));
// Assert.That(r.get<double>("high"), Is.EqualTo(high).Within(1e-9));
// Assert.That(r.get<double>("low"), Is.EqualTo(low).Within(1e-9));
// Assert.That(r.get<double>("close"), Is.EqualTo(close).Within(1e-9));
// Assert.That(r.get<double>("volume"), Is.EqualTo(volume).Within(1e-9));
// Assert.That(r.get<int>("trade_count"), Is.EqualTo(tradeCount));
// Assert.That(r.get<double>("vwap"), Is.EqualTo(vwap).Within(1e-9));
// Assert.That(r.get<bool>("is_forming"), Is.EqualTo(isForming));
// }
// sealed class Subscription : IDisposable {
// readonly Action _dispose;
// public Subscription(Action dispose) => _dispose = dispose;
// public void Dispose() => _dispose();
// }
// }
@@ -109,8 +109,7 @@ struct ExecutionGatewayProvider::PImpl {
return make_gw<ICEExecutionGateway>(conn, conn, *l, o);
case api::VENUE_GLBX:
if (conn.use_ilink3()) {
return make_gw<ilink3::GLBXiLink3ExecutionGateway>(
conn, conn, *l, o);
make_gw<ilink3::GLBXiLink3ExecutionGateway>(conn, conn, *l, o);
}
return make_gw<GLBXExecutionGateway>(conn, conn, *l, o);
case api::VENUE_DERIBIT:
@@ -29,6 +29,7 @@ using std::vector;
struct OnixsGlbxSubscription::PImpl {
GlbxMarketDataConfig config;
shared_ptr<IDGenerator> sec_id_store;
shared_ptr<IMarketDataListener> listener;
PImpl(shared_ptr<IDGenerator> sec_id_store, GlbxMarketDataConfig config)
: config(std::move(config)), sec_id_store(std::move(sec_id_store)) {}
@@ -66,7 +67,8 @@ struct OnixsGlbxSubscription::PImpl {
FMT_JOIN(symbols, ", "));
vector<shared_ptr<IMDPlatform>> platforms;
auto main = std::make_shared<MDP3Main>();
main->start({symbols.begin(), symbols.end()}, nullptr, nullptr);
main->start(
{symbols.begin(), symbols.end()}, nullptr, nullptr, listener);
platforms.emplace_back(std::move(main));
dispatcher = &utils::Dispatcher::current();
heartbeat_timer.emplace(*dispatcher, 250, [&]() {
@@ -107,9 +109,10 @@ OnixsGlbxSubscription::OnixsGlbxSubscription(
OnixsGlbxSubscription::~OnixsGlbxSubscription() = default;
void OnixsGlbxSubscription::start(
shared_ptr<IMarketDataListener> /*listener*/) {
shared_ptr<IMarketDataListener> listener) {
std::atomic_thread_fence(std::memory_order_release);
bts_assert(!me_->dispatcher_thread.joinable());
me_->listener = std::move(listener);
me_->dispatcher_thread = std::thread{[&]() { me_->run(); }};
}
@@ -12,6 +12,8 @@ struct SecurityData {
: id(id), handle(h), mbo_state(h), electronic_volume(0) {}
uint32_t id; // exchange id
MDProducerHandle handle;
// Exception for now: MBO still maintains per-security working state locally
// in MDP3Listener until GMDL grows equivalent MBO support.
MBOWorkingState mbo_state;
uint32_t electronic_volume;
};
@@ -1,347 +1,428 @@
#include "MDP3Listener.h"
#include "spark/config/protos/market_data.pb.h"
#include "spark/md/protos/co2.pb.h"
#include "spark/utils/datetime.h"
#include "spark/utils/helper_macros.h"
#include <vector>
using namespace std;
using namespace bts::co2;
namespace bts {
namespace md {
MDP3Listener::MDP3Listener(
CMESecurityIndex &index,
MDProducer &producer,
MBOWriter *mbo,
const std::vector<MDProducerChannel> channels,
TradeSummarySignalDispatcher *trade_summary_dispatcher)
: _index(index), _producer(producer),
_verbose_ticker(config::get<CMEOptions>().verbose_ticker()),
_packet_arrived(), _latest_sequence(0),
// _settlement_recorder(settles),
_symbol_filter_storage(), _symbol_filter(), _channels(channels),
_concurrency_monitor(0), _book_updates(), _mbo(mbo),
_trade_summary_dispatcher(trade_summary_dispatcher) {
_book_updates.reserve(32);
}
MDP3Listener::~MDP3Listener() {}
//
// Warnings/Errors
void MDP3Listener::onError(onixs::Handler &, const onixs::ErrorArgs &error) {
tracepoint(
bts_trace, trace_order, (char *)"onError", _latest_sequence,
(uint16_t)_latest_sequence, 0);
LOG(md, Warn, "OnixS Error: {} - {}", error.description(), error.source());
}
void MDP3Listener::onWarning(
onixs::Handler &, const onixs::WarningArgs &warning) {
tracepoint(
bts_trace, trace_order, (char *)"onWarning", _latest_sequence,
(uint16_t)_latest_sequence, 0);
LOG(md, Warn, "OnixS Warn: {} - {}", warning.description(),
warning.source());
}
void MDP3Listener::onInstrumentRecovery(onixs::Handler &h) {
tracepoint(
bts_trace, trace_order, (char *)"onInstrumentRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
LOG(md, Info, "Beginning security definition recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onEndOfInstrumentRecovery(
onixs::Handler &h, const onixs::RecoveryCompletionArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfInstrumentRecovery",
_latest_sequence, (uint16_t)_latest_sequence, 0);
LOG(md, Info, "Finished Security definition recovery for channel {}",
h.settings().channel());
}
//
// Gap Recovery
void MDP3Listener::onMarketRecovery(onixs::Handler &h) {
tracepoint(
bts_trace, trace_order, (char *)"onMarketRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_PACKET_LOSS);
for (auto &c : _channels) {
c.gap();
}
LOG(md, Info, "Beginning market recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onEndOfMarketRecovery(
onixs::Handler &h, const onixs::RecoveryCompletionArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfMarketRecovery",
_latest_sequence, (uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_OK);
LOG(md, Info, "Finished market recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onTcpRecovery(onixs::Handler &h) {
tracepoint(
bts_trace, trace_order, (char *)"onTcpRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_PACKET_LOSS);
LOG(md, Info, "Beginning tcp recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onEndOfTcpRecovery(
onixs::Handler &h, const onixs::RecoveryCompletionArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfTcpRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_OK);
LOG(md, Info, "Finished tcp recovery for channel {}",
h.settings().channel());
}
//
// Mark the start/end of a packet
void MDP3Listener::onPacket(onixs::Handler &, const onixs::PacketArgs &args) {
// Mark the arrival of the packet
_packet_arrived = TimeStamp::now();
auto seq = args.seqNumber();
if (!_book_updates.empty()) {
if (_latest_sequence != seq) {
LOG(md, Error,
"Expected sequence {} got {} did not flush {} book updates.",
_latest_sequence, seq, _book_updates.size());
}
}
_latest_sequence = seq;
auto onixs_zero = args.receiveTime().sinceEpoch();
auto onixs_now = OnixS::CME::MDH::UtcWatch::now().sinceEpoch();
// needed for clang compilation
UNUSED(onixs_zero);
UNUSED(onixs_now);
// was needed for clang compilation
tracepoint(
bts_trace, trace_order, (char *)"onPacket", _latest_sequence,
(uint16_t)_latest_sequence, onixs_now - onixs_zero);
}
void MDP3Listener::onEndOfPacket(onixs::Handler &, const onixs::PacketArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfPacket.begin", _latest_sequence,
(uint16_t)_latest_sequence, 0);
flush_books();
tracepoint(
bts_trace, trace_order, (char *)"onEndOfPacket.end", _latest_sequence,
(uint16_t)_latest_sequence, 0);
}
//
// Book updates
void MDP3Listener::onBookUpdate(
onixs::Handler &,
const onixs::Security &sec,
const onixs::DirectBook &book) {
onBookUpdate<COCONUT_MAX_DEPTH>(sec, book, book_type_direct);
}
void MDP3Listener::onBookUpdate(
onixs::Handler &,
const onixs::Security &sec,
const onixs::ImpliedBook &book) {
onBookUpdate<COCONUT_MAX_IMPLIED_DEPTH>(sec, book, book_type_implied);
}
void MDP3Listener::onBookUpdate(
onixs::Handler &, const onixs::Security &, const onixs::MboBook &) {
#if 0
if (_mbo) {
auto data = _index.get_security(sec.id());
if (data == nullptr) return;
auto key = data->handle.key();
if (key == invalid_security_key) return;
auto* snapshot = _mbo->allocate_snapshot();
// copy from onixs book
for (const auto& bid : book.bids()) {
snapshot->bids.push_back({ ExchangeOrderKey(bid.id()), convert_price(bid.price(), 0), bid.quantity() });
}
for (const auto& ask : book.offers()) {
snapshot->asks.push_back({ ExchangeOrderKey(ask.id()), convert_price(ask.price(),0), ask.quantity() });
}
_mbo->validate_snapshot(sec.id(), SecurityKey(key), snapshot);
}
#endif
}
//
// Trades
// Called from onTradeSummary and onTradeRecovery, ends up calling
// MDProducerHandle::add_trade
void on_trade(
SecurityData *data,
const onixs::Decimal &price,
int size,
onixs::AggressorSide::Enum agside,
const onixs::Timestamp &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), data->electronic_volume + size);
}
//
// RFQ
void MDP3Listener::onQuoteRequest(
onixs::Handler &,
const onixs::Security &sec,
const onixs::QuoteRequest39RelatedSymArgs &arg) {
tracepoint(
bts_trace, trace_order, (char *)"onQuoteRequest", _latest_sequence,
(uint16_t)_latest_sequence, 0);
auto *data = _index.get_security(sec.id());
if (data != nullptr) {
auto ts = utils::TimeStamp::now();
co2::QuoteRequestMessage message;
message.set_key(data->handle.key());
auto time = ll_of_timestamp(arg.message().transactTime());
message.set_time(time);
onixs::StrRef id = arg.message().quoteReqId();
message.set_request_id(id.items(), id.size());
// https://www.cmegroup.com/confluence/display/EPICSANDBOX/MDP+3.0+-+Request+for+Quote
int8_t side;
if (arg.entry().side(side)) {
switch (side) {
case 1: // buy
case '1':
message.set_side(co2::QuoteRequestMessage::BUY);
break;
case 2: // sell
case '2':
message.set_side(co2::QuoteRequestMessage::SELL);
break;
case 8: // cross
case '8':
message.set_side(co2::QuoteRequestMessage::CROSS);
break;
}
}
message.set_tradable(arg.entry().quoteType() == 1);
int32_t size;
if (arg.entry().orderQty(size)) {
message.set_size(size);
}
data->handle.add_rfq(ts, message);
}
}
//
// Volume
void MDP3Listener::onElectronicVolume(
onixs::Handler &,
const onixs::Security &sec,
const onixs::Volume37Args &args) {
tracepoint(
bts_trace, trace_order, (char *)"onElectronicVolume.volume",
_latest_sequence, (uint16_t)_latest_sequence, 0);
auto *data = _index.get_security(sec.id());
if (data != nullptr) {
bts_assert_d(args.entry().entryType().value() == 'e');
bts_assert_d(
args.entry().updateAction() == onixs::UpdateAction::New ||
args.entry().updateAction() == onixs::UpdateAction::Change);
data->electronic_volume = args.entry().entrySize();
}
}
//
// Non-onixs calls
void MDP3Listener::add_filter_symbol(const std::string &symbol) {
LOG(md, Info, "MDP3Listener::add_filter_symbol symbol: {}", symbol);
_symbol_filter_storage.push_back(symbol);
_symbol_filter.clear();
for (const auto &str : _symbol_filter_storage) {
_symbol_filter.insert(onixs::StrRef(str.c_str(), str.size()));
}
}
void MDP3Listener::heartbeat() {
for (auto &c : _channels) {
c.heartbeat();
}
}
// Called by MDP3Main::prepare_listener as part of pre-load. Also called by
// MDP3Listener::onFuture, onOption and onSpread
void MDP3Listener::add_security(
const FixedSecurity &security, co2::TradingStatus status) {
bts_assert(security.numeric_id != 0);
// Set up the shared memory for this security
auto handle = _producer.add_security(security);
// Add it to the index so it can receive messages
_index.add_security(security.numeric_id, handle);
handle.update_exchange_status(utils::TimeStamp::now(), status);
}
// Private functions
void MDP3Listener::flush_books() {
// This is called at the end of the packet
// Write all book updates to shared memory and reset for the next packet
for (auto &entry : _book_updates) {
uint32_t sequence = _latest_sequence;
if (entry.type_flags == book_type_direct) {
entry.handle.update_direct(
_packet_arrived, entry.bids.first, entry.asks.first, sequence);
} else if (entry.type_flags == book_type_implied) {
entry.handle.update_implied(
_packet_arrived, entry.bids.second, entry.asks.second, sequence);
} else if (entry.type_flags == book_type_both) {
entry.handle.update_books(
_packet_arrived, entry.bids.first, entry.asks.first,
entry.bids.second, entry.asks.second, sequence);
}
}
// Reset pending updates
_book_updates.clear();
}
void MDP3Listener::update_all_status(CoconutSecurityStatus status) {
_index.walk_security_list(
[=](SecurityData &data) { data.handle.set_status(status); });
}
void MDP3Listener::update_group_exchange_status(
const onixs::StrRef &group, co2::TradingStatus status) {
_index.walk_security_list([=](SecurityData &data) {
if (data.handle.security().alt_symbol() == group) {
data.handle.update_exchange_status(utils::TimeStamp::now(), status);
}
});
}
void MDP3Listener::update_asset_exchange_status(
const onixs::StrRef &asset, co2::TradingStatus status) {
_index.walk_security_list([=](SecurityData &data) {
if (data.handle.security().symbol() == asset) {
data.handle.update_exchange_status(utils::TimeStamp::now(), status);
}
});
}
md::MDP3Listener::BookData::BookData(MDProducerHandle &handle)
: handle(handle), type_flags(0), bids(), asks() {}
} // namespace md
} // namespace bts
#include "MDP3Listener.h"
#include "spark/config/protos/market_data.pb.h"
#include "spark/domain/Book.h"
#include "spark/domain/Security.h"
#include "spark/domain/TradeRecord.h"
#include "spark/md/protos/co2.pb.h"
#include "spark/utils/datetime.h"
#include "spark/utils/helper_macros.h"
#include <vector>
using namespace std;
using namespace bts::co2;
namespace bts {
namespace md {
namespace {
domain::AggressorSide to_domain_aggressor(onixs::AggressorSide::Enum agside) {
switch (agside) {
case onixs::AggressorSide::Buy:
return domain::AggressorSide::Buy;
case onixs::AggressorSide::Sell:
return domain::AggressorSide::Sell;
default:
return domain::AggressorSide::None;
}
}
domain::Price to_domain_price(const PriceSize &ps) {
if (ps.is_nan()) {
return domain::Price::nan();
}
return domain::Price::from_double(ps.price());
}
domain::BookLevel to_domain_book_level(const PriceSize &ps) {
if (ps.is_nan() || ps.size() == 0) {
return domain::BookLevel::empty();
}
domain::BookLevel level;
level.price = to_domain_price(ps);
level.total_quantity = domain::Quantity(ps.size());
level.direct_quantity = domain::Quantity(ps.direct_size());
return level;
}
void copy_book_side(
const std::array<PriceSize, COCONUT_MAX_DEPTH> &from,
domain::BookSide &to) {
for (size_t i = 0; i < std::min(from.size(), to.size()); ++i) {
to[i] = to_domain_book_level(from[i]);
}
}
} // namespace
MDP3Listener::MDP3Listener(
CMESecurityIndex &index,
MDProducer &producer,
MBOWriter *mbo,
const std::vector<MDProducerChannel> channels,
TradeSummarySignalDispatcher *trade_summary_dispatcher,
std::shared_ptr<IMarketDataListener> market_data_listener)
: _index(index), _producer(producer),
_verbose_ticker(config::get<CMEOptions>().verbose_ticker()),
_packet_arrived(), _latest_sequence(0),
// _settlement_recorder(settles),
_symbol_filter_storage(), _symbol_filter(), _channels(channels),
_concurrency_monitor(0), _book_updates(), _mbo(mbo),
_trade_summary_dispatcher(trade_summary_dispatcher),
_market_data_listener(std::move(market_data_listener)) {
_book_updates.reserve(32);
}
MDP3Listener::~MDP3Listener() {}
//
// Warnings/Errors
void MDP3Listener::onError(onixs::Handler &, const onixs::ErrorArgs &error) {
tracepoint(
bts_trace, trace_order, (char *)"onError", _latest_sequence,
(uint16_t)_latest_sequence, 0);
LOG(md, Warn, "OnixS Error: {} - {}", error.description(), error.source());
}
void MDP3Listener::onWarning(
onixs::Handler &, const onixs::WarningArgs &warning) {
tracepoint(
bts_trace, trace_order, (char *)"onWarning", _latest_sequence,
(uint16_t)_latest_sequence, 0);
LOG(md, Warn, "OnixS Warn: {} - {}", warning.description(),
warning.source());
}
void MDP3Listener::onInstrumentRecovery(onixs::Handler &h) {
tracepoint(
bts_trace, trace_order, (char *)"onInstrumentRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
LOG(md, Info, "Beginning security definition recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onEndOfInstrumentRecovery(
onixs::Handler &h, const onixs::RecoveryCompletionArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfInstrumentRecovery",
_latest_sequence, (uint16_t)_latest_sequence, 0);
LOG(md, Info, "Finished Security definition recovery for channel {}",
h.settings().channel());
}
//
// Gap Recovery
void MDP3Listener::onMarketRecovery(onixs::Handler &h) {
tracepoint(
bts_trace, trace_order, (char *)"onMarketRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_PACKET_LOSS);
for (auto &c : _channels) {
c.gap();
}
LOG(md, Info, "Beginning market recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onEndOfMarketRecovery(
onixs::Handler &h, const onixs::RecoveryCompletionArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfMarketRecovery",
_latest_sequence, (uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_OK);
LOG(md, Info, "Finished market recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onTcpRecovery(onixs::Handler &h) {
tracepoint(
bts_trace, trace_order, (char *)"onTcpRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_PACKET_LOSS);
LOG(md, Info, "Beginning tcp recovery for channel {}",
h.settings().channel());
}
void MDP3Listener::onEndOfTcpRecovery(
onixs::Handler &h, const onixs::RecoveryCompletionArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfTcpRecovery", _latest_sequence,
(uint16_t)_latest_sequence, 0);
update_all_status(COCONUTSECURITYSTATUS_OK);
LOG(md, Info, "Finished tcp recovery for channel {}",
h.settings().channel());
}
//
// Mark the start/end of a packet
void MDP3Listener::onPacket(onixs::Handler &, const onixs::PacketArgs &args) {
// Mark the arrival of the packet
_packet_arrived = TimeStamp::now();
auto seq = args.seqNumber();
if (!_book_updates.empty()) {
if (_latest_sequence != seq) {
LOG(md, Error,
"Expected sequence {} got {} did not flush {} book updates.",
_latest_sequence, seq, _book_updates.size());
}
}
_latest_sequence = seq;
auto onixs_zero = args.receiveTime().sinceEpoch();
auto onixs_now = OnixS::CME::MDH::UtcWatch::now().sinceEpoch();
// needed for clang compilation
UNUSED(onixs_zero);
UNUSED(onixs_now);
// was needed for clang compilation
tracepoint(
bts_trace, trace_order, (char *)"onPacket", _latest_sequence,
(uint16_t)_latest_sequence, onixs_now - onixs_zero);
}
void MDP3Listener::onEndOfPacket(onixs::Handler &, const onixs::PacketArgs &) {
tracepoint(
bts_trace, trace_order, (char *)"onEndOfPacket.begin", _latest_sequence,
(uint16_t)_latest_sequence, 0);
flush_books();
tracepoint(
bts_trace, trace_order, (char *)"onEndOfPacket.end", _latest_sequence,
(uint16_t)_latest_sequence, 0);
}
//
// Book updates
void MDP3Listener::onBookUpdate(
onixs::Handler &,
const onixs::Security &sec,
const onixs::DirectBook &book) {
onBookUpdate<COCONUT_MAX_DEPTH>(sec, book, book_type_direct);
}
void MDP3Listener::onBookUpdate(
onixs::Handler &,
const onixs::Security &sec,
const onixs::ImpliedBook &book) {
onBookUpdate<COCONUT_MAX_IMPLIED_DEPTH>(sec, book, book_type_implied);
}
void MDP3Listener::onBookUpdate(
onixs::Handler &, const onixs::Security &, const onixs::MboBook &) {
#if 0
if (_mbo) {
auto data = _index.get_security(sec.id());
if (data == nullptr) return;
auto key = data->handle.key();
if (key == invalid_security_key) return;
auto* snapshot = _mbo->allocate_snapshot();
// copy from onixs book
for (const auto& bid : book.bids()) {
snapshot->bids.push_back({ ExchangeOrderKey(bid.id()), convert_price(bid.price(), 0), bid.quantity() });
}
for (const auto& ask : book.offers()) {
snapshot->asks.push_back({ ExchangeOrderKey(ask.id()), convert_price(ask.price(),0), ask.quantity() });
}
_mbo->validate_snapshot(sec.id(), SecurityKey(key), snapshot);
}
#endif
}
//
// Trades
// Called from onTradeSummary and onTradeRecovery, ends up calling
// MDProducerHandle::add_trade
void on_trade(
SecurityData *data,
const onixs::Decimal &price,
int size,
onixs::AggressorSide::Enum agside,
const onixs::Timestamp &onixs_date,
IMarketDataListener *market_data_listener) {
auto ts = utils::TimeStamp::now();
PriceSize ps = pricesize_of_price_size(
price, data->handle.security().display_factor, size);
if (market_data_listener != nullptr) {
domain::TradeRecord trade;
trade.sec_id = domain::SecurityID(data->handle.key());
trade.time_stamp = core::TimeStamp::now();
trade.agg_side = to_domain_aggressor(agside);
trade.trade_quantity = domain::Quantity(size);
trade.trade_price = to_domain_price(ps);
std::vector<domain::TradeRecord const *> trades{&trade};
// GMDL!!
market_data_listener->on_trades(trades);
return;
}
auto date = ll_of_timestamp(onixs_date);
data->handle.add_trade(
ts, ps, date, map_aggressor(agside), data->electronic_volume + size);
}
//
// RFQ
void MDP3Listener::onQuoteRequest(
onixs::Handler &,
const onixs::Security &sec,
const onixs::QuoteRequest39RelatedSymArgs &arg) {
tracepoint(
bts_trace, trace_order, (char *)"onQuoteRequest", _latest_sequence,
(uint16_t)_latest_sequence, 0);
auto *data = _index.get_security(sec.id());
if (data != nullptr) {
auto ts = utils::TimeStamp::now();
co2::QuoteRequestMessage message;
message.set_key(data->handle.key());
auto time = ll_of_timestamp(arg.message().transactTime());
message.set_time(time);
onixs::StrRef id = arg.message().quoteReqId();
message.set_request_id(id.items(), id.size());
// https://www.cmegroup.com/confluence/display/EPICSANDBOX/MDP+3.0+-+Request+for+Quote
int8_t side;
if (arg.entry().side(side)) {
switch (side) {
case 1: // buy
case '1':
message.set_side(co2::QuoteRequestMessage::BUY);
break;
case 2: // sell
case '2':
message.set_side(co2::QuoteRequestMessage::SELL);
break;
case 8: // cross
case '8':
message.set_side(co2::QuoteRequestMessage::CROSS);
break;
}
}
message.set_tradable(arg.entry().quoteType() == 1);
int32_t size;
if (arg.entry().orderQty(size)) {
message.set_size(size);
}
data->handle.add_rfq(ts, message);
}
}
//
// Volume
void MDP3Listener::onElectronicVolume(
onixs::Handler &,
const onixs::Security &sec,
const onixs::Volume37Args &args) {
tracepoint(
bts_trace, trace_order, (char *)"onElectronicVolume.volume",
_latest_sequence, (uint16_t)_latest_sequence, 0);
auto *data = _index.get_security(sec.id());
if (data != nullptr) {
bts_assert_d(args.entry().entryType().value() == 'e');
bts_assert_d(
args.entry().updateAction() == onixs::UpdateAction::New ||
args.entry().updateAction() == onixs::UpdateAction::Change);
data->electronic_volume = args.entry().entrySize();
}
}
//
// Non-onixs calls
domain::Book MDP3Listener::to_domain_book(const BookData &entry) const {
domain::Book book = domain::Book::empty(domain::SecurityID(entry.handle.key()));
copy_book_side(entry.bids.first, book.bids());
copy_book_side(entry.asks.first, book.asks());
return book;
}
void MDP3Listener::add_filter_symbol(const std::string &symbol) {
LOG(md, Info, "MDP3Listener::add_filter_symbol symbol: {}", symbol);
_symbol_filter_storage.push_back(symbol);
_symbol_filter.clear();
for (const auto &str : _symbol_filter_storage) {
_symbol_filter.insert(onixs::StrRef(str.c_str(), str.size()));
}
}
void MDP3Listener::heartbeat() {
for (auto &c : _channels) {
c.heartbeat();
}
}
// Called by MDP3Main::prepare_listener as part of pre-load. Also called by
// MDP3Listener::onFuture, onOption and onSpread
void MDP3Listener::add_security(
const FixedSecurity &security, co2::TradingStatus status) {
LOG(md, Info, "MDP3Listener::add_security id: {}", security.numeric_id);
bts_assert(security.numeric_id != 0);
// Set up the shared memory for this security
auto handle = _producer.add_security(security);
// Add it to the index so it can receive messages
_index.add_security(security.numeric_id, handle);
if (_market_data_listener != nullptr) {
domain::Security domain_security(convert_security(security));
std::vector<domain::Security const *> securities{&domain_security};
// GMDL!!
_market_data_listener->on_securities(securities);
}
handle.update_exchange_status(utils::TimeStamp::now(), status);
}
// Private functions
void MDP3Listener::flush_books() {
// This is called at the end of the packet
// Write all book updates to shared memory and reset for the next packet
for (auto &entry : _book_updates) {
uint32_t sequence = _latest_sequence;
if (_market_data_listener != nullptr) {
if (entry.type_flags & book_type_direct) {
// GMDL!!
_market_data_listener->on_book(to_domain_book(entry), _packet_arrived);
}
continue;
}
if (entry.type_flags == book_type_direct) {
entry.handle.update_direct(
_packet_arrived, entry.bids.first, entry.asks.first, sequence);
} else if (entry.type_flags == book_type_implied) {
entry.handle.update_implied(
_packet_arrived, entry.bids.second, entry.asks.second, sequence);
} else if (entry.type_flags == book_type_both) {
entry.handle.update_books(
_packet_arrived, entry.bids.first, entry.asks.first,
entry.bids.second, entry.asks.second, sequence);
}
}
// Reset pending updates
_book_updates.clear();
}
void MDP3Listener::update_all_status(CoconutSecurityStatus status) {
_index.walk_security_list(
[=](SecurityData &data) { data.handle.set_status(status); });
}
void MDP3Listener::update_group_exchange_status(
const onixs::StrRef &group, co2::TradingStatus status) {
_index.walk_security_list([=](SecurityData &data) {
if (data.handle.security().alt_symbol() == group) {
data.handle.update_exchange_status(utils::TimeStamp::now(), status);
}
});
}
void MDP3Listener::update_asset_exchange_status(
const onixs::StrRef &asset, co2::TradingStatus status) {
_index.walk_security_list([=](SecurityData &data) {
if (data.handle.security().symbol() == asset) {
data.handle.update_exchange_status(utils::TimeStamp::now(), status);
}
});
}
md::MDP3Listener::BookData::BookData(MDProducerHandle &handle)
: handle(handle), type_flags(0), bids(), asks() {}
} // namespace md
} // namespace bts
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,5 @@
#include "MDP3Main.h"
#include "ScriptedMdp3Feeder.h"
#include "spark/config/config.h"
#include "spark/config/protos/market_data.pb.h"
#include "spark/config/protos/system_config.pb.h"
@@ -16,6 +17,8 @@
#include "sparkd/md/onixs/OnixsUtils.h"
#include <boost/filesystem.hpp>
#include <thread>
#include <chrono>
#include <memory>
#include <set>
#include <sstream>
@@ -40,6 +43,8 @@ struct MDP3Main::PImpl {
std::map<std::string, std::unique_ptr<onixs::Handler>> handlers;
std::vector<std::unique_ptr<MDP3Listener>> listeners;
std::vector<std::unique_ptr<onixs::TcpRecoveryService>> recovery;
std::atomic<bool> scripted_running{false};
std::thread scripted_thread;
PImpl()
: index(), recorder(
nullptr,
@@ -53,7 +58,12 @@ struct MDP3Main::PImpl {
MDP3Main::MDP3Main()
: me_(std::make_unique<PImpl>()) {}
MDP3Main::~MDP3Main() = default;
MDP3Main::~MDP3Main() {
me_->scripted_running = false;
if (me_->scripted_thread.joinable()) {
me_->scripted_thread.join();
}
}
const CmeChannelConfig channel_settings_for(const string &id) {
const auto &config = config::get<CMEOptions>();
@@ -178,7 +188,8 @@ onixs::SessionSettings session_settings_for_channel(
void MDP3Main::start(
const std::vector<UserSymbol> &symbols,
MBOWriter *mbo,
TradeSummarySignalDispatcher *tssd) {
TradeSummarySignalDispatcher *tssd,
std::shared_ptr<IMarketDataListener> market_data_listener) {
std::ostringstream oss;
for (const auto &us : symbols) {
oss << us << " ";
@@ -191,7 +202,8 @@ void MDP3Main::start(
me_->engines = create_feed_engines(channels);
for (const auto &channel : channels) {
unique_ptr<onixs::Handler> phandler = prepare_handler(channel.id, mbo);
me_->listeners.push_back(prepare_listener(*phandler, channel, mbo, tssd));
me_->listeners.push_back(prepare_listener(
*phandler, channel, mbo, tssd, market_data_listener));
me_->handlers.insert(std::make_pair(channel.id, std::move(phandler)));
std::stringstream symstr;
for (const auto &sym : channel.symbols) {
@@ -210,6 +222,98 @@ void MDP3Main::start(
LOG(md, Info, "** CME MDP3 Publisher started **");
}
void MDP3Main::start_scripted(
const std::vector<UserSymbol> &symbols,
MBOWriter *mbo,
TradeSummarySignalDispatcher *tssd,
std::shared_ptr<IMarketDataListener> market_data_listener) {
std::ostringstream oss;
for (const auto &us : symbols) {
oss << us << " ";
}
LOG(md, Info, "MDP3Main::start_scripted symbols: {}", oss.str());
const auto &channels = parse_channels(symbols);
if (channels.empty()) {
LOG(md, Warn, "MDP3Main::start_scripted found no CME channels");
return;
}
auto channel_it = std::find_if(
channels.begin(), channels.end(), [](const CMEChannel &channel) {
return std::any_of(
channel.symbols.begin(), channel.symbols.end(),
[](const UserSymbol &symbol) {
return symbol.symbol() == "ES" &&
symbol.type() == api::SECURITYTYPE_FUTURE;
});
});
if (channel_it == channels.end()) {
channel_it = channels.begin();
LOG(md, Warn,
"MDP3Main::start_scripted did not find an ES future channel; using channel {}",
channel_it->id);
}
const auto &channel = *channel_it;
std::vector<MDProducerChannel> producer_channels;
for (const auto &symbol : channel.symbols) {
producer_channels.push_back(me_->producer.get_channel(
symbol.symbol().c_str(), symbol.type(), symbol.exchange()));
}
auto listener = std::make_unique<MDP3Listener>(
me_->index, me_->producer, mbo, producer_channels, tssd,
market_data_listener);
for (const auto &symbol : channel.symbols) {
listener->add_filter_symbol(symbol.symbol());
}
ScriptedMdp3Feeder feeder(*listener);
feeder.publish_hard_coded_values();
me_->scripted_running = false;
if (me_->scripted_thread.joinable()) {
me_->scripted_thread.join();
}
me_->scripted_running = true;
auto *listener_ptr = listener.get();
me_->scripted_thread = std::thread([this, listener_ptr]() {
ScriptedMdp3Feeder loop_feeder(*listener_ptr);
std::uint32_t sequence = 2;
int tick_offset = 0;
int tick_direction = -1;
while (me_->scripted_running.load()) {
std::this_thread::sleep_for(std::chrono::seconds(1));
if (!me_->scripted_running.load()) {
break;
}
tick_offset += tick_direction;
if (tick_offset <= -10) {
tick_offset = -10;
tick_direction = 1;
} else if (tick_offset >= 0) {
tick_offset = 0;
tick_direction = -1;
}
loop_feeder.publish_hard_coded_direct_book(
sequence++, 0.25 * tick_offset);
}
});
std::stringstream symstr;
for (const auto &sym : channel.symbols) {
symstr << sym.symbol() << "-" << SecurityType_Name(sym.type()) << " ";
}
LOG(md, Info, "CME: Initialized scripted channel {} ({})", channel.id,
symstr.str());
me_->listeners.push_back(std::move(listener));
LOG(md, Info, "** CME MDP3 Scripted Publisher started **");
}
void MDP3Main::send_heartbeats() {
for (const auto &listener : me_->listeners) {
listener->heartbeat();
@@ -386,7 +490,8 @@ unique_ptr<MDP3Listener> MDP3Main::prepare_listener(
onixs::Handler &handler,
const CMEChannel &channel,
MBOWriter *mbo,
TradeSummarySignalDispatcher *trade_summary_dispatcher) {
TradeSummarySignalDispatcher *trade_summary_dispatcher,
std::shared_ptr<IMarketDataListener> market_data_listener) {
LOG(md, Info, "MDP3Main::prepare_listener channel: {}", channel);
// We need to get a handler to the producer channels so we can produce
// heartbeats
@@ -398,7 +503,7 @@ unique_ptr<MDP3Listener> MDP3Main::prepare_listener(
unique_ptr<MDP3Listener> listener(new MDP3Listener(
me_->index, me_->producer, mbo, producer_channels,
trade_summary_dispatcher));
trade_summary_dispatcher, std::move(market_data_listener)));
for (auto &symbol : channel.symbols) {
listener->add_filter_symbol(symbol.symbol());
}
@@ -2,13 +2,16 @@
#include "CMESecurityIndex.h"
#include "MDP3Listener.h"
#include "spark/md/IMarketDataListener.h"
#include "spark/md/coconut2.h"
#include "spark/utils/bts_no_copy.h"
#include "onixs.h"
#include "sparkd/md/platforms/IMDPlatform.h"
#include <atomic>
#include <map>
#include <memory>
#include <thread>
#include <vector>
namespace bts {
@@ -37,7 +40,13 @@ class MDP3Main : public IMDPlatform {
void start(
const std::vector<UserSymbol> &symbols,
MBOWriter *mbo,
TradeSummarySignalDispatcher *tssd);
TradeSummarySignalDispatcher *tssd,
std::shared_ptr<IMarketDataListener> market_data_listener = nullptr);
void start_scripted(
const std::vector<UserSymbol> &symbols,
MBOWriter *mbo,
TradeSummarySignalDispatcher *tssd,
std::shared_ptr<IMarketDataListener> market_data_listener = nullptr);
void send_heartbeats() override;
void initialize(const std::string &license_store);
@@ -47,7 +56,8 @@ class MDP3Main : public IMDPlatform {
onixs::Handler &handler,
const CMEChannel &channel,
MBOWriter *,
TradeSummarySignalDispatcher *);
TradeSummarySignalDispatcher *,
std::shared_ptr<IMarketDataListener> market_data_listener = nullptr);
private:
struct PImpl;
@@ -0,0 +1,188 @@
#include "ScriptedMdp3Feeder.h"
#include "spark/api/domain/Venue.pb.h"
#include "spark/api/domain/SecurityType.pb.h"
#include "spark/md/IntPrice.h"
#include "spark/md/common.h"
#include <OnixS/CME/MDH/DirectBook.h>
#include <OnixS/CME/MDH/Handler.h>
#include <OnixS/CME/MDH/HandlerSettings.h>
#include <OnixS/CME/MDH/Packet.h>
#include <OnixS/CME/MDH/Security.h>
#include <cmath>
#include <memory>
namespace bts::md {
namespace {
constexpr std::uint32_t scripted_exchange_security_id = 1000001;
class ScriptedSecurity : public onixs::Security {
public:
explicit ScriptedSecurity(uint32_t id) : onixs::Security(id) {}
using onixs::Security::asset;
using onixs::Security::group;
using onixs::Security::symbol;
void sequence(std::uint32_t value) { seqNumber(value); }
};
struct ScriptedPacketHeader {
onixs::SequenceNumber seqNumber = 0;
onixs::Timestamp sendingTime;
};
PriceSize make_level(double price, float size) {
if (size == 0) {
return PriceSize();
}
return PriceSize(IntPrice_from_double<7>(price), size);
}
onixs::Decimal to_onixs_decimal(const PriceSize &level) {
// MDP3Listener applies the security display_factor when converting OnixS
// prices, so the scripted price must be expressed in pre-display-factor
// exchange units here. For ES with display_factor=-2, 7000.00 becomes
// mantissa 700000 with exponent 0.
return onixs::Decimal(
static_cast<onixs::Decimal::Mantissa>(std::llround(level.price() * 100.0)),
0);
}
using DirectBookPtr = std::unique_ptr<onixs::DirectBook, void (*)(onixs::DirectBook *)>;
DirectBookPtr make_direct_book(const ScriptedMdp3Feeder::DirectBookUpdate &update) {
DirectBookPtr book(
onixs::DirectBookFactory::construct(COCONUT_MAX_DEPTH),
&onixs::DirectBookFactory::destruct);
std::size_t bid_depth = 0;
std::size_t ask_depth = 0;
while (bid_depth < update.bids.size() && !update.bids[bid_depth].is_nan() &&
update.bids[bid_depth].size() != 0) {
++bid_depth;
}
while (ask_depth < update.asks.size() && !update.asks[ask_depth].is_nan() &&
update.asks[ask_depth].size() != 0) {
++ask_depth;
}
book->depth(static_cast<onixs::MbpBookDepth>(std::max(bid_depth, ask_depth)));
book->bids().resize(static_cast<onixs::MbpBookDepth>(bid_depth));
book->offers().resize(static_cast<onixs::MbpBookDepth>(ask_depth));
for (std::size_t i = 0; i < bid_depth; ++i) {
book->bids()[i] = onixs::DirectPriceLevel(
to_onixs_decimal(update.bids[i]),
static_cast<int>(update.bids[i].size()),
1);
}
for (std::size_t i = 0; i < ask_depth; ++i) {
book->offers()[i] = onixs::DirectPriceLevel(
to_onixs_decimal(update.asks[i]),
static_cast<int>(update.asks[i].size()),
1);
}
return book;
}
onixs::Handler &scripted_handler() {
static onixs::HandlerSettings settings;
static bool initialized = false;
if (!initialized) {
settings.channel(1);
initialized = true;
}
static onixs::Handler handler(settings);
return handler;
}
ScriptedSecurity &scripted_security() {
static ScriptedSecurity security(scripted_exchange_security_id);
static bool initialized = false;
if (!initialized) {
security.symbol(onixs::StrRef("ESM6", 4));
security.group(onixs::StrRef("ES", 2));
security.asset(onixs::StrRef("ES", 2));
initialized = true;
}
return security;
}
} // namespace
ScriptedMdp3Feeder::ScriptedMdp3Feeder(MDP3Listener &listener)
: _listener(listener) {}
void ScriptedMdp3Feeder::publish_hard_coded_future() const {
FixedFutureSecurity security;
fill_hard_coded_future(security);
_listener.add_security(security, co2::TRADINGSTATUS_NORMAL);
}
void ScriptedMdp3Feeder::publish_hard_coded_direct_book() const {
publish_hard_coded_direct_book(1, 0.0);
}
void ScriptedMdp3Feeder::publish_hard_coded_direct_book(
std::uint32_t sequence, double mid_price_shift) const {
const auto update = hard_coded_direct_book(sequence, mid_price_shift);
auto book = make_direct_book(update);
auto &handler = scripted_handler();
auto &security = scripted_security();
security.sequence(sequence);
ScriptedPacketHeader packet_header;
packet_header.seqNumber = sequence;
onixs::PacketArgs packet(&packet_header, sizeof(packet_header));
packet.receiveTime(onixs::Timestamp(update.packet_time.to_uint64()));
_listener.onPacket(handler, packet);
_listener.onBookUpdate(handler, security, *book);
_listener.onEndOfPacket(handler, packet);
}
void ScriptedMdp3Feeder::publish_hard_coded_values() const {
publish_hard_coded_future();
publish_hard_coded_direct_book();
}
void ScriptedMdp3Feeder::fill_hard_coded_future(FixedFutureSecurity &security) {
security.key = invalid_security_key;
security.numeric_id = scripted_exchange_security_id;
security.type = api::SECURITYTYPE_FUTURE;
security.exchange = api::Venue::VENUE_GLBX;
security.symbol("ES");
security.alt_symbol("ES");
security.security_desc("ESM6");
security.currency("USD");
security.display_factor = -2;
security.low_tick = 25.0;
security.high_tick = 25.0;
security.price_break = 0.0;
security.cash_per_point = 50.0;
security.expiration_year = 2026;
security.expiration_month = 6;
security.expiration_day = 19;
}
ScriptedMdp3Feeder::DirectBookUpdate
ScriptedMdp3Feeder::hard_coded_direct_book(
std::uint32_t sequence, double mid_price_shift) {
DirectBookUpdate update;
const double best_bid = 7000.0 + mid_price_shift;
const double best_ask = 7001.0 + mid_price_shift;
update.exchange_security_id = scripted_exchange_security_id;
update.bids[0] = make_level(best_bid, 10);
update.bids[1] = make_level(best_bid - 0.25, 10);
update.bids[2] = make_level(best_bid - 0.50, 10);
update.asks[0] = make_level(best_ask, 10);
update.asks[1] = make_level(best_ask + 0.25, 10);
update.asks[2] = make_level(best_ask + 0.50, 10);
update.packet_time = utils::TimeStamp::now();
update.sequence = sequence;
return update;
}
} // namespace bts::md
@@ -0,0 +1,39 @@
#pragma once
#include "MDP3Listener.h"
#include "spark/md/PriceSize.h"
#include "spark/utils/TimeStamp.h"
#include <array>
#include <cstdint>
namespace bts::md {
class ScriptedMdp3Feeder {
public:
struct DirectBookUpdate {
uint32_t exchange_security_id = 0;
std::array<PriceSize, COCONUT_MAX_DEPTH> bids = {};
std::array<PriceSize, COCONUT_MAX_DEPTH> asks = {};
utils::TimeStamp packet_time = utils::TimeStamp::now();
uint32_t sequence = 1;
};
explicit ScriptedMdp3Feeder(MDP3Listener &listener);
void publish_hard_coded_future() const;
void publish_hard_coded_direct_book() const;
void publish_hard_coded_direct_book(std::uint32_t sequence,
double mid_price_shift) const;
void publish_hard_coded_values() const;
static void fill_hard_coded_future(FixedFutureSecurity &security);
static DirectBookUpdate hard_coded_direct_book(
std::uint32_t sequence = 1, double mid_price_shift = 0.0);
private:
MDP3Listener &_listener;
};
} // namespace bts::md
@@ -254,7 +254,7 @@ namespace mbts.spark {
add_col(
Columns.Price,
DefaultColumnHeaders.Price,
r => _get_row(r).security.spec_or_default().format(r.fill.LastPrice),
r => _get_row(r).security.spec_or_default().format(r.fill.AvgPrice),
new DoubleMinMax<FillTuple>(r => r.fill.LastPrice),
DataGridFilterKnownTemplates.DoubleMinMax,
fs => fs.price,
+1 -4
View File
@@ -40,10 +40,7 @@ namespace Spark.Api.Orders {
) {
_order_service = order_service;
var scheduler = ThreadPoolScheduler.Instance;
if(interval is not null)
logger.Information("originally OrdersClient polling interval {0}", interval);
interval = TimeSpan.FromMilliseconds(1);
logger.Information("OrdersClient polling interval {0}", interval);
interval ??= TimeSpan.FromSeconds(0.1);
var bootstraps = new DisposableBuilder();
positions = position_service.subscribei_position_data().Table().Cache();
@@ -30,6 +30,5 @@ OrdermanCfg {
poll: false
hosted_actor: "*"
}
fallback_cust_order_handling_inst: "Y"
}
}
@@ -10,7 +10,6 @@
#include "spark/orderman/orderman_utils/orderman_common.h"
#include "spark/tracing/bts_trace.h"
#include "spark/utils/TimeStamp.h"
#include "spark/utils/bts_assert.h"
#include "spark/utils/bts_chrono.h"
#include "spark/utils/datetime.h"
#include "spark/utils/thread_manager.h"
@@ -98,8 +97,7 @@ struct CoreGateway::PImpl {
: cfg(cfg), observer(observer), make_connection(conn_factory),
make_store(store_factory), state(State::OFF), start_of_pause(),
session_info(), event_queue(), timer_thread(), destroy(false),
is_on(false), has_replayed(false), gave_up_permanently(false),
send_batch(), recv_batch(),
is_on(false), has_replayed(false), send_batch(), recv_batch(),
connection_attempts(0), perf_log(l) {
send_batch.reserve(1024);
recv_batch.reserve(1024);
@@ -118,7 +116,6 @@ struct CoreGateway::PImpl {
std::atomic<bool> destroy;
bool is_on;
bool has_replayed;
bool gave_up_permanently;
std::vector<EventData> send_batch;
std::vector<EventData> recv_batch;
uint32_t connection_attempts;
@@ -332,11 +329,6 @@ void CoreGateway::sync_session_ready(EventData const &) {
case State::WSESSION_TERMINATE:
break;
case State::CONNECTING:
LOG(Jetfix, Info,
"Jetfix session {} is now READY after socket connect. attempts={} "
"max_attempts={}",
me->cfg.name(), me->connection_attempts,
me->cfg.max_connection_attempts());
transition(State::READY);
me->observer.ready();
break;
@@ -354,18 +346,10 @@ void CoreGateway::sync_session_terminated(EventData const &) {
break;
case State::WSESSION_TERMINATE:
LOG(Jetfix, Warn,
"Session terminated callback received for {} while waiting for "
"reader disconnect. attempts_so_far={}",
me->cfg.name(), me->connection_attempts);
pause_or_shutdown();
break;
case State::READY:
LOG(Jetfix, Warn,
"Session terminated for {} from READY. Closing socket and waiting "
"for reader disconnect.",
me->cfg.name());
me->session_info->session.reset();
me->session_info->connection->shutdown();
transition(State::WREADER_DISCONNECT);
@@ -373,10 +357,6 @@ void CoreGateway::sync_session_terminated(EventData const &) {
break;
case State::CONNECTING:
LOG(Jetfix, Warn,
"Session terminated for {} during CONNECTING before READY. "
"Closing socket and waiting for reader disconnect.",
me->cfg.name());
me->session_info->session.reset();
me->session_info->connection->shutdown();
transition(State::WREADER_DISCONNECT);
@@ -396,28 +376,17 @@ void CoreGateway::sync_reader_disconnected(EventData const &) {
break;
case State::READY:
LOG(Jetfix, Warn,
"Socket reader disconnected for {} from READY. "
"The exchange or network closed the TCP session.",
me->cfg.name());
me->session_info->session.reset();
me->observer.disconnect();
transition(State::WSESSION_TERMINATE);
break;
case State::CONNECTING:
LOG(Jetfix, Warn,
"Socket reader disconnected for {} during CONNECTING before READY. "
"The TCP socket connected, but the session never completed logon.",
me->cfg.name());
me->session_info->session.reset();
transition(State::WSESSION_TERMINATE);
break;
case State::WREADER_DISCONNECT:
LOG(Jetfix, Info,
"Reader disconnect completed for {} after session shutdown.",
me->cfg.name());
pause_or_shutdown();
break;
@@ -461,46 +430,27 @@ void CoreGateway::sync_in_msg_sequenced(EventData const &ev) {
bts_assert(false);
}
}
void CoreGateway::sync_time(EventData const &ev) {
switch (me->state) {
case State::OFF:
break;
case State::PAUSED:
if (me->gave_up_permanently)
break;
if (datetime::is_at_least_secs_old(
me->start_of_pause, me->cfg.seconds_to_pause())) {
LOG(Jetfix, Info,
"Pause ended for jetfix connection {}. pause_secs={} "
"attempts_so_far={} max_attempts={} host={}:{} segment={} "
"session_window={}-{} {}-{} replayed={}",
me->cfg.name(), me->cfg.seconds_to_pause(),
me->connection_attempts, me->cfg.max_connection_attempts(),
me->cfg.socket_connect_host_ip(), me->cfg.socket_connect_port(),
me->cfg.cme_market_segment_id(), me->cfg.start_time(),
me->cfg.end_time(), me->cfg.start_day(), me->cfg.end_day(),
me->has_replayed);
LOG(Jetfix, Info, "Pause period ended for jetfix connection {}",
me->cfg.name());
me->session_info = std::make_unique<SessionInfo>();
me->session_info->store.reset(me->make_store(me->cfg));
auto const session_active = me->session_info->store->session_active();
LOG(Jetfix, Info,
"Loaded FIX store for {}. session_active={} next_attempt={} "
"max_attempts={}",
me->cfg.name(), session_active, me->connection_attempts + 1,
me->cfg.max_connection_attempts());
if (session_active) {
if (me->session_info->store->session_active()) {
me->connection_attempts++;
LOG(Jetfix, Info,
"Attempting socket connect for jetfix connection {}. "
"attempt={} max_attempts={}",
me->cfg.name(), me->connection_attempts,
me->cfg.max_connection_attempts());
if (!me->has_replayed) {
auto msgs_to_replay = me->session_info->store->replay();
LOG(Jetfix, Warn,
"Replaying {} FIX msgs for {} before reconnect",
msgs_to_replay.size(), me->cfg.name());
LOG(Jetfix, Warn, "Replaying {} FIX msgs",
msgs_to_replay.size());
me->observer.replay(msgs_to_replay);
me->has_replayed = true;
}
@@ -508,20 +458,14 @@ void CoreGateway::sync_time(EventData const &ev) {
if (me->connection_attempts > me->cfg.max_connection_attempts()) {
me->session_info.reset();
me->start_of_pause = datetime::now();
me->gave_up_permanently = true;
LOG(Jetfix, Error,
"Failed to connect to exchange gateway {} too many "
"times. Giving up permanently. attempts={} "
"max_attempts={} pause_secs={} host={}:{} segment={}. "
"You must bounce the server to recover.",
me->cfg.name(), me->connection_attempts,
me->cfg.max_connection_attempts(),
me->cfg.seconds_to_pause(),
me->cfg.socket_connect_host_ip(),
me->cfg.socket_connect_port(),
me->cfg.cme_market_segment_id());
"times. Giving up permanently. You must bounce "
"the server to recover.",
me->cfg.name());
break;
}
me->session_info->connection.reset(me->make_connection(me->cfg));
LOG(Jetfix, Warn, "Trying to connect to exchange for {} ({}/{})",
me->cfg.name(), me->connection_attempts,
@@ -545,18 +489,11 @@ void CoreGateway::sync_time(EventData const &ev) {
me->session_info.reset();
me->start_of_pause = datetime::now();
LOG(Jetfix, Warn,
"Failed to connect to exchange for {}. ({}/{}) "
"Will retry after {} seconds.",
"Failed to connect to exchange for {}. ({}/{}) ",
me->cfg.name(), me->connection_attempts,
me->cfg.max_connection_attempts(),
me->cfg.seconds_to_pause());
me->cfg.max_connection_attempts());
}
} else {
LOG(Jetfix, Warn,
"FIX store for {} is not active yet. Deferring reconnect. "
"session_window={}-{} {}-{}",
me->cfg.name(), me->cfg.start_time(), me->cfg.end_time(),
me->cfg.start_day(), me->cfg.end_day());
me->session_info.reset();
me->start_of_pause = datetime::now();
}
@@ -579,12 +516,6 @@ void CoreGateway::pause_or_shutdown() {
if (me->is_on) {
me->start_of_pause = datetime::now();
LOG(Jetfix, Info,
"Pausing jetfix gateway {}. pause_secs={} attempts_so_far={} "
"max_attempts={} gave_up_permanently={}",
me->cfg.name(), me->cfg.seconds_to_pause(),
me->connection_attempts, me->cfg.max_connection_attempts(),
me->gave_up_permanently);
transition(State::PAUSED);
} else
transition(State::OFF);
@@ -114,15 +114,6 @@ void Session::start() {
me->start_of_logon = me->now();
me->last_seq_num = me->begin_of_this_session;
me->last_seq_num_processed = me->store.last_seq_num_processed();
LOG(Jetfix, Info,
"Starting jetfix session {}. sender_compid={} sender_subid={} "
"target_compid={} target_subid={} secure_logon={} raw_data_len={} "
"user_name_present={} seq_num={} last_processed={}",
me->cfg.name(), me->cfg.sender_compid(), me->cfg.sender_subid(),
me->cfg.target_compid(), me->cfg.target_subid(),
me->cfg.use_cme_secure_logon(), me->cfg.raw_data().size(),
!me->cfg.user_name().empty(), me->last_seq_num + 1,
me->last_seq_num_processed);
transition(State::WLOGON);
internal_send(make_logon(
me->last_seq_num + 1, me->last_seq_num_processed, *me->current_time,
@@ -54,6 +54,7 @@
#include <google/protobuf/timestamp.pb.h>
#include <google/protobuf/util/time_util.h>
#include <memory>
#include <mutex>
#include <optional>
#include <sstream>
#include <string>
@@ -295,6 +296,7 @@ struct GeneralMarketDataListener::PImpl {
// (a flag is used to tell if bts::domain::SecurityID can be used as bts id
// as well)
std::unordered_map<bts::domain::SecurityID, uint64_t> cc_sec_id_map = {};
std::mutex callback_mutex;
MDArray bids = {};
MDArray asks = {};
IncrementalBookData inc_book_data = {};
@@ -387,10 +389,13 @@ GeneralMarketDataListener::~GeneralMarketDataListener() {}
void GeneralMarketDataListener::on_securities(
const std::vector<domain::Security const *> &complete_security_list) {
std::lock_guard<std::mutex> lock(me->callback_mutex);
LOG_SECURITIES_EVENT(Info, complete_security_list.size());
for (auto s_ptr : complete_security_list) {
const domain::Security &sec = *s_ptr;
CCSecSearchResult search_result = _find_sec(sec, true);
LOG(md, Info, "GeneralMarketDataListener::on_securities bef: {} after: {} key: {}", search_result.existed_before,
search_result.exists_now, search_result.key);
if (search_result.existed_before) {
LOG_SECURITY(
Warn, sec.venue(), sec.type(), sec.desc(), *sec.id(), 0,
@@ -424,6 +429,7 @@ void GeneralMarketDataListener::on_security_state(
void GeneralMarketDataListener::on_security_statistics(
const domain::SecurityMarketDataStatistics &sec_stats) {
std::lock_guard<std::mutex> lock(me->callback_mutex);
auto handle = _find_handle(sec_stats.security_id);
bts_assert_msgf(
handle != nullptr,
@@ -442,6 +448,7 @@ void GeneralMarketDataListener::on_security_statistics(
void GeneralMarketDataListener::on_book(
const bts::domain::Book &book, std::optional<utils::TimeStamp> time) {
std::lock_guard<std::mutex> lock(me->callback_mutex);
LOG_BOOK(Diag, book, BookLog_Status::PROCESSING);
// in case this is called externally in conjunction iwth inc book udpates
me->inc_book_data.overwrite_book(book);
@@ -450,6 +457,7 @@ void GeneralMarketDataListener::on_book(
void GeneralMarketDataListener::on_book_increment(
const IMarketDataListener::BookOp &book_op) {
std::lock_guard<std::mutex> lock(me->callback_mutex);
LOG_BOOK_OP(Diag, book_op, BookOpLog_Status::PROCESSING);
if (!me->inc_book_data.update_incremental(book_op)) {
return;
@@ -488,6 +496,7 @@ co2::AggressorSide try_fill_agg_side(
}
void GeneralMarketDataListener::on_trades(
const std::vector<domain::TradeRecord const *> &trades) {
std::lock_guard<std::mutex> lock(me->callback_mutex);
utils::Stopwatch sw;
for (auto tp : trades) {
sw.lap();
@@ -630,6 +639,8 @@ SecurityIndexData *GeneralMarketDataListener::_find_handle(
void GeneralMarketDataListener::_add_future(const bts::domain::Security &sec) {
bts_assert(sec.type() == SEC_TYPE(FUTURE));
auto search_result = _find_sec(sec, false);
LOG(md, Info, "GeneralMarketDataListener::_add_future bef: {} after: {} key: {}", search_result.existed_before,
search_result.exists_now, search_result.key);
bts_assert(search_result.existed_before);
FixedFutureSecurity ff_sec;
_copy_security_common(sec, search_result.key, ff_sec);
@@ -706,6 +717,7 @@ void GeneralMarketDataListener::_add_spot(const bts::domain::Security &sec) {
void GeneralMarketDataListener::_commit_security(const FixedSecurity &sec) {
// Set up the shared memory for this security
LOG(md, Info, "GeneralMarketDataListener::_commit_security numeric_id: {}", sec.numeric_id);
bts_assert(sec.numeric_id != 0);
auto handle = me->md_producer.add_security(sec);
// Add it to the index so it can receive messages
+1 -1
View File
@@ -174,7 +174,7 @@ MDProducerImpl &MDProducer::get_producer(
MDProducerHandle MDProducer::add_security(const FixedSecurity &security) {
bts_assert_d(strlen(security.symbol()) > 0);
bts_assert(security.size >= sizeof(FixedSecurity));
LOG(md, Diag, "MDProducer::add_security desc:{} key: {} num_id: {}",
LOG(md, Info, "MDProducer::add_security desc:{} key: {} num_id: {}",
std::string(security.security_desc()), security.key,
security.numeric_id);
std::lock_guard<std::mutex> lock(*_mutex);
@@ -395,9 +395,14 @@ void SimExecutionGateway::send_msgs(
bts::os::get_thread_id(), bts::os::get_thread_name(), msg_vec.size());
for (auto &m : msg_vec) {
auto mtype = msg_type(m);
LOG(OrderMan, Info,
"SimExecutionGateway::send_msgs tid: {} tname: {} m_type: {}",
bts::os::get_thread_id(), bts::os::get_thread_name(), mtype);
std::visit(
[&](auto const &typed_msg) {
LOG(OrderMan, Info,
"SimExecutionGateway::send_msgs tid: {} tname: {} m_type: {} msg: {}",
bts::os::get_thread_id(), bts::os::get_thread_name(), mtype,
typed_msg);
},
m);
me->buffered_order_ops.push(m);
}
}
+12 -12
View File
@@ -47,7 +47,7 @@ IL3GW::IL3GW(
: _config(conf), _x_state(State::INIT), _buffer(buffer),
_on_state_change([](auto) {}), _on_exe_report([](auto) {}),
_on_session_change([](auto) {}), _connection(con), _session(session),
_msg_count(0), _time(), _pool("IL3GW_rprts", 1024*2, 100), _exe_parser(cfg, db), _retransmit() {
_msg_count(0), _time(), _pool(), _exe_parser(cfg, db), _retransmit() {
LOG(OrderMan, Info,
"IL3GW::IL3GW cme_session: {} uuid: {} to_cme: {} from_cme: {}",
_config.cme_session, _session.uuid, _session.to_cme, _session.from_cme);
@@ -179,10 +179,15 @@ uint64_t IL3GW::send_party_details(const api::orderman::RoutingRecord &route) {
using namespace iLinkBinary;
auto msg = _buffer.frame<PartyDetailsDefinitionRequest518>(
// Use the generated helper so group sizing stays in sync with the
// active schema when CME updates the template layout.
PartyDetailsDefinitionRequest518::computeLength(3, 0) -
PartyDetailsDefinitionRequest518::sbeBlockLength());
// 2 repeating group header.
// 1 for party details and 1 for trade reg
// This seems unsafe but the api doesn't seem to want you to know how to
// size buffers ahead of time
2 * PartyDetailsDefinitionRequest518::NoPartyDetails::sbeHeaderSize() +
// N * size of each block
3 * PartyDetailsDefinitionRequest518::NoPartyDetails::sbeBlockLength() +
0 * PartyDetailsDefinitionRequest518::NoTrdRegPublications::
sbeBlockLength());
msg.partyDetailsListReqID(0);
msg.sendingTimeEpoch(_time.now());
msg.listUpdateAction(ListUpdAct::Add);
@@ -632,13 +637,8 @@ void IL3GW::handle(
handle_common(msg);
}
void IL3GW::handle(const iLinkBinary::BusinessReject521 &msg) {
LOG(iLink3, Error,
"Business Reject: reason={} '{}' ref_seq={} ref_tag={} ref_msg_type='{}' "
"ref_id={} text='{}'",
msg.businessRejectReason(),
string{translate_business_reject_reason(msg.businessRejectReason())},
msg.refSeqNum(), msg.refTagID(), msg.getRefMsgTypeAsStringView(),
msg.businessRejectRefID(), msg.getTextAsStringView());
LOG(iLink3, Error, "Business Reject: {} '{}'.", msg.businessRejectReason(),
string{translate_business_reject_reason(msg.businessRejectReason())});
handle_common(msg);
// A business reject can de-sync the sequence number because it rejects
// the sequence number of the rejected message. Send a sequence message
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(330);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(521);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -32,7 +32,7 @@ public:
{
GiveUp = static_cast<char>(71),
SGXoffset = static_cast<char>(83),
NULL_VALUE = static_cast<char>(0)
NULL_VALUE = static_cast<char>(0x00)
};
static CmtaGiveUpCD::Value get(const char value)
@@ -41,7 +41,7 @@ public:
{
case static_cast<char>(71): return GiveUp;
case static_cast<char>(83): return SGXoffset;
case static_cast<char>(0): return NULL_VALUE;
case static_cast<char>(0x00): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum CmtaGiveUpCD [E103]");
@@ -1,75 +0,0 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_CROSSTYPEENUM_H_
#define _ILINKBINARY_CROSSTYPEENUM_H_
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <iomanip>
#include <limits>
#include <ostream>
#include <stdexcept>
#include <sstream>
#include <string>
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class CrossTypeEnum
{
public:
enum Value
{
Cross = static_cast<std::uint8_t>(3),
RCross = static_cast<std::uint8_t>(20),
CCross = static_cast<std::uint8_t>(21),
NULL_VALUE = static_cast<std::uint8_t>(255)
};
static CrossTypeEnum::Value get(const std::uint8_t value)
{
switch (value)
{
case static_cast<std::uint8_t>(3): return Cross;
case static_cast<std::uint8_t>(20): return RCross;
case static_cast<std::uint8_t>(21): return CCross;
case static_cast<std::uint8_t>(255): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum CrossTypeEnum [E103]");
}
static const char *c_str(const CrossTypeEnum::Value value)
{
switch (value)
{
case Cross: return "Cross";
case RCross: return "RCross";
case CCross: return "CCross";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum CrossTypeEnum [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> & operator << (
std::basic_ostream<CharT, Traits> &os, CrossTypeEnum::Value m)
{
return os << CrossTypeEnum::c_str(m);
}
};
}
#endif
@@ -36,7 +36,7 @@ public:
AlgoEngine = static_cast<char>(72),
DeskElectronic = static_cast<char>(87),
ClientElectronic = static_cast<char>(89),
NULL_VALUE = static_cast<char>(0)
NULL_VALUE = static_cast<char>(48)
};
static CustOrdHandlInst::Value get(const char value)
@@ -49,7 +49,7 @@ public:
case static_cast<char>(72): return AlgoEngine;
case static_cast<char>(87): return DeskElectronic;
case static_cast<char>(89): return ClientElectronic;
case static_cast<char>(0): return NULL_VALUE;
case static_cast<char>(48): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum CustOrdHandlInst [E103]");
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *lengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -38,7 +38,7 @@ public:
CalculationDifference = static_cast<char>(70),
NoMatchingExecutionReport = static_cast<char>(71),
Other = static_cast<char>(90),
NULL_VALUE = static_cast<char>(0)
NULL_VALUE = static_cast<char>(48)
};
static DKReason::Value get(const char value)
@@ -53,7 +53,7 @@ public:
case static_cast<char>(70): return CalculationDifference;
case static_cast<char>(71): return NoMatchingExecutionReport;
case static_cast<char>(90): return Other;
case static_cast<char>(0): return NULL_VALUE;
case static_cast<char>(48): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum DKReason [E103]");
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -213,7 +213,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t mantissaSinceVersion() SBE_NOEXCEPT
{
return 9;
return 6;
}
SBE_NODISCARD bool mantissaInActingVersion() SBE_NOEXCEPT
@@ -255,7 +255,7 @@ public:
SBE_NODISCARD std::int64_t mantissa() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
if (m_actingVersion < 6)
{
return INT64_C(9223372036854775807);
}
@@ -288,7 +288,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t exponentSinceVersion() SBE_NOEXCEPT
{
return 9;
return 6;
}
SBE_NODISCARD bool exponentInActingVersion() SBE_NOEXCEPT
@@ -330,7 +330,7 @@ public:
SBE_NODISCARD std::int8_t exponent() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
if (m_actingVersion < 6)
{
return static_cast<std::int8_t>(127);
}
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(132);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(503);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(39);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(38);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(504);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(39);
return static_cast<std::uint16_t>(38);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -970,82 +968,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *EnvironmentIndicatorMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "optional";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t environmentIndicatorId() SBE_NOEXCEPT
{
return 39032;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t environmentIndicatorSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool environmentIndicatorInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= environmentIndicatorSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingOffset() SBE_NOEXCEPT
{
return 38;
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorNullValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(255);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMinValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(0);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMaxValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(254);
}
static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::uint8_t environmentIndicator() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return static_cast<std::uint8_t>(255);
}
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 38, sizeof(std::uint8_t));
return (val);
}
EstablishmentAck504 &environmentIndicator(const std::uint8_t value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 38, &val, sizeof(std::uint8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> & operator << (
std::basic_ostream<CharT, Traits> &builder, EstablishmentAck504 _writer)
@@ -1098,10 +1020,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << R"("SplitMsg": )";
builder << '"' << writer.splitMsg() << '"';
builder << ", ";
builder << R"("EnvironmentIndicator": )";
builder << +writer.environmentIndicator();
builder << '}';
return builder;
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(73);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(72);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(505);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(73);
return static_cast<std::uint16_t>(72);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -963,82 +961,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *EnvironmentIndicatorMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "optional";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t environmentIndicatorId() SBE_NOEXCEPT
{
return 39032;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t environmentIndicatorSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool environmentIndicatorInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= environmentIndicatorSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingOffset() SBE_NOEXCEPT
{
return 72;
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorNullValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(255);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMinValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(0);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMaxValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(254);
}
static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::uint8_t environmentIndicator() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return static_cast<std::uint8_t>(255);
}
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 72, sizeof(std::uint8_t));
return (val);
}
EstablishmentReject505 &environmentIndicator(const std::uint8_t value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 72, &val, sizeof(std::uint8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> & operator << (
std::basic_ostream<CharT, Traits> &builder, EstablishmentReject505 _writer)
@@ -1084,10 +1006,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << R"("SplitMsg": )";
builder << '"' << writer.splitMsg() << '"';
builder << ", ";
builder << R"("EnvironmentIndicator": )";
builder << +writer.environmentIndicator();
builder << '}';
return builder;
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
ExecInst &clear()
@@ -32,7 +32,7 @@ public:
{
Aggressive = static_cast<char>(65),
Passive = static_cast<char>(80),
NULL_VALUE = static_cast<char>(0)
NULL_VALUE = static_cast<char>(0x00)
};
static ExecMode::Value get(const char value)
@@ -41,7 +41,7 @@ public:
{
case static_cast<char>(65): return Aggressive;
case static_cast<char>(80): return Passive;
case static_cast<char>(0): return NULL_VALUE;
case static_cast<char>(0x00): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum ExecMode [E103]");
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(101);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(539);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(247);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(534);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(219);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(524);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(226);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(531);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(226);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(522);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(219);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(564);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(196);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(565);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(483);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(523);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(513);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(532);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(266);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(222);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(548);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(266);
return static_cast<std::uint16_t>(222);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -3112,7 +3110,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -3159,7 +3157,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -3249,313 +3247,6 @@ public:
return m_benchmarkPrice;
}
SBE_NODISCARD static const char *MDTradeEntryIDMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t mDTradeEntryIDId() SBE_NOEXCEPT
{
return 37711;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t mDTradeEntryIDSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool mDTradeEntryIDInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= mDTradeEntryIDSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t mDTradeEntryIDEncodingOffset() SBE_NOEXCEPT
{
return 222;
}
static SBE_CONSTEXPR std::uint32_t mDTradeEntryIDNullValue() SBE_NOEXCEPT
{
return SBE_NULLVALUE_UINT32;
}
static SBE_CONSTEXPR std::uint32_t mDTradeEntryIDMinValue() SBE_NOEXCEPT
{
return UINT32_C(0x0);
}
static SBE_CONSTEXPR std::uint32_t mDTradeEntryIDMaxValue() SBE_NOEXCEPT
{
return UINT32_C(0xfffffffe);
}
static SBE_CONSTEXPR std::size_t mDTradeEntryIDEncodingLength() SBE_NOEXCEPT
{
return 4;
}
SBE_NODISCARD std::uint32_t mDTradeEntryID() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return UINT32_C(0xffffffff);
}
std::uint32_t val;
std::memcpy(&val, m_buffer + m_offset + 222, sizeof(std::uint32_t));
return SBE_LITTLE_ENDIAN_ENCODE_32(val);
}
ExecutionReportTradeAddendumOutright548 &mDTradeEntryID(const std::uint32_t value) SBE_NOEXCEPT
{
std::uint32_t val = SBE_LITTLE_ENDIAN_ENCODE_32(value);
std::memcpy(m_buffer + m_offset + 222, &val, sizeof(std::uint32_t));
return *this;
}
SBE_NODISCARD static const char *ExecRefIDMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "String";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t execRefIDId() SBE_NOEXCEPT
{
return 19;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t execRefIDSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool execRefIDInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= execRefIDSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t execRefIDEncodingOffset() SBE_NOEXCEPT
{
return 226;
}
static SBE_CONSTEXPR char execRefIDNullValue() SBE_NOEXCEPT
{
return static_cast<char>(0);
}
static SBE_CONSTEXPR char execRefIDMinValue() SBE_NOEXCEPT
{
return static_cast<char>(32);
}
static SBE_CONSTEXPR char execRefIDMaxValue() SBE_NOEXCEPT
{
return static_cast<char>(126);
}
static SBE_CONSTEXPR std::size_t execRefIDEncodingLength() SBE_NOEXCEPT
{
return 40;
}
static SBE_CONSTEXPR std::uint64_t execRefIDLength() SBE_NOEXCEPT
{
return 40;
}
SBE_NODISCARD const char *execRefID() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return nullptr;
}
return m_buffer + m_offset + 226;
}
SBE_NODISCARD char *execRefID() SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return nullptr;
}
return m_buffer + m_offset + 226;
}
SBE_NODISCARD char execRefID(const std::uint64_t index) const
{
if (index >= 40)
{
throw std::runtime_error("index out of range for execRefID [E104]");
}
if (m_actingVersion < 9)
{
return static_cast<char>(0);
}
char val;
std::memcpy(&val, m_buffer + m_offset + 226 + (index * 1), sizeof(char));
return (val);
}
ExecutionReportTradeAddendumOutright548 &execRefID(const std::uint64_t index, const char value)
{
if (index >= 40)
{
throw std::runtime_error("index out of range for execRefID [E105]");
}
char val = (value);
std::memcpy(m_buffer + m_offset + 226 + (index * 1), &val, sizeof(char));
return *this;
}
std::uint64_t getExecRefID(char *const dst, const std::uint64_t length) const
{
if (length > 40)
{
throw std::runtime_error("length too large for getExecRefID [E106]");
}
if (m_actingVersion < 9)
{
return 0;
}
std::memcpy(dst, m_buffer + m_offset + 226, sizeof(char) * static_cast<std::size_t>(length));
return length;
}
ExecutionReportTradeAddendumOutright548 &putExecRefID(const char *const src) SBE_NOEXCEPT
{
std::memcpy(m_buffer + m_offset + 226, src, sizeof(char) * 40);
return *this;
}
SBE_NODISCARD std::string getExecRefIDAsString() const
{
const char *buffer = m_buffer + m_offset + 226;
std::size_t length = 0;
for (; length < 40 && *(buffer + length) != '\0'; ++length);
std::string result(buffer, length);
return result;
}
std::string getExecRefIDAsJsonEscapedString()
{
if (m_actingVersion < 9)
{
return std::string("");
}
std::ostringstream oss;
std::string s = getExecRefIDAsString();
for (const auto c : s)
{
switch (c)
{
case '"': oss << "\\\""; break;
case '\\': oss << "\\\\"; break;
case '\b': oss << "\\b"; break;
case '\f': oss << "\\f"; break;
case '\n': oss << "\\n"; break;
case '\r': oss << "\\r"; break;
case '\t': oss << "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f')
{
oss << "\\u" << std::hex << std::setw(4)
<< std::setfill('0') << (int)(c);
}
else
{
oss << c;
}
}
}
return oss.str();
}
#if __cplusplus >= 201703L
SBE_NODISCARD std::string_view getExecRefIDAsStringView() const SBE_NOEXCEPT
{
const char *buffer = m_buffer + m_offset + 226;
std::size_t length = 0;
for (; length < 40 && *(buffer + length) != '\0'; ++length);
std::string_view result(buffer, length);
return result;
}
#endif
#if __cplusplus >= 201703L
ExecutionReportTradeAddendumOutright548 &putExecRefID(const std::string_view str)
{
const std::size_t srcLength = str.length();
if (srcLength > 40)
{
throw std::runtime_error("string too large for putExecRefID [E106]");
}
std::memcpy(m_buffer + m_offset + 226, str.data(), srcLength);
for (std::size_t start = srcLength; start < 40; ++start)
{
m_buffer[m_offset + 226 + start] = 0;
}
return *this;
}
#else
ExecutionReportTradeAddendumOutright548 &putExecRefID(const std::string &str)
{
const std::size_t srcLength = str.length();
if (srcLength > 40)
{
throw std::runtime_error("string too large for putExecRefID [E106]");
}
std::memcpy(m_buffer + m_offset + 226, str.c_str(), srcLength);
for (std::size_t start = srcLength; start < 40; ++start)
{
m_buffer[m_offset + 226 + start] = 0;
}
return *this;
}
#endif
class NoFills
{
private:
@@ -4948,7 +4639,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -4995,7 +4686,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -5352,15 +5043,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << "{}";
}
builder << ", ";
builder << R"("MDTradeEntryID": )";
builder << +writer.mDTradeEntryID();
builder << ", ";
builder << R"("ExecRefID": )";
builder << '"' <<
writer.getExecRefIDAsJsonEscapedString().c_str() << '"';
builder << ", ";
{
bool atLeastOne = false;
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(227);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(187);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(549);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(227);
return static_cast<std::uint16_t>(187);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -2965,237 +2963,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *ExecRefIDMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "String";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t execRefIDId() SBE_NOEXCEPT
{
return 19;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t execRefIDSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool execRefIDInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= execRefIDSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t execRefIDEncodingOffset() SBE_NOEXCEPT
{
return 187;
}
static SBE_CONSTEXPR char execRefIDNullValue() SBE_NOEXCEPT
{
return static_cast<char>(0);
}
static SBE_CONSTEXPR char execRefIDMinValue() SBE_NOEXCEPT
{
return static_cast<char>(32);
}
static SBE_CONSTEXPR char execRefIDMaxValue() SBE_NOEXCEPT
{
return static_cast<char>(126);
}
static SBE_CONSTEXPR std::size_t execRefIDEncodingLength() SBE_NOEXCEPT
{
return 40;
}
static SBE_CONSTEXPR std::uint64_t execRefIDLength() SBE_NOEXCEPT
{
return 40;
}
SBE_NODISCARD const char *execRefID() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return nullptr;
}
return m_buffer + m_offset + 187;
}
SBE_NODISCARD char *execRefID() SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return nullptr;
}
return m_buffer + m_offset + 187;
}
SBE_NODISCARD char execRefID(const std::uint64_t index) const
{
if (index >= 40)
{
throw std::runtime_error("index out of range for execRefID [E104]");
}
if (m_actingVersion < 9)
{
return static_cast<char>(0);
}
char val;
std::memcpy(&val, m_buffer + m_offset + 187 + (index * 1), sizeof(char));
return (val);
}
ExecutionReportTradeAddendumSpread549 &execRefID(const std::uint64_t index, const char value)
{
if (index >= 40)
{
throw std::runtime_error("index out of range for execRefID [E105]");
}
char val = (value);
std::memcpy(m_buffer + m_offset + 187 + (index * 1), &val, sizeof(char));
return *this;
}
std::uint64_t getExecRefID(char *const dst, const std::uint64_t length) const
{
if (length > 40)
{
throw std::runtime_error("length too large for getExecRefID [E106]");
}
if (m_actingVersion < 9)
{
return 0;
}
std::memcpy(dst, m_buffer + m_offset + 187, sizeof(char) * static_cast<std::size_t>(length));
return length;
}
ExecutionReportTradeAddendumSpread549 &putExecRefID(const char *const src) SBE_NOEXCEPT
{
std::memcpy(m_buffer + m_offset + 187, src, sizeof(char) * 40);
return *this;
}
SBE_NODISCARD std::string getExecRefIDAsString() const
{
const char *buffer = m_buffer + m_offset + 187;
std::size_t length = 0;
for (; length < 40 && *(buffer + length) != '\0'; ++length);
std::string result(buffer, length);
return result;
}
std::string getExecRefIDAsJsonEscapedString()
{
if (m_actingVersion < 9)
{
return std::string("");
}
std::ostringstream oss;
std::string s = getExecRefIDAsString();
for (const auto c : s)
{
switch (c)
{
case '"': oss << "\\\""; break;
case '\\': oss << "\\\\"; break;
case '\b': oss << "\\b"; break;
case '\f': oss << "\\f"; break;
case '\n': oss << "\\n"; break;
case '\r': oss << "\\r"; break;
case '\t': oss << "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f')
{
oss << "\\u" << std::hex << std::setw(4)
<< std::setfill('0') << (int)(c);
}
else
{
oss << c;
}
}
}
return oss.str();
}
#if __cplusplus >= 201703L
SBE_NODISCARD std::string_view getExecRefIDAsStringView() const SBE_NOEXCEPT
{
const char *buffer = m_buffer + m_offset + 187;
std::size_t length = 0;
for (; length < 40 && *(buffer + length) != '\0'; ++length);
std::string_view result(buffer, length);
return result;
}
#endif
#if __cplusplus >= 201703L
ExecutionReportTradeAddendumSpread549 &putExecRefID(const std::string_view str)
{
const std::size_t srcLength = str.length();
if (srcLength > 40)
{
throw std::runtime_error("string too large for putExecRefID [E106]");
}
std::memcpy(m_buffer + m_offset + 187, str.data(), srcLength);
for (std::size_t start = srcLength; start < 40; ++start)
{
m_buffer[m_offset + 187 + start] = 0;
}
return *this;
}
#else
ExecutionReportTradeAddendumSpread549 &putExecRefID(const std::string &str)
{
const std::size_t srcLength = str.length();
if (srcLength > 40)
{
throw std::runtime_error("string too large for putExecRefID [E106]");
}
std::memcpy(m_buffer + m_offset + 187, str.c_str(), srcLength);
for (std::size_t start = srcLength; start < 40; ++start)
{
m_buffer[m_offset + 187 + start] = 0;
}
return *this;
}
#endif
class NoFills
{
private:
@@ -5611,11 +5378,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << R"("ShortSaleType": )";
builder << '"' << writer.shortSaleType() << '"';
builder << ", ";
builder << R"("ExecRefID": )";
builder << '"' <<
writer.getExecRefIDAsJsonEscapedString().c_str() << '"';
builder << ", ";
{
bool atLeastOne = false;
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(236);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(196);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(550);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(236);
return static_cast<std::uint16_t>(196);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -2546,7 +2544,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -2593,7 +2591,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -2636,237 +2634,6 @@ public:
return m_grossTradeAmt;
}
SBE_NODISCARD static const char *ExecRefIDMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "String";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t execRefIDId() SBE_NOEXCEPT
{
return 19;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t execRefIDSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool execRefIDInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= execRefIDSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t execRefIDEncodingOffset() SBE_NOEXCEPT
{
return 196;
}
static SBE_CONSTEXPR char execRefIDNullValue() SBE_NOEXCEPT
{
return static_cast<char>(0);
}
static SBE_CONSTEXPR char execRefIDMinValue() SBE_NOEXCEPT
{
return static_cast<char>(32);
}
static SBE_CONSTEXPR char execRefIDMaxValue() SBE_NOEXCEPT
{
return static_cast<char>(126);
}
static SBE_CONSTEXPR std::size_t execRefIDEncodingLength() SBE_NOEXCEPT
{
return 40;
}
static SBE_CONSTEXPR std::uint64_t execRefIDLength() SBE_NOEXCEPT
{
return 40;
}
SBE_NODISCARD const char *execRefID() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return nullptr;
}
return m_buffer + m_offset + 196;
}
SBE_NODISCARD char *execRefID() SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return nullptr;
}
return m_buffer + m_offset + 196;
}
SBE_NODISCARD char execRefID(const std::uint64_t index) const
{
if (index >= 40)
{
throw std::runtime_error("index out of range for execRefID [E104]");
}
if (m_actingVersion < 9)
{
return static_cast<char>(0);
}
char val;
std::memcpy(&val, m_buffer + m_offset + 196 + (index * 1), sizeof(char));
return (val);
}
ExecutionReportTradeAddendumSpreadLeg550 &execRefID(const std::uint64_t index, const char value)
{
if (index >= 40)
{
throw std::runtime_error("index out of range for execRefID [E105]");
}
char val = (value);
std::memcpy(m_buffer + m_offset + 196 + (index * 1), &val, sizeof(char));
return *this;
}
std::uint64_t getExecRefID(char *const dst, const std::uint64_t length) const
{
if (length > 40)
{
throw std::runtime_error("length too large for getExecRefID [E106]");
}
if (m_actingVersion < 9)
{
return 0;
}
std::memcpy(dst, m_buffer + m_offset + 196, sizeof(char) * static_cast<std::size_t>(length));
return length;
}
ExecutionReportTradeAddendumSpreadLeg550 &putExecRefID(const char *const src) SBE_NOEXCEPT
{
std::memcpy(m_buffer + m_offset + 196, src, sizeof(char) * 40);
return *this;
}
SBE_NODISCARD std::string getExecRefIDAsString() const
{
const char *buffer = m_buffer + m_offset + 196;
std::size_t length = 0;
for (; length < 40 && *(buffer + length) != '\0'; ++length);
std::string result(buffer, length);
return result;
}
std::string getExecRefIDAsJsonEscapedString()
{
if (m_actingVersion < 9)
{
return std::string("");
}
std::ostringstream oss;
std::string s = getExecRefIDAsString();
for (const auto c : s)
{
switch (c)
{
case '"': oss << "\\\""; break;
case '\\': oss << "\\\\"; break;
case '\b': oss << "\\b"; break;
case '\f': oss << "\\f"; break;
case '\n': oss << "\\n"; break;
case '\r': oss << "\\r"; break;
case '\t': oss << "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f')
{
oss << "\\u" << std::hex << std::setw(4)
<< std::setfill('0') << (int)(c);
}
else
{
oss << c;
}
}
}
return oss.str();
}
#if __cplusplus >= 201703L
SBE_NODISCARD std::string_view getExecRefIDAsStringView() const SBE_NOEXCEPT
{
const char *buffer = m_buffer + m_offset + 196;
std::size_t length = 0;
for (; length < 40 && *(buffer + length) != '\0'; ++length);
std::string_view result(buffer, length);
return result;
}
#endif
#if __cplusplus >= 201703L
ExecutionReportTradeAddendumSpreadLeg550 &putExecRefID(const std::string_view str)
{
const std::size_t srcLength = str.length();
if (srcLength > 40)
{
throw std::runtime_error("string too large for putExecRefID [E106]");
}
std::memcpy(m_buffer + m_offset + 196, str.data(), srcLength);
for (std::size_t start = srcLength; start < 40; ++start)
{
m_buffer[m_offset + 196 + start] = 0;
}
return *this;
}
#else
ExecutionReportTradeAddendumSpreadLeg550 &putExecRefID(const std::string &str)
{
const std::size_t srcLength = str.length();
if (srcLength > 40)
{
throw std::runtime_error("string too large for putExecRefID [E106]");
}
std::memcpy(m_buffer + m_offset + 196, str.c_str(), srcLength);
for (std::size_t start = srcLength; start < 40; ++start)
{
m_buffer[m_offset + 196 + start] = 0;
}
return *this;
}
#endif
class NoFills
{
private:
@@ -3564,11 +3331,11 @@ public:
m_buffer = buffer;
m_bufferLength = bufferLength;
GroupSize dimensions(buffer, *pos, bufferLength, actingVersion);
dimensions.blockLength(static_cast<std::uint16_t>(45));
dimensions.blockLength(static_cast<std::uint16_t>(27));
dimensions.numInGroup(static_cast<std::uint8_t>(count));
m_index = 0;
m_count = count;
m_blockLength = 45;
m_blockLength = 27;
m_actingVersion = actingVersion;
m_initialPosition = *pos;
m_positionPtr = pos;
@@ -3582,7 +3349,7 @@ public:
static SBE_CONSTEXPR std::uint64_t sbeBlockLength() SBE_NOEXCEPT
{
return 45;
return 27;
}
SBE_NODISCARD std::uint64_t sbePosition() const SBE_NOEXCEPT
@@ -4255,100 +4022,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *ContraGrossTradeAmtMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t contraGrossTradeAmtId() SBE_NOEXCEPT
{
return 5542;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t contraGrossTradeAmtSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool contraGrossTradeAmtInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= contraGrossTradeAmtSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t contraGrossTradeAmtEncodingOffset() SBE_NOEXCEPT
{
return 27;
}
private:
Decimal64NULL m_contraGrossTradeAmt;
public:
SBE_NODISCARD Decimal64NULL &contraGrossTradeAmt()
{
m_contraGrossTradeAmt.wrap(m_buffer, m_offset + 27, m_actingVersion, m_bufferLength);
return m_contraGrossTradeAmt;
}
SBE_NODISCARD static const char *ContraCalculatedCcyLastQtyMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t contraCalculatedCcyLastQtyId() SBE_NOEXCEPT
{
return 5971;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t contraCalculatedCcyLastQtySinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool contraCalculatedCcyLastQtyInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= contraCalculatedCcyLastQtySinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t contraCalculatedCcyLastQtyEncodingOffset() SBE_NOEXCEPT
{
return 36;
}
private:
Decimal64NULL m_contraCalculatedCcyLastQty;
public:
SBE_NODISCARD Decimal64NULL &contraCalculatedCcyLastQty()
{
m_contraCalculatedCcyLastQty.wrap(m_buffer, m_offset + 36, m_actingVersion, m_bufferLength);
return m_contraCalculatedCcyLastQty;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> & operator << (
std::basic_ostream<CharT, Traits> &builder, NoOrderEvents writer)
@@ -4382,28 +4055,6 @@ public:
builder << R"("OriginalOrderEventExecID": )";
builder << +writer.originalOrderEventExecID();
builder << ", ";
builder << R"("ContraGrossTradeAmt": )";
if (writer.contraGrossTradeAmtInActingVersion())
{
builder << writer.contraGrossTradeAmt();
}
else
{
builder << "{}";
}
builder << ", ";
builder << R"("ContraCalculatedCcyLastQty": )";
if (writer.contraCalculatedCcyLastQtyInActingVersion())
{
builder << writer.contraCalculatedCcyLastQty();
}
else
{
builder << "{}";
}
builder << '}';
return builder;
@@ -4609,11 +4260,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << "{}";
}
builder << ", ";
builder << R"("ExecRefID": )";
builder << '"' <<
writer.getExecRefIDAsJsonEscapedString().c_str() << '"';
builder << ", ";
{
bool atLeastOne = false;
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(293);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(525);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -4096,7 +4094,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -4143,7 +4141,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -5719,7 +5717,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -5766,7 +5764,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(230);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(526);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(219);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(527);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -2762,7 +2760,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -2809,7 +2807,7 @@ public:
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
@@ -3549,11 +3547,11 @@ public:
m_buffer = buffer;
m_bufferLength = bufferLength;
GroupSize dimensions(buffer, *pos, bufferLength, actingVersion);
dimensions.blockLength(static_cast<std::uint16_t>(41));
dimensions.blockLength(static_cast<std::uint16_t>(23));
dimensions.numInGroup(static_cast<std::uint8_t>(count));
m_index = 0;
m_count = count;
m_blockLength = 41;
m_blockLength = 23;
m_actingVersion = actingVersion;
m_initialPosition = *pos;
m_positionPtr = pos;
@@ -3567,7 +3565,7 @@ public:
static SBE_CONSTEXPR std::uint64_t sbeBlockLength() SBE_NOEXCEPT
{
return 41;
return 23;
}
SBE_NODISCARD std::uint64_t sbePosition() const SBE_NOEXCEPT
@@ -4164,100 +4162,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *ContraGrossTradeAmtMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t contraGrossTradeAmtId() SBE_NOEXCEPT
{
return 5542;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t contraGrossTradeAmtSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool contraGrossTradeAmtInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= contraGrossTradeAmtSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t contraGrossTradeAmtEncodingOffset() SBE_NOEXCEPT
{
return 23;
}
private:
Decimal64NULL m_contraGrossTradeAmt;
public:
SBE_NODISCARD Decimal64NULL &contraGrossTradeAmt()
{
m_contraGrossTradeAmt.wrap(m_buffer, m_offset + 23, m_actingVersion, m_bufferLength);
return m_contraGrossTradeAmt;
}
SBE_NODISCARD static const char *ContraCalculatedCcyLastQtyMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "Qty";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t contraCalculatedCcyLastQtyId() SBE_NOEXCEPT
{
return 5971;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t contraCalculatedCcyLastQtySinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool contraCalculatedCcyLastQtyInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= contraCalculatedCcyLastQtySinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t contraCalculatedCcyLastQtyEncodingOffset() SBE_NOEXCEPT
{
return 32;
}
private:
Decimal64NULL m_contraCalculatedCcyLastQty;
public:
SBE_NODISCARD Decimal64NULL &contraCalculatedCcyLastQty()
{
m_contraCalculatedCcyLastQty.wrap(m_buffer, m_offset + 32, m_actingVersion, m_bufferLength);
return m_contraCalculatedCcyLastQty;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> & operator << (
std::basic_ostream<CharT, Traits> &builder, NoOrderEvents writer)
@@ -4287,28 +4191,6 @@ public:
builder << R"("OrderEventReason": )";
builder << +writer.orderEventReason();
builder << ", ";
builder << R"("ContraGrossTradeAmt": )";
if (writer.contraGrossTradeAmtInActingVersion())
{
builder << writer.contraGrossTradeAmt();
}
else
{
builder << "{}";
}
builder << ", ";
builder << R"("ContraCalculatedCcyLastQty": )";
if (writer.contraCalculatedCcyLastQtyInActingVersion())
{
builder << writer.contraCalculatedCcyLastQty();
}
else
{
builder << "{}";
}
builder << '}';
return builder;
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *blockLengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -32,7 +32,7 @@ public:
{
Limit = static_cast<char>(50),
StopLimit = static_cast<char>(52),
NULL_VALUE = static_cast<char>(0)
NULL_VALUE = static_cast<char>(48)
};
static MassActionOrdTyp::Value get(const char value)
@@ -41,7 +41,7 @@ public:
{
case static_cast<char>(50): return Limit;
case static_cast<char>(52): return StopLimit;
case static_cast<char>(0): return NULL_VALUE;
case static_cast<char>(48): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum MassActionOrdTyp [E103]");
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(123);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(517);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(352);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(351);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(545);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(352);
return static_cast<std::uint16_t>(351);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -2346,79 +2344,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *QuoteEntryControlMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t quoteEntryControlId() SBE_NOEXCEPT
{
return 39034;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t quoteEntryControlSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool quoteEntryControlInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= quoteEntryControlSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t quoteEntryControlEncodingOffset() SBE_NOEXCEPT
{
return 351;
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t quoteEntryControlEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::uint8_t quoteEntryControlRaw() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return static_cast<std::uint8_t>(255);
}
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 351, sizeof(std::uint8_t));
return (val);
}
SBE_NODISCARD BooleanNULL::Value quoteEntryControl() const
{
if (m_actingVersion < 9)
{
return BooleanNULL::NULL_VALUE;
}
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 351, sizeof(std::uint8_t));
return BooleanNULL::get((val));
}
MassQuoteAck545 &quoteEntryControl(const BooleanNULL::Value value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 351, &val, sizeof(std::uint8_t));
return *this;
}
class NoQuoteEntries
{
private:
@@ -3045,10 +2970,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << R"("QuoteEntryOpen": )";
builder << '"' << writer.quoteEntryOpen() << '"';
builder << ", ";
builder << R"("QuoteEntryControl": )";
builder << '"' << writer.quoteEntryControl() << '"';
builder << ", ";
{
bool atLeastOne = false;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *yearMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *blockLengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(76);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(500);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(69);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(68);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(502);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(69);
return static_cast<std::uint16_t>(68);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -892,82 +890,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *EnvironmentIndicatorMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "optional";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t environmentIndicatorId() SBE_NOEXCEPT
{
return 39032;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t environmentIndicatorSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool environmentIndicatorInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= environmentIndicatorSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingOffset() SBE_NOEXCEPT
{
return 68;
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorNullValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(255);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMinValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(0);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMaxValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(254);
}
static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::uint8_t environmentIndicator() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return static_cast<std::uint8_t>(255);
}
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 68, sizeof(std::uint8_t));
return (val);
}
NegotiationReject502 &environmentIndicator(const std::uint8_t value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 68, &val, sizeof(std::uint8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> & operator << (
std::basic_ostream<CharT, Traits> &builder, NegotiationReject502 _writer)
@@ -1009,10 +931,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << R"("SplitMsg": )";
builder << '"' << writer.splitMsg() << '"';
builder << ", ";
builder << R"("EnvironmentIndicator": )";
builder << +writer.environmentIndicator();
builder << '}';
return builder;
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -167,10 +165,10 @@ private:
}
public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(33);
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(32);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(501);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -224,7 +222,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(33);
return static_cast<std::uint16_t>(32);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t sbeBlockAndHeaderLength() SBE_NOEXCEPT
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -953,82 +951,6 @@ public:
return *this;
}
SBE_NODISCARD static const char *EnvironmentIndicatorMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "optional";
default: return "";
}
}
static SBE_CONSTEXPR std::uint16_t environmentIndicatorId() SBE_NOEXCEPT
{
return 39032;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t environmentIndicatorSinceVersion() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD bool environmentIndicatorInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= environmentIndicatorSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingOffset() SBE_NOEXCEPT
{
return 32;
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorNullValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(255);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMinValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(0);
}
static SBE_CONSTEXPR std::uint8_t environmentIndicatorMaxValue() SBE_NOEXCEPT
{
return static_cast<std::uint8_t>(254);
}
static SBE_CONSTEXPR std::size_t environmentIndicatorEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::uint8_t environmentIndicator() const SBE_NOEXCEPT
{
if (m_actingVersion < 9)
{
return static_cast<std::uint8_t>(255);
}
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 32, sizeof(std::uint8_t));
return (val);
}
NegotiationResponse501 &environmentIndicator(const std::uint8_t value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 32, &val, sizeof(std::uint8_t));
return *this;
}
SBE_NODISCARD static const char *CredentialsMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
@@ -1256,10 +1178,6 @@ friend std::basic_ostream<CharT, Traits> & operator << (
builder << R"("PreviousUUID": )";
builder << +writer.previousUUID();
builder << ", ";
builder << R"("EnvironmentIndicator": )";
builder << +writer.environmentIndicator();
builder << ", ";
builder << R"("Credentials": )";
builder << '"' <<
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(74);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(544);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(132);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(514);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(17);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(513);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(409);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(535);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(409);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(536);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(133);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(515);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(96);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(516);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(130);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(562);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(79);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(529);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(68);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(530);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(62);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(533);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -34,7 +34,7 @@ public:
Limit = static_cast<char>(50),
StopLimit = static_cast<char>(52),
MarketWithLeftoverAsLimit = static_cast<char>(75),
NULL_VALUE = static_cast<char>(0)
NULL_VALUE = static_cast<char>(48)
};
static OrderType::Value get(const char value)
@@ -45,7 +45,7 @@ public:
case static_cast<char>(50): return Limit;
case static_cast<char>(52): return StopLimit;
case static_cast<char>(75): return MarketWithLeftoverAsLimit;
case static_cast<char>(0): return NULL_VALUE;
case static_cast<char>(48): return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum OrderType [E103]");
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -194,7 +194,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static const char *mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(147);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(518);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(159);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(519);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(93);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(538);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
@@ -127,9 +127,7 @@
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "Side.h"
#include "OrderStatus.h"
#include "CrossTypeEnum.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
@@ -170,7 +168,7 @@ public:
static const std::uint16_t SBE_BLOCK_LENGTH = static_cast<std::uint16_t>(20);
static const std::uint16_t SBE_TEMPLATE_ID = static_cast<std::uint16_t>(537);
static const std::uint16_t SBE_SCHEMA_ID = static_cast<std::uint16_t>(8);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(9);
static const std::uint16_t SBE_SCHEMA_VERSION = static_cast<std::uint16_t>(8);
enum MetaAttribute
{
@@ -244,7 +242,7 @@ public:
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return static_cast<std::uint16_t>(9);
return static_cast<std::uint16_t>(8);
}
SBE_NODISCARD static SBE_CONSTEXPR const char *sbeSemanticType() SBE_NOEXCEPT
Loaded 100 of 123 files, more files were not shown because too many files have changed in this diff. Show more