Compare commits
114
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f61907eefb | ||
|
|
e01a37e4cf | ||
|
|
64fd23f0ed | ||
|
|
0220401011 | ||
|
|
af52c752f0 | ||
|
|
dc86ebd92e | ||
|
|
1ca23d7d8a | ||
|
|
bf564eb918 | ||
|
|
10637db1eb | ||
|
|
ea13bb31ec | ||
|
|
c20bd60ff7 | ||
|
|
305dc62389 | ||
|
|
f599c940b3 | ||
|
|
21477b90fe | ||
|
|
582a442ae8 | ||
|
|
b0bc03335d | ||
|
|
318db81ced | ||
|
|
454fa05692 | ||
|
|
ebba07b994 | ||
|
|
e53b7713a4 | ||
|
|
ad43b8535b | ||
|
|
ba07a6cc8a | ||
|
|
bb419cf048 | ||
|
|
7b74ff1525 | ||
|
|
2974a04281 | ||
|
|
0089bafeaa | ||
|
|
217d83e955 | ||
|
|
8ea18cb74a | ||
|
|
1b836b24a8 | ||
|
|
bad703a847 | ||
|
|
27dce596f5 | ||
|
|
bda097c754 | ||
|
|
09353b897b | ||
|
|
31009e38bb | ||
|
|
e1d66e9a0e | ||
|
|
616361eaf1 | ||
|
|
67b70d2d8c | ||
|
|
9f0a24f1ec | ||
|
|
85ad072837 | ||
|
|
6327bcc109 | ||
|
|
2e51aebc94 | ||
|
|
50ec2f14f7 | ||
|
|
2457fe4e35 | ||
|
|
59240ae45f | ||
|
|
04acb4f459 | ||
|
|
23a1f65c5f | ||
|
|
c0de84c4ec | ||
|
|
2ce99ddbd2 | ||
|
|
301df9ca36 | ||
|
|
3c58607fe1 | ||
|
|
561d8d66d5 | ||
|
|
14fc68f8e6 | ||
|
|
f19391dac5 | ||
|
|
64226d3698 | ||
|
|
65728df991 | ||
|
|
897c9808d0 | ||
|
|
022a489b18 | ||
|
|
49e3ec2f05 | ||
|
|
e8f98102d2 | ||
|
|
e6d845f970 | ||
|
|
e3b3663a78 | ||
|
|
afefaa36d1 | ||
|
|
e934e28b43 | ||
|
|
eb55be6066 | ||
|
|
27c410c485 | ||
|
|
cd8dc02487 | ||
|
|
e31a4f7265 | ||
|
|
2e83868209 | ||
|
|
0cce94129b | ||
|
|
8c643d74c6 | ||
|
|
394f495bd1 | ||
|
|
68d5a28fd4 | ||
|
|
4182b30d22 | ||
|
|
7f44233ae3 | ||
|
|
a4510ebbd9 | ||
|
|
69d9e36b4e | ||
|
|
c496a426ab | ||
|
|
1612ae7959 | ||
|
|
7c7aa727e2 | ||
|
|
45d6d0f673 | ||
|
|
80a5ec5265 | ||
|
|
09cc78914f | ||
|
|
546dbfbd54 | ||
|
|
a9e5fb8f46 | ||
|
|
7dd6efb477 | ||
|
|
0c150e1caa | ||
|
|
d2278e6b4a | ||
|
|
1b81ad7638 | ||
|
|
bd21cf56fe | ||
|
|
c37d4479b5 | ||
|
|
3f7e7d38ff | ||
|
|
591239b13e | ||
|
|
08494728f0 | ||
|
|
ef833c5705 | ||
|
|
44216afd51 | ||
|
|
cad407827d | ||
|
|
9714135b7d | ||
|
|
c82e598313 | ||
|
|
e7806d2fec | ||
|
|
c30bab899f | ||
|
|
46544f36f1 | ||
|
|
c7df3ac43c | ||
|
|
9d1b03d1e2 | ||
|
|
9a677cf980 | ||
|
|
25445d58d0 | ||
|
|
0b313a8aa8 | ||
|
|
54f954fd4b | ||
|
|
980f38ba03 | ||
|
|
9eada2724b | ||
|
|
b5f53ee918 | ||
|
|
efc175f654 | ||
|
|
6074afd999 | ||
|
|
219dff4055 | ||
|
|
9a3b07b622 |
No files matched your search
+6
-2
@@ -4,8 +4,7 @@ cmake-build-debug/
|
||||
.idea/
|
||||
.dir-locals.el
|
||||
*.pyc
|
||||
.vscode/*
|
||||
!.vscode/*.json
|
||||
*.vscode/*
|
||||
.vs
|
||||
obj/
|
||||
*.csproj.user
|
||||
@@ -37,3 +36,8 @@ trace_data/
|
||||
*.rej
|
||||
/build
|
||||
.clangd/
|
||||
/.cache/
|
||||
.venv/**
|
||||
install/**
|
||||
.devcontainer/**
|
||||
/src/Spark.Admin.WebApp/src/bin/
|
||||
Vendored
-107
@@ -1,107 +0,0 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/src",
|
||||
"${workspaceRoot}/externals/linux/include"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/src",
|
||||
"${workspaceRoot}/externals/linux/include"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"compileCommands": "${workspaceFolder}/build/ninja_debug/compile_commands.json"
|
||||
},
|
||||
{
|
||||
"name": "Windows",
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"includePath": [
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/build/src",
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/local/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include"
|
||||
],
|
||||
"defines": [
|
||||
"__linux__",
|
||||
"__x86_64__"
|
||||
],
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/build/src",
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/local/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/*"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
},
|
||||
{
|
||||
"name": "WindowsQuick",
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"includePath": [
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/build/src",
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/local/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include"
|
||||
],
|
||||
"defines": [
|
||||
"__linux__",
|
||||
"__x86_64__"
|
||||
],
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceRoot}/src"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": "${workspaceRoot}/.vscode/browse.vc.db"
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
-399
@@ -1,399 +0,0 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Spark Local",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/ninja_debug/server/sparkd",
|
||||
"args": [
|
||||
"run",
|
||||
"test",
|
||||
"-a",
|
||||
"OutrightVanillaOrder"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/ninja_debug/server/",
|
||||
"environment": [
|
||||
{ "name": "TZ", "value": "America/Chicago" }
|
||||
],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SparkVM Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"-a",
|
||||
"[ilink3]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "LD LIBRARY",
|
||||
"text": "set env LD_LIBRARY_PATH=.",
|
||||
"ignoreFailures": false
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/ninja_debug/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"run"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/ninja_debug/src/server/sparkd",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Client Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "SDK Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark_sdk.exe",
|
||||
"args": [
|
||||
"md",
|
||||
"GLBX",
|
||||
"Future",
|
||||
"CL",
|
||||
"CLZ9",
|
||||
"--user=bts",
|
||||
"--pass="
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Excel Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "C:/Program Files/Microsoft Office/Office14/EXCEL.EXE",
|
||||
"args": [
|
||||
"${workspaceRoot}/build/Debug/bin/net471/spark_excel-addin64-packed.xll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Tests",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/sparkcmd.exe",
|
||||
"args": [
|
||||
"test",
|
||||
"ApiUpdateTests"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Attach",
|
||||
"type": "clr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
},
|
||||
{
|
||||
"name": "Spreader Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[spreader]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin Service Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[admin_service]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limiter Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[limiter]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MD Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[algo]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SparkVM attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"MIMode": "gdb",
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"stopOnEntry": false,
|
||||
"pythonPath": "${config:python.pythonPath}",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {},
|
||||
"envFile": "${workspaceRoot}/.env",
|
||||
"args": [
|
||||
"DEBUG"
|
||||
],
|
||||
"debugOptions": [
|
||||
"WaitOnAbnormalExit",
|
||||
"WaitOnNormalExit",
|
||||
"RedirectOutput"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Remote Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/home/bts/vsdbg/vsdbg",
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"quoteArgs": true
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
},
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Remote Launch",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "/usr/bin/dotnet",
|
||||
"args": [
|
||||
"sparkcmd.dll",
|
||||
"test",
|
||||
"test_join_create_and_takeout_market"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/server",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/home/bts/vsdbg/vsdbg",
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"quoteArgs": true
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
},
|
||||
"justMyCode": false
|
||||
},
|
||||
]
|
||||
}
|
||||
Vendored
-16
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"list": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"vector": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xstring": "cpp",
|
||||
"system_error": "cpp",
|
||||
"array": "cpp",
|
||||
"string_view": "cpp"
|
||||
"xutility": "cpp",
|
||||
"*.ipp": "cpp"
|
||||
}
|
||||
}
|
||||
Vendored
-63
@@ -1,63 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "client_build",
|
||||
"type": "shell",
|
||||
"command": ".\\tools\\buildspark.cmd",
|
||||
"problemMatcher":"$msCompile",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"group": "build"
|
||||
},
|
||||
{
|
||||
"label": "server_build",
|
||||
"type": "shell",
|
||||
"command": ".\\tools\\buildsparkd.cmd",
|
||||
"problemMatcher": {
|
||||
"base": "$gcc",
|
||||
"owner": "cpp",
|
||||
"fileLocation": [
|
||||
"relative",
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"pattern": {
|
||||
"regexp": "(.?)(home)(.?)(bts)(.?)(spark)(.?)(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)",
|
||||
"file": 8,
|
||||
"line": 9,
|
||||
"column": 10,
|
||||
"severity": 11,
|
||||
"message": 12
|
||||
}
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "new"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "linux build (Debug)",
|
||||
"type": "shell",
|
||||
"command": "cd build/ninja_debug; time ninja",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+9
-26
@@ -12,42 +12,22 @@ set (SPARK_PYTHON "${EXTERNALS_ROOT}/python")
|
||||
set (SPARK_BIN "${EXTERNALS_ROOT}/bin")
|
||||
set (SPARK_INCLUDE "${EXTERNALS_ROOT}/include")
|
||||
set (SPARK_LIB "${EXTERNALS_ROOT}/lib/${CMAKE_BUILD_TYPE}")
|
||||
set (BUILD_SDK OFF CACHE BOOL "Build the sdk")
|
||||
|
||||
include_directories (BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
|
||||
link_directories (${SPARK_LIB})
|
||||
|
||||
if (WIN32)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
||||
/MP \
|
||||
/WX /wd4251 /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 \
|
||||
/DCURL_STATICLIB \
|
||||
/D_WINSOCK_DEPRECATED_NO_WARNINGS \
|
||||
/D__TBB_NO_IMPLICIT_LINKAGE \
|
||||
/DBOOST_ALL_NO_LIB \
|
||||
/D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600")
|
||||
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} /MT")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF /LTCG")
|
||||
|
||||
add_subdirectory(src/lib)
|
||||
else ()
|
||||
# so that sparkd looks for libspark.so in its directory
|
||||
set (CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set (CMAKE_INSTALL_RPATH ".")
|
||||
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} \
|
||||
-fPIC -Wall -pedantic -Wextra -Werror \
|
||||
-Wno-missing-braces -Wno-ignored-qualifiers \
|
||||
--std=c++17 -fdiagnostics-color")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -DNDEBUG -O3")
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wno-undef")
|
||||
# so that sparkd looks for libspark.so in its directory
|
||||
add_subdirectory(src/server/sparkd)
|
||||
add_subdirectory(src/lib)
|
||||
add_subdirectory(src/web)
|
||||
# add_subdirectory(src/web)
|
||||
add_subdirectory(doc/user)
|
||||
add_subdirectory(src/sdk)
|
||||
if(BUILD_SDK)
|
||||
add_subdirectory(src/sdk)
|
||||
endif()
|
||||
add_subdirectory(src/data_files)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/server
|
||||
@@ -63,4 +43,7 @@ else ()
|
||||
DEPENDS sparkd data_files_dir)
|
||||
|
||||
add_custom_target(server_layout ALL DEPENDS ${CMAKE_BINARY_DIR}/server)
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/externals/linux/lib/${CMAKE_BUILD_TYPE}/libACE-5.7.5.so" DESTINATION bin)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/externals/linux/lib/${CMAKE_BUILD_TYPE}/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0" DESTINATION bin)
|
||||
endif()
|
||||
@@ -0,0 +1,179 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "spark",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"environment": {
|
||||
"SPARK_CMAKE_CXX_FLAGS": "/MP /WX /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 /bigobj /EHsc /DCURL_STATICLIB /D_WINSOCK_DEPRECATED_NO_WARNINGS /D__TBB_NO_IMPLICIT_LINKAGE /DBOOST_ALL_NO_LIB /std:c++17 /D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600",
|
||||
"DOTNET_TARGET_FRAMEWORK": "net471"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "$env{SPARK_CMAKE_CXX_FLAGS}",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "$env{SPARK_CMAKE_CXX_FLAGS} /MTd",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "$env{SPARK_CMAKE_CXX_FLAGS} /MT",
|
||||
"CMAKE_CXX_STANDARD": "17",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_DEBUG": "/DEBUG",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "/OPT:REF /OPT:ICF /LTCG",
|
||||
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/$env{DOTNET_TARGET_FRAMEWORK}",
|
||||
"EXTERNALS_ROOT": "${sourceDir}/externals/windows",
|
||||
"SPARK_BIN": "${sourceDir}/externals/windows/bin",
|
||||
"SPARK_INCLUDE": "${sourceDir}/externals/windows/include",
|
||||
"SPARK_LIB": "${sourceDir}/externals/windows/lib/$<CONFIG>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sparkd",
|
||||
"hidden": true,
|
||||
"description": "Sparkd common config",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"generator": "Ninja",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_WITH_INSTALL_RPATH": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
},
|
||||
"CMAKE_CXX_STANDARD": "17",
|
||||
"CMAKE_EXE_LINKER_FLAGS": "-Wno-undef",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
|
||||
"CMAKE_INSTALL_RPATH": ".",
|
||||
"EXTERNALS_ROOT": "${sourceDir}/externals/linux",
|
||||
"SPARK_BIN": "${sourceDir}/externals/linux/bin",
|
||||
"SPARK_INCLUDE": "${sourceDir}/externals/linux/include"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sparkd-debug-clang",
|
||||
"displayName": "Debug (clang)",
|
||||
"description": "Debug build compiled w/ clang",
|
||||
"inherits": "sparkd",
|
||||
"binaryDir": "${sourceDir}/build/clang/debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_C_COMPILER": "clang",
|
||||
"CMAKE_CXX_COMPILER": "clang++",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-deprecated-copy -Wno-unused-but-set-variable -Wno-c++17-extensions --std=c++17 -fdiagnostics-color -DDEBUG",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
},
|
||||
"SPARK_LIB": "${sourceDir}/externals/linux/lib/Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sparkd-release-clang",
|
||||
"displayName": "Release (clang)",
|
||||
"description": "Release build compiled w/ clang",
|
||||
"binaryDir": "${sourceDir}/build/clang/release",
|
||||
"inherits": "sparkd",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_C_COMPILER": "clang",
|
||||
"CMAKE_CXX_COMPILER": "clang++",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-deprecated-copy -Wno-c++17-extensions --std=c++17 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3",
|
||||
"SPARK_LIB": "${sourceDir}/externals/linux/lib/Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sparkd-debug-gcc",
|
||||
"displayName": "Debug (gcc)",
|
||||
"description": "Debug build compiled w/ gcc",
|
||||
"inherits": "sparkd",
|
||||
"binaryDir": "${sourceDir}/build/gcc/debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_C_COMPILER": "gcc",
|
||||
"CMAKE_CXX_COMPILER": "g++",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-deprecated-copy -Wno-catch-value --std=c++17 -fdiagnostics-color -DDEBUG",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": {
|
||||
"type": "BOOL",
|
||||
"value": true
|
||||
},
|
||||
"SPARK_LIB": "${sourceDir}/externals/linux/lib/Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sparkd-release-gcc",
|
||||
"displayName": "Release (gcc)",
|
||||
"description": "Release build compiled w/ gcc",
|
||||
"inherits": "sparkd",
|
||||
"binaryDir": "${sourceDir}/build/gcc/release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_C_COMPILER": "/usr/local/bin/gcc",
|
||||
"CMAKE_CXX_COMPILER": "/usr/local/bin/g++",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-deprecated-copy -Wno-catch-value --std=c++17 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3",
|
||||
"SPARK_LIB": "${sourceDir}/externals/linux/lib/Release"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "spark",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "spark-debug",
|
||||
"displayName": "Debug",
|
||||
"inherits": "spark",
|
||||
"configurePreset": "spark",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "spark-release",
|
||||
"displayName": "Release",
|
||||
"inherits": "spark",
|
||||
"configurePreset": "spark",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "sparkd",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "sparkd-debug-clang",
|
||||
"configurePreset": "sparkd-debug-clang",
|
||||
"displayName": "Debug (clang)",
|
||||
"inherits": "sparkd"
|
||||
},
|
||||
{
|
||||
"name": "sparkd-debug-gcc",
|
||||
"configurePreset": "sparkd-debug-gcc",
|
||||
"displayName": "Debug (gcc)",
|
||||
"inherits": "sparkd"
|
||||
},
|
||||
{
|
||||
"name": "sparkd-release-clang",
|
||||
"configurePreset": "sparkd-release-clang",
|
||||
"displayName": "Release (clang)",
|
||||
"inherits": "sparkd"
|
||||
},
|
||||
{
|
||||
"name": "sparkd-release-gcc",
|
||||
"configurePreset": "sparkd-release-gcc",
|
||||
"displayName": "Release (gcc)",
|
||||
"inherits": "sparkd"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
set(sources /home/ppinto/Dropbox/bts/spark/doc/user/build.sh;content/_index.md;content/bts_spark/Glossary/_index.md;content/bts_spark/Help/_index.md;content/bts_spark/Help/about_spark.png;content/bts_spark/Help/image39.png;content/bts_spark/Help/image58.png;content/bts_spark/Launcher/_index.md;content/bts_spark/Launcher/image38.png;content/bts_spark/Launcher/image68.png;content/bts_spark/Logging-In-to-the-System/_index.md;content/bts_spark/Logging-In-to-the-System/image3.png;content/bts_spark/Logging-In-to-the-System/image64.png;content/bts_spark/Market/_index.md;content/bts_spark/Market/change_securities.png;content/bts_spark/Market/image11.png;content/bts_spark/Market/image14.png;content/bts_spark/Market/image20.png;content/bts_spark/Market/image21.png;content/bts_spark/Market/image23.png;content/bts_spark/Market/image24.png;content/bts_spark/Market/image34.png;content/bts_spark/Market/image49.png;content/bts_spark/Market/image53.png;content/bts_spark/Market/image66.png;content/bts_spark/Market/image69.png;content/bts_spark/Market/market_view.png;content/bts_spark/Market/settings_icon.png;content/bts_spark/Market/time_and_sales.png;content/bts_spark/My-Windows/_index.md;content/bts_spark/My-Windows/image15.png;content/bts_spark/My-Windows/image16.png;content/bts_spark/My-Windows/image37.png;content/bts_spark/Settings/_index.md;content/bts_spark/Settings/image51.png;content/bts_spark/Settings/image9.png;content/bts_spark/Spreader/_index.md;content/bts_spark/Spreader/image10.png;content/bts_spark/Spreader/image13.png;content/bts_spark/Spreader/image18.png;content/bts_spark/Spreader/image19.png;content/bts_spark/Spreader/image28.png;content/bts_spark/Spreader/image29.png;content/bts_spark/Spreader/image31.png;content/bts_spark/Spreader/image35.png;content/bts_spark/Spreader/image40.png;content/bts_spark/Spreader/image43.png;content/bts_spark/Spreader/image54.png;content/bts_spark/Spreader/image55.png;content/bts_spark/Spreader/image56.png;content/bts_spark/Spreader/image6.png;content/bts_spark/Spreader/image7.png;content/bts_spark/Spreader/image70.png;content/bts_spark/Spreader/image72.png;content/bts_spark/Spreader/image8.png;content/bts_spark/Trading/OrderTypes/index.md;content/bts_spark/Trading/_index.md;content/bts_spark/Trading/algo_studio.png;content/bts_spark/Trading/collapse_all_icon.png;content/bts_spark/Trading/cover_algo_control.png;content/bts_spark/Trading/expand_all_icon.png;content/bts_spark/Trading/image1.png;content/bts_spark/Trading/image17.png;content/bts_spark/Trading/image2.png;content/bts_spark/Trading/image25.png;content/bts_spark/Trading/image27.png;content/bts_spark/Trading/image33.png;content/bts_spark/Trading/image42.png;content/bts_spark/Trading/image44.png;content/bts_spark/Trading/image47.png;content/bts_spark/Trading/image48.png;content/bts_spark/Trading/image5.png;content/bts_spark/Trading/image50.png;content/bts_spark/Trading/image52.png;content/bts_spark/Trading/image57.png;content/bts_spark/Trading/image59.png;content/bts_spark/Trading/image60.png;content/bts_spark/Trading/image61.png;content/bts_spark/Trading/image62.png;content/bts_spark/Trading/image73.png;content/bts_spark/Trading/image74.png;content/bts_spark/Trading/join_algo_control.png;content/bts_spark/Trading/ladder.png;content/bts_spark/Trading/ladder_badges.png;content/bts_spark/Trading/ladder_main_part.png;content/bts_spark/Trading/lean_algo_control.png;content/bts_spark/Trading/mini_orderbook.png;content/bts_spark/Trading/oco_algo_control.png;content/bts_spark/Trading/offset_algo_control.png;content/bts_spark/Trading/pnl_calculation.png;content/bts_spark/Trading/pnl_window.png;content/bts_spark/Trading/recreate_icon.png;content/bts_spark/Trading/settings_icon.png;content/bts_spark/Trading/spark_menu_order_book.png;content/bts_spark/Trading/top_algo_control.png;content/bts_spark/Trading/trigger_algo_control.png;content/bts_spark/_index.md;content/release_notes/_index.md;content/system_requirements/_index.md;static/book.js;static/favicon.ico;static/image.js;templates/index.html;templates/page.html;templates/section.html;templates/shortcodes/back_button.html)
|
||||
+1
-1
Submodule docker/linux updated: 6f0dd9324b...26de8f7b3b.
+1
-1
Submodule externals updated: 2ea5e355a6...e9120dabfe.
@@ -0,0 +1,17 @@
|
||||
astroid==2.7.3
|
||||
autopep8==1.5.7
|
||||
cffi==1.14.6
|
||||
colorama==0.4.4
|
||||
isort==5.9.3
|
||||
lazy-object-proxy==1.6.0
|
||||
mccabe==0.6.1
|
||||
platformdirs==2.3.0
|
||||
protobuf==3.19.1
|
||||
pybars3==0.9.7
|
||||
pycodestyle==2.7.0
|
||||
pycparser==2.20
|
||||
pylint==2.10.2
|
||||
PyMeta3==0.5.1
|
||||
toml==0.10.2
|
||||
wrapt==1.12.1
|
||||
yapf==0.31.0
|
||||
+168
-232
@@ -1,232 +1,168 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2024
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api", "src\client\spark_api\spark_api.csproj", "{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspark", "build\src\lib\libspark.vcxproj", "{3335AAF0-489D-359D-8305-9B7A44E2C760}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spark", "src\client\spark\Spark.csproj", "{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sparkcmd", "src\client\sparkcmd\sparkcmd.csproj", "{387566C6-C6F6-412C-A30C-9855BBCB4816}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_core", "src\client\spark_core\spark_core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZERO_CHECK", "build\ZERO_CHECK.vcxproj", "{2256015B-E7D5-3614-8F39-814CA68A4444}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_sdk", "src\client\spark_sdk\spark_sdk.csproj", "{6963C314-83C4-4667-B0D0-C2F7AE208C29}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760} = {3335AAF0-489D-359D-8305-9B7A44E2C760}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_test", "src\client\spark_test\spark_test.csproj", "{ECD78CC5-138F-4809-A764-2358C2AC2E82}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_excel", "src\client\spark_excel\spark_excel.csproj", "{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
MinSizeRel|Any CPU = MinSizeRel|Any CPU
|
||||
MinSizeRel|x64 = MinSizeRel|x64
|
||||
MinSizeRel|x86 = MinSizeRel|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
RelWithDebInfo|Any CPU = RelWithDebInfo|Any CPU
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
RelWithDebInfo|x86 = RelWithDebInfo|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.Build.0 = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x86.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Debug|x64.Build.0 = Debug|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Release|x64.ActiveCfg = Release|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Release|x64.Build.0 = Release|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.Release|x86.ActiveCfg = Release|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{3335AAF0-489D-359D-8305-9B7A44E2C760}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.Build.0 = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x64.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x64.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x86.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x86.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x64.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x86.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.Build.0 = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x86.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Debug|x64.Build.0 = Debug|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.MinSizeRel|Any CPU.ActiveCfg = MinSizeRel|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Release|x64.ActiveCfg = Release|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Release|x64.Build.0 = Release|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.Release|x86.ActiveCfg = Release|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.RelWithDebInfo|Any CPU.ActiveCfg = RelWithDebInfo|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{2256015B-E7D5-3614-8F39-814CA68A4444}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x64.Build.0 = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x64.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x86.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x86.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x86.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Debug|x64.Build.0 = Debug|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Release|x64.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Release|x64.Build.0 = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.Release|x86.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{BE9F27C3-B583-47DF-95FA-1F8BBC89DCCB}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {422D1620-0166-4C26-9A81-CA8A2EB1AB58}
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2024
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api", "src\client\spark_api\spark_api.csproj", "{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spark", "src\client\spark\Spark.csproj", "{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sparkcmd", "src\client\sparkcmd\sparkcmd.csproj", "{387566C6-C6F6-412C-A30C-9855BBCB4816}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_core", "src\client\spark_core\spark_core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_sdk", "src\client\spark_sdk\spark_sdk.csproj", "{6963C314-83C4-4667-B0D0-C2F7AE208C29}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_test", "src\client\spark_test\spark_test.csproj", "{ECD78CC5-138F-4809-A764-2358C2AC2E82}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
MinSizeRel|Any CPU = MinSizeRel|Any CPU
|
||||
MinSizeRel|x64 = MinSizeRel|x64
|
||||
MinSizeRel|x86 = MinSizeRel|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
RelWithDebInfo|Any CPU = RelWithDebInfo|Any CPU
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
RelWithDebInfo|x86 = RelWithDebInfo|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x64.Build.0 = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x86.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.Build.0 = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x64.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x64.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Release|x86.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.MinSizeRel|x86.Build.0 = Debug|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x64.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.Release|x86.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
|
||||
{387566C6-C6F6-412C-A30C-9855BBCB4816}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x64.Build.0 = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x86.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x64.Build.0 = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|Any CPU.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|Any CPU.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x86.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.MinSizeRel|x86.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x64.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.Release|x86.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|Any CPU.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x86.ActiveCfg = Release|x64
|
||||
{6963C314-83C4-4667-B0D0-C2F7AE208C29}.RelWithDebInfo|x86.Build.0 = Release|x64
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.MinSizeRel|x86.Build.0 = Debug|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x86.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {422D1620-0166-4C26-9A81-CA8A2EB1AB58}
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,6 +1,7 @@
|
||||
using bts.api;
|
||||
using bts.co2;
|
||||
using bts.utils;
|
||||
using bts.utils.csv;
|
||||
using mbts;
|
||||
using mbts.spark;
|
||||
using mbts.ui.controls;
|
||||
@@ -49,6 +50,18 @@ namespace bts.shell.time_and_sales {
|
||||
public void raise_invalidated() =>
|
||||
invalidated?.Invoke();
|
||||
|
||||
public static System.Collections.Specialized.OrderedDictionary csv_ordered_properties =>
|
||||
CsvHelper.create_ordering_maintainer(
|
||||
typeof(TimeAndSalesRowVM),
|
||||
new string[] {
|
||||
nameof(security),
|
||||
nameof(time),
|
||||
nameof(price),
|
||||
nameof(size),
|
||||
nameof(aggressor_side),
|
||||
nameof(security_key),
|
||||
});
|
||||
|
||||
public bool Equals(TimeAndSalesRowVM other) =>
|
||||
other != null &&
|
||||
row_key == other.row_key;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using bts.shell.fills;
|
||||
using bts.spark;
|
||||
using bts.view;
|
||||
using bts.utils.csv;
|
||||
using mbts;
|
||||
using mbts.co2;
|
||||
using mbts.persist;
|
||||
@@ -124,6 +125,8 @@ namespace bts.shell.time_and_sales {
|
||||
show_in_context_menu = _can_pause_updates
|
||||
};
|
||||
_commands = new SparkCommand[] {
|
||||
// csv export
|
||||
new SparkCommandCommand("Export to csv", Icons.Export, FileDialogCommand.export_csv(() => _vm.rows.ToCsv(TimeAndSalesRowVM.csv_ordered_properties), "TaS")),
|
||||
// ladder
|
||||
SparkCommands.ShowLadderAutoLookup(SparkCommands.KeyGestures.ShowLadder)
|
||||
.complete(current_sec_key_src, sec_keys => sec_keys.Count > 0),
|
||||
|
||||
@@ -5,6 +5,7 @@ using bts.collections;
|
||||
using bts.shell.fills;
|
||||
using bts.spark;
|
||||
using bts.utils;
|
||||
using bts.utils.csv;
|
||||
using mbts.collections;
|
||||
using mbts.persist;
|
||||
using mbts.spark.filters;
|
||||
@@ -333,6 +334,27 @@ namespace mbts.spark {
|
||||
public override bool Equals(object obj) => Equals(obj as Row);
|
||||
public override int GetHashCode() => _fill.FillKey.GetHashCode() ^ _order.Key.GetHashCode();
|
||||
|
||||
public static System.Collections.Specialized.OrderedDictionary csv_ordered_properties =>
|
||||
CsvHelper.create_ordering_maintainer(typeof(Row),
|
||||
new string[] {
|
||||
nameof(security),
|
||||
nameof(order_type),
|
||||
nameof(root_algo_display_name),
|
||||
nameof(side),
|
||||
nameof(fill_time),
|
||||
nameof(user),
|
||||
nameof(account),
|
||||
nameof(exchange),
|
||||
nameof(time_in_force),
|
||||
nameof(size),
|
||||
nameof(price),
|
||||
nameof(fill_kind),
|
||||
nameof(fill_status),
|
||||
nameof(fill_key),
|
||||
nameof(order_key),
|
||||
nameof(security_key)
|
||||
});
|
||||
|
||||
public event Action invalidated;
|
||||
void IRowVM.raise_invalidated() => invalidated?.Invoke();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using bts.shell;
|
||||
using bts.shell.fills;
|
||||
using bts.spark;
|
||||
using bts.view;
|
||||
using bts.utils.csv;
|
||||
using mbts.persist;
|
||||
using mbts.ui;
|
||||
using mbts.ui.settings;
|
||||
@@ -61,6 +62,7 @@ namespace mbts.spark {
|
||||
_view = new FillsView { DataContext = _vm };
|
||||
|
||||
_commands = new List<SparkCommand> {
|
||||
new SparkCommandCommand("Export to csv", Icons.Export, FileDialogCommand.export_csv(() => _vm.rows.ToCsv(FillsVM.Row.csv_ordered_properties), "Fills")),
|
||||
// wrap the grid settings view factory in a dialogCommand here since the vm is destroyed/recreated when the security criteria changes
|
||||
SparkCommands.window_settings_command(new DialogCommand(() => {
|
||||
var vm = new ShellSettingsDialogVM<GridSettings, SimpleGridSettingsVM>(
|
||||
|
||||
@@ -4,6 +4,7 @@ using bts.api.orderman;
|
||||
using bts.collections;
|
||||
using bts.spark;
|
||||
using bts.utils;
|
||||
using bts.utils.csv;
|
||||
using mbts.ui;
|
||||
using mbts.ui.controls;
|
||||
using System;
|
||||
@@ -11,6 +12,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reactive.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Columns = mbts.spark.OrderBookGridView.ColumnKeys;
|
||||
@@ -60,6 +62,35 @@ namespace mbts.spark {
|
||||
public event Action<(OrderSecurityRootPair oldval, OrderSecurityRootPair newval)> updated;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public static System.Collections.Specialized.OrderedDictionary csv_ordered_properties =>
|
||||
CsvHelper.create_ordering_maintainer(
|
||||
typeof(OrderBookRowVM),
|
||||
new string[] {
|
||||
nameof(security_text),
|
||||
nameof(symbol),
|
||||
nameof(time_created),
|
||||
nameof(last_change),
|
||||
nameof(user),
|
||||
nameof(account),
|
||||
nameof(exchange),
|
||||
nameof(time_in_force),
|
||||
nameof(order_type),
|
||||
nameof(root_algo_display_name),
|
||||
nameof(order_sub_type),
|
||||
nameof(side),
|
||||
nameof(quantity),
|
||||
nameof(filled_quantity),
|
||||
nameof(price),
|
||||
nameof(avg_price),
|
||||
nameof(last_price),
|
||||
nameof(piq),
|
||||
nameof(status),
|
||||
// last message (could contains commas, so skipping)
|
||||
nameof(security_key),
|
||||
nameof(order_key),
|
||||
nameof(parent_order_key),
|
||||
});
|
||||
|
||||
// Core
|
||||
public OrderSecurityRootPair order_tuple { get; private set; }
|
||||
public OrderRecordImmutable order => order_tuple.order.order;
|
||||
|
||||
@@ -6,6 +6,7 @@ using bts.shell.fills;
|
||||
using bts.shell.orderbook;
|
||||
using bts.spark;
|
||||
using bts.view;
|
||||
using bts.utils.csv;
|
||||
using mbts.persist;
|
||||
using mbts.spark.utilities;
|
||||
using mbts.ui;
|
||||
@@ -231,6 +232,7 @@ namespace mbts.spark {
|
||||
toggle_collapse_all_command,
|
||||
toggle_expand_all_command,
|
||||
show_grid_settings_command,
|
||||
new SparkCommandCommand("Export to csv", Icons.Export, FileDialogCommand.export_csv(() => _vm.rows.ToCsv(OrderBookRowVM.csv_ordered_properties), "OrderBook")),
|
||||
// hidden cmds (i.e., keyboard shortcuts at window level)
|
||||
hidden_cmd(new SparkCommandCommand(OrderBookView.CommandDescriptions.ModifyOrders, null, _vm.modify_selected_orders_cmd, OrderBookView.KeyboardShortcuts.ModifyOrders)),
|
||||
hidden_cmd(new SparkCommandCommand(OrderBookView.CommandDescriptions.RevertOrders, null, _vm.revert_selected_orders_cmd, OrderBookView.KeyboardShortcuts.RevertOrders)),
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<RuntimeIdentifiers>win7-x64</RuntimeIdentifiers>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<LanguageTargets>$(MSBuildExtensionsPath)\$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
|
||||
<LanguageTargets Condition="'$(VisualStudioVersion)'=='16.0'">$(MSBuildToolsPath)\Microsoft.CSharp.targets</LanguageTargets>
|
||||
<LanguageTargets Condition="'$(VisualStudioVersion)'=='17.0'">
|
||||
C:/Program Files/Microsoft Visual Studio/2022/Community/Msbuild/Current/Bin/amd64/Microsoft.CSharp.targets
|
||||
</LanguageTargets>
|
||||
<ApplicationIcon>logo.ico</ApplicationIcon>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<StartupObject>mbts.ui.shell.App</StartupObject>
|
||||
@@ -34,7 +35,7 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.24.3" />
|
||||
<PackageReference Include="IronPython" Version="2.7.7" />
|
||||
<PackageReference Include="NAudio" Version="1.8.4" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
|
||||
@@ -64,6 +64,25 @@ namespace mbts.ui {
|
||||
}
|
||||
}, can_execute == null ? null : new Func<object, bool>(_ => can_execute()));
|
||||
|
||||
public static IDialogCommand export_csv(
|
||||
Func<string> get_file_content,
|
||||
string source_window_name) =>
|
||||
new AnonymousFileDialogCommand<object>(_ =>
|
||||
_create_save_file_dialog(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
|
||||
$"BTS_Spark_{source_window_name}_{DateTime.Now.ToString("yyyyMMdd_HHmm")}.csv",
|
||||
new[] { ("CSV (comma delimited)", new string[] { "csv" }) }
|
||||
),
|
||||
(_, file) => {
|
||||
try {
|
||||
File.WriteAllText(file, get_file_content.Invoke());
|
||||
} catch (Exception ex) {
|
||||
BTSMessageBox.Show($"Error exporting data to csv: {ex}.", "CSV Export Error", BTSMessageBoxButtons.OK, System.Windows.MessageBoxImage.Error, true, false, true);
|
||||
}
|
||||
},
|
||||
// we are always able to perform an export, even when no rows (it will just be a header)
|
||||
(_) => true);
|
||||
|
||||
static TDialog _create_file_dialog<TDialog>(string initial_dir = null, IReadOnlyList<(string name, string[] extensions)> filter_items = null) where TDialog : FileDialog, new() {
|
||||
var rv = new TDialog();
|
||||
if (!string.IsNullOrEmpty(initial_dir))
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.24.3" />
|
||||
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
|
||||
<PackageReference Include="System.Reactive" Version="3.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace bts.utils.csv {
|
||||
public static class CsvHelper {
|
||||
|
||||
public static string ToCsv<T>(this IEnumerable<T> items, OrderedDictionary properties = null) where T : class {
|
||||
var output = "";
|
||||
var delimiter = ",";
|
||||
if (properties == null) {
|
||||
properties = new OrderedDictionary();
|
||||
foreach (var pi in typeof(T).GetProperties()) {
|
||||
properties.Add(pi.Name, pi);
|
||||
}
|
||||
}
|
||||
|
||||
using (var sw = new StringWriter()) {
|
||||
var dict_values = properties.Values.OfType<PropertyInfo>();
|
||||
var header = dict_values.Select(n => n.Name).Aggregate((first, second) => first + delimiter + second);
|
||||
sw.WriteLine(header);
|
||||
foreach (var i in items) {
|
||||
var row = dict_values.Select(x => x.GetValue(i, null))
|
||||
.Select(x => x == null ? "null" : x.ToString())
|
||||
.Aggregate((first, second) => first + delimiter + second);
|
||||
sw.WriteLine(row);
|
||||
}
|
||||
output = sw.ToString();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static OrderedDictionary create_ordering_maintainer(Type t, string[] property_names_in_order) {
|
||||
OrderedDictionary od = new OrderedDictionary();
|
||||
var props = t.GetProperties();
|
||||
foreach (var n in property_names_in_order) {
|
||||
var query = props.Where(pi => pi.Name == n);
|
||||
if (query.Any()) {
|
||||
var property_info = query.First();
|
||||
if (!od.Contains(property_info)) {
|
||||
od.Add(n, property_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return od;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
using System.IO;
|
||||
using System.Security.Policy;
|
||||
using System.Diagnostics;
|
||||
|
||||
using ExcelDna.Integration;
|
||||
using ExcelDna.IntelliSense;
|
||||
using ExcelDna.Logging;
|
||||
|
||||
namespace bts.excel
|
||||
{
|
||||
public class TestMethod
|
||||
{
|
||||
[ExcelFunction]
|
||||
static public string bts_excel_test_string(string x) { return "Hello " + x; }
|
||||
[ExcelFunction]
|
||||
static public object bts_excel_test_int(int x) { return x; }
|
||||
[ExcelFunction]
|
||||
static public object bts_excel_test_long(long x) { return x; }
|
||||
}
|
||||
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public class ContextTeardown : ExcelComAddIn
|
||||
{
|
||||
private api.core.ServiceContext _context;
|
||||
public ContextTeardown(api.core.ServiceContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
//This is called on application shutdown
|
||||
public override void OnBeginShutdown(ref Array custom)
|
||||
{
|
||||
_context.Dispose();
|
||||
_context = null;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public class ExcelAddin : IExcelAddIn
|
||||
{
|
||||
public void AutoClose()
|
||||
{
|
||||
//don't do anything here, it's only called when the addin is removed, not on shutdown
|
||||
IntelliSenseServer.Uninstall();
|
||||
}
|
||||
public void AutoOpen() //This is called on EXCEL startup, when the addin is loaded
|
||||
{
|
||||
Trace.Listeners.Add(new LogDisplayTraceListener("bts"));
|
||||
IntelliSenseServer.Install();
|
||||
ExcelIntegration.RegisterUnhandledExceptionHandler(ex => ex.ToString());
|
||||
|
||||
load_assemblies();
|
||||
ExcelComAddInHelper.LoadComAddIn(new ContextTeardown(APIDispatch.service_context.Value));
|
||||
}
|
||||
|
||||
private void load_assemblies()
|
||||
{
|
||||
var config = System.Configuration.ConfigurationManager.AppSettings["load_assemblies"];
|
||||
if (config != null)
|
||||
{
|
||||
var asses = config.Split(new char[] { ';', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var ass in asses)
|
||||
Utilities.bts_load_assembly(ass);
|
||||
}
|
||||
}
|
||||
|
||||
public static void calculate_full_rebuild()
|
||||
{
|
||||
object app = ExcelDnaUtil.Application;
|
||||
var mi = app?.GetType().GetMethod("CalculateFullRebuild", BindingFlags.Instance | BindingFlags.Public);
|
||||
if(mi != null)
|
||||
mi.Invoke(app, null);
|
||||
}
|
||||
|
||||
public static void calculate_full()
|
||||
{
|
||||
object app = ExcelDnaUtil.Application;
|
||||
var mi = app?.GetType().GetMethod("CalculateFull", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (mi != null)
|
||||
mi.Invoke(app, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("spark")]
|
||||
[assembly: InternalsVisibleTo("spark_core")]
|
||||
[assembly: InternalsVisibleTo("sparkcmd")]
|
||||
[assembly: InternalsVisibleTo("spark_test")]
|
||||
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b319f835-7390-47e5-8093-461ed0dfce63")]
|
||||
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="ExcelDnaProps"> -->
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--
|
||||
If you change properties in this file, they may not come into effect until you:
|
||||
* Rebuild the solution/project
|
||||
|
||||
or
|
||||
|
||||
* Close Visual Studio
|
||||
* Delete .vs folder, if exists
|
||||
* Delete ProjectName.csproj.user (or equivalent for VB, F#, etc.), if exists
|
||||
* Delete SolutionName.suo, if exists
|
||||
* Open your solution/project again in Visual Studio
|
||||
-->
|
||||
|
||||
<!--
|
||||
Configuration properties for building .dna files
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Enable/Disable automatic generation of platform-specific versions of .dna files
|
||||
-->
|
||||
<ExcelDnaCreate32BitAddIn Condition="'$(ExcelDnaCreate32BitAddIn)' == ''">false</ExcelDnaCreate32BitAddIn>
|
||||
<ExcelDnaCreate64BitAddIn Condition="'$(ExcelDnaCreate64BitAddIn)' == ''">true</ExcelDnaCreate64BitAddIn>
|
||||
|
||||
<!--
|
||||
Define the suffix used for each platform-specific file e.g. MyAddIn64.dna
|
||||
-->
|
||||
<ExcelDna32BitAddInSuffix Condition="'$(ExcelDna32BitAddInSuffix)' == ''"></ExcelDna32BitAddInSuffix>
|
||||
<ExcelDna64BitAddInSuffix Condition="'$(ExcelDna64BitAddInSuffix)' == ''">64</ExcelDna64BitAddInSuffix>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
Configuration properties for packing .dna files
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Enable/Disable packing of .dna files
|
||||
-->
|
||||
<RunExcelDnaPack Condition="'$(RunExcelDnaPack)' == ''">true</RunExcelDnaPack>
|
||||
|
||||
<!--
|
||||
Suffix used for packed .xll files e.g. MyAddIn-packed.xll
|
||||
-->
|
||||
<ExcelDnaPackXllSuffix Condition="'$(ExcelDnaPackXllSuffix)' == ''">-packed</ExcelDnaPackXllSuffix>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace bts.excel.extensions
|
||||
{
|
||||
public static class EnumParser
|
||||
{
|
||||
public static T ToEnum<T>(this string val, T default_val = default(T)) where T : struct, IConvertible, IComparable
|
||||
{
|
||||
val = val ?? string.Empty;
|
||||
T eval;
|
||||
if (!Enum.TryParse(val, true, out eval))
|
||||
{
|
||||
string[] names = Enum.GetNames(typeof(T));
|
||||
val = names.FirstOrDefault(x => x.ToLower().Contains(val));
|
||||
if(val != null)
|
||||
Enum.TryParse(val, true, out eval);
|
||||
|
||||
if (eval.CompareTo(default(T)) == 0 && default_val.CompareTo(default(T)) != 0)
|
||||
eval = default_val;
|
||||
}
|
||||
return eval;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ExcelDna.Integration;
|
||||
using ExcelDna.Integration.Rtd;
|
||||
using ExcelDna.Registration.Utils;
|
||||
|
||||
using bts.api.admin;
|
||||
using bts.excel;
|
||||
using bts.excel.extensions;
|
||||
using bts.excel.rtd;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace bts.api.orderman
|
||||
{
|
||||
public partial class OrderService_Excel
|
||||
{
|
||||
readonly static Lazy<user.AuthService> _users = new Lazy<user.AuthService>(() => Locator.locate<user.AuthService>(), true);
|
||||
readonly static Lazy<admin.AdminService> _admin = new Lazy<admin.AdminService>(() => Locator.locate<admin.AdminService>(), true);
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Get All Accessible Accounts")]
|
||||
async public static void spark_get_accounts(string login_token, ExcelAsyncHandle handle)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<string> accts = new List<string>();
|
||||
var admin = await _admin.Value.get_filtered_admin_data_async(new FilteredAdminDataRequest());
|
||||
if (admin.success)
|
||||
{
|
||||
foreach (var acc in admin.value.Accounts)
|
||||
if(acc.IsPresent)
|
||||
accts.Add(acc.Name);
|
||||
}
|
||||
var res = Utilities.make_column_vector(accts.ToArray());
|
||||
handle.SetResult(res);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
handle.SetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Cancel an Order by Order ID", IsMacroType = true)]
|
||||
public static object spark_orderservice_cancel_order(long order_id)
|
||||
{
|
||||
var resp = _service.Value.cancel_order(new Cancel() { OrderKey = Convert.ToUInt32(order_id) });
|
||||
return parse_response(resp);
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Update an Order by Order ID", IsMacroType = true)]
|
||||
public static object spark_orderservice_update_order(long order_id, double price, long quantity)
|
||||
{
|
||||
var resp = _service.Value.update_order(new Update() { OrderKey = Convert.ToUInt32(order_id), Price = price, Quantity = Convert.ToUInt32(quantity) });
|
||||
return parse_response(resp);
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Send an Order to Spark via security_key", IsMacroType = true)]
|
||||
public static object spark_orderservice_send_order_key(
|
||||
[ExcelArgument("Required. Only send the order if > last")] long local_order_id,
|
||||
[ExcelArgument("Required. Security key")] long security_key,
|
||||
[ExcelArgument("Required. Side BUY or SELL")] string side,
|
||||
[ExcelArgument("Required. User")] string user,
|
||||
[ExcelArgument("Required. Account")] string account,
|
||||
[ExcelArgument("Required. Price")] double price,
|
||||
[ExcelArgument("Required. Quantity")] long quantity,
|
||||
[ExcelArgument("Required. OrderType (Limit, Stop, Stop_Limit, Iceberg) - Default Limit")] string order_type,
|
||||
[ExcelArgument("OPTIONAL. Order Params JSON (\"stop_price\" : 51.88)")] string order_params = null,
|
||||
|
||||
[ExcelArgument("OPTIONAL. (DAY,GTC,IOC) - Default DAY")] string time_in_force = null,
|
||||
[ExcelArgument("OPTIONAL. (YES,NO) - Default YES")] string manual_order_indicator = null,
|
||||
[ExcelArgument("OPTIONAL. (1,2,3,4) - Default 1")] string cti_code = null,
|
||||
[ExcelArgument("OPTIONAL. (CUSTOMER,FIRM) - Default FIRM")] string customer_or_firm = null)
|
||||
{
|
||||
if (local_order_id <= _local_order_id)
|
||||
return "local_order_id must be greater than " + _local_order_id;
|
||||
Create cr = new Create();
|
||||
cr.NewOrder = new OrderDefinition()
|
||||
{
|
||||
SecurityKey = Convert.ToUInt32(security_key),
|
||||
Side = EnumParser.ToEnum<api.Side>(side),
|
||||
TimeInForce = time_in_force.ToEnum<TimeInForce>(TimeInForce.Day),
|
||||
ManualOrderIndicator = manual_order_indicator.ToEnum<ManualOrderIndicator>(ManualOrderIndicator.Yes),
|
||||
CtiCode = cti_code.ToEnum<CTICode>(CTICode.CtiCode1),
|
||||
CustomerOrFirm = customer_or_firm.ToEnum<CustomerOrFirm>(CustomerOrFirm.Firm),
|
||||
};
|
||||
cr.Price = price;
|
||||
cr.Quantity = Convert.ToUInt32(quantity);
|
||||
|
||||
var btsuser = resolve_user(user);
|
||||
if(btsuser == null)
|
||||
return "Could not resolve user: " + user;
|
||||
cr.NewOrder.User = btsuser.Name;
|
||||
cr.NewOrder.UserId = btsuser.Id;
|
||||
var btaccount = resolve_account(account);
|
||||
if(btaccount == null)
|
||||
return "Could not resolve account: " + account;
|
||||
cr.NewOrder.Account = btaccount.Name;
|
||||
cr.NewOrder.AccountId = btaccount.Id;
|
||||
cr.NewOrder.CustomDef = custom_def(order_type, order_params);
|
||||
if(cr.NewOrder.CustomDef == null || cr.NewOrder.CustomDef.CustomCase == CustomOrderDefinition.CustomOneofCase.None)
|
||||
return "Could not parse order_type and/or order_params info";
|
||||
|
||||
var resp = _service.Value.create_order(cr);
|
||||
_local_order_id = local_order_id;
|
||||
return parse_response(resp, true);
|
||||
}
|
||||
|
||||
private static object parse_response(Response resp, bool show_vertically = false)
|
||||
{
|
||||
object[,] response_cells = new JsonFormatter(resp).format(false);
|
||||
if(show_vertically)
|
||||
response_cells = bts.excel.Utilities.transpose_keep_dimension(response_cells);
|
||||
return response_cells;
|
||||
}
|
||||
|
||||
static Lazy<AdminData> _admin_data = new Lazy<AdminData>(() => _admin.Value.get_admin_data(new VoidMessage()), true);
|
||||
static BTSUser resolve_user(string username)
|
||||
{
|
||||
var user = _admin_data.Value.Users.FirstOrDefault(x => username != null ? x.Name.ToLowerInvariant() == username.ToLowerInvariant() : true);
|
||||
return user;
|
||||
}
|
||||
|
||||
static BTSAccount resolve_account(string acctname)
|
||||
{
|
||||
var acc = _admin_data.Value.Accounts.FirstOrDefault(x => x.Name.ToLowerInvariant() == acctname.ToLowerInvariant());
|
||||
return acc;
|
||||
}
|
||||
|
||||
static CustomOrderDefinition custom_def(string order_type, string order_params)
|
||||
{
|
||||
var member = ReflectionExtensions.get_fields_or_properties(typeof(CustomOrderDefinition))
|
||||
.Where(x => x.Name.ToLower() == order_type.ToLower()).FirstOrDefault();
|
||||
if (member != null)
|
||||
{
|
||||
var mi = member.member_type();
|
||||
var instance = APIDispatch.generate_imessage(mi, order_params, false);
|
||||
var cust = new CustomOrderDefinition();
|
||||
ReflectionExtensions.set_value(member, cust, instance);
|
||||
return cust;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
static long _local_order_id = 0;
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Send an Order to Spark via security_key", IsMacroType = true)]
|
||||
public static object spark_orderservice_send_order(
|
||||
[ExcelArgument("Required. Only send the order if > last")] long local_order_id,
|
||||
[ExcelArgument("Required. Exchange (GLBX,SIM)")] string exchange,
|
||||
[ExcelArgument("Required. Security Desc (ZNZ9 or ZNZ9-ZNH0)")] string security_desc,
|
||||
[ExcelArgument("Required. Side BUY or SELL")] string side,
|
||||
[ExcelArgument("Required. User")] string user,
|
||||
[ExcelArgument("Required. Account")] string account,
|
||||
[ExcelArgument("Required. Price")] double price,
|
||||
[ExcelArgument("Required. Quantity")] long quantity,
|
||||
[ExcelArgument("Required. OrderType (Limit, Stop, Stop_Limit, Iceberg) - Default Limit")] string order_type,
|
||||
[ExcelArgument("OPTIONAL. Order Params JSON (\"stop_price\" : 51.88)")] string order_params = null,
|
||||
|
||||
[ExcelArgument("OPTIONAL. (DAY,GTC,IOC) - Default DAY")] string time_in_force = null,
|
||||
[ExcelArgument("OPTIONAL. (YES,NO) - Default YES")] string manual_order_indicator = null,
|
||||
[ExcelArgument("OPTIONAL. (1,2,3,4) - Default 1")] string cti_code = null,
|
||||
[ExcelArgument("OPTIONAL. (CUSTOMER,FIRM) - Default FIRM")] string customer_or_firm = null)
|
||||
{
|
||||
if (local_order_id <= _local_order_id)
|
||||
return "local_order_id must be greater than " + _local_order_id;
|
||||
Venue ven;
|
||||
if (!Utilities.parse_venue(exchange, out ven))
|
||||
return "Can't Parse Exchange: " + (exchange ?? string.Empty);
|
||||
|
||||
uint key;
|
||||
if (MDSubscribe.market_data(ven).lookup_security_key_from_desc(security_desc, out key))
|
||||
{
|
||||
return spark_orderservice_send_order_key(local_order_id, (long)key, side, user, account, price, quantity, order_type, order_params,
|
||||
time_in_force, manual_order_indicator, cti_code, customer_or_firm);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Can't find security desc " + security_desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
namespace bts.excel.extensions
|
||||
{
|
||||
public static class ReflectionExtensions
|
||||
{
|
||||
public static void set_value(this MemberInfo info, object target, object value)
|
||||
{
|
||||
if (info is FieldInfo)
|
||||
((FieldInfo)info).SetValue(target, value);
|
||||
else if (info is PropertyInfo)
|
||||
((PropertyInfo)info).SetValue(target, value);
|
||||
}
|
||||
|
||||
public static object get_value(this MemberInfo info, object target)
|
||||
{
|
||||
if (info is FieldInfo)
|
||||
return ((FieldInfo)info).GetValue(target);
|
||||
else if (info is PropertyInfo)
|
||||
return ((PropertyInfo)info).GetValue(target);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MemberInfo[] get_fields_or_properties(this Type t)
|
||||
{
|
||||
MemberInfo[] mi = t.GetMembers(BindingFlags.Instance | BindingFlags.Public
|
||||
| BindingFlags.NonPublic).Where(m => (m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property)).ToArray();
|
||||
return mi;
|
||||
}
|
||||
|
||||
public static MemberInfo[] get_fields(this Type t)
|
||||
{
|
||||
MemberInfo[] mi = t.GetMembers(BindingFlags.Instance | BindingFlags.Public
|
||||
| BindingFlags.NonPublic).Where(m => (m.MemberType == MemberTypes.Field)).ToArray();
|
||||
return mi;
|
||||
}
|
||||
|
||||
public static MemberInfo[] get_properties(this Type t)
|
||||
{
|
||||
MemberInfo[] mi = t.GetMembers(BindingFlags.Instance | BindingFlags.Public
|
||||
| BindingFlags.NonPublic).Where(m => (m.MemberType == MemberTypes.Property)).ToArray();
|
||||
return mi;
|
||||
}
|
||||
|
||||
public static MemberInfo get_field_or_property(this Type t, string name)
|
||||
{
|
||||
MemberInfo[] mi = t.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(m => (m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property))
|
||||
.Where(m => (m.Name == name))
|
||||
.ToArray();
|
||||
if (mi != null && mi.Length > 0)
|
||||
return mi[0];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MemberInfo get_static_field_or_property(this Type t, string name)
|
||||
{
|
||||
MemberInfo[] mi = t.GetMembers(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(m => (m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property))
|
||||
.Where(m => (m.Name == name))
|
||||
.ToArray();
|
||||
if (mi != null && mi.Length > 0)
|
||||
return mi[0];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MemberInfo[] search_field_or_property(this Type t, Func<MemberInfo, bool> criteria)
|
||||
{
|
||||
MemberInfo[] mi = t.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(m => (m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property))
|
||||
.Where(criteria)
|
||||
.ToArray();
|
||||
if (mi != null && mi.Length > 0)
|
||||
return mi;
|
||||
else
|
||||
return new MemberInfo[0];
|
||||
}
|
||||
|
||||
|
||||
public static Type member_type(this MemberInfo info)
|
||||
{
|
||||
if (info is FieldInfo)
|
||||
return ((FieldInfo)info).FieldType;
|
||||
else if (info is PropertyInfo)
|
||||
return ((PropertyInfo)info).PropertyType;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static MethodInfo[] find_method(this Type t, Func<MethodInfo, bool> criteria)
|
||||
{
|
||||
var mi = t.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(criteria).ToArray();
|
||||
if (mi != null && mi.Length > 0)
|
||||
return mi;
|
||||
else
|
||||
return new MethodInfo[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ExcelDna.AddIn" version="0.34.6" targetFramework="net471" />
|
||||
<package id="ExcelDna.Integration" version="0.34.6" targetFramework="net471" />
|
||||
</packages>
|
||||
@@ -1,127 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
using ExcelDna.Integration;
|
||||
using ExcelDna.Integration.Rtd;
|
||||
using bts.excel.extensions;
|
||||
using bts.api.core;
|
||||
using bts.api;
|
||||
using bts.api.md;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public class APIRTDServer : ExcelRtdServer
|
||||
{
|
||||
readonly Dictionary<int, IObservable<object>> _subs = new Dictionary<int, IObservable<object>>();
|
||||
readonly List<IDisposable> _disps = new List<IDisposable>();
|
||||
readonly static ConcurrentDictionary<string, object> data_store = new ConcurrentDictionary<string, object>();
|
||||
public APIRTDServer()
|
||||
{
|
||||
}
|
||||
|
||||
static public bool retrieve(string key, out object data)
|
||||
{
|
||||
return data_store.TryGetValue(key, out data);
|
||||
}
|
||||
|
||||
protected override bool ServerStart() { return true; }
|
||||
protected override void ServerTerminate() { }
|
||||
|
||||
protected override ExcelRtdServer.Topic CreateTopic(int topicId, IList<string> topicInfo)
|
||||
{
|
||||
string[] tagvals = new string[topicInfo.Count - 2];
|
||||
Array.Copy(topicInfo.ToArray(), 2, tagvals, 0, tagvals.Length);
|
||||
var bt = new APITopic(this, topicId, topicInfo[0], topicInfo[1], tagvals);
|
||||
return bt;
|
||||
}
|
||||
|
||||
protected override object ConnectData(Topic topic, IList<string> topicInfo, ref bool newValues)
|
||||
{
|
||||
//return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA);
|
||||
newValues = true;
|
||||
TopicBase bt = (TopicBase)topic;
|
||||
IObservable<object> obs = null;
|
||||
try
|
||||
{
|
||||
string error = subscribe(bt, out obs);
|
||||
if (obs == null)
|
||||
return error;
|
||||
_subs[topic.TopicId] = obs;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return "PLEASE RESUBSCRIBE! Error: " + e.ToString();
|
||||
}
|
||||
_disps.Add(obs.Subscribe((data) =>
|
||||
{
|
||||
string gstring = bt.id.ToString();
|
||||
|
||||
data_store[gstring] = data;
|
||||
bt.UpdateValue(gstring);
|
||||
bt.UpdateNotify();
|
||||
},
|
||||
(error) =>
|
||||
{
|
||||
topic.UpdateValue(error.ToString());
|
||||
},
|
||||
() => { }));
|
||||
return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA); //success!
|
||||
}
|
||||
|
||||
protected override void DisconnectData(ExcelRtdServer.Topic topic)
|
||||
{
|
||||
IObservable<object> sub;
|
||||
if (_subs.TryGetValue(topic.TopicId, out sub))
|
||||
{
|
||||
IDisposable disp = sub as IDisposable;
|
||||
if (disp != null)
|
||||
disp.Dispose();
|
||||
_subs.Remove(topic.TopicId);
|
||||
}
|
||||
}
|
||||
|
||||
protected override int Heartbeat()
|
||||
{
|
||||
return base.Heartbeat();
|
||||
}
|
||||
|
||||
|
||||
string subscribe(TopicBase topic, out IObservable<object> stream)
|
||||
{
|
||||
if(topic is APITopic apitopic)
|
||||
return subscribe(apitopic, out stream);
|
||||
else
|
||||
{
|
||||
stream = null;
|
||||
return "Unknown Topic Type";
|
||||
}
|
||||
}
|
||||
|
||||
string subscribe(APITopic topic, out IObservable<object> stream)
|
||||
{
|
||||
stream = null;
|
||||
if (topic.service_type == null)
|
||||
return "Unknown ServiceType: " + topic.service_type_string;
|
||||
if (topic.request_type == null)
|
||||
return "Unknown MethodName: " + topic.method_name;
|
||||
|
||||
var service = APIDispatch.locate_service(topic.service_type);
|
||||
var request = APIDispatch.generate_request(topic.service_type, topic.method_name, topic.parameters[0]);
|
||||
if (service != null) //request can be null here
|
||||
{
|
||||
var subscription = APIDispatch.invoke_service_call(service, topic.method_name, request);
|
||||
stream = subscription as IObservable<object>;
|
||||
if (stream != null)
|
||||
{
|
||||
dynamic dtable = ObservableUpdateExtensions.Table((dynamic)subscription);
|
||||
stream = dtable as IObservable<object>;
|
||||
}
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using ExcelDna.Integration;
|
||||
using ExcelDna.Integration.Rtd;
|
||||
using bts.excel.extensions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class TopicBase : ExcelRtdServer.Topic
|
||||
{
|
||||
public Guid id { get; protected set; }
|
||||
|
||||
public TopicBase(ExcelRtdServer server, int topicid) : base(server, topicid)
|
||||
{
|
||||
id = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
|
||||
class APITopic : TopicBase
|
||||
{
|
||||
public Type service_type { get; private set; }
|
||||
public Type request_type { get; private set; }
|
||||
public string method_name { get; private set; }
|
||||
public string[] parameters { get; private set; }
|
||||
|
||||
public string service_type_string { get; private set; }
|
||||
public const string topic_type = "api";
|
||||
|
||||
public APITopic(ExcelRtdServer server, int topicid,
|
||||
string serv_type, string methodname, string[] param) : base(server, topicid)
|
||||
{
|
||||
service_type_string = serv_type;
|
||||
method_name = methodname;
|
||||
service_type = find_api_type(service_type_string, null, typeof(bts.api.core.IApiClient));
|
||||
request_type = APIDispatch.find_request_type(service_type, method_name);
|
||||
parameters = param;
|
||||
}
|
||||
|
||||
Type find_api_type(string type, string assem_regex = null, Type assignable = null)
|
||||
{
|
||||
return Utilities.find_full_type_in_all_assemblies(type, assem_regex, assignable);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var h = service_type?.GetHashCode() ^ request_type?.GetHashCode() ^ all_params().GetHashCode();
|
||||
if (h.HasValue)
|
||||
return h.Value;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
string all_params()
|
||||
{
|
||||
if (parameters != null)
|
||||
return parameters.Aggregate((a, b) => a + b);
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
APITopic top = (obj as APITopic);
|
||||
if (top == null)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return top.service_type.Equals(this.service_type) &&
|
||||
top.request_type.Equals(this.request_type) &&
|
||||
top.all_params().Equals(this.all_params());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,319 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using bts.excel.extensions;
|
||||
using System.Text.RegularExpressions;
|
||||
using bts.api.core;
|
||||
|
||||
namespace bts.excel
|
||||
{
|
||||
public class DataParser
|
||||
{
|
||||
private static Type analyze_type(Type type, out bool is_array)
|
||||
{
|
||||
Type element_type = type;
|
||||
is_array = false;
|
||||
if (element_type.IsArray)
|
||||
{
|
||||
is_array = true;
|
||||
element_type = element_type.GetElementType();
|
||||
}
|
||||
return element_type;
|
||||
}
|
||||
|
||||
public static bool supported_primitive(Type t)
|
||||
{
|
||||
bool dummy;
|
||||
return supported_primitive(t, out dummy);
|
||||
}
|
||||
|
||||
public static bool supported_primitive(Type t, out bool is_array)
|
||||
{
|
||||
is_array = t.IsArray;
|
||||
if (is_array)
|
||||
t = t.GetElementType();
|
||||
return t.IsPrimitive || t.IsEnum || t == typeof(string) || t == typeof(DateTime);
|
||||
}
|
||||
|
||||
public static bool excluded_member(MemberInfo s)
|
||||
{
|
||||
return s.Name.ToLower() == "extensionobject" ||
|
||||
s.Name.ToLower() == "proto" ||
|
||||
s.Name.ToLower() == "descriptor" ||
|
||||
|
||||
s.Name.Contains(".")
|
||||
;
|
||||
}
|
||||
|
||||
private static void analyze_fields(Type element_type,
|
||||
out List<MemberInfo> superduperfields, out List<MemberInfo> superfields, out List<MemberInfo> fields,
|
||||
out List<string> superdupernames, out List<string> supernames, out List<string> names, out List<string> combined)
|
||||
{
|
||||
var members = ReflectionExtensions.get_fields_or_properties(element_type);
|
||||
superduperfields = new List<MemberInfo>();
|
||||
superfields = new List<MemberInfo>();
|
||||
fields = new List<MemberInfo>();
|
||||
superdupernames = new List<string>();
|
||||
supernames = new List<string>();
|
||||
names = new List<string>();
|
||||
combined = new List<string>();
|
||||
foreach (var r in members)
|
||||
{
|
||||
if (excluded_member(r))
|
||||
continue;
|
||||
if (supported_primitive(ReflectionExtensions.member_type(r)))
|
||||
{
|
||||
superduperfields.Add(r);
|
||||
superdupernames.Add(r.Name);
|
||||
superfields.Add(r);
|
||||
supernames.Add(r.Name);
|
||||
fields.Add(r);
|
||||
names.Add(r.Name);
|
||||
combined.Add(r.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sub = ReflectionExtensions.get_fields_or_properties(ReflectionExtensions.member_type(r));
|
||||
foreach (var s in sub)
|
||||
{
|
||||
if (excluded_member(s))
|
||||
continue;
|
||||
if (supported_primitive(ReflectionExtensions.member_type(s)))
|
||||
{
|
||||
superduperfields.Add(r);
|
||||
superdupernames.Add(r.Name);
|
||||
superfields.Add(r);
|
||||
supernames.Add(r.Name);
|
||||
fields.Add(s);
|
||||
names.Add(s.Name);
|
||||
combined.Add(r.Name + "." + s.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
var subsub = ReflectionExtensions.get_fields_or_properties(ReflectionExtensions.member_type(s));
|
||||
foreach (var ss in subsub)
|
||||
{
|
||||
if (excluded_member(ss) || !supported_primitive(ReflectionExtensions.member_type(ss)))
|
||||
continue;
|
||||
superduperfields.Add(r);
|
||||
superdupernames.Add(r.Name);
|
||||
superfields.Add(s);
|
||||
supernames.Add(s.Name);
|
||||
fields.Add(ss);
|
||||
names.Add(ss.Name);
|
||||
combined.Add(r.Name + "." + s.Name + "." + ss.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public object gather_data(Type type, object[,] data)
|
||||
{
|
||||
if (type == null)
|
||||
return null;
|
||||
bool is_array;
|
||||
Type element_type = analyze_type(type, out is_array);
|
||||
|
||||
bool field_name_headers = true;
|
||||
List<MemberInfo> superduperfields, superfields, fields;
|
||||
List<string> superdupernames, supernames, names, combined;
|
||||
analyze_fields(element_type, out superduperfields, out superfields, out fields,
|
||||
out superdupernames, out supernames, out names, out combined);
|
||||
|
||||
int object_len = data.GetLength(1) - (field_name_headers ? 1 : 0);
|
||||
Array objects = Array.CreateInstance(element_type, object_len);
|
||||
for (int j = 0; j < objects.Length; j++)
|
||||
{
|
||||
object target = Activator.CreateInstance(element_type);
|
||||
for (int zz = 0; zz < superduperfields.Count; zz++)
|
||||
{
|
||||
if (Regex.Matches(combined[zz], @"\.").Count == 2)
|
||||
ReflectionExtensions.set_value(superduperfields[zz], target, Activator.CreateInstance(ReflectionExtensions.member_type(superduperfields[zz])));
|
||||
}
|
||||
for (int z = 0; z < superfields.Count; z++)
|
||||
{
|
||||
if (combined[z].Contains("."))
|
||||
ReflectionExtensions.set_value(superfields[z], target, Activator.CreateInstance(ReflectionExtensions.member_type(superfields[z])));
|
||||
}
|
||||
for (int i = 0; i < data.GetLength(0); i++)
|
||||
{
|
||||
string name = data[i, 0].ToString();
|
||||
int idx = combined.IndexOf(name);
|
||||
if (idx < 0 || idx >= combined.Count)
|
||||
continue;
|
||||
|
||||
MemberInfo fi = fields[idx];
|
||||
object val = val = data[i, j + (field_name_headers ? 1 : 0)];
|
||||
val = read_data(ReflectionExtensions.member_type(fi), val);
|
||||
int dotcount = Regex.Matches(combined[i], @"\.").Count;
|
||||
if (dotcount == 2)
|
||||
{
|
||||
object subsubtarget = ReflectionExtensions.get_value(superduperfields[i], target);
|
||||
if (subsubtarget != null)
|
||||
{
|
||||
object subtarget = ReflectionExtensions.get_value(superfields[i], subsubtarget);
|
||||
if (subtarget != null)
|
||||
ReflectionExtensions.set_value(fi, subtarget, val);
|
||||
}
|
||||
}
|
||||
else if (dotcount == 1)
|
||||
{
|
||||
object subtarget = ReflectionExtensions.get_value(superfields[i], target);
|
||||
if (subtarget != null)
|
||||
ReflectionExtensions.set_value(fi, subtarget, val);
|
||||
}
|
||||
else if (dotcount == 0)
|
||||
ReflectionExtensions.set_value(fi, target, val);
|
||||
}
|
||||
objects.SetValue(target, j);
|
||||
}
|
||||
|
||||
if (is_array)
|
||||
return objects;
|
||||
else if (objects.Length > 0)
|
||||
return objects.GetValue(0);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static object read_data(Type field_type, object val)
|
||||
{
|
||||
if (typeof(Array).IsAssignableFrom(field_type))
|
||||
val = unstringify_array(val, field_type);
|
||||
else if (field_type == typeof(DateTime))
|
||||
val = DateTime.FromOADate(Convert.ToDouble(val));
|
||||
else if (field_type.IsEnum)
|
||||
val = Enum.Parse(field_type, val.ToString());
|
||||
else
|
||||
val = Convert.ChangeType(val, field_type);
|
||||
return val;
|
||||
}
|
||||
|
||||
public static Tuple<object[], object[]> key_value_tuple<T, TKey>(TableUpdate<T, TKey> source) where TKey : IEquatable<TKey>
|
||||
{
|
||||
return Tuple.Create(source.state.Keys.Cast<object>().ToArray(), source.state.Values.Cast<object>().ToArray());
|
||||
}
|
||||
|
||||
public static object[,] scatter_data(object data, bool include_field_names = true, Type type_override = null)
|
||||
{
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
bool is_array;
|
||||
Type type = type_override ?? data.GetType();
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(TableUpdate<,>)))
|
||||
{
|
||||
Tuple<object[], object[]> tup = key_value_tuple((dynamic)data);
|
||||
return scatter_data(tup.Item2, include_field_names, tup.Item2.FirstOrDefault()?.GetType().MakeArrayType());
|
||||
}
|
||||
Type element_type = analyze_type(type, out is_array);
|
||||
|
||||
List<MemberInfo> superduperfields, superfields, fields;
|
||||
List<string> superdupernames, supernames, names, combined;
|
||||
analyze_fields(element_type, out superduperfields, out superfields, out fields,
|
||||
out superdupernames, out supernames, out names, out combined);
|
||||
|
||||
Array the_data = (is_array) ? (Array)data : new object[] { data };
|
||||
int len = the_data.GetLength(0);
|
||||
|
||||
var ret = new object[fields.Count, len + (include_field_names ? 1 : 0)];
|
||||
for (int j = 0; j < ret.GetLength(1); j++)
|
||||
{
|
||||
for (int i = 0; i < ret.GetLength(0); i++)
|
||||
{
|
||||
object dat = "";
|
||||
int dotcount = Regex.Matches(combined[i], @"\.").Count;
|
||||
if (dotcount == 2)
|
||||
{
|
||||
if (j == 0 && include_field_names)
|
||||
dat = combined[i];
|
||||
else
|
||||
{
|
||||
object subsub = ReflectionExtensions.get_value(superduperfields[i], the_data.GetValue(j - (include_field_names ? 1 : 0)));
|
||||
if (subsub != null)
|
||||
{
|
||||
object sub = ReflectionExtensions.get_value(superfields[i], subsub);
|
||||
if (sub != null)
|
||||
dat = ReflectionExtensions.get_value(fields[i], sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dotcount == 1)
|
||||
{
|
||||
if (j == 0 && include_field_names)
|
||||
dat = combined[i];
|
||||
else
|
||||
{
|
||||
object sub = ReflectionExtensions.get_value(superfields[i], the_data.GetValue(j - (include_field_names ? 1 : 0)));
|
||||
if (sub != null)
|
||||
dat = ReflectionExtensions.get_value(fields[i], sub);
|
||||
}
|
||||
}
|
||||
else if (dotcount == 0)
|
||||
{
|
||||
if (j == 0 && include_field_names)
|
||||
dat = names[i];
|
||||
else
|
||||
dat = ReflectionExtensions.get_value(fields[i], the_data.GetValue(j - (include_field_names ? 1 : 0)));
|
||||
}
|
||||
else
|
||||
dat = "Unknown value: " + combined[i];
|
||||
write_data(out ret[i, j], dat);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void write_data(out object ret, object dat)
|
||||
{
|
||||
ret = dat;
|
||||
if (dat is DateTime)
|
||||
ret = ((DateTime)dat).ToOADate();
|
||||
else if (dat is Enum)
|
||||
ret = dat.ToString();
|
||||
else if (dat is Array)
|
||||
{
|
||||
Array ary = (Array)dat;
|
||||
ret = stringify_array(ary);
|
||||
}
|
||||
}
|
||||
|
||||
public static string stringify_array(Array array)
|
||||
{
|
||||
string stringify = "{ ";
|
||||
int idx = 0;
|
||||
foreach (object d in array)
|
||||
{
|
||||
object o;
|
||||
write_data(out o, d);
|
||||
stringify += o.ToString() + ((idx++ == array.Length - 1) ? string.Empty : ",");
|
||||
}
|
||||
stringify += " }";
|
||||
return stringify;
|
||||
}
|
||||
|
||||
public static Array unstringify_array(object val, Type field_type = null)
|
||||
{
|
||||
if (field_type == null)
|
||||
field_type = typeof(string[]);
|
||||
|
||||
string[] data = val.ToString().Split(new char[] { ',', '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Type dt = field_type.GetElementType();
|
||||
Array ary = Array.CreateInstance(dt, data.Length);
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
object entry = null;
|
||||
try
|
||||
{
|
||||
entry = read_data(dt, Convert.ChangeType(data[i], dt));
|
||||
}
|
||||
catch (FormatException) { }
|
||||
ary.SetValue(entry, i);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System;
|
||||
using bts.md;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class BookMDFormatter : IExcelFormatter
|
||||
{
|
||||
readonly IMDBook _update;
|
||||
public BookMDFormatter(IMDBook upd)
|
||||
{
|
||||
_update = upd;
|
||||
}
|
||||
|
||||
public object[,] format(bool include_headers = false)
|
||||
{
|
||||
return format(_update, include_headers);
|
||||
}
|
||||
|
||||
static public object[,] format(IMDBook update, bool include_headers = false)
|
||||
{
|
||||
const int cols = 5;
|
||||
const int rows = 30;
|
||||
var ret = new object[rows, cols];
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = 0; j < cols; j++)
|
||||
ret[i, j] = string.Empty;
|
||||
|
||||
if (update != null)
|
||||
{
|
||||
int idx = 0;
|
||||
for (int j = update.asks.Count - 1; j >= 0 && idx < rows; j--)
|
||||
{
|
||||
var ask = update.asks[j];
|
||||
ret[idx, 1] = ask.price;
|
||||
ret[idx, 2] = ask.size;
|
||||
idx++;
|
||||
}
|
||||
for (int j = 0; j < update.bids.Count && idx < rows; j++)
|
||||
{
|
||||
var bid = update.bids[j];
|
||||
ret[idx, 1] = bid.price;
|
||||
ret[idx, 0] = bid.size;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using bts.md;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class FormatterFactory
|
||||
{
|
||||
public static IExcelFormatter make_formatter(object data)
|
||||
{
|
||||
if(data is IMDBook upd)
|
||||
return new BookMDFormatter(upd);
|
||||
else
|
||||
{
|
||||
return new JsonFormatter(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
internal interface IExcelFormatter
|
||||
{
|
||||
object[,] format(bool include_headers = false);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using Google.Protobuf;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using ExcelDna.Integration;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class JsonFormatter : IExcelFormatter
|
||||
{
|
||||
private object _data;
|
||||
static Google.Protobuf.JsonFormatter _protoformatter =
|
||||
new Google.Protobuf.JsonFormatter(Google.Protobuf.JsonFormatter.Settings.Default.WithFormatDefaultValues(true));
|
||||
public JsonFormatter(object data)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
#region parser
|
||||
static IDictionary<string, object> parse_dictionary(object[,] range)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
if (range.Rank > 1)
|
||||
{
|
||||
for (int i = 0; i < range.GetLength(0); i++)
|
||||
{
|
||||
for (int j = 1; j < range.GetLength(1); j++)
|
||||
dict[range.GetValue(i, 0).ToString()] = range.GetValue(i, j);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 1; j < range.Length; j++)
|
||||
dict[range.GetValue(0).ToString()] = range.GetValue(j);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static string parse_json(Type type, object[,] range)
|
||||
{
|
||||
var dict = parse_dictionary(range);
|
||||
string str = JsonConvert.SerializeObject(dict);
|
||||
return str;
|
||||
}
|
||||
|
||||
public static object parse_json_object(Type type, object[,] range)
|
||||
{
|
||||
string json = parse_json(type, range);
|
||||
var obj = JsonConvert.DeserializeObject(json);
|
||||
return obj;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public object[,] format(bool include_headers = false)
|
||||
{
|
||||
if (_data is IEnumerable iem)
|
||||
return format_many(iem, include_headers);
|
||||
else
|
||||
return format_one(_data, include_headers);
|
||||
}
|
||||
|
||||
object[,] format_many(IEnumerable data, bool include_headers = false)
|
||||
{
|
||||
List<SortedDictionary<string, object>> res = new List<SortedDictionary<string, object>>();
|
||||
foreach (var d in data)
|
||||
res.Add(to_dictionary(d));
|
||||
object[,] ret = fill_object_array(res, include_headers);
|
||||
return ret;
|
||||
}
|
||||
|
||||
object[,] format_one(object data, bool include_headers = false)
|
||||
{
|
||||
var d = to_dictionary(data);
|
||||
object[,] ret = fill_object_array(new[] { d }, include_headers);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SortedDictionary<string, object> to_dictionary(object data)
|
||||
{
|
||||
string json = null;
|
||||
if(data is IMessage imsg)
|
||||
json = _protoformatter.Format(imsg);
|
||||
else
|
||||
json = JsonConvert.SerializeObject(data);
|
||||
|
||||
JObject jo = JObject.Parse(json);
|
||||
SortedDictionary<string, object> results = new SortedDictionary<string, object>();
|
||||
parse_object(jo, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
void parse_object(JObject jo, SortedDictionary<string, object> results)
|
||||
{
|
||||
foreach (var kvp in jo)
|
||||
{
|
||||
if (kvp.Value is JArray jar) //arrays we'll just leave
|
||||
{
|
||||
for (int i = 0; i < jar.Count; i++)
|
||||
results[kvp.Key + "_" + i] = jar[i].ToString();
|
||||
}
|
||||
else if (kvp.Value is JValue jv)
|
||||
results[kvp.Key] = jv.ToString();
|
||||
else if (kvp.Value.HasValues)
|
||||
parse_object((JObject)kvp.Value, results);
|
||||
}
|
||||
}
|
||||
|
||||
object[,] fill_object_array(IEnumerable<SortedDictionary<string, object>> data, bool include_headers = false)
|
||||
{
|
||||
int count = 0;
|
||||
SortedDictionary<string, string> keys = new SortedDictionary<string, string>();
|
||||
foreach (var d in data)
|
||||
{
|
||||
count++;
|
||||
foreach (var kv in d)
|
||||
keys[kv.Key] = null;
|
||||
}
|
||||
object[,] ret = new object[count + (include_headers ? 1 : 0), keys.Count];
|
||||
int r = 0, c = 0;
|
||||
if (include_headers)
|
||||
{
|
||||
foreach (var k in keys.Keys)
|
||||
ret[r, c++] = k;
|
||||
r++;
|
||||
}
|
||||
foreach (var d in data)
|
||||
{
|
||||
c = 0;
|
||||
foreach (var k in keys.Keys)
|
||||
{
|
||||
d.TryGetValue(k, out object val);
|
||||
ret[r, c++] = val; //It found me!
|
||||
}
|
||||
r++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using bts.md;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class LastMDFormatter : IExcelFormatter
|
||||
{
|
||||
readonly IMDLast _update;
|
||||
public LastMDFormatter(IMDLast upd)
|
||||
{
|
||||
_update = upd;
|
||||
}
|
||||
|
||||
public object[,] format(bool include_headers = false)
|
||||
{
|
||||
return format(_update, include_headers);
|
||||
}
|
||||
|
||||
static public object[,] format(IMDLast update, bool include_headers = false)
|
||||
{
|
||||
const int cols = 3;
|
||||
const int rows = 1;
|
||||
var ret = new object[rows, cols];
|
||||
|
||||
if (update != null)
|
||||
{
|
||||
ret[0, 0] = update.last?.price;
|
||||
ret[0, 1] = update.last?.size;
|
||||
ret[0, 1] = update.last_time;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using bts.md;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class MiscMDFormatter : IExcelFormatter
|
||||
{
|
||||
readonly IMDMisc _update;
|
||||
public MiscMDFormatter(IMDMisc upd)
|
||||
{
|
||||
_update = upd;
|
||||
}
|
||||
|
||||
public object[,] format(bool include_headers = false)
|
||||
{
|
||||
return format(_update, include_headers);
|
||||
}
|
||||
|
||||
static public object[,] format(IMDMisc update, bool include_headers = false)
|
||||
{
|
||||
return new object[0, 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using bts.md;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class TopOfBookMDFormatter : IExcelFormatter
|
||||
{
|
||||
readonly IMDBook _update;
|
||||
public TopOfBookMDFormatter(IMDBook upd)
|
||||
{
|
||||
_update = upd;
|
||||
}
|
||||
|
||||
public object[,] format(bool include_headers = false)
|
||||
{
|
||||
return format(_update, include_headers);
|
||||
}
|
||||
|
||||
static public object[,] format(IMDBook update, bool include_headers = false)
|
||||
{
|
||||
const int cols = 4;
|
||||
const int rows = 1;
|
||||
var ret = new object[rows, cols];
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = 0; j < cols; j++)
|
||||
ret[i, j] = string.Empty;
|
||||
|
||||
if (update != null)
|
||||
{
|
||||
int idx = 0;
|
||||
for (int j = 0; j < update.asks.Count && idx < rows; j++)
|
||||
{
|
||||
var ask = update.asks[j];
|
||||
ret[idx, 2] = ask.price;
|
||||
ret[idx, 3] = ask.size;
|
||||
idx++;
|
||||
}
|
||||
idx = 0;
|
||||
for (int j = 0; j < update.bids.Count && idx < rows; j++)
|
||||
{
|
||||
var bid = update.bids[j];
|
||||
ret[idx, 1] = bid.price;
|
||||
ret[idx, 0] = bid.size;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
|
||||
using System;
|
||||
using bts.md;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
class TopicMDFormatter : IExcelFormatter
|
||||
{
|
||||
readonly IMDCombined _update;
|
||||
readonly string _topic;
|
||||
public TopicMDFormatter(IMDCombined upd, string topic)
|
||||
{
|
||||
_update = upd;
|
||||
_topic = topic;
|
||||
}
|
||||
|
||||
public object[,] format(bool include_headers = false)
|
||||
{
|
||||
return format(_update, _topic, include_headers);
|
||||
}
|
||||
|
||||
static public object[,] format(IMDCombined update, string topic, bool include_headers = false)
|
||||
{
|
||||
var retval = new object[1, 1];
|
||||
if(update == null || string.IsNullOrEmpty(topic))
|
||||
return retval;
|
||||
|
||||
switch (topic.ToLower())
|
||||
{
|
||||
case "bid":
|
||||
case "bidprice":
|
||||
retval[0, 0] = update.bids?[0]?.price;
|
||||
break;
|
||||
case "ask":
|
||||
case "askprice":
|
||||
retval[0, 0] = update.asks?[0]?.price;
|
||||
break;
|
||||
case "bidsize":
|
||||
case "bidqty":
|
||||
retval[0, 0] = update.bids?[0]?.size;
|
||||
break;
|
||||
case "asksize":
|
||||
case "askqty":
|
||||
retval[0, 0] = update.asks?[0]?.size;
|
||||
break;
|
||||
case "impliedbid":
|
||||
case "impliedbidprice":
|
||||
retval[0, 0] = update.bids?[0]?.price; //TODO is this the first price with impsz > 0?
|
||||
break;
|
||||
case "impliedask":
|
||||
case "impliedaskprice":
|
||||
retval[0, 0] = update.asks?[0]?.price;
|
||||
break;
|
||||
case "impliedbidsize":
|
||||
case "impliedbidqty":
|
||||
retval[0, 0] = update.bids?[0]?.implied_size;
|
||||
break;
|
||||
case "impliedasksize":
|
||||
case "impliedaskqty":
|
||||
retval[0, 0] = update.asks?[0]?.implied_size;
|
||||
break;
|
||||
case "settlement":
|
||||
case "settlementprice":
|
||||
retval[0, 0] = update.settlement_price;
|
||||
break;
|
||||
case "previoussettlement":
|
||||
case "previoussettlementprice":
|
||||
retval[0, 0] = update.previous_settlement_price;
|
||||
break;
|
||||
case "open":
|
||||
case "openprice":
|
||||
retval[0, 0] = update.open_price;
|
||||
break;
|
||||
case "close":
|
||||
case "closeprice":
|
||||
retval[0, 0] = update.close_price;
|
||||
break;
|
||||
case "high":
|
||||
case "highprice":
|
||||
retval[0, 0] = update.session_high;
|
||||
break;
|
||||
case "low":
|
||||
case "lowprice":
|
||||
retval[0, 0] = update.session_low;
|
||||
break;
|
||||
case "last":
|
||||
case "lastprice":
|
||||
retval[0, 0] = update?.last?.price;
|
||||
break;
|
||||
case "lastsize":
|
||||
case "lastqty":
|
||||
retval[0, 0] = update?.last?.size;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using ExcelDna.Integration;
|
||||
using ExcelDna.Integration.Rtd;
|
||||
using ExcelDna.Registration.Utils;
|
||||
using System.Reactive.Linq;
|
||||
using bts.api;
|
||||
using bts.md;
|
||||
using bts.api.orderman;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
public class MDSubscribe
|
||||
{
|
||||
[ExcelFunction(Category = "BTS", Description = "Log in to BTS Spark")]
|
||||
async public static void spark_login(string login, string password, ExcelAsyncHandle handle)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = await Locator.login(login, password);
|
||||
if (res.success && Locator.token.HasValue)
|
||||
{
|
||||
_md.set_auth_token(Locator.token);
|
||||
handle.SetResult("Login Successful");
|
||||
}
|
||||
else
|
||||
handle.SetResult("Login Error: Could not log in check user/pass " + res.reason);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
handle.SetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static MarketDataClient _md = new MarketDataClient();
|
||||
public static MarketDataClient market_data(api.Venue exchange)
|
||||
{
|
||||
return _md;
|
||||
}
|
||||
|
||||
static public object spark_lookup_security_desc(string exchange, long security_key)
|
||||
{
|
||||
Venue ven;
|
||||
if (!Utilities.parse_venue(exchange, out ven))
|
||||
return Observable.Return("Can't Parse Exchange: " + exchange ?? string.Empty);
|
||||
MDSubscribe.market_data(ven).lookup_security_desc((uint)security_key, out string desc);
|
||||
return desc ?? string.Empty;
|
||||
}
|
||||
|
||||
static IObservable<IEnumerable<object>> md_observable(string contract, string symbol, string security_type, string exchange)
|
||||
{
|
||||
security_type = string.IsNullOrEmpty(security_type) ? SecurityType.Future.ToString() : security_type;
|
||||
exchange = string.IsNullOrEmpty(exchange) ? Security.ExchangeDataOneofCase.Glbx.ToString() : exchange;
|
||||
symbol = string.IsNullOrEmpty(symbol) ? contract.Substring(0, 2) : symbol;
|
||||
|
||||
Venue ven;
|
||||
SecurityType sectype;
|
||||
if (!Utilities.parse_venue(exchange, out ven))
|
||||
return Observable.Return(new [] {"Can't Parse Exchange: " + exchange ?? string.Empty});
|
||||
if (!Utilities.parse_security_type(security_type, out sectype))
|
||||
return Observable.Return(new [] {"Can't Parse Security Type: " + security_type ?? string.Empty});
|
||||
if (string.IsNullOrEmpty(symbol))
|
||||
return Observable.Return(new []{"Can't Parse Symbol: " + symbol ?? string.Empty});
|
||||
if (string.IsNullOrEmpty(contract))
|
||||
return Observable.Return(new []{"Can't Parse Contract: " + contract ?? string.Empty});
|
||||
|
||||
Func<SecurityImmutable, bool> desc = null;
|
||||
switch(ven)
|
||||
{
|
||||
case Venue.Sim:
|
||||
case Venue.Glbx:
|
||||
desc = (x=> x.Glbx.SecurityDesc == contract);
|
||||
break;
|
||||
case Venue.Ice:
|
||||
desc = (x=> x.Ice.SecurityDesc == contract);
|
||||
break;
|
||||
default:
|
||||
desc = (x => true);
|
||||
break;
|
||||
}
|
||||
|
||||
Func<SecurityImmutable, bool> where = (x => x.Exchange == ven && x.Symbol == symbol && x.security_type() == sectype && desc(x) );
|
||||
|
||||
var stream = market_data(ven).subscribe_combined(where);
|
||||
return stream;
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Subscribe to BTS Spark full depth market data")]
|
||||
public static object spark_md_book(
|
||||
[ExcelArgument("Required. The specific contract, GCZ8 or ZNU8-ZNZ8, etc")] string contract,
|
||||
[ExcelArgument("Required. The symbol, GC or ZN, etc")] string symbol,
|
||||
[ExcelArgument("Optional. The type, Future or Spread, default = Future")] string security_type = null,
|
||||
[ExcelArgument("Optional. The exchange, default = GLBX")] string exchange = null)
|
||||
{
|
||||
|
||||
var param = new object[] { contract, symbol, security_type, exchange };
|
||||
return ObservableRtdUtil.Observe(nameof(spark_md_book), param,
|
||||
() => md_observable(contract, symbol, security_type, exchange).Select(data =>
|
||||
{
|
||||
var x = data.FirstOrDefault();
|
||||
if (x != null && x is IMDBook upd)
|
||||
return BookMDFormatter.format(upd);
|
||||
return x;
|
||||
}));
|
||||
// security_type = string.IsNullOrEmpty(security_type) ? SecurityType.Future.ToString() : security_type;
|
||||
// exchange = string.IsNullOrEmpty(exchange) ? Security.ExchangeDataOneofCase.Glbx.ToString() : exchange;
|
||||
// symbol = string.IsNullOrEmpty(symbol) ? contract.Substring(0, 2) : symbol;
|
||||
// string[] topic = new[] { MDTopic.topic_type, MDTopic.book_request_type,
|
||||
// contract, symbol, security_type, exchange};
|
||||
// object val = XlCall.RTD(typeof(RTDServer).FullName, null, topic);
|
||||
// return Subscribe.spark_unpack(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Subscribe to BTS Spark top of book market data")]
|
||||
public static object spark_md_top_of_book(
|
||||
[ExcelArgument("Required. The specific contract, GCZ8 or ZNU8-ZNZ8, etc")] string contract,
|
||||
[ExcelArgument("Required. The symbol, GC or ZN, etc")] string symbol,
|
||||
[ExcelArgument("Optional. The type, Future or Spread, default = Future")] string security_type = null,
|
||||
[ExcelArgument("Optional. The exchange, default = GLBX")] string exchange = null)
|
||||
{
|
||||
var param = new object[] { contract, symbol, security_type, exchange };
|
||||
return ObservableRtdUtil.Observe(nameof(spark_md_top_of_book), param,
|
||||
() => md_observable(contract, symbol, security_type, exchange).Select(data =>
|
||||
{
|
||||
var x = data.FirstOrDefault();
|
||||
if (x != null && x is IMDBook upd)
|
||||
return TopOfBookMDFormatter.format(upd);
|
||||
return x;
|
||||
}));
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Subscribe to BTS Spark last trade market data")]
|
||||
public static object spark_md_last(
|
||||
[ExcelArgument("Required. The specific contract, GCZ8 or ZNU8-ZNZ8, etc")] string contract,
|
||||
[ExcelArgument("Required. The symbol, GC or ZN, etc")] string symbol,
|
||||
[ExcelArgument("Optional. The type, Future or Spread, default = Future")] string security_type = null,
|
||||
[ExcelArgument("Optional. The exchange, default = GLBX")] string exchange = null)
|
||||
{
|
||||
var param = new object[] { contract, symbol, security_type, exchange };
|
||||
return ObservableRtdUtil.Observe(nameof(spark_md_last), param,
|
||||
() => md_observable(contract, symbol, security_type, exchange).Select(data =>
|
||||
{
|
||||
var x = data.FirstOrDefault();
|
||||
if (x != null && x is IMDLast upd)
|
||||
return LastMDFormatter.format(upd);
|
||||
return x;
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Subscribe to BTS Spark miscellaneous market data")]
|
||||
public static object spark_md_misc(
|
||||
[ExcelArgument("Required. The specific contract, GCZ8 or ZNU8-ZNZ8, etc")] string contract,
|
||||
[ExcelArgument("Required. The symbol, GC or ZN, etc")] string symbol,
|
||||
[ExcelArgument("Optional. The type, Future or Spread, default = Future")] string security_type = null,
|
||||
[ExcelArgument("Optional. The exchange, default = GLBX")] string exchange = null)
|
||||
{
|
||||
var param = new object[] { contract, symbol, security_type, exchange };
|
||||
return ObservableRtdUtil.Observe(nameof(spark_md_misc), param,
|
||||
() => md_observable(contract, symbol, security_type, exchange).Select(data =>
|
||||
{
|
||||
var x = data.FirstOrDefault();
|
||||
if (x != null && x is IMDMisc upd)
|
||||
return MiscMDFormatter.format(upd);
|
||||
return x;
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Subscribe to BTS Spark topic based market data")]
|
||||
public static object spark_md(
|
||||
[ExcelArgument("Required. The 'Topic' string, 'bid', 'ask', etc")] string topic,
|
||||
[ExcelArgument("Required. The specific contract, GCZ8 or ZNU8-ZNZ8, etc")] string contract,
|
||||
[ExcelArgument("Required. The symbol, GC or ZN, etc")] string symbol,
|
||||
[ExcelArgument("Optional. The type, Future or Spread, default = Future")] string security_type = null,
|
||||
[ExcelArgument("Optional. The exchange, default = GLBX")] string exchange = null)
|
||||
{
|
||||
var param = new object[] { topic, contract, symbol, security_type, exchange };
|
||||
return ObservableRtdUtil.Observe(nameof(spark_md), param,
|
||||
() => md_observable(contract, symbol, security_type, exchange).Select(data =>
|
||||
{
|
||||
var x = data.FirstOrDefault();
|
||||
if (x != null && x is IMDCombined upd)
|
||||
return TopicMDFormatter.format(upd, topic);
|
||||
return x;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using ExcelDna.Integration;
|
||||
using ExcelDna.Integration.Rtd;
|
||||
using ExcelDna.Registration;
|
||||
using ExcelDna.Registration.Utils;
|
||||
using System.Reactive.Linq;
|
||||
using bts.api;
|
||||
using bts.api.md;
|
||||
using bts.api.core;
|
||||
using bts.api.orderman;
|
||||
using bts.co2;
|
||||
|
||||
namespace bts.excel.rtd
|
||||
{
|
||||
public class Subscribe
|
||||
{
|
||||
[ExcelFunction(Category = "BTS", Description = "Subscribe to BTS Spark API Service")]
|
||||
public static object spark_api_subscribe(string service_type, string method_name, object parameters)
|
||||
{
|
||||
IList<string> topic = Utilities.get_tokens(parameters);
|
||||
topic.Insert(0, method_name);
|
||||
topic.Insert(0, service_type);
|
||||
object val = XlCall.RTD(typeof(APIRTDServer).FullName, null, topic.ToArray());
|
||||
return val;
|
||||
}
|
||||
|
||||
[ExcelFunction(Category = "BTS", Description = "Unpacks BTS Spark data from a GUID reference")]
|
||||
public static object spark_unpack(object reference)
|
||||
{
|
||||
object data;
|
||||
if(unpack(reference, out data))
|
||||
return data;
|
||||
else
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static bool unpack(object reference, out object data)
|
||||
{
|
||||
object tempdata; data = null;
|
||||
if (reference is string && APIRTDServer.retrieve(reference.ToString(), out tempdata))
|
||||
{
|
||||
if (tempdata is IExcelFormatter fdata)
|
||||
data = fdata.format();
|
||||
else
|
||||
data = DataParser.scatter_data(tempdata);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//[ExcelFunction]
|
||||
//public static object bts_subscribe_deprecated(string service_type, string request_type, object parameters)
|
||||
//{
|
||||
// IList<string> topic = Utilities.get_tokens(parameters);
|
||||
// topic.Insert(0, request_type);
|
||||
// topic.Insert(0, service_type);
|
||||
// object val = XlCall.RTD(typeof(APIRTDServer).FullName, null, topic.ToArray());
|
||||
|
||||
// if(val is string)
|
||||
// {
|
||||
// //I can't marshal just any old object through the excel machinery, so in order to retain a 'registration free'
|
||||
// //model, I have to pass this string-guid from the RTDServer, up through excel and back here.
|
||||
// object data;
|
||||
// if(APIRTDServer.retrieve(val.ToString(), out data))
|
||||
// {
|
||||
// object[,] ret = DataParser.scatter_data(data);
|
||||
// return ret;
|
||||
// }
|
||||
// }
|
||||
// return val;
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<DnaLibrary Name="spark_excel" RuntimeVersion="v4.0">
|
||||
<ExternalLibrary Path="spark_excel.dll" ExplicitExports="false" LoadFromBytes="true" Pack="true" />
|
||||
|
||||
<Reference Path="ExcelDna.IntelliSense.dll" Pack="true" />
|
||||
<Reference Path="ExcelDna.Registration.dll" Pack="true" />
|
||||
<Reference Path="ExcelDna.Integration.dll" Pack="true" />
|
||||
|
||||
<Reference Path="Google.Protobuf.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="System.Linq.Dynamic.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="Newtonsoft.Json.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="nunit.framework.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="System.Reactive.Core.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="System.Reactive.Interfaces.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="System.Reactive.Providers.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="System.Reactive.Linq.dll" Pack="true" ExplicitExports="true" />
|
||||
<Reference Path="System.Reactive.Runtime.Remoting.dll" Pack="true" ExplicitExports="true" />
|
||||
|
||||
<!--
|
||||
The RuntimeVersion attribute above allows two settings:
|
||||
* RuntimeVersion="v2.0" - for .NET 2.0, 3.0 and 3.5
|
||||
* RuntimeVersion="v4.0" - for .NET 4 and 4.5
|
||||
|
||||
Additional referenced assemblies can be specified by adding 'Reference' tags.
|
||||
These libraries will not be examined and registered with Excel as add-in libraries,
|
||||
but will be packed into the -packed.xll file and loaded at runtime as needed.
|
||||
For example:
|
||||
|
||||
<Reference Path="Another.Library.dll" Pack="true" />
|
||||
|
||||
Excel-DNA also allows the xml for ribbon UI extensions to be specified in the .dna file.
|
||||
See the main Excel-DNA site at http://excel-dna.net for downloads of the full distribution.
|
||||
-->
|
||||
|
||||
</DnaLibrary>
|
||||
@@ -1,83 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
|
||||
<TargetFrameworks>net471</TargetFrameworks>
|
||||
<OutputType>Library</OutputType>
|
||||
<!-- <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput> -->
|
||||
|
||||
<Authors>Blue Trading Systems</Authors>
|
||||
<Company>Blue Trading Systems</Company>
|
||||
<Product>Spark</Product>
|
||||
<Description />
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
<Version>$(major).$(minor).$(patch)</Version>
|
||||
<Version Condition="'$(version)'=='..'">1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
|
||||
<PackageReference Include="System.Reactive" Version="3.1.1" />
|
||||
<PackageReference Include="System.Reactive.PlatformServices" Version="3.1.1" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="System.Linq.Dynamic" Version="1.0.7" />
|
||||
|
||||
<PackageReference Include="ExcelDna.AddIn" Version="0.34.6" />
|
||||
<PackageReference Include="ExcelDna.Integration" Version="0.34.6" />
|
||||
<PackageReference Include="ExcelDna.IntelliSense" Version="1.1.0" />
|
||||
<PackageReference Include="ExcelDna.Registration" Version="0.34.7" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="spark_excel-AddIn.dna" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\ExcelDna.Build.props" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../spark_api/spark_api.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Proto3Excel Include="**/*.proto" />
|
||||
<Proto3Excel Include="../../lib/api/services/*.proto" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="spark_excel_example_2019.xlsm"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></None>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
|
||||
<ItemGroup>
|
||||
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
|
||||
<BuildOutputInPackage Include="$(OutputPath)..\net471\libspark.dll"/>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
-->
|
||||
|
||||
<!-- <Import Project="$(NuGetPackageRoot)\ExcelDna.AddIn\0.34.6\tools\ExcelDna.AddIn.targets" Condition="Exists('$(NuGetPackageRoot)\ExcelDna.AddIn\0.34.6\tools\ExcelDna.AddIn.targets')" /> -->
|
||||
<Import Project="$(NuGetPackageRoot)\ExcelDna.AddIn\0.34.6\tools\ExcelDna.AddIn.targets"/>
|
||||
<Target Name="EnsureExcelDnaTargetsImported" BeforeTargets="BeforeBuild" Condition="'$(ExcelDnaTargetsImported)' == ''">
|
||||
<Error Condition="!Exists('$(NuGetPackageRoot)\ExcelDna.AddIn\0.34.6\tools\ExcelDna.AddIn.targets') And ('$(RunExcelDnaBuild)' != '' And $(RunExcelDnaBuild))" Text="You are trying to build with ExcelDna, but the NuGet targets file that ExcelDna depends on is not available on this computer. This is probably because the ExcelDna package has not been committed to source control, or NuGet Package Restore is not enabled. Please enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
|
||||
<Error Condition="Exists('$(NuGetPackageRoot)\ExcelDna.AddIn\0.34.6\tools\ExcelDna.AddIn.targets') And ('$(RunExcelDnaBuild)' != '' And $(RunExcelDnaBuild))" Text="ExcelDna cannot be run because NuGet packages were restored prior to the build running, and the targets file was unavailable when the build started. Please build the project again to include these packages in the build. You may also need to make sure that your build server does not delete packages prior to each build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
|
||||
</Target>
|
||||
</Project>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,134 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ExcelDna.Integration;
|
||||
|
||||
using bts.api.core;
|
||||
using bts.excel.extensions;
|
||||
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.Reflection;
|
||||
|
||||
namespace bts.excel
|
||||
{
|
||||
public class APIDispatch
|
||||
{
|
||||
public static Lazy<ServiceContext> service_context = new Lazy<ServiceContext>(() => new ServiceContext(), true);
|
||||
static MethodInfo _locate_meth;
|
||||
readonly static Dictionary<object, object> _services = new Dictionary<object, object>();
|
||||
const string descriptor_property_name = "Descriptor";
|
||||
|
||||
static MethodInfo locate_method
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_locate_meth == null)
|
||||
{
|
||||
_locate_meth = service_context.Value.GetType().find_method((_) =>
|
||||
{
|
||||
return _.Name == nameof(ServiceContext.locate) && _.IsGenericMethod;
|
||||
})[0];
|
||||
}
|
||||
return _locate_meth;
|
||||
}
|
||||
}
|
||||
|
||||
static public object api_call_internal(Type service_type, string method_name, IMessage parameters)
|
||||
{
|
||||
object response = null;
|
||||
if (service_type != null && method_name != null)
|
||||
{
|
||||
object service = locate_service(service_type);
|
||||
response = invoke_service_call(service, method_name, parameters);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
//static public object invoke_service_call(object service, Type request_type, IMessage request)
|
||||
//{
|
||||
// var sub_method = service.GetType().GetMethods().Where(meth =>
|
||||
// {
|
||||
// var par = meth.GetParameters().FirstOrDefault();
|
||||
// return (par != null && par.ParameterType.IsAssignableFrom(request_type));
|
||||
// }).FirstOrDefault();
|
||||
// object subscription = null;
|
||||
// if(sub_method != null)
|
||||
// subscription = sub_method.Invoke(service, new[] { request });
|
||||
// return subscription;
|
||||
//}
|
||||
|
||||
static public object invoke_service_call(object service, string method_name, IMessage request)
|
||||
{
|
||||
var sub_method = service.GetType().GetMethod(method_name);
|
||||
object subscription = null;
|
||||
if (sub_method != null)
|
||||
subscription = sub_method.Invoke(service, new[] { request });
|
||||
return subscription;
|
||||
}
|
||||
|
||||
public static Type find_request_type(Type service_type, string method_name)
|
||||
{
|
||||
return service_type?.GetMethod(method_name)?.GetParameters().FirstOrDefault()?.ParameterType;
|
||||
}
|
||||
|
||||
static public IMessage generate_imessage(Type type, string json, bool null_for_empty = false)
|
||||
{
|
||||
IMessage request = null;
|
||||
var descproperty = type?.get_static_field_or_property(descriptor_property_name);
|
||||
if (descproperty != null)
|
||||
{
|
||||
MessageDescriptor desc = (MessageDescriptor)descproperty.get_value(null);
|
||||
if (null_for_empty)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(json) && json != "{ }" && json != "{}")
|
||||
request = JsonParser.Default.Parse(json, desc);
|
||||
else
|
||||
request = null; //TODO this is a workaround for Eric's bug that requires 'empty' requests to pass null instead
|
||||
}
|
||||
else
|
||||
{
|
||||
if(string.IsNullOrEmpty(json))
|
||||
json = "{}";
|
||||
request = JsonParser.Default.Parse(json, desc);
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
static public IMessage generate_request(Type service_type, string method_name, string request_json)
|
||||
{
|
||||
Type request_type = find_request_type(service_type, method_name);
|
||||
return generate_imessage(request_type, request_json, true);
|
||||
}
|
||||
|
||||
static public object locate_service(Type service_type)
|
||||
{
|
||||
//object svc = null;
|
||||
//if(service_type != null && !_services.TryGetValue(service_type, out svc))
|
||||
//{
|
||||
var method = locate_method?.MakeGenericMethod(service_type);
|
||||
object svc = method?.Invoke(service_context.Value, new object[] { null });
|
||||
if (svc != null)
|
||||
_services[svc] = null;
|
||||
return svc;
|
||||
}
|
||||
|
||||
|
||||
[ExcelFunction]
|
||||
static public object spark_api_call(string service_type, string method_name, object parameters)
|
||||
{
|
||||
Type svc = Utilities.find_full_type_in_all_assemblies(service_type, ".*api.*");
|
||||
|
||||
var tok = Utilities.get_tokens(parameters);
|
||||
string json = tok.FirstOrDefault();
|
||||
IMessage request = generate_request(svc, method_name, json);
|
||||
object resp = api_call_internal(svc, method_name, request);
|
||||
if (resp != null)
|
||||
return DataParser.scatter_data(resp);
|
||||
else
|
||||
return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using ExcelDna.Integration;
|
||||
using bts.api;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace bts.excel
|
||||
{
|
||||
public class Utilities
|
||||
{
|
||||
|
||||
[ExcelFunction]
|
||||
public static object bts_json_lookup(string json, string key1, string key2 = null, string key3 = null)
|
||||
{
|
||||
var jo = JObject.Parse(json);
|
||||
JToken val = json;
|
||||
if (!string.IsNullOrEmpty(key1) && !string.IsNullOrEmpty(key2) && !string.IsNullOrEmpty(key3))
|
||||
val = jo[key1][key2][key3];
|
||||
else if (!string.IsNullOrEmpty(key1) && !string.IsNullOrEmpty(key2))
|
||||
val = jo[key1][key2];
|
||||
else if (!string.IsNullOrEmpty(key1))
|
||||
val = jo[key1];
|
||||
return val.ToString();
|
||||
}
|
||||
|
||||
public static bool parse_venue(string exch, out Venue ven)
|
||||
{
|
||||
if (!Enum.TryParse(exch.ToUpper(), true, out ven))
|
||||
return Enum.TryParse("VENUE_" + exch.ToUpper(), true, out ven);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool parse_security_type(string sectype, out SecurityType st)
|
||||
{
|
||||
if (!Enum.TryParse(sectype.ToUpper(), true, out st))
|
||||
return Enum.TryParse("SECURITY_TYPE" + sectype.ToUpper(), true, out st);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static ConcurrentDictionary<string, Type> _types = new ConcurrentDictionary<string, Type>();
|
||||
public static Type find_full_type_in_all_assemblies(string type, string assembly_regex = null, Type assignable_from = null)
|
||||
{
|
||||
if (assignable_from == null)
|
||||
assignable_from = typeof(object);
|
||||
if (type == null)
|
||||
return null;
|
||||
Type res = null;
|
||||
if (!_types.TryGetValue(type, out res))
|
||||
{
|
||||
int idx = type.IndexOf("<");
|
||||
if (idx > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] zargs = type.Substring(idx + 1, type.Length - idx - 1).Replace(">", string.Empty).Split(',');
|
||||
string gtstring = type.Substring(0, idx) + "`" + zargs.Length.ToString();
|
||||
var gt = find_full_type_in_all_assemblies(gtstring, assembly_regex);
|
||||
Type[] args = new Type[zargs.Length];
|
||||
for (int i = 0; i < zargs.Length; i++)
|
||||
args[i] = find_full_type_in_all_assemblies(zargs[i], assembly_regex);
|
||||
res = gt.MakeGenericType(args);
|
||||
}
|
||||
catch (Exception) { /*TODO log?*/ }
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Type> alltypes = find_all_types_in_all_assemblies(type, assembly_regex);
|
||||
foreach (Type at in alltypes)
|
||||
{
|
||||
if (!assignable_from.IsAssignableFrom(at))
|
||||
continue;
|
||||
res = at;
|
||||
_types[type] = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static public List<Type> find_all_types_in_all_assemblies(string type, string assembly_regex = null)
|
||||
{
|
||||
List<Type> res = new List<Type>();
|
||||
var asses = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly a in asses)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(assembly_regex))
|
||||
{
|
||||
if (!Regex.Match(a.GetName().Name, assembly_regex).Success)
|
||||
continue;
|
||||
}
|
||||
Type t = a.GetType(type, false, true);
|
||||
if (t != null)
|
||||
res.Add(t);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static public T[,] transpose_keep_dimension<T>(T[,] array)
|
||||
{
|
||||
var res = new T[array.GetLength(1), array.GetLength(0)];
|
||||
for (int i = 0; i < array.GetLength(1); i++)
|
||||
for (int j = 0; j < array.GetLength(0); j++)
|
||||
res[i, j] = array[j, i];
|
||||
return res;
|
||||
}
|
||||
|
||||
static public T[,] transpose<T>(T[,] array)
|
||||
{
|
||||
var res = new T[array.Length, 1];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
res[i, 0] = array[0, i];
|
||||
return res;
|
||||
}
|
||||
|
||||
static public T[,] transpose<T>(T[] array)
|
||||
{
|
||||
var res = new T[array.Length, 1];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
res[i, 0] = array[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
static public object[,] transpose(Array array)
|
||||
{
|
||||
var res = new object[array.Length, 1];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
res[i, 0] = array.GetValue(i);
|
||||
return res;
|
||||
}
|
||||
|
||||
static public T[,] make_column_vector<T>(T[] row_array)
|
||||
{
|
||||
return transpose<T>(row_array);
|
||||
}
|
||||
|
||||
static public T[] make_row_vector<T>(T[,] col_array)
|
||||
{
|
||||
var res = new List<T>();
|
||||
for (int i = 0; i < col_array.GetLength(0); i++)
|
||||
{
|
||||
for (int j = 0; j < col_array.GetLength(1); j++)
|
||||
{
|
||||
res.Add(col_array[i, j]);
|
||||
}
|
||||
}
|
||||
return res.ToArray();
|
||||
}
|
||||
|
||||
|
||||
static public Array make_row_vector(Type type, object[,] col_array)
|
||||
{
|
||||
var res = Array.CreateInstance(type, col_array.Length);
|
||||
int len = col_array.GetLength(1);
|
||||
for (int i = 0; i < col_array.GetLength(0); i++)
|
||||
{
|
||||
for (int j = 0; j < len; j++)
|
||||
{
|
||||
var obj = col_array[i, j];
|
||||
if (type.IsAssignableFrom(obj.GetType()))
|
||||
res.SetValue(obj, i * len + j);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static public string bts_stringify_array_typed(object[,] data, string typename)
|
||||
{
|
||||
Type type = find_full_type_in_all_assemblies(typename);
|
||||
object array = DataParser.gather_data(type, data);
|
||||
|
||||
object ret;
|
||||
DataParser.write_data(out ret, array);
|
||||
return ret.ToString();
|
||||
}
|
||||
|
||||
static public string bts_stringify_array(object[] array)
|
||||
{
|
||||
object ret;
|
||||
DataParser.write_data(out ret, array);
|
||||
return ret.ToString();
|
||||
}
|
||||
|
||||
static public object[,] bts_read_stringified_array(object array, string typename)
|
||||
{
|
||||
Type type = find_full_type_in_all_assemblies(typename);
|
||||
object data = DataParser.read_data(type, array);
|
||||
object[,] ret = DataParser.scatter_data(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public object[,] bts_read_double_array(object array)
|
||||
{
|
||||
object data = DataParser.read_data(typeof(double[]), array);
|
||||
object[,] ret = DataParser.scatter_data(data, false);
|
||||
var t = transpose(ret);
|
||||
return t;
|
||||
}
|
||||
|
||||
static public object[,] bts_read_string_array(object array)
|
||||
{
|
||||
object data = DataParser.read_data(typeof(string[]), array);
|
||||
object[,] ret = DataParser.scatter_data(data, false);
|
||||
var t = transpose(ret);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static public T[,] combine_arrays_vertically<T>(IEnumerable<T[,]> arrays)
|
||||
{
|
||||
int rows = 0, cols = 0;
|
||||
foreach (var a in arrays)
|
||||
{
|
||||
if (a.GetLength(1) > cols)
|
||||
cols = a.GetLength(1);
|
||||
rows += a.GetLength(0);
|
||||
}
|
||||
T[,] result = new T[rows, cols]; int idx = 0;
|
||||
foreach (T[,] a in arrays)
|
||||
{
|
||||
for (int i = 0; i < a.GetLength(0); i++)
|
||||
{
|
||||
for (int j = 0; j < a.GetLength(1); j++)
|
||||
result[idx, j] = (T)a.GetValue(i, j);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static private Dictionary<string, System.Reflection.Assembly> _ass = new Dictionary<string, System.Reflection.Assembly>();
|
||||
[ExcelFunction(IsMacroType = true)]
|
||||
public static string bts_load_assembly(string assembly_path)
|
||||
{
|
||||
//XlCall.Excel(XlCall.xlfVolatile, false);
|
||||
System.Reflection.Assembly ass;
|
||||
if (!_ass.TryGetValue(assembly_path, out ass))
|
||||
{
|
||||
ass = System.Reflection.Assembly.Load(assembly_path);
|
||||
_ass[assembly_path] = ass;
|
||||
}
|
||||
return (ass == null) ? "ERROR: Couldn't load assembly " + assembly_path : "Assembly Loaded: " + assembly_path + " " + DateTime.Now.ToLongTimeString();
|
||||
}
|
||||
|
||||
static public IList<string> get_tokens(object tag)
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
if (tag is Array)
|
||||
{
|
||||
Array array = (Array)tag;
|
||||
if (array.Rank > 1)
|
||||
{
|
||||
for (int i = 0; i < array.GetLength(0); i++)
|
||||
{
|
||||
for (int j = 0; j < array.GetLength(1); j++)
|
||||
list.Add(array.GetValue(i, j).ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < array.Length; j++)
|
||||
list.Add(array.GetValue(j).ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
list.Add(tag.ToString());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.24.3" />
|
||||
<PackageReference Include="System.Reactive" Version="3.1.1" />
|
||||
<PackageReference Include="System.Reactive.PlatformServices" Version="3.1.1" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
@@ -47,54 +47,39 @@
|
||||
</PropertyGroup>
|
||||
-->
|
||||
<!-- $(SparkRoot) is something we define on our build at BTS, if it's empty, this project file is in the wild-->
|
||||
<ItemGroup Condition= " '$(SparkRoot)' != '' ">
|
||||
<ProjectReference Include="../spark_api/spark_api.csproj"/>
|
||||
<ItemGroup Condition=" '$(SparkRoot)' != '' ">
|
||||
<ProjectReference Include="../spark_api/spark_api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition= " '$(SparkRoot)' != '' and '$(TargetFramework)' == 'net471' ">
|
||||
<ItemGroup Condition=" '$(SparkRoot)' != '' and '$(TargetFramework)' == 'net471' ">
|
||||
<!-- This is so we can ship excel in the nupkg -->
|
||||
<ProjectReference Include="../spark_excel/spark_excel.csproj"/>
|
||||
<ProjectReference Include="../spark_excel/spark_excel.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition= " '$(SparkRoot)' != '' ">
|
||||
<None Include="README.md" pack="true" PackagePath="." />
|
||||
<None Include="$(OutputPath)\net471\spark_excel_example_2019.xlsm" pack="true" PackagePath=".\excel\spark_excel_example_2019.xlsm" />
|
||||
<None Include="$(OutputPath)\net471\spark_excel-addin64-packed.xll" pack="true" PackagePath=".\excel\spark_excel-addin64-packed.xll" />
|
||||
<None Include="$(OutputPath)\net471\spark_excel-addin64.dna" pack="true" PackagePath=".\excel\spark_excel-addin64.dna" />
|
||||
<None Include="doc/**" pack="true" PackagePath=".\doc\" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences" Condition= " '$(SparkRoot)' != '' ">
|
||||
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences" Condition=" '$(SparkRoot)' != '' ">
|
||||
<ItemGroup>
|
||||
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
|
||||
<BuildOutputInPackage Include="$(OutputPath)..\net471\libspark.dll"/>
|
||||
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
|
||||
<BuildOutputInPackage Include="$(OutputPath)..\net471\libspark.dll" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- deployed sdk build net471 -->
|
||||
<ItemGroup Condition= " '$(SparkRoot)' == '' and '$(TargetFramework)' == 'net471'">
|
||||
<ItemGroup Condition=" '$(SparkRoot)' == '' and '$(TargetFramework)' == 'net471'">
|
||||
<Reference Include="spark_api">
|
||||
<HintPath>..\..\lib\net471\spark_api.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- deployed sdk build netcoreapp2.1 -->
|
||||
<ItemGroup Condition= " '$(SparkRoot)' == '' and '$(TargetFramework)' == 'netcoreapp2.1'">
|
||||
<ItemGroup Condition=" '$(SparkRoot)' == '' and '$(TargetFramework)' == 'netcoreapp2.1'">
|
||||
<Reference Include="spark_api">
|
||||
<HintPath>..\..\lib\netcoreapp2.1\spark_api.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<Target Name="copy_lib_deployed" AfterTargets="PostBuildEvent" Condition= " '$(SparkRoot)' == '' " >
|
||||
<Target Name="copy_lib_deployed" AfterTargets="PostBuildEvent" Condition=" '$(SparkRoot)' == '' ">
|
||||
<Copy SourceFiles="..\..\lib\net471\libspark.dll" DestinationFolder="$(OutputPath)\" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
<Target Name="copy_lib_deployed471" AfterTargets="PostBuildEvent" Condition= " '$(SparkRoot)' == '' and '$(TargetFramework)' == 'net471'" >
|
||||
<Copy SourceFiles="..\..\lib\net471\spark_excel.dll" DestinationFolder="$(OutputPath)\" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="..\..\excel\spark_excel_example_2019.xlsm" DestinationFolder="$(OutputPath)\" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="..\..\excel\spark_excel-addin64-packed.xll" DestinationFolder="$(OutputPath)\" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="..\..\excel\spark_excel-addin64.dna" DestinationFolder="$(OutputPath)\" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -1 +0,0 @@
|
||||
set(sources files/audit_ilink3.py;files/audit_upload.sh;files/audit_uploader.py;files/cert_secure_logon.txt;files/example.conf;files/futures.coconut.xz;files/onixs_ice/ConnectivityConfiguration.APITest.xml;files/onixs_ice/ConnectivityConfiguration.APITest.xml.orig;files/onixs_ice/ConnectivityConfiguration.PerfTest.xml;files/onixs_ice/ConnectivityConfiguration.Production.xml;files/perf_trace/compiled.css;files/perf_trace/index.html;files/perf_trace/jquery-3.3.1.min.js;files/perf_trace/main.js;files/perf_trace/perf_log.sql;files/perf_trace/perf_trace_analysis.sql;files/perf_trace/plotly-latest.min.js)
|
||||
@@ -1 +0,0 @@
|
||||
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/service_helpers/AlgoServiceUtils.cpp;api/service_helpers/PositionUtilities.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/BasePositionService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.proto;api/services/MarginService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/MarketDataService.proto;api/services/MoneyFileService.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/keycode.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/position_cfg.conf;config/defaults/span.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/AlgoTypes.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/jetfix.proto;config/protos/keycode.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.proto;config/protos/position_cfg.proto;config/protos/quickbus_cfg.proto;config/protos/span.proto;config/protos/spreader.proto;config/protos/subprocess.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/sod.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;jetfix/codec/FIXArray.cpp;jetfix/common/OutFIX.cpp;jetfix/connection/AsyncReader.cpp;jetfix/connection/IConnection.cpp;jetfix/connection/SocketConnection.cpp;jetfix/gateway/CoreGateway.cpp;jetfix/gateway/JetFIXGateway.cpp;jetfix/gateway/Session.cpp;jetfix/store/FIXFileStore.cpp;jetfix/store/session_name.cpp;jetfix/tests/async_reader_tests.cpp;jetfix/tests/decoding_tests.cpp;jetfix/tests/fix_encoding_stream_tests.cpp;jetfix/tests/fix_fragment_tests.cpp;jetfix/tests/jetfix_performance_tests.cpp;jetfix/tests/sample_fix.cpp;jetfix/tests/store_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/Product.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityMapper.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/service/MarketDataServiceServer.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.cpp;md/test/synthetic_book_merge_tests.cpp;md/vendor/OnixsUtils.cpp;mercury/actors/IPollableActor.cpp;mercury/broker/Broker.cpp;mercury/broker/BrokerProxy.cpp;mercury/broker/ILocalBroker.cpp;mercury/broker/IRemoteBroker.cpp;mercury/common/mercury_common.cpp;mercury/events/TimerEvent.cpp;mercury/executor/Executor.cpp;mercury/topics/Topic.cLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/service_helpers/AlgoServiceUtils.cpp;api/service_helpers/PositionUtilities.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/BasePositionService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.proto;api/services/MarginService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/MarketDataService.proto;api/services/MoneyFileService.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/keycode.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/position_cfg.conf;config/defaults/span.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/AlgoTypes.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/jetfix.proto;config/protos/keycode.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.proto;config/protos/position_cfg.proto;config/protos/quickbus_cfg.proto;config/protos/span.proto;config/protos/spreader.proto;config/protos/subprocess.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/sod.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/Product.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityMapper.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/service/MarketDataServiceServer.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.cpp;md/test/synthetic_book_merge_tests.cpp;md/vendor/OnixsUtils.cpp;os/os.cpp;os/tests/os_tests.cpp;quickbus/core/LocalNode.cpp;quickbus/core/Quickbus.cpp;quickbus/core/SubscriptionID.cpp;quickbus/core/TableID.cpp;quickbus/message_model/Update.cpp;quickbus/message_model/merge_updates.cpp;quickbus/network/QBConnection.cpp;quickbus/network/QBConnectionManager.cpp;quickbus/network/endpoint_description.cpp;quickbus/network/quickbus_msgs.proto;quickbus/pubsub/TablePublisher.cpp;quickbus/pubsub/TableSubscriber.cpp;quickbus/pubsub/tests/qb_pubsub_tests.cpp;quickbus/routing/INode.cpp;quickbus/routing/NodeID.cpp;quickbus/routing/Router.cpp;quickbus/rpc/RPCClient.cpp;quickbus/rpc/RPCServer.cpp;quickbus/rpc/RPCSessionID.cpp;quickbus/rpc/rpc_utils.cpp;quickbus/rpc/tests/qb_rpc_tests.cpp;quickbus/tests/quickbus_tests.cpp;sparkproto/SparkProtos.proto;testing/catch_test_runner.cpp;utils/AuthSessioLine truncated
|
||||
+29
-5
@@ -4,6 +4,10 @@ set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
include(${CMAKE_SOURCE_DIR}/tools/safe_dep_glob.cmake)
|
||||
include(${CMAKE_SOURCE_DIR}/tools/Protobuf.cmake)
|
||||
|
||||
if (DEFINED DOTNET_BINARY_DIR OR DEFINED DOTNET_WINDOWS_BINARY_DIR)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/AddCopyBinariesTarget.cmake)
|
||||
endif()
|
||||
|
||||
# DEPENDENCIES
|
||||
file(GLOB_RECURSE Config_Protos RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} config/protos/*.proto)
|
||||
file (GLOB_RECURSE Service_Protos RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} api/services/*.proto)
|
||||
@@ -18,6 +22,7 @@ if (WIN32)
|
||||
domain_model/*.cpp
|
||||
expression/*.cpp
|
||||
logging/*.cpp
|
||||
io/*.cpp
|
||||
md/*.cpp
|
||||
os/*.cpp
|
||||
quickbus/*.cpp
|
||||
@@ -97,7 +102,8 @@ target_include_directories( libspark PUBLIC ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINA
|
||||
if (WIN32)
|
||||
target_link_libraries( libspark
|
||||
libcurl
|
||||
libfmt
|
||||
debug fmtd
|
||||
optimized fmt
|
||||
libtbb
|
||||
libboost_system
|
||||
libboost_thread
|
||||
@@ -107,7 +113,11 @@ if (WIN32)
|
||||
libboost_date_time
|
||||
libboost_atomic
|
||||
libprotobuf
|
||||
)
|
||||
libprotoc
|
||||
libssl
|
||||
libcrypto
|
||||
crypt32
|
||||
)
|
||||
else ()
|
||||
target_link_libraries( libspark
|
||||
protobuf
|
||||
@@ -135,11 +145,25 @@ else ()
|
||||
-ldl
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
-pthread)
|
||||
-pthread)
|
||||
|
||||
install(TARGETS libspark DESTINATION bin)
|
||||
endif()
|
||||
|
||||
# Copy binaries to Dotnet build dirs (for csprojs that depend on libspark)
|
||||
if (DEFINED DOTNET_BINARY_DIR)
|
||||
add_copy_binaries_target(
|
||||
copy_to_dotnet_binary_dir
|
||||
${DOTNET_BINARY_DIR}
|
||||
"Copy ${PROJECT_NAME} bins to Dotnet build dir")
|
||||
endif()
|
||||
if (DEFINED DOTNET_WINDOWS_BINARY_DIR)
|
||||
add_copy_binaries_target(
|
||||
copy_to_dotnet_windows_binary_dir
|
||||
${DOTNET_WINDOWS_BINARY_DIR}
|
||||
"Copy ${PROJECT_NAME} bins to Dotnet Windows build dir")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
include(${CMAKE_SOURCE_DIR}/tools/vs_filters.cmake)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "lib/config/protos/system.pb.h"
|
||||
#include "lib/config/protos/Ports.pb.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <excpt.h>
|
||||
#endif
|
||||
|
||||
@@ -60,8 +60,8 @@ CAPI Quickbus* api_create_quickbus(const char* qbconfig, long length) {
|
||||
return new Quickbus(temp_conf);
|
||||
}
|
||||
|
||||
CAPI void api_destroy_quickbus(Quickbus* qbus) {
|
||||
#ifndef WIN32
|
||||
CAPI void api_destroy_quickbus(Quickbus *qbus) {
|
||||
#ifndef _WIN32
|
||||
if (qbus != nullptr) {
|
||||
delete qbus;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ protected:
|
||||
ResponseHeader header;
|
||||
header.set_code(ApiError::SUCCESS);
|
||||
header.set_request_id(request_id);
|
||||
int header_size = header.ByteSize() + 1;
|
||||
int body_size = response.ByteSize();
|
||||
int header_size = header.ByteSizeLong() + 1;
|
||||
int body_size = response.ByteSizeLong();
|
||||
int total_size = header_size + body_size;
|
||||
if (total_size <= 1024) {
|
||||
uint8_t buffer[1024];
|
||||
|
||||
@@ -40,11 +40,11 @@ public:
|
||||
header.set_request_id(++_id);
|
||||
auto ptoken = _context.token();
|
||||
if (ptoken) header.mutable_token()->CopyFrom(*ptoken);
|
||||
int header_size = header.ByteSize()+1;
|
||||
int header_size = header.ByteSizeLong()+1;
|
||||
assert(header_size < 128);
|
||||
|
||||
std::string request_buffer;
|
||||
request_buffer.reserve(header_size + request.ByteSize());
|
||||
request_buffer.reserve(header_size + request.ByteSizeLong());
|
||||
request_buffer += (char)(header_size);
|
||||
bool success = header.AppendToString(&request_buffer);
|
||||
success = success && request.AppendToString(&request_buffer);
|
||||
@@ -77,8 +77,8 @@ public:
|
||||
|
||||
|
||||
template <typename T>
|
||||
rxcpp::observable<RawUpdate<std::shared_ptr<const T>>> subscribe(int method_id, const char* method, const std::string& qualifier) {
|
||||
return rxcpp::observable<>::create<RawUpdate<std::shared_ptr<const T>>>([=](rxcpp::subscriber<RawUpdate<std::shared_ptr<const T>>> observer) {
|
||||
rxcpp::observable<RawUpdate<std::shared_ptr<T>>> subscribe(int method_id, const char* method, const std::string& qualifier) {
|
||||
return rxcpp::observable<>::create<RawUpdate<std::shared_ptr<T>>>([=](rxcpp::subscriber<RawUpdate<std::shared_ptr<T>>> observer) {
|
||||
StreamAccessRequest request;
|
||||
request.set_qualifier(qualifier);
|
||||
send<StreamAccessRequest,StreamAccessResponse>(method_id, request, [=](const Result<StreamAccessResponse>& response) {
|
||||
@@ -95,11 +95,12 @@ public:
|
||||
bool first_update = true;
|
||||
auto cb = [observer, first_update, qualifier](EventType event_type, const StreamUpdate* changes, int change_count) mutable {
|
||||
if (event_type == EventType::TABLE_UPDATED) {
|
||||
std::vector<std::shared_ptr<const T>> added_items, changed_items;
|
||||
std::vector<std::shared_ptr<T>> added_items, changed_items;
|
||||
std::vector<int> added_keys,
|
||||
changed_keys,
|
||||
removed_keys;
|
||||
for (size_t x = 0; x < change_count; ++x) {
|
||||
for (std::size_t x = 0;
|
||||
x < static_cast<std::size_t>(change_count); ++x) {
|
||||
const StreamUpdate& change = changes[x];
|
||||
switch(change.type) {
|
||||
case StreamUpdate::REMOVE:
|
||||
@@ -115,11 +116,11 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
observer.on_next(RawUpdate<std::shared_ptr<const T>>(added_items, added_keys, changed_items, changed_keys, removed_keys));
|
||||
observer.on_next(RawUpdate<std::shared_ptr<T>>(added_items, added_keys, changed_items, changed_keys, removed_keys));
|
||||
}
|
||||
else if (event_type == EventType::TABLE_CREATED) {
|
||||
if (!first_update) {
|
||||
observer.on_next(RawUpdate<std::shared_ptr<const T>>::Reset());
|
||||
observer.on_next(RawUpdate<std::shared_ptr<T>>::Reset());
|
||||
}
|
||||
first_update = false;
|
||||
}
|
||||
|
||||
+101
-92
@@ -1,112 +1,121 @@
|
||||
#pragma once
|
||||
|
||||
#include "RawUpdate.h"
|
||||
#include <rxcpp/rx.hpp>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <rxcpp/rx.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace bts {
|
||||
namespace api {
|
||||
|
||||
template <typename T>
|
||||
class Change {
|
||||
T _old, _new;
|
||||
public:
|
||||
Change(const T& old_value, const T& new_value) : _old(old_value), _new(new_value) { }
|
||||
const T& previous() const { return _old; }
|
||||
const T& current() const { return _new; }
|
||||
};
|
||||
template <typename T> class Change {
|
||||
T _old, _new;
|
||||
|
||||
template <typename T, typename TKey, typename ServiceType>
|
||||
struct Update {
|
||||
Update(std::vector<T>& all, std::vector<T>& added, std::vector<Change<T>> changed, std::vector<T>& removed) :
|
||||
_all_items(std::move(all)),
|
||||
_added_items(std::move(added)),
|
||||
public:
|
||||
Change(const T &old_value, const T &new_value)
|
||||
: _old(old_value), _new(new_value) {}
|
||||
const T &previous() const { return _old; }
|
||||
const T ¤t() const { return _new; }
|
||||
};
|
||||
|
||||
template <typename T, typename TKey, typename ServiceType> struct Update {
|
||||
Update(
|
||||
std::vector<T> &all,
|
||||
std::vector<T> &added,
|
||||
std::vector<Change<T>> changed,
|
||||
std::vector<T> &removed)
|
||||
: _all_items(std::move(all)), _added_items(std::move(added)),
|
||||
_changed_items(std::move(changed)),
|
||||
_removed_items(std::move(removed))
|
||||
{}
|
||||
_removed_items(std::move(removed)) {}
|
||||
|
||||
Update(const Update& other) : _all_items(other._all_items),
|
||||
_added_items(other._added_items),
|
||||
_changed_items(other._changed_items),
|
||||
_removed_items(other._removed_items)
|
||||
{}
|
||||
|
||||
Update(Update&& other) :
|
||||
_all_items(std::move(other._all_items)),
|
||||
Update(const Update &other)
|
||||
: _all_items(other._all_items), _added_items(other._added_items),
|
||||
_changed_items(other._changed_items),
|
||||
_removed_items(other._removed_items) {}
|
||||
|
||||
Update(Update &&other)
|
||||
: _all_items(std::move(other._all_items)),
|
||||
_added_items(std::move(other._added_items)),
|
||||
_changed_items(std::move(other._changed_items)),
|
||||
_removed_items(std::move(other._removed_items))
|
||||
{}
|
||||
_removed_items(std::move(other._removed_items)) {}
|
||||
|
||||
TKey key(const T& t) const { return ServiceType::key(t); }
|
||||
const std::vector<T>& all() const { return _all_items; }
|
||||
const std::vector<T>& added() const { return _added_items; }
|
||||
const std::vector<Change<T>>& changed() const { return _changed_items; }
|
||||
const std::vector<T>& removed() const { return _removed_items; }
|
||||
TKey key(const T &t) const { return ServiceType::key(t); }
|
||||
const std::vector<T> &all() const { return _all_items; }
|
||||
const std::vector<T> &added() const { return _added_items; }
|
||||
const std::vector<Change<T>> &changed() const { return _changed_items; }
|
||||
const std::vector<T> &removed() const { return _removed_items; }
|
||||
|
||||
private:
|
||||
std::vector<T> _all_items;
|
||||
std::vector<T> _added_items;
|
||||
std::vector<Change<T>> _changed_items;
|
||||
std::vector<T> _removed_items;
|
||||
private:
|
||||
std::vector<T> _all_items;
|
||||
std::vector<T> _added_items;
|
||||
std::vector<Change<T>> _changed_items;
|
||||
std::vector<T> _removed_items;
|
||||
};
|
||||
|
||||
template <typename T, typename TKey, typename ServiceType>
|
||||
std::function<rxcpp::observable<Update<T, TKey, ServiceType>>(
|
||||
const rxcpp::observable<RawUpdate<T>> &)>
|
||||
reconstitute() {
|
||||
return [](const rxcpp::observable<RawUpdate<T>> &inputi) {
|
||||
auto *input_ptr = const_cast<rxcpp::observable<RawUpdate<T>>*>(&inputi);
|
||||
auto &input = *input_ptr;
|
||||
auto state = std::make_shared<std::unordered_map<int, T>>();
|
||||
return input.map([state](const RawUpdate<T> &craw) {
|
||||
auto *raw_ptr = const_cast<RawUpdate<T>*>(&craw);
|
||||
RawUpdate<T> &raw = *raw_ptr;
|
||||
if (raw.is_reset) {
|
||||
std::vector<T> removed;
|
||||
removed.reserve(state->size());
|
||||
for (auto &t : *state) {
|
||||
removed.push_back(std::move(t.second));
|
||||
}
|
||||
state->clear();
|
||||
std::vector<T> all, added;
|
||||
std::vector<Change<T>> changed;
|
||||
return Update<T, TKey, ServiceType>(all, added, changed, removed);
|
||||
} else {
|
||||
//
|
||||
// Remove
|
||||
std::vector<T> removed;
|
||||
removed.reserve(raw.removed_keys.size());
|
||||
for (int key : raw.removed_keys) {
|
||||
auto iter = state->find(key);
|
||||
if (iter != state->end()) {
|
||||
removed.push_back(iter->second);
|
||||
state->erase(iter);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Add
|
||||
for (size_t x = 0; x < raw.added_keys.size(); ++x) {
|
||||
(*state)[raw.added_keys[x]] = raw.added_items[x];
|
||||
}
|
||||
//
|
||||
// Change
|
||||
std::vector<Change<T>> changed;
|
||||
changed.reserve(raw.changed_keys.size());
|
||||
for (size_t x = 0; x < raw.changed_keys.size(); ++x) {
|
||||
changed.push_back(Change<T>{
|
||||
(*state)[raw.changed_keys[x]], raw.changed_items[x]});
|
||||
(*state)[raw.changed_keys[x]] = raw.changed_items[x];
|
||||
}
|
||||
//
|
||||
// All
|
||||
std::vector<T> all;
|
||||
all.reserve(state->size());
|
||||
for (const auto &item : *state) {
|
||||
all.push_back(item.second);
|
||||
}
|
||||
|
||||
return Update<T, TKey, ServiceType>(
|
||||
all, raw.added_items, changed, removed);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, typename TKey, typename ServiceType>
|
||||
std::function<rxcpp::observable<Update<T,TKey,ServiceType>>(const rxcpp::observable<RawUpdate<T>>&)> reconstitute() {
|
||||
return [](const rxcpp::observable<RawUpdate<T>>& input) {
|
||||
auto state = std::make_shared<std::unordered_map<int, T>>();
|
||||
return input.map([state](RawUpdate<T>& raw) {
|
||||
if (raw.is_reset) {
|
||||
std::vector<T> removed;
|
||||
removed.reserve(state->size());
|
||||
for (auto& t : *state) {
|
||||
removed.push_back(std::move(t.second));
|
||||
}
|
||||
state->clear();
|
||||
std::vector<T> all, added;
|
||||
std::vector<Change<T>> changed;
|
||||
return Update<T, TKey, ServiceType>(all, added, changed, removed);
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Remove
|
||||
std::vector<T> removed;
|
||||
removed.reserve(raw.removed_keys.size());
|
||||
for (int key : raw.removed_keys) {
|
||||
auto iter = state->find(key);
|
||||
if (iter != state->end()) {
|
||||
removed.push_back(iter->second);
|
||||
state->erase(iter);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Add
|
||||
for (size_t x = 0; x < raw.added_keys.size(); ++x) {
|
||||
(*state)[raw.added_keys[x]] = raw.added_items[x];
|
||||
}
|
||||
//
|
||||
// Change
|
||||
std::vector<Change<T>> changed;
|
||||
changed.reserve(raw.changed_keys.size());
|
||||
for (size_t x = 0; x < raw.changed_keys.size(); ++x) {
|
||||
changed.push_back(Change<T>{(*state)[raw.changed_keys[x]], raw.changed_items[x]});
|
||||
(*state)[raw.changed_keys[x]] = raw.changed_items[x];
|
||||
}
|
||||
//
|
||||
// All
|
||||
std::vector<T> all;
|
||||
all.reserve(state->size());
|
||||
for (const auto& item : *state) {
|
||||
all.push_back(item.second);
|
||||
}
|
||||
|
||||
return Update<T, TKey, ServiceType>(all, raw.added_items, changed, removed);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
} // namespace api
|
||||
} // namespace bts
|
||||
|
||||
|
||||
}}//namespace
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python
|
||||
import os, sys
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -30,8 +30,7 @@ import apioptions_pb2
|
||||
def loadTemplate(lang, name):
|
||||
path = os.path.join("templates", lang, name)
|
||||
text = open(path).read()
|
||||
utext = unicode(text, "utf-8")
|
||||
return compiler.compile(utext)
|
||||
return compiler.compile(text)
|
||||
|
||||
def option(options, key, default=None):
|
||||
if options.HasExtension(key):
|
||||
@@ -307,10 +306,9 @@ def generate_code(request, response):
|
||||
|
||||
#### MAIN #########
|
||||
if __name__ == "__main__":
|
||||
if DEBUG:
|
||||
data = open("data", mode='rb').read()
|
||||
else:
|
||||
data = sys.stdin.read()
|
||||
data_in = open(0, mode='rb')
|
||||
data = data_in.read()
|
||||
data_in.close()
|
||||
request = plugin.CodeGeneratorRequest()
|
||||
# open("data", 'wb').write(data)
|
||||
request.ParseFromString(data)
|
||||
@@ -319,8 +317,8 @@ if __name__ == "__main__":
|
||||
|
||||
if DEBUG:
|
||||
for f in response.file:
|
||||
print f.content
|
||||
print (f.content)
|
||||
else:
|
||||
output = response.SerializeToString()
|
||||
sys.stdout.write(output)
|
||||
sys.stdout.buffer.write(output)
|
||||
|
||||
@@ -19,12 +19,12 @@ using namespace rxcpp::operators;
|
||||
rxcpp::observable<{{cap name}}Update> {{../name}}::subscribe_{{name}}(std::string const&qualifier) {
|
||||
return
|
||||
_pchannel->subscribe<{{output_type_cpp}}>({{@index}}, "{{name}}", qualifier)
|
||||
| (bts::api::reconstitute<std::shared_ptr<const {{output_type_cpp}}>,const {{key_type.cpptype}}, {{../name}}>());
|
||||
| (bts::api::reconstitute<std::shared_ptr<{{output_type_cpp}}>,const {{key_type.cpptype}}, {{../name}}>());
|
||||
}
|
||||
rxcpp::observable<{{cap name}}Update> {{../name}}::subscribe_{{name}}() {
|
||||
return
|
||||
_pchannel->subscribe<{{output_type_cpp}}>({{@index}}, "{{name}}", "")
|
||||
| (bts::api::reconstitute<std::shared_ptr<const {{output_type_cpp}}>,const {{key_type.cpptype}}, {{../name}}>());
|
||||
| (bts::api::reconstitute<std::shared_ptr<{{output_type_cpp}}>,const {{key_type.cpptype}}, {{../name}}>());
|
||||
}
|
||||
|
||||
{{#if key_type.natural_key}}
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
#include "lib/api/public/Update.h"
|
||||
#include "lib/utils/bts_export.h"
|
||||
|
||||
#include <rxcpp/rx.hpp>
|
||||
#include <string>
|
||||
#include <google/protobuf/arena.h>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <rxcpp/rx.hpp>
|
||||
#include <string>
|
||||
|
||||
{{ns-open package}}
|
||||
|
||||
@@ -22,7 +23,7 @@ class {{name}};
|
||||
{{#each service}}
|
||||
{{#each method}}{{#if server_streaming}}
|
||||
class {{../name}};
|
||||
typedef bts::api::Update<std::shared_ptr<const {{output_type_cpp}}>, const {{key_type.cpptype}}, {{../name}}> {{cap name}}Update;
|
||||
typedef bts::api::Update<std::shared_ptr<{{output_type_cpp}}>, const {{key_type.cpptype}}, {{../name}}> {{cap name}}Update;
|
||||
{{/if}}{{/each}}
|
||||
|
||||
// {{comment}}
|
||||
|
||||
@@ -63,7 +63,7 @@ void Authenticated{{name}}Base::dispatch(const bts::api::RequestHeader& header,
|
||||
response.set_request_id(header.request_id());
|
||||
response.set_code(bts::api::ApiError::MISSING_METHOD);
|
||||
uint8_t buffer[64];
|
||||
int header_size = response.ByteSize() + 1;
|
||||
int header_size = response.ByteSizeLong() + 1;
|
||||
serialize(header_size, response, buffer);
|
||||
on_response(buffer, header_size);
|
||||
} break;
|
||||
@@ -128,7 +128,7 @@ void Authenticated{{name}}Base::dispatch(const bts::api::RequestHeader& header,
|
||||
{{else}}
|
||||
update.key = get_key({{name}}_key(item));
|
||||
{{/if}}
|
||||
update.buffer_len = item.ByteSize();
|
||||
update.buffer_len = item.ByteSizeLong();
|
||||
char* buffer = new char[update.buffer_len];
|
||||
item.SerializePartialToArray(buffer, update.buffer_len);
|
||||
update.buffer =buffer;
|
||||
@@ -143,7 +143,7 @@ void Authenticated{{name}}Base::dispatch(const bts::api::RequestHeader& header,
|
||||
{{else}}
|
||||
update.key = get_key({{name}}_key(item));
|
||||
{{/if}}
|
||||
update.buffer_len = item.ByteSize();
|
||||
update.buffer_len = item.ByteSizeLong();
|
||||
char* buffer = new char[update.buffer_len];
|
||||
item.SerializePartialToArray(buffer, update.buffer_len);
|
||||
update.buffer =buffer;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,11 @@
|
||||
function(add_copy_binaries_target tgt_name dest_dir)
|
||||
set(_output ${dest_dir}/${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
add_custom_command(
|
||||
OUTPUT ${_output}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E copy
|
||||
${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
${dest_dir}/${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
DEPENDS ${PROJECT_NAME})
|
||||
add_custom_target(${tgt_name} ALL DEPENDS ${_output} COMMENT ${ARGN})
|
||||
endfunction()
|
||||
@@ -29,7 +29,10 @@
|
||||
#define URDL_DISALE_SSL 1
|
||||
#include <urdl/url.hpp>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "lib/config_defaults.h"
|
||||
#include "lib/config_proto_files.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Winsock2.h>
|
||||
#include <d2d1.h>
|
||||
#else
|
||||
@@ -39,9 +42,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "lib/config_proto_files.h"
|
||||
#include "lib/config_defaults.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace bts {
|
||||
@@ -51,7 +51,6 @@ namespace internal {
|
||||
const char* MESSAGE_STRING_RULE = "rule";
|
||||
const char* MESSAGE_STRING_VALUE = "value";
|
||||
const char* MESSAGE_STRING_INCLUDE = "include";
|
||||
const char* MESSAGE_STRING_INCLUDE_BACKUP = "fallback";
|
||||
const char* MESSAGE_STRING_MACRO_TYPE = "MacroType";
|
||||
const char* MESSAGE_STRING_MACRO = "macro";
|
||||
|
||||
@@ -89,13 +88,10 @@ std::string get_command_argument(const char* key)
|
||||
if (boost::iequals(*begin, key))
|
||||
{
|
||||
begin++;
|
||||
if (begin == end) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
os::setenv(CONFIG_SERVER_ENV_VAR, begin->c_str());
|
||||
if (begin != end) {
|
||||
return *begin;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@@ -115,13 +111,19 @@ string ConfigurationState::settings_path()
|
||||
return os::sparkdata_path("conf");
|
||||
}
|
||||
|
||||
void ConfigurationState::initialize_defaults(IConfigLog& log)
|
||||
{
|
||||
void ConfigurationState::initialize_defaults(IConfigLog &log) {
|
||||
initialize_defaults(
|
||||
log,
|
||||
{std::string("lib/config/protos/"), std::string("lib/api/domain/")});
|
||||
}
|
||||
|
||||
void ConfigurationState::initialize_defaults(
|
||||
IConfigLog &log, const std::vector<std::string> &proto_dirs) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_initialization_mutex);
|
||||
if (_is_initialized) return;
|
||||
|
||||
generate_all_config_proto(log);
|
||||
|
||||
generate_all_config_proto(log, proto_dirs);
|
||||
|
||||
std::shared_ptr<proto::Message> new_message(_prototype->New());
|
||||
ErrorsOnlyLog elog(log);
|
||||
|
||||
@@ -349,14 +351,25 @@ void ConfigurationState::initialize_settings()
|
||||
initialize_defaults(log);
|
||||
|
||||
std::string settings = settings_path();
|
||||
std::string fallback = get_command_argument("-ConfigFallback");
|
||||
bts_assert_msg(!settings.empty(), "Failed to determine config path");
|
||||
os::setenv(CONFIG_SERVER_ENV_VAR, settings.c_str());
|
||||
|
||||
DEFER(// Do this even if load() fails
|
||||
initialize_builtins();
|
||||
initialize_macros();
|
||||
_deferred_queue->process();
|
||||
);
|
||||
load(settings, fallback, log);
|
||||
{
|
||||
DEFER( // Do this even if load() fails
|
||||
initialize_builtins(); initialize_macros();
|
||||
_deferred_queue->process(););
|
||||
load(settings, log);
|
||||
}
|
||||
|
||||
std::vector<std::string> descs;
|
||||
std::vector<std::shared_ptr<proto::Message>>::iterator iter;
|
||||
for (iter = _config_chain.begin(); iter != _config_chain.end(); ++iter) {
|
||||
const proto::Message &imsg = **iter;
|
||||
descs.push_back(imsg.DebugString());
|
||||
}
|
||||
std::string config_desc =
|
||||
fmt::to_string(fmt::join(descs, "\n***********************\n"));
|
||||
log.info(fmt::format("initialized config:\n{}", config_desc));
|
||||
}
|
||||
|
||||
void ConfigurationState::reset()
|
||||
@@ -375,41 +388,26 @@ void ConfigurationState::reset()
|
||||
_port = 80;
|
||||
}
|
||||
|
||||
int ConfigurationState::load(const std::string& url, const std::string& fallback_url, IConfigLog& log)
|
||||
{
|
||||
int ConfigurationState::load(const std::string &url, IConfigLog &log) {
|
||||
std::shared_ptr<proto::Message> new_message(_prototype->New());
|
||||
|
||||
bool loaded = false;
|
||||
try {
|
||||
loaded = load_message(url, *new_message.get(), log, *_deferred_queue.get());
|
||||
}
|
||||
catch(ServerUnreachableException&) {
|
||||
if (fallback_url.empty()) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
loaded = load_message(url, *new_message.get(), log, *_deferred_queue.get());
|
||||
|
||||
if (!loaded && !fallback_url.empty())
|
||||
{
|
||||
std::string message = "Failed to load: " + url + " using fallback.";
|
||||
log.warning(message);
|
||||
loaded = load_message(fallback_url, *new_message.get(), log, *_deferred_queue.get());
|
||||
if (_host.empty() || _host == "localhost") { tie(_host, _port) = hostname(fallback_url); }
|
||||
if (_host.empty() || _host == "localhost") {
|
||||
tie(_host, _port) = hostname(url);
|
||||
}
|
||||
if (_host.empty() || _host == "localhost") { tie(_host, _port) = hostname(url); }
|
||||
if (!loaded) return 0;
|
||||
|
||||
if (!loaded)
|
||||
return 0;
|
||||
|
||||
std::string include = get_include(*new_message.get());
|
||||
std::string fallback = get_fallback(*new_message.get());
|
||||
|
||||
// insert at front?
|
||||
_config_chain.push_back(new_message);
|
||||
|
||||
// Recursively load includes
|
||||
if (!include.empty())
|
||||
{
|
||||
return 1 + load(include, fallback, log);
|
||||
if (!include.empty()) {
|
||||
return 1 + load(include, log);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -426,14 +424,12 @@ int ConfigurationState::load_string(const std::string& values, bool print_errors
|
||||
parse_stream("test string", input_stream, *new_message.get(), log, *_deferred_queue.get());
|
||||
|
||||
std::string include = get_include(*new_message.get());
|
||||
std::string fallback = get_fallback(*new_message.get());
|
||||
|
||||
_config_chain.push_back(new_message);
|
||||
|
||||
int count = 0;
|
||||
if (!include.empty())
|
||||
{
|
||||
count += load(include, fallback, log);
|
||||
if (!include.empty()) {
|
||||
count += load(include, log);
|
||||
}
|
||||
|
||||
if (_host.empty()) {
|
||||
@@ -477,10 +473,11 @@ void ConfigurationState::add_metadata_field(proto::FileDescriptorProto* file_dp,
|
||||
}
|
||||
|
||||
// Construct a new Message that describes the save file format
|
||||
// This can then be used with google::protobuf::TextFormat to load and save files
|
||||
void ConfigurationState::generate_all_config_proto(IConfigLog& log)
|
||||
{
|
||||
const char* bts_config_classname = "__BTSConfig";
|
||||
// This can then be used with google::protobuf::TextFormat to load and save
|
||||
// files
|
||||
void ConfigurationState::generate_all_config_proto(
|
||||
IConfigLog &log, const std::vector<std::string> &proto_dirs) {
|
||||
const char *bts_config_classname = "__BTSConfig";
|
||||
int field_number = 0;
|
||||
|
||||
proto::FileDescriptorProto bts_config_dp;
|
||||
@@ -495,13 +492,6 @@ void ConfigurationState::generate_all_config_proto(IConfigLog& log)
|
||||
include_field->set_type(proto::FieldDescriptorProto_Type_TYPE_STRING);
|
||||
include_field->set_label(proto::FieldDescriptorProto_Label_LABEL_OPTIONAL);
|
||||
|
||||
// Add the 'fallback' field
|
||||
proto::FieldDescriptorProto* backup_field = config_message->add_field();
|
||||
backup_field->set_name(MESSAGE_STRING_INCLUDE_BACKUP);
|
||||
backup_field->set_number(++field_number);
|
||||
backup_field->set_type(proto::FieldDescriptorProto_Type_TYPE_STRING);
|
||||
backup_field->set_label(proto::FieldDescriptorProto_Label_LABEL_OPTIONAL);
|
||||
|
||||
// Add 'macro' message type
|
||||
proto::DescriptorProto* macro_message = bts_config_dp.add_message_type();
|
||||
macro_message->set_name(MESSAGE_STRING_MACRO_TYPE);
|
||||
@@ -526,23 +516,29 @@ void ConfigurationState::generate_all_config_proto(IConfigLog& log)
|
||||
|
||||
// add a meta type and field for each generated message
|
||||
proto::DescriptorPool::generated_pool();
|
||||
for (size_t x = 0; x < BTS_ARRAYSIZE(config_proto_files); x++)
|
||||
{
|
||||
std::string proto_path = "lib/config/protos/";
|
||||
proto_path += config_proto_files[x];
|
||||
const proto::FileDescriptor* file_desc = proto::DescriptorPool::generated_pool()->FindFileByName(proto_path);
|
||||
if (file_desc != nullptr)
|
||||
{
|
||||
|
||||
auto find_proto_file = [&proto_dirs](const std::string &name) -> const proto::FileDescriptor * {
|
||||
for (const auto &proto_dir : proto_dirs) {
|
||||
const auto * res = proto::DescriptorPool::generated_pool()->FindFileByName(
|
||||
proto_dir + name);
|
||||
if (res != nullptr) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
for (size_t x = 0; x < BTS_ARRAYSIZE(config_proto_files); x++) {
|
||||
const auto *file_desc = find_proto_file(config_proto_files[x]);
|
||||
if (file_desc != nullptr) {
|
||||
bts_config_dp.add_dependency(file_desc->name());
|
||||
for (int y=0; y < file_desc->message_type_count(); y++)
|
||||
{
|
||||
const proto::Descriptor* message_desc = file_desc->message_type(y);
|
||||
add_metadata_field(&bts_config_dp, config_message, message_desc, ++field_number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
// on linux the linker might throw away config protos that
|
||||
// are not used in sparkd. On windows we build a dll so that
|
||||
// should not happen
|
||||
@@ -903,10 +899,6 @@ std::string get_include(const proto::Message& message)
|
||||
return get_field(message, MESSAGE_STRING_INCLUDE);
|
||||
}
|
||||
|
||||
std::string get_fallback(const proto::Message& message)
|
||||
{
|
||||
return get_field(message, MESSAGE_STRING_INCLUDE_BACKUP);
|
||||
}
|
||||
|
||||
}}}//end namespaces
|
||||
|
||||
} // namespace internal
|
||||
} // namespace config
|
||||
} // namespace bts
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#ifndef CONFIGURATIONSTATE_H_
|
||||
#define CONFIGURATIONSTATE_H_
|
||||
|
||||
@@ -51,9 +52,10 @@ namespace internal {
|
||||
~ConfigurationState(void);
|
||||
|
||||
void initialize_defaults(IConfigLog& log);
|
||||
void initialize_defaults(IConfigLog &log, const std::vector<std::string> &proto_dirs);
|
||||
void initialize_settings();
|
||||
|
||||
int load(const std::string& url, const std::string& fallback, IConfigLog&);
|
||||
int load(const std::string& url, IConfigLog&);
|
||||
int load_string(const std::string& values, bool print_errors=false);
|
||||
void reset();
|
||||
|
||||
@@ -78,7 +80,7 @@ namespace internal {
|
||||
void initialize_macros();
|
||||
void add_macro(const proto::Message*);
|
||||
void add_metadata_field(proto::FileDescriptorProto* file_dp, proto::DescriptorProto* message_dp, const proto::Descriptor* base_field, int index);
|
||||
void generate_all_config_proto(IConfigLog&);
|
||||
void generate_all_config_proto(IConfigLog&, const std::vector<std::string> &proto_dirs);
|
||||
const proto::Message* try_get_value(const std::string& field_name, const proto::Message& message) const;
|
||||
|
||||
std::string settings_path();
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
# source: tools/cpp_helper/generate-cpps.ps1
|
||||
#
|
||||
|
||||
CppConfig
|
||||
{
|
||||
value
|
||||
CppConfig
|
||||
{
|
||||
value
|
||||
{
|
||||
cpp_entry { key: "0A" value: 100 }
|
||||
cpp_entry { key: "0B" value: 100 }
|
||||
@@ -357,6 +357,9 @@ CppConfig
|
||||
cpp_entry { key: "BR7" value: 1000 }
|
||||
cpp_entry { key: "BSF" value: 25 }
|
||||
cpp_entry { key: "BTC" value: 5 }
|
||||
cpp_entry { key: "ETH" value: 50 }
|
||||
cpp_entry { key: "MET" value: 0.1 }
|
||||
cpp_entry { key: "MBT" value: 0.1 }
|
||||
cpp_entry { key: "BTT" value: 50 }
|
||||
cpp_entry { key: "BUB" value: 1000 }
|
||||
cpp_entry { key: "BUC" value: 42000 }
|
||||
@@ -1457,12 +1460,12 @@ CppConfig
|
||||
cpp_entry { key: "ZT" value: 2000 }
|
||||
cpp_entry { key: "ZW" value: 50 }
|
||||
cpp_entry { key: "ZWT" value: 50 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CmeSymbolMics
|
||||
{
|
||||
value
|
||||
CmeSymbolMics
|
||||
{
|
||||
value
|
||||
{
|
||||
cme_mic { key: "0A" value: NYMEX }
|
||||
cme_mic { key: "0B" value: NYMEX }
|
||||
@@ -1814,6 +1817,9 @@ CmeSymbolMics
|
||||
cme_mic { key: "BR7" value: NYMEX }
|
||||
cme_mic { key: "BSF" value: CBT }
|
||||
cme_mic { key: "BTC" value: CME }
|
||||
cme_mic { key: "MET" value: CME }
|
||||
cme_mic { key: "ETH" value: CME }
|
||||
cme_mic { key: "MBT" value: CME }
|
||||
cme_mic { key: "BTT" value: CME }
|
||||
cme_mic { key: "BUB" value: CBT }
|
||||
cme_mic { key: "BUC" value: NYMEX }
|
||||
@@ -2914,5 +2920,5 @@ CmeSymbolMics
|
||||
cme_mic { key: "ZT" value: CBT }
|
||||
cme_mic { key: "ZW" value: CBT }
|
||||
cme_mic { key: "ZWT" value: CBT }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#nusers: 1
|
||||
#nusers: 100
|
||||
#allow concurrent : true
|
||||
#expires: 2021-Jan-01 00:00:00 637450560000000000
|
||||
#generation_time: 2020-Apr-03 18:39:31.010863 5248901378137496534
|
||||
#expires: 2022-Jun-01 00:00:00 637896384000000000
|
||||
#generation_time: 2021-Mar-25 15:21:51.824504 5249208843545632944
|
||||
EncryptedKeyCode {
|
||||
value {
|
||||
keycode: "BJBQWsbdTXWa/iLmOf3ekE8vP/NYkf0Q/nUsp/rJ78Ze3W9pNXICCMabmmsr1xOM7aqRIclPgZd955uSSfvFkdNWFTxwPQ5IfnDGopj3QdhUVxhzgVLaXHN+vC0H/MWrDQ5K4WY5J/6VXgUn1LSN/2HNb5iR2sKXeh3Alamg87YtCWEi+scelffE7HK5ERT/3A3Y/e0pqUFhP6xouIjHRhC2FRBb6OoJQVvFwVDADSuKZNo9B6GhC3H0YdHqjFhGDoky5ecgzeKIX8uWJEQNnQXQJ0iTgQ95+YR5IMU+XWdlVfSrc0fuTmj3YWcBQ8Kl2ItEcobyZzJYega3tu6Ftw=="
|
||||
keycode: "HdVz7cDRyofLl3vA8TPulaIHkquYzq24QTXThZccEpZkvk5mDF5dKkQa9fWG5JOWnswNZVfVct0bpHG99X3XHDTdhHyZy0xb+eEI4PS50vaHQGw3fHmFh/ku9EwLxMZZYCEnhelsg2LADjIG8ebqsgmVi6asHZo70nZCaIXzwu8KCjak/sD7K2EP5odhnRpPL4JdsSkgUAwmrr0V17pFxH1RmTS6pXYUvko3DTOIM8yudWabVlSrdmcsnCEzHN5WbZiMdPNEykhEdEtKM58TR9tVnk+JuDIU8uczEQsLK2tT1VVoleGLc5TM/p8jhWokkvr8WdbToIGaalhp72VG6g=="
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +85,10 @@ message JetFIX {
|
||||
optional uint32 max_order_msgs_per_window = 344 [default=166]; // At the CME 166 ~= 500 / 3
|
||||
optional uint32 window_duration_msecs = 345 [default=1000]; // leave it alone
|
||||
|
||||
optional uint32 max_connection_attempts = 346 [default=10];
|
||||
optional uint32 max_connection_attempts = 346 [default=1];
|
||||
optional bool auto_fix_seq_num = 347 [default=false];
|
||||
optional bool use_ilink3 = 348 [default=false] ;
|
||||
optional uint32 uuid_offset = 349 [default=0];
|
||||
}
|
||||
|
||||
repeated Connection connection = 10;
|
||||
|
||||
@@ -66,7 +66,10 @@ message CustomFormatIceSecurities{
|
||||
message IgnoreNansInDayPnL {
|
||||
optional bool enabled = 1 [default = true];
|
||||
}
|
||||
|
||||
message SendLimitOrderForPositionFlattener {
|
||||
optional bool enabled = 1 [default = true];
|
||||
optional uint32 quantity = 2 [default = 0];
|
||||
}
|
||||
message DynamicAlgos{
|
||||
optional bool enable_dorman = 1 [default = false];
|
||||
optional bool enable_pyramid = 2 [default = false];
|
||||
|
||||
@@ -9,33 +9,28 @@ namespace config {
|
||||
namespace internal {
|
||||
|
||||
HTTPServer::HTTPServer()
|
||||
: _io_service(),
|
||||
_acceptor(_io_service, tcp::endpoint(boost::asio::ip::address_v4::loopback(), 0)),
|
||||
_cur_socket(),
|
||||
_request_response_pairs(),
|
||||
_thread(),
|
||||
_done(false)
|
||||
{
|
||||
|
||||
}
|
||||
: _io_service(),
|
||||
_acceptor(
|
||||
_io_service,
|
||||
tcp::endpoint(boost::asio::ip::address_v4::loopback(), 0)),
|
||||
_cur_socket(), _request_response_pairs(), _thread(), _done(false) {}
|
||||
|
||||
unsigned int HTTPServer::port() const
|
||||
{
|
||||
unsigned int HTTPServer::port() const {
|
||||
return _acceptor.local_endpoint().port();
|
||||
}
|
||||
|
||||
void HTTPServer::add_response(const std::string& path, const std::string& response, const std::string& content)
|
||||
{
|
||||
void HTTPServer::add_response(
|
||||
const std::string &path,
|
||||
const std::string &response,
|
||||
const std::string &content) {
|
||||
_request_response_pairs[path] = response + content;
|
||||
}
|
||||
|
||||
void HTTPServer::start()
|
||||
{
|
||||
void HTTPServer::start() {
|
||||
_thread.reset(new boost::thread(boost::bind(&HTTPServer::worker, this)));
|
||||
}
|
||||
|
||||
void HTTPServer::stop()
|
||||
{
|
||||
void HTTPServer::stop() {
|
||||
_done = true;
|
||||
_io_service.stop();
|
||||
|
||||
@@ -45,55 +40,52 @@ void HTTPServer::stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HTTPServer::worker()
|
||||
{
|
||||
void HTTPServer::worker() {
|
||||
start_accept();
|
||||
|
||||
|
||||
_io_service.run();
|
||||
}
|
||||
|
||||
void HTTPServer::start_accept()
|
||||
{
|
||||
void HTTPServer::start_accept() {
|
||||
_cur_socket.reset(new boost::asio::ip::tcp::socket(_io_service));
|
||||
_acceptor.async_accept(*_cur_socket.get(), boost::bind(&HTTPServer::handle_accept, this, _cur_socket.get(), boost::asio::placeholders::error));
|
||||
_acceptor.async_accept(
|
||||
*_cur_socket.get(),
|
||||
boost::bind(
|
||||
&HTTPServer::handle_accept, this, _cur_socket.get(),
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void HTTPServer::handle_accept(boost::asio::ip::tcp::socket* socket, const boost::system::error_code& error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
void HTTPServer::handle_accept(
|
||||
boost::asio::ip::tcp::socket *socket,
|
||||
const boost::system::error_code &error) {
|
||||
if (!error) {
|
||||
handle_connect(socket);
|
||||
}
|
||||
start_accept();
|
||||
}
|
||||
|
||||
void HTTPServer::handle_connect(boost::asio::ip::tcp::socket* socket)
|
||||
{
|
||||
void HTTPServer::handle_connect(boost::asio::ip::tcp::socket *socket) {
|
||||
boost::asio::streambuf buffer;
|
||||
size_t size = boost::asio::read_until(*socket, buffer, "\r\n\r\n");
|
||||
std::string request(size, 0);
|
||||
buffer.sgetn(&request[0], size);
|
||||
|
||||
|
||||
size_t start = request.find("GET ") + 4;
|
||||
size_t end = request.find(" HTTP/1.1\r\n");
|
||||
size_t url_args = request.find("?");
|
||||
if (url_args != std::string::npos)
|
||||
end = std::min(end, url_args);
|
||||
std::string request_path = request.substr(start, end-start);
|
||||
std::string request_path = request.substr(start, end - start);
|
||||
|
||||
std::map<std::string, std::string>::iterator request_match =
|
||||
_request_response_pairs.find(request_path);
|
||||
|
||||
if (request_match == _request_response_pairs.end())
|
||||
{
|
||||
std::map<std::string, std::string>::iterator request_match =
|
||||
_request_response_pairs.find(request_path);
|
||||
|
||||
if (request_match == _request_response_pairs.end()) {
|
||||
std::string response = "HTTP/1.0 404 NOT FOUND\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n"
|
||||
"not found\r\n";
|
||||
boost::asio::write(*socket, boost::asio::buffer(response));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
boost::asio::write(*socket, boost::asio::buffer(request_match->second));
|
||||
}
|
||||
|
||||
@@ -102,4 +94,6 @@ void HTTPServer::handle_connect(boost::asio::ip::tcp::socket* socket)
|
||||
socket->close(ec);
|
||||
}
|
||||
|
||||
}}}
|
||||
} // namespace internal
|
||||
} // namespace config
|
||||
} // namespace bts
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <boost/asio/read_until.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
@@ -17,28 +18,31 @@
|
||||
#include <boost/asio/connect.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace bts {
|
||||
namespace config {
|
||||
namespace internal {
|
||||
|
||||
class HTTPServer
|
||||
{
|
||||
public:
|
||||
class HTTPServer {
|
||||
public:
|
||||
HTTPServer();
|
||||
unsigned int port() const;
|
||||
|
||||
void start();
|
||||
void add_response(const std::string& path, const std::string& response, const std::string& content);
|
||||
void add_response(
|
||||
const std::string &path,
|
||||
const std::string &response,
|
||||
const std::string &content);
|
||||
void stop();
|
||||
|
||||
private:
|
||||
private:
|
||||
void worker();
|
||||
void start_accept();
|
||||
void handle_accept(boost::asio::ip::tcp::socket*, const boost::system::error_code& error);
|
||||
void handle_connect(boost::asio::ip::tcp::socket*);
|
||||
void handle_accept(
|
||||
boost::asio::ip::tcp::socket *, const boost::system::error_code &error);
|
||||
void handle_connect(boost::asio::ip::tcp::socket *);
|
||||
|
||||
boost::asio::io_service _io_service;
|
||||
boost::asio::ip::tcp::acceptor _acceptor;
|
||||
@@ -46,8 +50,9 @@ private:
|
||||
std::map<std::string, std::string> _request_response_pairs;
|
||||
boost::scoped_ptr<boost::thread> _thread;
|
||||
bool _done;
|
||||
|
||||
};
|
||||
|
||||
}}} // end namespace
|
||||
} // namespace internal
|
||||
} // namespace config
|
||||
} // namespace bts
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,8 +1,8 @@
|
||||
#include "lib/utils/TempFile.h"
|
||||
|
||||
#include "../config.h"
|
||||
#include "../ConfigurationState.h"
|
||||
#include "../ConfigurationException.h"
|
||||
#include "../ConfigurationState.h"
|
||||
#include "../config.h"
|
||||
#include "lib/expression/ParserExceptions.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/is_unittest_environment.h"
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
#define URDL_HEADER_ONLY 1
|
||||
#define URDL_DISALE_SSL 1
|
||||
#include <urdl/url.hpp>
|
||||
#include <urdl/test/http_server.hpp>
|
||||
#include <catch/catch.hpp>
|
||||
#include <urdl/test/http_server.hpp>
|
||||
#include <urdl/url.hpp>
|
||||
|
||||
using namespace bts::config;
|
||||
using namespace bts::config::internal;
|
||||
@@ -31,124 +31,107 @@ using bts::config::test::Foo;
|
||||
using bts::config::test::FooGroup;
|
||||
using bts::config::test::StringTable;
|
||||
|
||||
|
||||
|
||||
namespace bts {
|
||||
int config_tests = 0;
|
||||
|
||||
TEST_CASE("Configuration Tests","[config]") {
|
||||
TEST_CASE("Configuration Tests", "[config]") {
|
||||
|
||||
bts::utils::internal::force_unittest_environment();
|
||||
|
||||
SECTION("basic_get_value_test")
|
||||
{
|
||||
initialize_for_test(
|
||||
"Foo { \n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" name: \"Name A\"\n"
|
||||
" id: 65\n"
|
||||
" email: \"test@example.com\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
SECTION("basic_get_value_test") {
|
||||
initialize_for_test("Foo { \n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" name: \"Name A\"\n"
|
||||
" id: 65\n"
|
||||
" email: \"test@example.com\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
const Foo& foo = get<Foo>();
|
||||
const Foo &foo = get<Foo>();
|
||||
|
||||
REQUIRE(foo.name() == "Name A");
|
||||
REQUIRE(foo.id() == 65);
|
||||
REQUIRE(foo.email().Get(0) == "test@example.com");
|
||||
}
|
||||
|
||||
SECTION("default_value_test")
|
||||
{
|
||||
SECTION("default_value_test") {
|
||||
initialize_for_test(""); // Only loads defaults.conf
|
||||
|
||||
// Should load a Foo from testkeys.conf
|
||||
const Foo& foo = get<Foo>();
|
||||
const Foo &foo = get<Foo>();
|
||||
REQUIRE(foo.name() == "Blue Foo"); // from testkeys.proto
|
||||
REQUIRE(foo.id() == 1234); // from testkeys.proto
|
||||
REQUIRE(foo.id() == 1234); // from testkeys.proto
|
||||
REQUIRE(foo.email().size() > 0);
|
||||
REQUIRE(foo.email().Get(0) == "default@example.com"); // from testkeys.conf
|
||||
REQUIRE(
|
||||
foo.email().Get(0) == "default@example.com"); // from testkeys.conf
|
||||
}
|
||||
|
||||
SECTION("default_include_test")
|
||||
{
|
||||
SECTION("default_include_test") {
|
||||
// test defaults.conf with an include
|
||||
}
|
||||
|
||||
SECTION("invalid_key_type_test")
|
||||
{
|
||||
SECTION("invalid_key_type_test") {
|
||||
// Load an initialize with no files - OK all values default
|
||||
|
||||
const Foo& foo = get<Foo>(); // OK
|
||||
const Foo &foo = get<Foo>(); // OK
|
||||
REQUIRE(foo.name() == "Blue Foo");
|
||||
|
||||
bool error = false;
|
||||
try
|
||||
{
|
||||
try {
|
||||
get<config::test::InvalidMessageType>(); // BAD
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
} catch (...) {
|
||||
error = true;
|
||||
}
|
||||
REQUIRE(error == true);
|
||||
}
|
||||
|
||||
SECTION("invalid_config_test2")
|
||||
{
|
||||
SECTION("invalid_config_test2") {
|
||||
utils::TempFile config_b;
|
||||
|
||||
*config_b.out() <<
|
||||
"Foo {\n"
|
||||
" value { \n"
|
||||
" name: \"bob\"\n"
|
||||
" id: 7319 \n"
|
||||
" }";
|
||||
*config_b.out() << "Foo {\n"
|
||||
" value { \n"
|
||||
" name: \"bob\"\n"
|
||||
" id: 7319 \n"
|
||||
" }";
|
||||
|
||||
bool error = false;
|
||||
try
|
||||
{
|
||||
try {
|
||||
initialize_for_test("include: \"" + config_b.path() + "\"", false);
|
||||
}
|
||||
catch(const ConfigurationException& err)
|
||||
{
|
||||
} catch (const ConfigurationException &err) {
|
||||
std::string what = err.what();
|
||||
bts_assert(what.find("Expected identifier.") != std::string::npos);
|
||||
error = true;
|
||||
}
|
||||
REQUIRE(error == true);
|
||||
|
||||
}
|
||||
|
||||
// Tests that we can load using a File:/// url
|
||||
// Tests complex value load
|
||||
SECTION("file_url_test")
|
||||
{
|
||||
SECTION("file_url_test") {
|
||||
utils::TempFile config_a;
|
||||
utils::TempFile config_b;
|
||||
|
||||
*config_a.out() << "include: \"" << config_b.path() << "\"" << std::endl <<
|
||||
"Foo { \n"
|
||||
" rule: \"false\"\n"
|
||||
" value {\n"
|
||||
" name: \"Name A\"\n"
|
||||
" id: 65\n"
|
||||
" email: \"A@bluecg.com\"\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
*config_a.out() << "include: \"" << config_b.path() << "\"" << std::endl
|
||||
<< "Foo { \n"
|
||||
" rule: \"false\"\n"
|
||||
" value {\n"
|
||||
" name: \"Name A\"\n"
|
||||
" id: 65\n"
|
||||
" email: \"A@bluecg.com\"\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
*config_b.out() <<
|
||||
"Foo {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" name: \"Name B\"\n"
|
||||
" id: 66 "
|
||||
" email: \"A@bluecg.com\" \n"
|
||||
" }}";
|
||||
*config_b.out() << "Foo {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" name: \"Name B\"\n"
|
||||
" id: 66 "
|
||||
" email: \"A@bluecg.com\" \n"
|
||||
" }}";
|
||||
|
||||
|
||||
// Get key Foo without loading any config files - this will show the default value
|
||||
// Get key Foo without loading any config files - this will show the
|
||||
// default value
|
||||
Foo foo = bts::config::get<Foo>();
|
||||
|
||||
REQUIRE(foo.name() == "Blue Foo");
|
||||
@@ -163,23 +146,20 @@ TEST_CASE("Configuration Tests","[config]") {
|
||||
REQUIRE(foo.id() == 66);
|
||||
}
|
||||
|
||||
SECTION("http_test")
|
||||
{
|
||||
SECTION("http_test") {
|
||||
HTTPServer server;
|
||||
std::string port = boost::lexical_cast<std::string>(server.port());
|
||||
std::string path = "/spark.conf";
|
||||
std::string response =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n";
|
||||
std::string content =
|
||||
"FooGroup {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" group: \"http_group\"\n"
|
||||
" foo {\n"
|
||||
" name: \"http\"\n"
|
||||
" id: 80\n"
|
||||
"}}}\n";
|
||||
std::string response = "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n";
|
||||
std::string content = "FooGroup {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" group: \"http_group\"\n"
|
||||
" foo {\n"
|
||||
" name: \"http\"\n"
|
||||
" id: 80\n"
|
||||
"}}}\n";
|
||||
|
||||
server.add_response(path, response, content);
|
||||
server.start();
|
||||
@@ -190,7 +170,7 @@ TEST_CASE("Configuration Tests","[config]") {
|
||||
|
||||
server.stop();
|
||||
|
||||
const FooGroup& foogrp = get<FooGroup>();
|
||||
const FooGroup &foogrp = get<FooGroup>();
|
||||
|
||||
REQUIRE(foogrp.group() == "http_group");
|
||||
REQUIRE(foogrp.foo().name() == "http");
|
||||
@@ -198,41 +178,41 @@ TEST_CASE("Configuration Tests","[config]") {
|
||||
REQUIRE(get<System>().config_host() == "127.0.0.1");
|
||||
}
|
||||
|
||||
SECTION("http_folder_test")
|
||||
{
|
||||
SECTION("http_folder_test") {
|
||||
HTTPServer server;
|
||||
std::string port = boost::lexical_cast<std::string>(server.port());
|
||||
std::string config_url = "http://localhost:" + port + "/";
|
||||
std::string response =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n";
|
||||
std::string response = "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n";
|
||||
|
||||
server.add_response("/spark.conf", response, "include: \"" + config_url + "other/\"");
|
||||
server.add_response("/testkeys.conf", response,
|
||||
"FooGroup {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" group: \"http_group\"\n"
|
||||
" foo {\n"
|
||||
" name: \"http\"\n"
|
||||
" id: 80\n"
|
||||
"}}}\n");
|
||||
|
||||
server.add_response("/other/spark.conf", response,
|
||||
"Foo {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value: {\n"
|
||||
" name: \"included_value\"\n"
|
||||
" id: 4096\n"
|
||||
" }}\n");
|
||||
server.add_response(
|
||||
"/spark.conf", response, "include: \"" + config_url + "other/\"");
|
||||
server.add_response(
|
||||
"/testkeys.conf", response,
|
||||
"FooGroup {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value {\n"
|
||||
" group: \"http_group\"\n"
|
||||
" foo {\n"
|
||||
" name: \"http\"\n"
|
||||
" id: 80\n"
|
||||
"}}}\n");
|
||||
|
||||
server.add_response(
|
||||
"/other/spark.conf", response,
|
||||
"Foo {\n"
|
||||
" rule: \"true\"\n"
|
||||
" value: {\n"
|
||||
" name: \"included_value\"\n"
|
||||
" id: 4096\n"
|
||||
" }}\n");
|
||||
|
||||
server.start();
|
||||
initialize_for_test("include: \"" + config_url + "\"");
|
||||
|
||||
server.stop();
|
||||
|
||||
const FooGroup& foogrp = get<FooGroup>();
|
||||
const FooGroup &foogrp = get<FooGroup>();
|
||||
|
||||
REQUIRE(foogrp.group() == "http_group");
|
||||
REQUIRE(foogrp.foo().name() == "http");
|
||||
@@ -242,44 +222,39 @@ TEST_CASE("Configuration Tests","[config]") {
|
||||
REQUIRE(get<Foo>().id() == 4096);
|
||||
}
|
||||
|
||||
|
||||
SECTION("test_rules")
|
||||
{
|
||||
initialize_for_test(
|
||||
"StringTable {\n"
|
||||
" value { \n"
|
||||
" entries: [\"foo\", \"bar\", \"baz\"] \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"RuleRef { \n"
|
||||
" # use this rule of StringTable has a cow \n"
|
||||
" rule: \"'cow' in StringTable.entries\" \n"
|
||||
" value { \n"
|
||||
" a_string: \"AAA\"\n"
|
||||
" a_int: -1\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"RuleRef { \n"
|
||||
" rule: \"'baz' in StringTable.entries\" \n"
|
||||
" value { \n"
|
||||
" a_string: \"BBB\"\n"
|
||||
" a_int: 99\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.a_int == 789\"\n"
|
||||
" value {\n"
|
||||
" name: \"A\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.a_string == 'BBB'\"\n"
|
||||
" value {\n"
|
||||
" name: \"B\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
SECTION("test_rules") {
|
||||
initialize_for_test("StringTable {\n"
|
||||
" value { \n"
|
||||
" entries: [\"foo\", \"bar\", \"baz\"] \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"RuleRef { \n"
|
||||
" # use this rule of StringTable has a cow \n"
|
||||
" rule: \"'cow' in StringTable.entries\" \n"
|
||||
" value { \n"
|
||||
" a_string: \"AAA\"\n"
|
||||
" a_int: -1\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"RuleRef { \n"
|
||||
" rule: \"'baz' in StringTable.entries\" \n"
|
||||
" value { \n"
|
||||
" a_string: \"BBB\"\n"
|
||||
" a_int: 99\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.a_int == 789\"\n"
|
||||
" value {\n"
|
||||
" name: \"A\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.a_string == 'BBB'\"\n"
|
||||
" value {\n"
|
||||
" name: \"B\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
// What should happen:
|
||||
// Foo A
|
||||
@@ -297,286 +272,262 @@ TEST_CASE("Configuration Tests","[config]") {
|
||||
// success a_string == 'BBB'
|
||||
// return Foo B
|
||||
|
||||
const Foo& foo = get<Foo>();
|
||||
const Foo &foo = get<Foo>();
|
||||
REQUIRE(foo.name() == "B");
|
||||
}
|
||||
|
||||
SECTION("test_recursive_rules") {
|
||||
initialize_for_test("StringTable {\n"
|
||||
" rule: \"Foo.name == 'foo'\"\n"
|
||||
" value { \n"
|
||||
" entries: [\"foo\", \"bar\", \"baz\"] \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"RuleRef { \n"
|
||||
" rule: \"'foo' in StringTable.entries\" \n"
|
||||
" value { \n"
|
||||
" a_string: \"AAA\"\n"
|
||||
" a_int: -1\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.a_string == 'BBB'\"\n"
|
||||
" value {\n"
|
||||
" name: \"foo\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
|
||||
SECTION("test_recursive_rules")
|
||||
{
|
||||
initialize_for_test(
|
||||
"StringTable {\n"
|
||||
" rule: \"Foo.name == 'foo'\"\n"
|
||||
" value { \n"
|
||||
" entries: [\"foo\", \"bar\", \"baz\"] \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"RuleRef { \n"
|
||||
" rule: \"'foo' in StringTable.entries\" \n"
|
||||
" value { \n"
|
||||
" a_string: \"AAA\"\n"
|
||||
" a_int: -1\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.a_string == 'BBB'\"\n"
|
||||
" value {\n"
|
||||
" name: \"foo\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
// Foo cannot be queried because RuleRef's rule requests StringTable which requests RuleRef
|
||||
// Foo cannot be queried because RuleRef's rule requests StringTable which
|
||||
// requests RuleRef
|
||||
bool error = false;
|
||||
try
|
||||
{
|
||||
try {
|
||||
get<Foo>();
|
||||
}
|
||||
catch(const expression::RecursivePropertyGetException&)
|
||||
{
|
||||
} catch (const expression::RecursivePropertyGetException &) {
|
||||
error = true;
|
||||
}
|
||||
REQUIRE(error);
|
||||
}
|
||||
|
||||
SECTION("test_nested_properties")
|
||||
{
|
||||
initialize_for_test(
|
||||
"RuleRef { \n"
|
||||
" value { \n"
|
||||
" nested {\n"
|
||||
" list_int: [7,8,9] \n"
|
||||
" nested {\n"
|
||||
" a_string: 'ABC' \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.nested.nested.a_string == 'ABC' and 9 in RuleRef.nested.list_int\"\n"
|
||||
" value {\n"
|
||||
" name: \"foo\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
SECTION("test_nested_properties") {
|
||||
initialize_for_test("RuleRef { \n"
|
||||
" value { \n"
|
||||
" nested {\n"
|
||||
" list_int: [7,8,9] \n"
|
||||
" nested {\n"
|
||||
" a_string: 'ABC' \n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"Foo { \n"
|
||||
" rule: \"RuleRef.nested.nested.a_string == 'ABC' "
|
||||
"and 9 in RuleRef.nested.list_int\"\n"
|
||||
" value {\n"
|
||||
" name: \"foo\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
REQUIRE(get<Foo>().name() == "foo");
|
||||
}
|
||||
|
||||
SECTION("built_in_properties_test")
|
||||
{
|
||||
initialize_for_test(
|
||||
"Foo { \n"
|
||||
" rule: \"System.unittest_environment == true \"\n"
|
||||
" value {\n"
|
||||
" name: \"unit tests\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
SECTION("built_in_properties_test") {
|
||||
initialize_for_test("Foo { \n"
|
||||
" rule: \"System.unittest_environment == true \"\n"
|
||||
" value {\n"
|
||||
" name: \"unit tests\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
REQUIRE(get<Foo>().name() == "unit tests");
|
||||
}
|
||||
|
||||
SECTION("nonbreaking_space_test")
|
||||
{
|
||||
SECTION("nonbreaking_space_test") {
|
||||
bool parse_error = false;
|
||||
try
|
||||
{
|
||||
try {
|
||||
initialize_for_test(
|
||||
"Foo { "
|
||||
" value {\xA0\xA0 "
|
||||
" name: \"valid name\""
|
||||
" \xA0 }"
|
||||
"} ", false);
|
||||
}
|
||||
catch(const bts::config::ConfigurationException)
|
||||
{
|
||||
"Foo { "
|
||||
" value {\xA0\xA0 "
|
||||
" name: \"valid name\""
|
||||
" \xA0 }"
|
||||
"} ",
|
||||
false);
|
||||
} catch (const bts::config::ConfigurationException &) {
|
||||
parse_error = true;
|
||||
}
|
||||
REQUIRE(parse_error);
|
||||
}
|
||||
|
||||
SECTION("macro_bool_test")
|
||||
{
|
||||
initialize_for_test(
|
||||
"macro"
|
||||
"{"
|
||||
" name: \"bool\""
|
||||
" expression: \"'c' in ['a', 'b', 'c', 'd']\""
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" rule: \"$bool\""
|
||||
" value {"
|
||||
" name: 'good'"
|
||||
" }"
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" value {"
|
||||
" name: 'bad'"
|
||||
" }"
|
||||
"}"
|
||||
);
|
||||
SECTION("macro_bool_test") {
|
||||
initialize_for_test("macro"
|
||||
"{"
|
||||
" name: \"bool\""
|
||||
" expression: \"'c' in ['a', 'b', 'c', 'd']\""
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" rule: \"$bool\""
|
||||
" value {"
|
||||
" name: 'good'"
|
||||
" }"
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" value {"
|
||||
" name: 'bad'"
|
||||
" }"
|
||||
"}");
|
||||
|
||||
REQUIRE(config::get<Foo>().name() == "good");
|
||||
|
||||
}
|
||||
|
||||
SECTION("macro_list_test")
|
||||
{
|
||||
initialize_for_test(
|
||||
"macro"
|
||||
"{"
|
||||
" name: \"list\""
|
||||
" expression: \"['a', 'b', 'c', 'd']\""
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" rule: \"'a' in $list\""
|
||||
" value {"
|
||||
" name: 'good'"
|
||||
" }"
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" value {"
|
||||
" name: 'bad'"
|
||||
" }"
|
||||
"}"
|
||||
);
|
||||
SECTION("macro_list_test") {
|
||||
initialize_for_test("macro"
|
||||
"{"
|
||||
" name: \"list\""
|
||||
" expression: \"['a', 'b', 'c', 'd']\""
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" rule: \"'a' in $list\""
|
||||
" value {"
|
||||
" name: 'good'"
|
||||
" }"
|
||||
"}"
|
||||
""
|
||||
"Foo"
|
||||
"{"
|
||||
" value {"
|
||||
" name: 'bad'"
|
||||
" }"
|
||||
"}");
|
||||
|
||||
REQUIRE(config::get<Foo>().name() == "good");
|
||||
}
|
||||
|
||||
SECTION("fallback_test") {
|
||||
//HTTPServer main;
|
||||
// HTTPServer main;
|
||||
HTTPServer fallback;
|
||||
//std::string main_url = "http://localhost:" + boost::lexical_cast<std::string>(main.port()) + "/";
|
||||
// std::string main_url = "http://localhost:" +
|
||||
// boost::lexical_cast<std::string>(main.port()) + "/";
|
||||
std::string main_url = "http://does_not_exist:12345/";
|
||||
//main.stop();
|
||||
std::string fallback_url = "http://127.0.0.1:" + boost::lexical_cast<std::string>(fallback.port()) + "/";
|
||||
std::string response =
|
||||
"HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n";
|
||||
// main.stop();
|
||||
std::string fallback_url =
|
||||
"http://127.0.0.1:" +
|
||||
boost::lexical_cast<std::string>(fallback.port()) + "/";
|
||||
std::string response = "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n\r\n";
|
||||
|
||||
std::string content =
|
||||
"FooGroup {\n"
|
||||
" value {\n"
|
||||
" group: \"http_group\"\n"
|
||||
" foo {\n"
|
||||
" name: \"http\"\n"
|
||||
" id: 80\n"
|
||||
"}}}\n";
|
||||
std::string content = "FooGroup {\n"
|
||||
" value {\n"
|
||||
" group: \"http_group\"\n"
|
||||
" foo {\n"
|
||||
" name: \"http\"\n"
|
||||
" id: 80\n"
|
||||
"}}}\n";
|
||||
|
||||
fallback.add_response("/spark.conf", response, content);
|
||||
|
||||
|
||||
fallback.start();
|
||||
initialize_for_test(
|
||||
"include: '" + main_url + "'\n"
|
||||
"fallback: '" + fallback_url + "'\n",false
|
||||
);
|
||||
"include: '" + main_url +
|
||||
"'\n"
|
||||
"fallback: '" +
|
||||
fallback_url + "'\n",
|
||||
false);
|
||||
fallback.stop();
|
||||
|
||||
|
||||
REQUIRE(get<FooGroup>().foo().name() == "http");
|
||||
REQUIRE(get<FooGroup>().foo().id() == 80);
|
||||
|
||||
}
|
||||
|
||||
SECTION("macro_definition_order_test") {
|
||||
// The $is_crusible test
|
||||
// o2_cme_enabled depends on Foo which has a rule which depends on is_crucible.
|
||||
// Eager evaluation caused a bug which would cause loading o2_cme_enabled to set is_crucible false. Case 3993
|
||||
initialize_for_test(
|
||||
"Foo {"
|
||||
" rule: '$is_crucible'"
|
||||
" value { name: 'cme_1u7_cert' }"
|
||||
"}"
|
||||
""
|
||||
"Foo {"
|
||||
" value { name: '' }"
|
||||
"}"
|
||||
""
|
||||
"macro {"
|
||||
" name: 'o2_cme_enabled'"
|
||||
" expression: \"Foo.name != ''\" "
|
||||
"}"
|
||||
""
|
||||
"macro {"
|
||||
" name: 'is_crucible'"
|
||||
" expression: 'true'"
|
||||
"}"
|
||||
);
|
||||
// o2_cme_enabled depends on Foo which has a rule which depends on
|
||||
// is_crucible. Eager evaluation caused a bug which would cause loading
|
||||
// o2_cme_enabled to set is_crucible false. Case 3993
|
||||
initialize_for_test("Foo {"
|
||||
" rule: '$is_crucible'"
|
||||
" value { name: 'cme_1u7_cert' }"
|
||||
"}"
|
||||
""
|
||||
"Foo {"
|
||||
" value { name: '' }"
|
||||
"}"
|
||||
""
|
||||
"macro {"
|
||||
" name: 'o2_cme_enabled'"
|
||||
" expression: \"Foo.name != ''\" "
|
||||
"}"
|
||||
""
|
||||
"macro {"
|
||||
" name: 'is_crucible'"
|
||||
" expression: 'true'"
|
||||
"}");
|
||||
|
||||
REQUIRE(get<Foo>().name() == "cme_1u7_cert");
|
||||
}
|
||||
|
||||
SECTION("repeated_value_order_preserved") {
|
||||
initialize_for_test(
|
||||
"Foo {"
|
||||
" value { name: 'edge-eharding' id: 80 }"
|
||||
"}"
|
||||
"StringTable {"
|
||||
" value {"
|
||||
" entries: 'http://'"
|
||||
" entries: @Foo.name"
|
||||
" entries: ':'"
|
||||
" entries: @Foo.id"
|
||||
" entries: '/risk'"
|
||||
" }"
|
||||
"}");
|
||||
initialize_for_test("Foo {"
|
||||
" value { name: 'edge-eharding' id: 80 }"
|
||||
"}"
|
||||
"StringTable {"
|
||||
" value {"
|
||||
" entries: 'http://'"
|
||||
" entries: @Foo.name"
|
||||
" entries: ':'"
|
||||
" entries: @Foo.id"
|
||||
" entries: '/risk'"
|
||||
" }"
|
||||
"}");
|
||||
std::string result;
|
||||
for (const auto& part : get<StringTable>().entries()) {
|
||||
for (const auto &part : get<StringTable>().entries()) {
|
||||
result += part;
|
||||
}
|
||||
REQUIRE(result == "http://edge-eharding:80/risk");
|
||||
}
|
||||
|
||||
SECTION("string_concat_test") {
|
||||
initialize_for_test(
|
||||
"Ports {\n"
|
||||
" value { \n"
|
||||
" config_port: 80 \n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"RuleRef { \n"
|
||||
" value { \n"
|
||||
" a_string: \"localhost\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"macro{\n"
|
||||
" name: 'list'\n"
|
||||
" expression: \"['http://', RuleRef.a_string, ':', Ports.config_port, '/risk']\"\n"
|
||||
"}"
|
||||
"StringTable {\n"
|
||||
"value {\n"
|
||||
" entries: 'http://'\n"
|
||||
" entries: @RuleRef.a_string\n"
|
||||
" entries: ':'\n"
|
||||
" entries: @Ports.config_port\n"
|
||||
" entries: '/risk'\n"
|
||||
"}}\n"
|
||||
"Foo { \n"
|
||||
" value {\n"
|
||||
" name: $list\n"
|
||||
" url: @StringTable.entries \n"
|
||||
" }\n"
|
||||
"}"
|
||||
);
|
||||
initialize_for_test("Ports {\n"
|
||||
" value { \n"
|
||||
" config_port: 80 \n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"RuleRef { \n"
|
||||
" value { \n"
|
||||
" a_string: \"localhost\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"macro{\n"
|
||||
" name: 'list'\n"
|
||||
" expression: \"['http://', RuleRef.a_string, ':', "
|
||||
"Ports.config_port, '/risk']\"\n"
|
||||
"}"
|
||||
"StringTable {\n"
|
||||
"value {\n"
|
||||
" entries: 'http://'\n"
|
||||
" entries: @RuleRef.a_string\n"
|
||||
" entries: ':'\n"
|
||||
" entries: @Ports.config_port\n"
|
||||
" entries: '/risk'\n"
|
||||
"}}\n"
|
||||
"Foo { \n"
|
||||
" value {\n"
|
||||
" name: $list\n"
|
||||
" url: @StringTable.entries \n"
|
||||
" }\n"
|
||||
"}");
|
||||
|
||||
auto foo = config::get<Foo>();
|
||||
auto expected = "http://localhost:80/risk";
|
||||
REQUIRE(foo.name() == expected);
|
||||
REQUIRE(foo.url() == expected);
|
||||
}
|
||||
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace bts
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <bits/stdint-uintn.h>
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include "OutFIX.h"
|
||||
|
||||
namespace bts {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include "AsyncReader.h"
|
||||
|
||||
#include "IConnection.h"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include "IConnection.h"
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
namespace bts {
|
||||
namespace trace {struct CorID;}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include "JetFIXGateway.h"
|
||||
|
||||
namespace bts {
|
||||
|
||||
@@ -129,11 +129,14 @@ SessionName session_name (config::JetFIX::Connection const &session_cfg)
|
||||
|
||||
if (session_cfg.has_start_day ()) {
|
||||
bts_assert (session_cfg.has_end_day ());
|
||||
return session_name (now,
|
||||
parse_weekday (session_cfg.start_day ()),
|
||||
parse_time (session_cfg.start_time ()),
|
||||
parse_weekday (session_cfg.end_day ()),
|
||||
parse_time (session_cfg.end_time ()));
|
||||
auto sn =
|
||||
session_name (now,
|
||||
parse_weekday (session_cfg.start_day ()),
|
||||
parse_time (session_cfg.start_time ()),
|
||||
parse_weekday (session_cfg.end_day ()),
|
||||
parse_time (session_cfg.end_time ()));
|
||||
sn.as_uint64_t += session_cfg.uuid_offset();
|
||||
return sn;
|
||||
} else
|
||||
return session_name (now,
|
||||
parse_time (session_cfg.start_time ()),
|
||||
|
||||
@@ -6,20 +6,21 @@
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
namespace bts {
|
||||
namespace log {
|
||||
|
||||
struct Level {
|
||||
using Rep = uint8_t;
|
||||
constexpr static auto Max = std::numeric_limits<Rep>::max();
|
||||
constexpr static auto Max = (std::numeric_limits<Rep>::max)();
|
||||
Rep ordinal;
|
||||
bool operator<(const Level &rhs) const {return ordinal < rhs.ordinal;}
|
||||
};
|
||||
|
||||
struct Subsystem {
|
||||
using Rep = uint8_t;
|
||||
constexpr static auto Max = std::numeric_limits<Rep>::max();
|
||||
constexpr static auto Max = (std::numeric_limits<Rep>::max)();
|
||||
Rep ordinal;
|
||||
bool operator<(const Subsystem &rhs) const {return ordinal < rhs.ordinal;}
|
||||
};
|
||||
|
||||
@@ -35,8 +35,8 @@ struct LogRec {
|
||||
};
|
||||
GCC_DIAG_RESTORE()
|
||||
|
||||
#ifndef WIN32
|
||||
//static_assert(sizeof(LogRec) == 256, "LogRec should be 128 bytes");
|
||||
#ifndef _WIN32
|
||||
// static_assert(sizeof(LogRec) == 256, "LogRec should be 128 bytes");
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "LogRec.h"
|
||||
#include "lib/os/os.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <numeric>
|
||||
|
||||
@@ -14,7 +14,7 @@ std::string format_tuple(const char*msg_template, Tuple const &t,std::index_sequ
|
||||
try {
|
||||
return fmt::format(msg_template,std::get<Is>(t)...);
|
||||
}
|
||||
catch (fmt::FormatError const &e)
|
||||
catch (fmt::format_error const &e)
|
||||
{
|
||||
return fmt::format("Bad log message template: '{}' Error: '{}'",
|
||||
msg_template,e.what());
|
||||
|
||||
+51
-64
@@ -2,85 +2,77 @@
|
||||
|
||||
#include "lib/logging/logging.h"
|
||||
#include "lib/os/os.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/datetime.h"
|
||||
#include "lib/utils/file_utils.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <fmt/ostream.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace bts {
|
||||
namespace log {
|
||||
|
||||
|
||||
struct InitSysLog {
|
||||
InitSysLog() {
|
||||
#ifndef WIN32
|
||||
openlog("spark",0,LOG_USER);
|
||||
#ifndef _WIN32
|
||||
openlog("spark", 0, LOG_USER);
|
||||
#endif
|
||||
|
||||
}
|
||||
} init;
|
||||
} init;
|
||||
|
||||
|
||||
auto formatter(LoggingConfig const&cfg) {
|
||||
return [cfg] (LogMsg const&m) {
|
||||
auto formatter(LoggingConfig const &cfg) {
|
||||
return [cfg](LogMsg const &m) {
|
||||
auto iso_date = datetime::iso_date_time_string(datetime::local_now());
|
||||
iso_date[sizeof("YYYY-MM-DD")-1] = ' ';
|
||||
iso_date[sizeof("YYYY-MM-DD") - 1] = ' ';
|
||||
#ifdef _WIN32
|
||||
return fmt::format("{}|{}|{:<8}|{:<5}|{:<3}|{:<4}|{:<35}|{}|{} ",
|
||||
iso_date,
|
||||
m.ts,
|
||||
m.subsystem_name,
|
||||
m.level_name,
|
||||
m.tid,
|
||||
//m.thread_name,
|
||||
os::process_id(),
|
||||
fmt::format("{}:{}",boost::filesystem::path(m.file).filename().string() , m.line),
|
||||
cfg.deployment_type,
|
||||
m.msg);
|
||||
return fmt::format(
|
||||
"{}|{}|{:<8}|{:<5}|{:<3}|{:<4}|{:<35}|{}|{} ", iso_date, m.ts,
|
||||
m.subsystem_name, m.level_name, m.tid,
|
||||
// m.thread_name,
|
||||
os::process_id(),
|
||||
fmt::format("{}:{}",
|
||||
boost::filesystem::path(m.file).filename().string(),
|
||||
m.line),
|
||||
cfg.deployment_type, m.msg);
|
||||
#else
|
||||
return fmt::format("{}|{}|{:<8}|{:<5}|{:<3}|{:<16}|{:<4}|{:<35}|{}|{} ",
|
||||
iso_date,
|
||||
m.ts,
|
||||
m.subsystem_name,
|
||||
m.level_name,
|
||||
m.tid,
|
||||
m.thread_name,
|
||||
os::process_id(),
|
||||
fmt::format("{}:{}",boost::filesystem::path(m.file).filename().string() , m.line),
|
||||
cfg.deployment_type,
|
||||
m.msg);
|
||||
return fmt::format(
|
||||
"{}|{}|{:<8}|{:<5}|{:<3}|{:<16}|{:<4}|{:<35}|{}|{} ", iso_date, m.ts,
|
||||
m.subsystem_name, m.level_name, m.tid, m.thread_name,
|
||||
os::process_id(),
|
||||
fmt::format("{}:{}",
|
||||
boost::filesystem::path(m.file).filename().string(),
|
||||
m.line),
|
||||
cfg.deployment_type, m.msg);
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
Sink console_sink(LoggingConfig const&cfg) {
|
||||
Sink console_sink(LoggingConfig const &cfg) {
|
||||
auto f = formatter(cfg);
|
||||
return [f] (LogMsg const &m) {std::cout << f(m) << std::endl;};
|
||||
return [f](LogMsg const &m) { std::cout << f(m) << std::endl; };
|
||||
}
|
||||
|
||||
Sink syslog_sink(LoggingConfig const&cfg) {
|
||||
#ifdef WIN32
|
||||
Sink syslog_sink(LoggingConfig const &cfg) {
|
||||
#ifdef _WIN32
|
||||
return null_sink();
|
||||
#else
|
||||
auto f = formatter(cfg);
|
||||
return [f] (LogMsg const &m) {syslog (LOG_INFO | LOG_USER,"%s",f(m).c_str ());};
|
||||
return [f](LogMsg const &m) {
|
||||
syslog(LOG_INFO | LOG_USER, "%s", f(m).c_str());
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
std::ifstream::pos_type filesize(std::string const&filename)
|
||||
{
|
||||
if(!boost::filesystem::exists(filename))
|
||||
std::ifstream::pos_type filesize(std::string const &filename) {
|
||||
if (!boost::filesystem::exists(filename))
|
||||
return 0;
|
||||
else {
|
||||
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
|
||||
@@ -88,24 +80,21 @@ std::ifstream::pos_type filesize(std::string const&filename)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Sink file_sink(LoggingConfig const&cfg) {
|
||||
Sink file_sink(LoggingConfig const &cfg) {
|
||||
static std::ofstream stream;
|
||||
static uint64_t bytes_written = 0;
|
||||
const auto max_sz = 120 * 1024 * 1024;
|
||||
|
||||
auto f= formatter(cfg);
|
||||
static uint64_t bytes_written = 0;
|
||||
const auto max_sz = 120 * 1024 * 1024 * 5;
|
||||
|
||||
auto f = formatter(cfg);
|
||||
auto path = log_path();
|
||||
path /= "log";
|
||||
|
||||
|
||||
auto parent = path.parent_path();
|
||||
|
||||
|
||||
if (!boost::filesystem::is_directory(parent))
|
||||
if (!boost::filesystem::is_directory(parent))
|
||||
bts_assert(boost::filesystem::create_directories(parent));
|
||||
|
||||
if(boost::filesystem::exists(path)) {
|
||||
if (boost::filesystem::exists(path)) {
|
||||
auto sz = boost::filesystem::file_size(path);
|
||||
if (sz > max_sz) {
|
||||
auto backup = boost::filesystem::path(path.string() + ".old");
|
||||
@@ -113,10 +102,9 @@ Sink file_sink(LoggingConfig const&cfg) {
|
||||
}
|
||||
}
|
||||
|
||||
stream = std::ofstream(path.string(),std::ofstream::app);
|
||||
|
||||
return [=] (LogMsg const &m) {
|
||||
stream = std::ofstream(path.string(), std::ofstream::app);
|
||||
|
||||
return [=](LogMsg const &m) {
|
||||
auto msg = f(m);
|
||||
bytes_written += msg.size();
|
||||
if (bytes_written >= max_sz) {
|
||||
@@ -124,16 +112,15 @@ Sink file_sink(LoggingConfig const&cfg) {
|
||||
stream.close();
|
||||
auto backup = boost::filesystem::path(path.string() + ".old");
|
||||
boost::filesystem::rename(path, backup);
|
||||
stream = std::ofstream(path.string(),std::ofstream::app);
|
||||
stream = std::ofstream(path.string(), std::ofstream::app);
|
||||
}
|
||||
stream << f(m) << std::endl;
|
||||
};
|
||||
}
|
||||
|
||||
Sink null_sink() {
|
||||
return [](const LogMsg&) {};
|
||||
return [](const LogMsg &) {};
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
} // namespace log
|
||||
} // namespace bts
|
||||
+77
-74
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/bts_array_size.h"
|
||||
#include "lib/domain_model/Security.pb.h"
|
||||
#include "lib/utils/bts_array_size.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
namespace bts {
|
||||
namespace md {
|
||||
@@ -9,10 +9,10 @@ namespace md {
|
||||
const extern double NO_PRICE;
|
||||
|
||||
static const double powers_10[] = {
|
||||
1E-20, 1E-19, 1E-18, 1E-17, 1E-16, 1E-15, 1E-14, 1E-13, 1E-12, 1E-11, 1E-10, 1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3, 1E-2, 1E-1,
|
||||
1E0,
|
||||
1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15, 1E16, 1E17, 1E18, 1E19, 1E20
|
||||
};
|
||||
1E-20, 1E-19, 1E-18, 1E-17, 1E-16, 1E-15, 1E-14, 1E-13, 1E-12, 1E-11, 1E-10,
|
||||
1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3, 1E-2, 1E-1, 1E0, 1E1,
|
||||
1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9, 1E10, 1E11, 1E12,
|
||||
1E13, 1E14, 1E15, 1E16, 1E17, 1E18, 1E19, 1E20};
|
||||
static const int max_abs_power_10 = BTS_ARRAYSIZE(powers_10) / 2;
|
||||
inline double pow10(int power) {
|
||||
const int offset = power + max_abs_power_10;
|
||||
@@ -26,103 +26,104 @@ inline double pow10(int power) {
|
||||
|
||||
class IntPrice {
|
||||
#ifdef _WIN32
|
||||
int64_t _mantissa : 56;
|
||||
int64_t _exponent : 8;
|
||||
int64_t _mantissa : 56;
|
||||
int64_t _exponent : 8;
|
||||
#else
|
||||
int64_t _mantissa : 56;
|
||||
int8_t _exponent : 8;
|
||||
int64_t _mantissa : 56;
|
||||
int8_t _exponent : 8;
|
||||
#endif
|
||||
|
||||
public:
|
||||
constexpr IntPrice() : _mantissa(0), _exponent(127) {/*nan*/}
|
||||
constexpr IntPrice(int64_t mantissa, int8_t exponent) : _mantissa(mantissa), _exponent(exponent) {}
|
||||
constexpr IntPrice(const IntPrice& other) : _mantissa(other._mantissa), _exponent(other._exponent) {}
|
||||
public:
|
||||
constexpr IntPrice &operator=(const IntPrice &other) {
|
||||
_mantissa = other._mantissa;
|
||||
_exponent = other._exponent;
|
||||
return *this;
|
||||
}
|
||||
constexpr IntPrice() : _mantissa(0), _exponent(127) { /*nan*/
|
||||
}
|
||||
constexpr IntPrice(int64_t mantissa, int8_t exponent)
|
||||
: _mantissa(mantissa), _exponent(exponent) {}
|
||||
constexpr IntPrice(const IntPrice &other)
|
||||
: _mantissa(other._mantissa), _exponent(other._exponent) {}
|
||||
|
||||
bool operator==(const IntPrice& other) const {
|
||||
if(_exponent == other._exponent) {
|
||||
bool operator==(const IntPrice &other) const {
|
||||
if (_exponent == other._exponent) {
|
||||
return _mantissa == other._mantissa;
|
||||
}
|
||||
else {
|
||||
return price()==other.price();
|
||||
} else {
|
||||
return price() == other.price();
|
||||
}
|
||||
}
|
||||
bool operator!=(const IntPrice& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
bool operator<(const IntPrice& other) const {
|
||||
bool operator!=(const IntPrice &other) const { return !(*this == other); }
|
||||
bool operator<(const IntPrice &other) const {
|
||||
if (_exponent == other._exponent) {
|
||||
return _mantissa < other._mantissa;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// avoiding conversion to double is 4-5% faster
|
||||
// return price() < other.price();
|
||||
auto delta = *this - other;
|
||||
return delta.mantissa() < 0;
|
||||
}
|
||||
}
|
||||
bool operator <=(const IntPrice& other) {
|
||||
bool operator<=(const IntPrice &other) {
|
||||
return *this == other || *this < other;
|
||||
}
|
||||
bool operator >=(const IntPrice& other) {
|
||||
return !(*this < other);
|
||||
}
|
||||
IntPrice operator - (const IntPrice& o) const {
|
||||
bool operator>=(const IntPrice &other) { return !(*this < other); }
|
||||
IntPrice operator-(const IntPrice &o) const {
|
||||
return op(o, [](int64_t m1, int64_t m2) { return m1 - m2; });
|
||||
}
|
||||
IntPrice operator + (const IntPrice& o) const {
|
||||
IntPrice operator+(const IntPrice &o) const {
|
||||
return op(o, [](int64_t m1, int64_t m2) { return m1 + m2; });
|
||||
}
|
||||
IntPrice operator * (const IntPrice& other) const {
|
||||
IntPrice operator*(const IntPrice &other) const {
|
||||
return op(other, [](int64_t m1, int64_t m2) { return m1 * m2; });
|
||||
}
|
||||
IntPrice operator / (double v) const {
|
||||
return { (int64_t)(_mantissa / v), exponent() };
|
||||
IntPrice operator/(double v) const {
|
||||
return {(int64_t)(_mantissa / v), exponent()};
|
||||
}
|
||||
|
||||
IntPrice sign_extend(int8_t new_exponent) const {
|
||||
int8_t delta = _exponent - new_exponent;
|
||||
int64_t m = _mantissa * pow10(delta);
|
||||
return { m, new_exponent };
|
||||
return {m, new_exponent};
|
||||
}
|
||||
|
||||
int64_t mantissa() const { return _mantissa; }
|
||||
int8_t exponent() const { return _exponent; }
|
||||
double price() const {
|
||||
if (is_nan()) return NO_PRICE;
|
||||
int8_t exponent() const { return _exponent; }
|
||||
double price() const {
|
||||
if (is_nan())
|
||||
return NO_PRICE;
|
||||
return mantissa() * pow10(exponent());
|
||||
}
|
||||
bool is_nan() const { return _exponent == 127; }
|
||||
|
||||
private:
|
||||
private:
|
||||
template <class MantissaOp>
|
||||
IntPrice op(const IntPrice& o, MantissaOp operation) const {
|
||||
if (_exponent==o._exponent) {
|
||||
return IntPrice { operation(_mantissa,o.mantissa()), exponent() };
|
||||
}
|
||||
else {
|
||||
if (is_nan() || o.is_nan()) return IntPrice();
|
||||
IntPrice op(const IntPrice &o, MantissaOp operation) const {
|
||||
if (_exponent == o._exponent) {
|
||||
return IntPrice{operation(_mantissa, o.mantissa()), exponent()};
|
||||
} else {
|
||||
if (is_nan() || o.is_nan())
|
||||
return IntPrice();
|
||||
bts_assert_d(o.exponent() <= 0 && _exponent <= 0);
|
||||
if (o.exponent() < _exponent) {
|
||||
int8_t delta = _exponent - o.exponent();
|
||||
int64_t m = _mantissa * pow10(delta);
|
||||
return { operation(m, o.mantissa()), o.exponent() };
|
||||
}
|
||||
else {
|
||||
return {operation(m, o.mantissa()), o.exponent()};
|
||||
} else {
|
||||
int8_t delta = o.exponent() - _exponent;
|
||||
int64_t m = o.mantissa() * pow10(delta);
|
||||
return { operation(_mantissa, m), exponent() };
|
||||
return {operation(_mantissa, m), exponent()};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
static_assert(sizeof(IntPrice) == 8, "IntPrice should be this big |--------|");
|
||||
extern IntPrice INT_NAN;
|
||||
extern IntPrice INT_ZERO;
|
||||
|
||||
template <uint8_t PRECISION>
|
||||
IntPrice IntPrice_from_double(double price) {
|
||||
if (os::is_nan(price)) return INT_NAN;
|
||||
template <uint8_t PRECISION> IntPrice IntPrice_from_double(double price) {
|
||||
if (os::is_nan(price))
|
||||
return INT_NAN;
|
||||
double temp;
|
||||
if (fabs(modf(price, &temp)) != 0.0) {
|
||||
const double rounding = 0.5 * pow10(-PRECISION);
|
||||
@@ -137,50 +138,52 @@ IntPrice IntPrice_from_double(double price) {
|
||||
// return { (int64_t)(price * pow10(-precision)), precision };
|
||||
// }
|
||||
|
||||
inline md::IntPrice round_to_quote_price(const IntPrice& tick, const IntPrice& price, api::Side side) {
|
||||
inline md::IntPrice round_to_quote_price(const IntPrice &tick,
|
||||
const IntPrice &price,
|
||||
api::Side side) {
|
||||
bts_assert_d(tick.mantissa() != 0);
|
||||
if (price.is_nan()) return price;
|
||||
if (price.is_nan())
|
||||
return price;
|
||||
bts_assert_d(price.exponent() <= 0 && tick.exponent() <= 0);
|
||||
if (price.exponent() == tick.exponent()) {
|
||||
auto mod = price.mantissa() % tick.mantissa();
|
||||
if (mod == 0) return price;
|
||||
if (mod == 0)
|
||||
return price;
|
||||
else if (side == api::SIDE_BUY) {
|
||||
// buy, round down
|
||||
if (price.mantissa() > 0) {
|
||||
return { price.mantissa() - mod, price.exponent() };
|
||||
return {price.mantissa() - mod, price.exponent()};
|
||||
} else {
|
||||
return {price.mantissa() - mod - tick.mantissa(), price.exponent()};
|
||||
}
|
||||
else {
|
||||
return { price.mantissa() - mod - tick.mantissa(), price.exponent() };
|
||||
}
|
||||
}
|
||||
else if (side == api::SIDE_SELL) {
|
||||
} else if (side == api::SIDE_SELL) {
|
||||
// sell, round up
|
||||
if (price.mantissa() > 0) {
|
||||
return { price.mantissa() - mod + tick.mantissa(), price.exponent() };
|
||||
}
|
||||
else {
|
||||
return { price.mantissa() - mod, price.exponent() };
|
||||
return {price.mantissa() - mod + tick.mantissa(), price.exponent()};
|
||||
} else {
|
||||
return {price.mantissa() - mod, price.exponent()};
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Uncommon path
|
||||
// Math is reversed because exponents are negative
|
||||
if (tick.exponent() < price.exponent()) {
|
||||
return round_to_quote_price(tick, price.sign_extend(tick.exponent()), side);
|
||||
}
|
||||
else {
|
||||
return round_to_quote_price(tick, price.sign_extend(tick.exponent()),
|
||||
side);
|
||||
} else {
|
||||
// Extend tick to price's exponent
|
||||
return round_to_quote_price(tick.sign_extend(price.exponent()), price, side);
|
||||
return round_to_quote_price(tick.sign_extend(price.exponent()), price,
|
||||
side);
|
||||
}
|
||||
}
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const IntPrice& p) {
|
||||
inline std::ostream &operator<<(std::ostream &os, const IntPrice &p) {
|
||||
os << p.price();
|
||||
return os;
|
||||
}
|
||||
|
||||
}}
|
||||
} // namespace md
|
||||
} // namespace bts
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <atomic>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <google/btree/btree_set.h>
|
||||
#include <btree/set.h>
|
||||
#endif
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
#include <tbb/concurrent_queue.h>
|
||||
@@ -45,9 +45,6 @@ void print_pool_stats(const utils::ConcurrentPool<MBOSnapshot>& pool) {
|
||||
|
||||
std::sort(bid_sz.begin(), bid_sz.end());
|
||||
std::sort(ask_sz.begin(), ask_sz.end());
|
||||
size_t bid_tot =0, ask_tot = 0;
|
||||
for(size_t i : bid_sz) { bid_tot += i; }
|
||||
for(size_t i : ask_sz) { ask_tot += i; }
|
||||
|
||||
std::stringstream bid_percentiles, ask_percentiles;
|
||||
for (double x : { 0.5, 0.75, 0.9, 0.95, 0.99 }) {
|
||||
@@ -123,8 +120,8 @@ struct MBOProcessorImpl {
|
||||
// after draining publish the set in small batches
|
||||
// re-check input queue regularly
|
||||
|
||||
btree::btree_set<MBOWorkingState*> dirty;
|
||||
std::vector<MBOWorkingState*> clean;
|
||||
btree::set<MBOWorkingState *> dirty;
|
||||
std::vector<MBOWorkingState *> clean;
|
||||
|
||||
while(running) {
|
||||
Incremental temp;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "ExchangeOrderKey.h"
|
||||
#include "MDProducerHandle.h"
|
||||
|
||||
#include "google/btree/btree_map.h"
|
||||
#include <btree/map.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@@ -107,8 +107,8 @@ struct MBOWorkingState {
|
||||
// Used for 'change' messages which update price
|
||||
std::unordered_map<ExchangeOrderKey, key_t> orderid_index;
|
||||
|
||||
btree::btree_map<key_t,Data,LessBid> bid;
|
||||
btree::btree_map<key_t,Data> ask;
|
||||
btree::map<key_t, Data, LessBid> bid;
|
||||
btree::map<key_t, Data> ask;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
#include "lib/config/protos/MarketData.pb.h"
|
||||
#include "lib/utils/sane_algorithm.h"
|
||||
|
||||
#include <tbb/queuing_mutex.h>
|
||||
#include <google/btree/btree_map.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <btree/map.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <tbb/queuing_mutex.h>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
using namespace bts::api;
|
||||
using namespace btree;
|
||||
// using namespace btree;
|
||||
namespace bts {
|
||||
namespace md {
|
||||
|
||||
@@ -160,8 +160,9 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
btree_map<security_key, tuple<const ColdEntry*,const void*>> search_handles(const std::set<security_key>& keys) {
|
||||
btree_map<security_key, tuple<const ColdEntry*, const void*>> result;
|
||||
btree::map<security_key, tuple<const ColdEntry *, const void *>>
|
||||
search_handles(const std::set<security_key> &keys) {
|
||||
btree::map<security_key, tuple<const ColdEntry *, const void *>> result;
|
||||
// Walk hot and cold lists and fill in any found handles
|
||||
if (!_cold.is_initialized()) return result;
|
||||
_cold.all_entries([&](const ColdEntry& entry) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "MDConsumerHandle.h"
|
||||
#include "MBOProcessor.h"
|
||||
#include "lib/domain_model/Security.h"
|
||||
#include "lib/os/os.h"
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#define never bts_assert(false)
|
||||
@@ -11,6 +12,7 @@ using small_vector = boost::container::small_vector<T,4>;
|
||||
|
||||
namespace bts {
|
||||
namespace md {
|
||||
using os::memset;
|
||||
|
||||
MDConsumerHandle::MDConsumerHandle() {
|
||||
memset(this, 0, sizeof(MDConsumerHandle));
|
||||
@@ -387,7 +389,7 @@ std::unique_ptr<MBOSnapshot,std::function<void(MBOSnapshot*)>> MDConsumerHandle:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}}//namespace
|
||||
|
||||
} // namespace md
|
||||
} // namespace bts
|
||||
|
||||
#endif
|
||||
+15
-19
@@ -1,6 +1,7 @@
|
||||
#ifndef NO_CPP0X
|
||||
#include "MDProducer.h"
|
||||
|
||||
#include "lib/os/os.h"
|
||||
#include "lib/utils/SharedList.h"
|
||||
#include "lib/utils/WaitFreeQueue.h"
|
||||
#include "Shm/MDStructure.h"
|
||||
@@ -11,7 +12,7 @@ using namespace std;
|
||||
|
||||
namespace bts {
|
||||
namespace md {
|
||||
|
||||
using os::memcpy;
|
||||
|
||||
// Owns shared memory for a single symbol+type
|
||||
class MDProducerImpl {
|
||||
@@ -109,23 +110,17 @@ private:
|
||||
// MDProducer
|
||||
//
|
||||
|
||||
MDProducer::MDProducer(Platform platform, MDProducerFlags flags) :
|
||||
_mutex(new std::mutex()),
|
||||
_producers(),
|
||||
_id_recorder(),
|
||||
_platform(platform),
|
||||
_flags(flags),
|
||||
_smapper(flags & MDProducerFlags::SecurityMapper)
|
||||
{ }
|
||||
#ifndef WIN32
|
||||
MDProducer::MDProducer(Platform platform, SecurityIDRecorder recorder, MDProducerFlags flags) :
|
||||
_mutex(new std::mutex()),
|
||||
_producers(),
|
||||
_id_recorder(std::make_unique<SecurityIDRecorder>(recorder)),
|
||||
_platform(platform),
|
||||
_flags(flags),
|
||||
_smapper(flags & MDProducerFlags::SecurityMapper)
|
||||
{ }
|
||||
MDProducer::MDProducer(Platform platform, MDProducerFlags flags)
|
||||
: _mutex(new std::mutex()), _producers(), _id_recorder(),
|
||||
_platform(platform), _flags(flags),
|
||||
_smapper(flags & MDProducerFlags::SecurityMapper) {}
|
||||
#ifndef _WIN32
|
||||
MDProducer::MDProducer(
|
||||
Platform platform, SecurityIDRecorder recorder, MDProducerFlags flags)
|
||||
: _mutex(new std::mutex()), _producers(),
|
||||
_id_recorder(std::make_unique<SecurityIDRecorder>(recorder)),
|
||||
_platform(platform), _flags(flags),
|
||||
_smapper(flags & MDProducerFlags::SecurityMapper) {}
|
||||
#endif
|
||||
MDProducer::MDProducer(MDProducer&& other) :
|
||||
_mutex(std::move(other._mutex)),
|
||||
@@ -195,6 +190,7 @@ void MDProducerChannel::add_trade(const co2::TradeMessage& trade) {_me->add_trad
|
||||
void MDProducerChannel::add_rfq(const co2::QuoteRequestMessage& rfq) {_me->add_rfq(rfq);}
|
||||
void MDProducerChannel::gap() { _me->gap(); }
|
||||
|
||||
}}//namespace
|
||||
} // namespace md
|
||||
} // namespace bts
|
||||
|
||||
#endif
|
||||
@@ -3,17 +3,17 @@
|
||||
#include "lib/utils/Dispatcher.h"
|
||||
#include "lib/utils/LockBox.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <google/btree/btree_map.h>
|
||||
#include <tbb/concurrent_queue.h>
|
||||
#include <btree/map.h>
|
||||
#include <mutex>
|
||||
#include <tbb/concurrent_queue.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace bts {
|
||||
namespace md {
|
||||
|
||||
struct SecurityCacheImpl {
|
||||
utils::LockBox<btree::btree_map<SecurityKey, SecurityPtr>> cache;
|
||||
utils::LockBox<btree::btree_map<ExchangeSecurityKey, SecurityPtr>> ex_cache;
|
||||
utils::LockBox<btree::map<SecurityKey, SecurityPtr>> cache;
|
||||
utils::LockBox<btree::map<ExchangeSecurityKey, SecurityPtr>> ex_cache;
|
||||
tbb::concurrent_queue<SecurityPtr> update_queue;
|
||||
void enqueue_update_db(const SecurityPtr&);
|
||||
void flush();
|
||||
@@ -44,8 +44,8 @@ void SecurityCacheImpl::flush() {
|
||||
SecurityCache::SecurityCache() : _me(std::make_shared<SecurityCacheImpl>()) {}
|
||||
SecurityCache::~SecurityCache() {}
|
||||
|
||||
const Security* SecurityCache::try_get_security(SecurityKey key) const {
|
||||
return _me->cache.lock([key](btree::btree_map<SecurityKey, SecurityPtr>& t) {
|
||||
const Security *SecurityCache::try_get_security(SecurityKey key) const {
|
||||
return _me->cache.lock([key](btree::map<SecurityKey, SecurityPtr> &t) {
|
||||
auto iter = t.find(key);
|
||||
if (iter != t.end()) {
|
||||
return iter->second.get();
|
||||
@@ -53,14 +53,15 @@ const Security* SecurityCache::try_get_security(SecurityKey key) const {
|
||||
return (const api::Security*)nullptr;
|
||||
});
|
||||
}
|
||||
const Security* SecurityCache::try_get_security(ExchangeSecurityKey key) const {
|
||||
return _me->ex_cache.lock([key](btree::btree_map<ExchangeSecurityKey,SecurityPtr>& t) {
|
||||
auto iter = t.find(key);
|
||||
if (iter != t.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
return (const api::Security*)nullptr;
|
||||
});
|
||||
const Security *SecurityCache::try_get_security(ExchangeSecurityKey key) const {
|
||||
return _me->ex_cache.lock(
|
||||
[key](btree::map<ExchangeSecurityKey, SecurityPtr> &t) {
|
||||
auto iter = t.find(key);
|
||||
if (iter != t.end()) {
|
||||
return iter->second.get();
|
||||
}
|
||||
return (const api::Security *)nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "SecurityDB.h"
|
||||
#ifndef WIN32
|
||||
#include "lib/logging/logging.h"
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <SQLiteCpp/SQLiteCpp.h>
|
||||
#include <sqlite/sqlite3.h>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#ifndef WIN32
|
||||
#include "lib/domain_model/Security.h"
|
||||
#ifndef _WIN32
|
||||
#include "SecurityIDRecorder.h"
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include "MDProducerHandle.h"
|
||||
#include "common.h"
|
||||
#include "MDProducerHandle.h"
|
||||
|
||||
|
||||
@@ -8,13 +8,12 @@
|
||||
#include "lib/domain_model/Security.h"
|
||||
#include "lib/utils/parse_enum.h"
|
||||
#ifndef _WIN32
|
||||
#include "google/btree/btree_map.h"
|
||||
#include <btree/map.h>
|
||||
|
||||
namespace bts {
|
||||
namespace md {
|
||||
struct DisplayFactorMapper : public ISecurityMapper
|
||||
{
|
||||
btree::btree_map<UserSymbol, int> _mapped;
|
||||
namespace bts {
|
||||
namespace md {
|
||||
struct DisplayFactorMapper : public ISecurityMapper {
|
||||
btree::map<UserSymbol, int> _mapped;
|
||||
DisplayFactorMapper() : _mapped() {
|
||||
for (const auto& ov : config::get<DisplayFactorOverride>().override()) {
|
||||
if (ov.has_price_multiplier()) {
|
||||
@@ -50,10 +49,9 @@ struct DisplayFactorMapper : public ISecurityMapper
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct CppOverride : public ISecurityMapper
|
||||
{
|
||||
btree::btree_map<std::string, double> _map;
|
||||
|
||||
struct CppOverride : public ISecurityMapper {
|
||||
btree::map<std::string, double> _map;
|
||||
CppOverride() : _map() {
|
||||
for (const auto& p : config::get<config::CppConfig>().cpp_entry()) {
|
||||
_map.insert(p);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include "SettlementRecorder.h"
|
||||
#include "lib/utils/Sqlite_utils.h"
|
||||
#include "lib/config/config.h"
|
||||
|
||||
Loaded 100 of 321 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user