Compare commits

..
Author SHA1 Message Date
John Colvin b95da40fec feat: Impl synthetic book 2022-11-28 10:42:05 -05:00
John Colvin 755f841a6e refactor: Change spreader leg qty to int
The synth book computation code doesn't support doubles
2022-11-25 13:20:34 -05:00
John Colvin 2d10c94b69 chore: Make csharp code compatible with net471, lang version 7 2022-11-25 13:20:33 -05:00
John Colvin dfc5fcc16a fix build (client): Change 'WIN32' macros to '_WIN32'
Not sure exactly how this broke, but the WIN32 macro is no longer defined.
2022-11-20 14:22:42 -05:00
Taha Afzal 864e2a3edc Comments 2022-11-10 07:18:42 -05:00
Taha Afzal b9142202e0 UI code complete 2022-11-09 23:13:16 -05:00
Taha Afzal 7353a6dc3c Added get_data() to LegControl.cs 2022-11-08 23:26:10 -05:00
Taha Afzal b55eecc8b9 Eagle front end 2022-11-06 18:52:38 -05:00
Taha Afzal 3f0078d582 Added sample test 2022-05-09 23:08:59 -04:00
Taha Afzal e47186f0fd Fixing tests 2022-05-08 22:47:10 -04:00
Taha Afzal 4b92292fa1 Pushed a sample test 2022-05-04 09:31:09 -04:00
Taha Afzal 3a8125bba3 Namespace changes and moving all shared files to spreader_order directory 2022-05-02 23:27:30 -04:00
Taha Afzal 0b14bd1ca3 ChildOrder changed to bts::spreader::ChildOrder 2022-05-01 12:41:39 -04:00
Taha Afzal 63252b017b Cleaning up the moved events 2022-04-30 22:31:37 -04:00
Taha Afzal df1efb2295 Moving events to bts::spreader 2022-04-29 18:19:29 -04:00
Taha Afzal 3f37777eb9 'Moved' book and accompaying classes over 2022-04-29 00:21:34 -04:00
Taha Afzal 04629f28e8 Removing SpreaderOrder's inheritence from Order 2022-04-26 23:35:43 -04:00
Taha Afzal 47c4d8c4a7 Order is being routed to IOrderGateway 2022-04-26 00:40:17 -04:00
Taha Afzal eb87ebcfa1 Removed IAlternateOrderGateway, fixing tests now 2022-04-24 22:21:02 -04:00
Taha Afzal 195fd11e2e IOrderGateway accessor added to ISpreaderManager 2022-04-24 15:45:35 -04:00
Taha Afzal 413c24d147 Completed LegOrderRouter, which will be used by SpreaderChildOrderState to send orders 2022-04-24 01:18:58 -04:00
Taha Afzal fe4be118ee Adding LegOrderRouter 2022-04-24 00:16:09 -04:00
Taha Afzal 7ff09902b8 IOrderGateway::report_spreader_state takes an bts::integration::OrderUpdate now 2022-04-23 21:53:17 -04:00
Taha Afzal f90e41ea65 Moved the new interface, types into their own files 2022-04-20 23:58:05 -04:00
Taha Afzal ff2546da56 Adding function that returns OrderDef to ISpreaderManager 2022-04-20 21:46:45 -04:00
Taha Afzal f7426d9f0f All tests moved to use SpreaderWrapper 2022-04-18 23:43:06 -04:00
Taha Afzal 36bbcf849c More tests for SpreaderWrapper 2022-04-18 22:43:19 -04:00
Taha Afzal bd39d407aa More spreader tests pass 2022-04-17 23:57:07 -04:00
Taha Afzal 81dde8e9df Moving tests over to use SpreaderWrapper instead of SpreaderOrder 2022-04-17 18:48:51 -04:00
Taha Afzal 3f4a4fbac8 The 3 wrappers SpreaderOrderBuilder, SpreaderOrderServices and SpreaderPreActivationOrderServices do not call into the Spark infrastructure any more 2022-04-17 15:08:56 -04:00
Taha Afzal 2e6676b151 Added Spreader Wrapper 2022-04-16 23:55:39 -04:00
4202 changed files with 713692 additions and 404336 deletions

No files matched your search

-1
View File
@@ -4,7 +4,6 @@ BinPackParameters: false
AlignAfterOpenBracket: AlwaysBreak
AlwaysBreakTemplateDeclarations: true
PenaltyReturnTypeOnItsOwnLine: 140
ReflowComments: false
---
Language: Proto
IndentWidth: 2
+1 -19
View File
@@ -7,24 +7,6 @@
"commands": [
"dotnet-format"
]
},
"fable": {
"version": "4.0.6",
"commands": [
"fable"
]
},
"fantomas": {
"version": "5.2.2",
"commands": [
"fantomas"
]
},
"fake-cli": {
"version": "6.0.0",
"commands": [
"fake"
]
}
}
}
}
-123
View File
@@ -1,123 +0,0 @@
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
# Note installations that take a while (more than 10s)
RUN apt-get update
RUN apt-get install -y ca-certificates
RUN apt-get install -y ccache
RUN apt-get install -y curl
RUN apt-get install -y fish
RUN apt-get install -y gdb
# git-all: ~250s
RUN apt-get install -y git-all
RUN apt-get install -y gnupg
# liblttng-ust-dev: ~30s
RUN apt-get install -y liblttng-ust-dev
RUN apt-get install -y libssh2-1-dev
RUN apt-get install -y locales
RUN apt-get install -y ninja-build
# openssh-server: ~40s
RUN apt-get install -y openssh-server
RUN apt-get install -y pkg-config
RUN apt-get install -y software-properties-common
RUN apt-get install -y sudo
RUN apt-get install -y tzdata
RUN apt-get install -y vim
RUN apt-get install -y zip
# Python: ~30s
RUN apt-get install -y \
python3-pip \
python3-venv \
&& python3 -m pip install --upgrade pip
# GCC
ARG gcc_major=13
RUN \
add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y g++-$gcc_major
# Clang
ARG clang_major=17
RUN \
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key 2> /dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/llvm-snapshot.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-$clang_major main" \
| tee -a "/etc/apt/sources.list.d/llvm.list" \
&& apt-get update \
&& apt-get install -y \
clang-$clang_major \
clang-format-$clang_major \
clangd-$clang_major
# CMake
RUN \
curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc 2> /dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" \
| tee /etc/apt/sources.list.d/kitware.list > /dev/null \
&& apt-get update \
&& apt-get install -y cmake
# Dotnet
RUN apt-get update && apt-get install -y dotnet7
RUN apt-get update && apt-get install -y dotnet8
# Node
ARG node_major=18
RUN mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$node_major.x nodistro main" \
| tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs
# Emumba (deps)
RUN apt-get update && apt-get -y install rapidjson-dev
# Emumba
COPY emumba /emumba
RUN dpkg -i /emumba/emumba-deribit-connector-3.3.1-Linux.LICENSE_DISABLED.deb \
&& rm -r /emumba
# Pcap
RUN apt-get update && apt-get install -y libpcap0.8-dev
# Set up default executables (update-alternatives)
RUN \
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$clang_major 100; \
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-$clang_major 100; \
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-$clang_major 100; \
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-$clang_major 100; \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$gcc_major 100; \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-$gcc_major 100
# Add compiler symlinks for ccache
RUN \
ln -s /usr/bin/ccache /usr/local/bin/clang; \
ln -s /usr/bin/ccache /usr/local/bin/clang++; \
ln -s /usr/bin/ccache /usr/local/bin/clang-$clang_major; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-$clang_major; \
ln -s /usr/bin/ccache /usr/local/bin/gcc; \
ln -s /usr/bin/ccache /usr/local/bin/g++
RUN locale-gen en_US.UTF-8
ARG docker_user="bts"
ARG docker_uid="1000"
ARG docker_pass="bts"
RUN \
groupadd -g "$docker_uid" "$docker_user" \
&& useradd \
-m \
-u "$docker_uid" \
-g "$docker_uid" \
-G sudo \
--password "$(openssl passwd -1 "$docker_pass")" \
"$docker_user"
-58
View File
@@ -1,58 +0,0 @@
{
"dockerFile": "Dockerfile",
// Creates local dir to mount to HOME in docker
"initializeCommand": "mkdir -p ${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId}",
"hostRequirements": {
"memory": "4gb",
"storage": "6gb"
},
"postCreateCommand": "/home/bts/spark/docker/sparkd/dev/devcontainer_post_create.sh",
"containerUser": "bts",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/bts/spark,type=bind",
"workspaceFolder": "/home/bts/spark",
"updateRemoteUserUID": true,
"shutdownAction": "none",
// Note: If running multiple containers on the same host, each must use a
// unique set of ports. Usually we just add 1000 to each port as needed. For
// example, if 8000-8003 is taken, go with 9000-9003, then 10000-10003, etc.
"runArgs": [
"--shm-size",
"2gb",
"-p",
"5000:5000",
"-p",
"5001:5001",
"-p",
"5173:5173",
"-p",
"5174:5174",
"-p",
"8000:8000",
"-p",
"8001:8001",
"-p",
"8002:8002",
"-p",
"8003:8003",
"-p",
"12345:12345",
],
"mounts": [
"source=${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId},target=/home/bts,type=bind"
],
"customizations": {
"vscode": {
"settings": {
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build/clang/debug"
]
},
"extensions": [
"eamodio.gitlens",
"llvm-vs-code-extensions.vscode-clangd",
"ms-vscode.cmake-tools",
"ms-vscode.cpptools"
]
}
}
}
@@ -1,4 +0,0 @@
#!/usr/bin/env bash
this_dir="$(realpath "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")"
sudo dpkg -i "$this_dir/emumba-deribit-connector-3.3.1-Linux.LICENSE_DISABLED.deb"
+16 -30
View File
@@ -207,23 +207,17 @@ dotnet_naming_symbols.parameters.applicable_accessibilities = public,internal,pr
dotnet_naming_symbols.private_symbols.applicable_kinds = property,method,field,event,delegate
dotnet_naming_symbols.private_symbols.applicable_accessibilities = protected,private
# local symbols
dotnet_naming_symbols.local_symbols.applicable_kinds = local
# parameter symbols
dotnet_naming_symbols.parameter_symbols.applicable_kinds = parameter
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.snake_case.required_prefix =
dotnet_naming_style.snake_case.required_suffix =
dotnet_naming_style.snake_case.word_separator = _
dotnet_naming_style.snake_case.capitalization = all_lower
dotnet_naming_style.camel_case.required_prefix =
dotnet_naming_style.camel_case.required_suffix =
dotnet_naming_style.camel_case.word_separator =
dotnet_naming_style.camel_case.capitalization = camel_case
dotnet_naming_style.private_snake_case.required_prefix = _
dotnet_naming_style.private_snake_case.required_suffix =
dotnet_naming_style.private_snake_case.word_separator = _
dotnet_naming_style.private_snake_case.capitalization = all_lower
dotnet_naming_style.user_types.required_prefix =
dotnet_naming_style.user_types.required_suffix =
@@ -235,10 +229,6 @@ dotnet_naming_style.interface.required_suffix =
dotnet_naming_style.interface.word_separator =
dotnet_naming_style.interface.capitalization = pascal_case
dotnet_naming_style.local.capitalization = camel_case
dotnet_naming_style.parameter.capitalization = camel_case
# rules
dotnet_naming_rule.user_types.symbols = user_types
dotnet_naming_rule.user_types.style = user_types
@@ -248,18 +238,14 @@ dotnet_naming_rule.interfaces.symbols = interface
dotnet_naming_rule.interfaces.style = interface_style
dotnet_naming_rule.interfaces.severity = suggestion
dotnet_naming_rule.public_members.symbols = public_symbols
dotnet_naming_rule.public_members.style = pascal_case
dotnet_naming_rule.public_members.severity = suggestion
dotnet_naming_rule.public_members_snake_case.symbols = public_symbols
dotnet_naming_rule.public_members_snake_case.style = snake_case
dotnet_naming_rule.public_members_snake_case.severity = suggestion
dotnet_naming_rule.private_members.symbols = private_symbols
dotnet_naming_rule.private_members.style = camel_case
dotnet_naming_rule.private_members.severity = suggestion
dotnet_naming_rule.private_members_snake_case.symbols = private_symbols
dotnet_naming_rule.private_members_snake_case.style = private_snake_case
dotnet_naming_rule.private_members_snake_case.severity = suggestion
dotnet_naming_rule.variables_are_camel_case.severity = suggestion
dotnet_naming_rule.variables_are_camel_case.symbols = local_symbols
dotnet_naming_rule.variables_are_camel_case.style = local
dotnet_naming_rule.parameters.symbols = parameter_symbols
dotnet_naming_rule.parameters.style = parameter
dotnet_naming_rule.parameters.symbols = parameters
dotnet_naming_rule.parameters.style = snake_case
dotnet_naming_rule.parameters.severity = suggestion
-3
View File
@@ -1,3 +0,0 @@
*.cmd text=auto eol=crlf
*.cs text=auto eol=crlf
*.sh text=auto eol=lf
+6 -14
View File
@@ -1,6 +1,5 @@
nohup.out
build/**
install/**
build/
.build_proxy/
cmake-build-debug/
.cache/
@@ -8,9 +7,7 @@ cmake-build-debug/
.idea/
.dir-locals.el
*.pyc
**.vscode/*
!.vscode/launch.json
!.vscode/tasks.json
**.vscode
.vs
obj/
*.csproj.user
@@ -43,19 +40,14 @@ trace_data/
.ionide/*
/.ignore
*.rej
/build
/build.*/*
.clangd/
*CMakeDeps.cmake
/sniper.ipynb
/src/.clang-format
/src/server/sparkd/cmds/spartan/analysis/.ipynb_checkpoints
/src/server/sparkd/cmds/spartan/analysis/data
.tmp/
.venv*/
*.tmp/*
/.venv*/*
.cache/
/src/Spark.Admin.WebApp/tsconfig.*.g.json
/src/Spark.Admin.WebApp/src/bin/
**/CMakeDeps.cmake
**/CMakeDeps_win.cmake
.devcontainer/
*.Generated.cs
*.lst
+10 -4
View File
@@ -1,6 +1,12 @@
[submodule "externals"]
path = externals
url = https://bitbucket.org/bluetradesys/externals.git
[submodule "vcpkg"]
path = vcpkg
url = https://github.com/microsoft/vcpkg.git
url = git@bitbucket.org:bluetradesys/externals.git
[submodule "docker/linux"]
path = docker/linux
url = git@bitbucket.org:bluetradesys/linux_docker.git
[submodule "docker/windows"]
path = docker/windows
url = git@bitbucket.org:bluetradesys/windows_docker.git
[submodule "src/deribit-crypto-connector-demo-application"]
path = src/deribit-crypto-connector-demo-application
url = git@gitlab.com:cryptoexchanges1/deribit-crypto-connector-demo-application.git
-213
View File
@@ -1,213 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
},
{
"name": "Bts.DataStreamWebApp.Server",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStream WebApp (Debug)",
"program": "${workspaceFolder}/build/Debug/bin/net8.0/Bts.DataStreamWebApp.Server.dll",
"args": [
"--sparkd",
"http://localhost:8000/config",
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy",
}
},
{
"name": "Bts.DataStreamWebApp.Server (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/build/Debug/bin/net8.0/Bts.DataStreamWebApp.Server.dll",
// "args": [
// "--config",
// "${workspaceFolder}/src/DataStreamSuite/Bts.DataStreamWebApp.Server/Configurations/DevServer.json",
// ],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy",
}
},
{
"name": "DataStreamPublisher",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStream (Debug)",
"program": "",
"linux": {
"program": "DataStreamPublisher",
},
"windows": {
"program": "DataStreamPublisher.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamPublisher/Configurations/${input:dataStreamPublisherConfig}.json"
],
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0",
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "DataStreamPublisher (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"linux": {
"program": "DataStreamPublisher",
},
"windows": {
"program": "DataStreamPublisher.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamPublisher/Configurations/${input:dataStreamPublisherConfig}.json"
],
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0",
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "DataStreamQueryAnalyzer",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStreamQueryAnalyzer (Debug)",
"program": "",
"windows": {
"program": "DataStreamQueryAnalyzer.exe",
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamQueryAnalyzer/Configurations/DataStreamQueryAnalyzer.json"
],
"cwd": "build/Debug/bin/net7.0-windows",
"env": {
"PYTHON_EXE": "${workspaceFolder}/.venv/Scripts/python.exe"
},
},
"stopAtEntry": false,
"console": "integratedTerminal",
},
{
"name": "PubSubServer",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build DataStream (Debug)",
"program": "",
"linux": {
"program": "PubSubServer",
},
"windows": {
"program": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json"
],
"cwd": "build/Debug/bin/net7.0",
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "PubSubServer (Skip Build)",
"type": "coreclr",
"request": "launch",
"program": "",
"linux": {
"program": "PubSubServer",
},
"windows": {
"program": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json"
],
"cwd": "build/Debug/bin/net7.0",
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark",
"type": "coreclr",
"request": "launch",
"program": "",
"windows": {
"preLaunchTask": "Build Spark (Debug)",
"program": "Spark.exe",
"cwd": "build/Debug/bin/net7.0-windows",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Spark (Parameterized)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build Spark (Debug)",
"program": "",
"windows": {
"program": "Spark.exe",
"args": [
"--sparkd",
"${input:sparkConfigServer}"
],
"cwd": "build/Debug/bin/net7.0-windows",
},
"stopAtEntry": false,
"console": "integratedTerminal"
},
{
"name": "Sparkd",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build Sparkd (Debug | Clang)",
"program": "",
"linux": {
"program": "sparkd",
},
"args": [
"run"
],
"cwd": "build/sparkd-debug-clang/server",
"stopAtEntry": false,
"console": "integratedTerminal"
}
],
"inputs": [
{
"id": "dataStreamPublisherConfig",
"type": "pickString",
"description": "Publisher Configuration",
"options": [
"MarketDataPublisher",
"SimpleEchoClient",
"SimpleTestDataPublisher",
"TestDataPublisher",
],
"default": "MarketDataPublisher",
},
{
"id": "pubSubServerConfig",
"type": "pickString",
"description": "PubSub Configuration",
"options": [
"PubSubServer",
"SimpleEchoClient",
],
"default": "PubSubServer",
},
{
"id": "sparkConfigServer",
"type": "promptString",
"description": "Config Server URL",
"default": "http://localhost:8000/config",
},
]
}
-935
View File
@@ -1,935 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Api Server",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_api_server.sh",
},
"windows": {
"command": "tools/build_api_server.cmd",
},
"args": [
"--configuration",
"${input:buildConfiguration}",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Api Server (Debug)",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_api_server.sh",
},
"windows": {
"command": "tools/build_api_server.cmd",
},
"args": [
"--configuration",
"Debug",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Api Server (Release)",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_api_server.cmd",
},
"linux": {
"command": "tools/build_api_server.sh",
},
"args": [
"--configuration",
"Release",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStream",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_data_stream.sh",
},
"windows": {
"command": "tools/build_data_stream.cmd",
},
"args": [
"--configuration",
"${input:buildConfiguration}",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStream (Debug)",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_data_stream.sh",
},
"windows": {
"command": "tools/build_data_stream.cmd",
},
"args": [
"--configuration",
"Debug",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStream (Release)",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_data_stream.sh",
},
"windows": {
"command": "tools/build_data_stream.cmd",
},
"args": [
"--configuration",
"Release",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStreamQueryAnalyzer",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_data_stream_query_analyzer.cmd",
},
"args": [
"--configuration",
"${input:buildConfiguration}",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStreamQueryAnalyzer (Debug)",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_data_stream_query_analyzer.cmd",
},
"args": [
"--configuration",
"Debug",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStreamQueryAnalyzer (Release)",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_data_stream_query_analyzer.cmd",
},
"args": [
"--configuration",
"Release",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStream WebApp",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_data_stream_web_app.sh",
},
"windows": {
"command": "tools/build_data_stream_web_app.cmd",
},
"args": [
"--configuration",
"${input:buildConfiguration}",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build DataStream WebApp (Debug)",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/build_data_stream_web_app.sh",
},
"windows": {
"command": "tools/build_data_stream_web_app.cmd",
},
"args": [
"--configuration",
"Debug",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Spark",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_spark.cmd",
},
"args": [
"--configuration",
"${input:buildConfiguration}",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Spark (Debug)",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_spark.cmd",
},
"args": [
"--configuration",
"Debug",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Spark (Release)",
"group": "build",
"type": "process",
"command": "",
"windows": {
"command": "tools/build_spark.cmd",
},
"args": [
"--configuration",
"Release",
],
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--preset",
"${input:sparkdCmakePreset}",
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd (Debug)",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--build-type",
"Debug",
"--compiler",
"${input:sparkdCompiler}"
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd (Debug | Gcc)",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--build-type",
"Debug",
"--compiler",
"gcc"
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd (Debug | Clang)",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--build-type",
"Debug",
"--compiler",
"clang"
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd (Release)",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--build-type",
"Release",
"--compiler",
"${input:sparkdCompiler}"
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd (Release | Gcc)",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--build-type",
"Release",
"--compiler",
"gcc"
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Build Sparkd (Release | Clang)",
"group": "build",
"type": "shell",
"command": "",
"linux": {
"command": "tools/build_sparkd.sh",
"args": [
"--build-type",
"Release",
"--compiler",
"clang"
],
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Publish DataStreamWebApp",
"group": "build",
"type": "process",
"command": "",
"linux": {
"command": "tools/publish_data_stream_web_app.sh",
},
"windows": {
"command": "tools/publish_data_stream_web_app.cmd",
},
"icon": {
"id": "terminal",
"color": "terminal.ansiCyan"
},
},
{
"label": "Edit DataStream Config",
"type": "process",
"command": "",
"linux": {
"command": "editor",
"args": [
"${env:HOME}/.local/share/DataStream/conf/spark.conf"
],
},
"windows": {
"command": "vim",
"args": [
"${env:APPDATA}/bts/DataStream/conf/spark.conf"
],
},
"presentation": {
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"close": true,
},
"icon": {
"id": "wrench"
},
},
{
"label": "Edit Spark Config",
"type": "process",
"command": "",
"windows": {
"command": "vim",
"args": [
"${env:APPDATA}/bts/conf/spark.conf"
],
},
"presentation": {
"reveal": "always",
"focus": true,
"panel": "dedicated",
"showReuseMessage": false,
"close": true,
},
"icon": {
"id": "wrench"
},
},
{
"label": "Run DataStreamQueryAnalyzer",
"dependsOn": "Build DataStreamQueryAnalyzer",
"type": "process",
"command": "",
"windows": {
"command": "DataStreamQueryAnalyzer.exe",
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamQueryAnalyzer/Configurations/DataStreamQueryAnalyzer.json",
],
"options": {
"cwd": "${workspaceFolder}/build/${input:buildConfiguration}/bin/net7.0-windows"
},
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run DataStreamQueryAnalyzer (Debug)",
"dependsOn": "Build DataStreamQueryAnalyzer (Debug)",
"type": "process",
"command": "",
"windows": {
"command": "DataStreamQueryAnalyzer.exe",
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamQueryAnalyzer/Configurations/DataStreamQueryAnalyzer.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0-windows"
},
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run DataStreamQueryAnalyzer (Release)",
"dependsOn": "Build DataStreamQueryAnalyzer (Release)",
"type": "process",
"command": "",
"windows": {
"command": "DataStreamQueryAnalyzer.exe",
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamQueryAnalyzer/Configurations/DataStreamQueryAnalyzer.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Release/bin/net7.0-windows"
},
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run DataStreamPublisher",
"dependsOn": "Build DataStream",
"type": "process",
"command": "",
"linux": {
"command": "DataStreamPublisher",
},
"windows": {
"command": "DataStreamPublisher.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamPublisher/Configurations/${input:dataStreamPublisherConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/${input:buildConfiguration}/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run DataStreamPublisher (Debug)",
"dependsOn": "Build DataStream (Debug)",
"type": "process",
"command": "",
"linux": {
"command": "DataStreamPublisher",
},
"windows": {
"command": "DataStreamPublisher.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamPublisher/Configurations/${input:dataStreamPublisherConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run DataStreamPublisher (Release)",
"dependsOn": "Build DataStream (Release)",
"type": "process",
"command": "",
"linux": {
"command": "DataStreamPublisher",
},
"windows": {
"command": "DataStreamPublisher.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/DataStreamPublisher/Configurations/${input:dataStreamPublisherConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Release/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run PubSubServer",
"dependsOn": "Build DataStream",
"type": "process",
"command": "",
"linux": {
"command": "PubSubServer",
},
"windows": {
"command": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/${input:buildConfiguration}/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run PubSubServer (Debug)",
"dependsOn": "Build DataStream (Debug)",
"type": "process",
"command": "",
"linux": {
"command": "PubSubServer",
},
"windows": {
"command": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run PubSubServer (Debug | Skip Build)",
"type": "process",
"command": "",
"linux": {
"command": "PubSubServer",
},
"windows": {
"command": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run PubSubServer (Release)",
"dependsOn": "Build DataStream (Release)",
"type": "process",
"command": "",
"linux": {
"command": "PubSubServer",
},
"windows": {
"command": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Release/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run PubSubServer (Release | Skip Build)",
"type": "process",
"command": "",
"linux": {
"command": "PubSubServer",
},
"windows": {
"command": "PubSubServer.exe",
},
"args": [
"--config",
"${workspaceFolder}/src/DataStreamSuite/PubSubServer/Configurations/${input:pubSubServerConfig}.json",
],
"options": {
"cwd": "${workspaceFolder}/build/Release/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run Spark",
"dependsOn": "Build Spark",
"type": "process",
"command": "",
"windows": {
"command": "Spark.exe",
"options": {
"cwd": "${workspaceFolder}/build/${input:buildConfiguration}/bin/net7.0-windows"
},
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
}
},
{
"label": "Run Spark (Debug)",
"dependsOn": "Build Spark (Debug)",
"type": "process",
"command": "",
"windows": {
"command": "Spark.exe",
"options": {
"cwd": "${workspaceFolder}/build/Debug/bin/net7.0-windows"
},
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
}
},
{
"label": "Run Spark (Release)",
"dependsOn": "Build Spark (Release)",
"type": "process",
"command": "",
"windows": {
"command": "Spark.exe",
"options": {
"cwd": "${workspaceFolder}/build/Release/bin/net7.0-windows"
},
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
}
},
{
"label": "Run Spark Config Query",
"dependsOn": "Build Spark",
"type": "process",
"command": "",
"linux": {
"command": "Spark.Console",
},
"windows": {
"command": "Spark.Console.exe",
},
"args": [
"config",
"--query",
"${input:sparkConfigQuery}",
],
"options": {
"cwd": "${workspaceFolder}/build/${input:buildConfiguration}/bin/net7.0"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run Sparkd",
"dependsOn": "Build Sparkd",
"type": "process",
"command": "",
"linux": {
"command": "sparkd",
},
"args": [
"run"
],
"options": {
"cwd": "${workspaceFolder}/build/${input:sparkdCmakePreset}/server"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "Run Sparkd Config Query",
"dependsOn": "Build Sparkd",
"type": "process",
"command": "",
"linux": {
"command": "sparkd",
},
"args": [
"config",
"--query",
"${input:sparkdConfigQuery}",
],
"options": {
"cwd": "${workspaceFolder}/build/${input:sparkdCompiler}/${input:sparkdBuildType}/server"
},
"icon": {
"id": "run",
"color": "terminal.ansiGreen",
},
},
{
"label": "View DataStreamQueryAnalyzer Logs (Last Run)",
"type": "process",
"command": "",
"windows": {
"command": "tools/logging/show_last_run.cmd",
"args": [
"DataStream",
"DataStreamQueryAnalyzer.exe",
"'Starting DataStreamQueryAnalyzer'"
]
},
"presentation": {
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"close": true,
},
"icon": {
"id": "wrench"
},
},
{
"label": "View PubSubServer Logs (Last Run)",
"type": "process",
"command": "",
"linux": {
"command": "tools/logging/show_last_run.sh",
"args": [
"${env:HOME}/.local/share/DataStream/data/logging.PubSubServer",
"Starting PubSubServer"
]
},
"windows": {
"command": "tools/logging/show_last_run.cmd",
"args": [
"DataStream",
"PubSubServer.exe",
"Starting PubSubServer"
]
},
"presentation": {
"reveal": "always",
"focus": true,
"panel": "shared",
"showReuseMessage": false,
"close": true,
},
"icon": {
"id": "wrench"
},
},
],
"inputs": [
{
"id": "buildConfiguration",
"type": "pickString",
"description": "Configuration",
"options": [
"Debug",
"Release",
],
"default": "Debug",
},
{
"id": "sparkdCmakePreset",
"type": "pickString",
"description": "Configuration",
"options": [
"sparkd-debug-clang",
"sparkd-debug-gcc",
"sparkd-release-clang",
"sparkd-release-gcc",
],
"default": "sparkd-debug-clang",
},
{
"id": "sparkdCompiler",
"type": "pickString",
"description": "Configuration",
"options": [
"clang",
"gcc",
],
"default": "sparkd-debug-clang",
},
{
"id": "dataStreamPublisherConfig",
"type": "pickString",
"description": "Publisher Configuration",
"options": [
"MarketDataPublisher",
"SimpleEchoClient",
"SimpleTestDataPublisher",
"TestDataPublisher",
],
"default": "MarketDataPublisher",
},
{
"id": "pubSubServerConfig",
"type": "pickString",
"description": "PubSub Configuration",
"options": [
"PubSubServer",
"SimpleEchoClient",
],
"default": "PubSubServer",
},
{
"id": "sparkConfigQuery",
"type": "promptString",
"description": "Config Type(s)"
},
{
"id": "sparkdConfigQuery",
"type": "promptString",
"description": "Config Type(s)"
}
]
}
+62 -123
View File
@@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.5)
project(spark)
set(CMAKE_CXX_STANDARD 20)
if(WIN32)
set(platform "windows")
@@ -8,148 +7,88 @@ else()
set(platform "linux")
endif()
set(
EXTERNALS_ROOT
"${CMAKE_SOURCE_DIR}/externals/${platform}"
CACHE
STRING
"External dependencies root folder (should contain folders: lib, bin, include")
# SHARED_MEMORY_PREFIX serves as a kind of namespace so multiple applications
# can run simultaneously without fighting over the same shm files (e.g., sparkd,
# api server, etc.).
set(SHARED_MEMORY_PREFIX "bts" CACHE STRING "Prefix to use when creating shared memory files")
set(EXTERNALS_ROOT "${CMAKE_SOURCE_DIR}/externals/${platform}")
set(SPARK_PYTHON "${EXTERNALS_ROOT}/python")
set(SPARK_BIN "${EXTERNALS_ROOT}/bin")
set(SPARK_INCLUDE "${EXTERNALS_ROOT}/include")
set(SPARK_LIB "${EXTERNALS_ROOT}/lib/$<CONFIG>")
set(BUILD_DOCS OFF CACHE BOOL "Build documentation")
set(SPARK_LIB "${EXTERNALS_ROOT}/lib/${CMAKE_BUILD_TYPE}")
set(BUILD_SDK OFF CACHE BOOL "Build the sdk")
set(EXPORT_MD_CONSUMER OFF CACHE BOOL "Export (extern) C functions for MD consumer interop")
if (WIN32)
set(BUILD_SPARKD OFF CACHE BOOL "Build sparkd")
set(BUILD_ADMIN_WEB_APP OFF CACHE BOOL "Build the Admin WebApp")
else()
set(BUILD_SPARKD ON CACHE BOOL "Build sparkd")
set(BUILD_ADMIN_WEB_APP ON CACHE BOOL "Build the Admin WebApp")
endif()
include_directories(BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
link_directories(${SPARK_LIB})
add_compile_definitions(SHARED_MEMORY_PREFIX="${SHARED_MEMORY_PREFIX}")
add_compile_definitions(APP_DATA_DIR="${APP_DATA_DIR}")
if(DEFINED APP_DATA_DIR_OVERRIDE)
add_compile_definitions(APP_DATA_DIR_OVERRIDE="${APP_DATA_DIR_OVERRIDE}")
endif()
add_compile_definitions(EXPORT_MD_CONSUMER="${EXPORT_MD_CONSUMER}")
if(WIN32)
# flags
set(
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} \
/MP \
/WX /wd4251 /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 \
/bigobj \
/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")
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")
# subdirs
add_subdirectory(src/lib)
else()
# make sparkd look for libspark.so in its directory
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH ".")
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install")
set(SPARK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/$<CONFIG>")
if(BUILD_SPARKD)
# Note: All macros that begin w/ 'CCAPI' are ccapi's macros (defined and/or
# read by their code). We override some below.
add_compile_definitions(SPARK_ENABLE_CCAPI)
# This allows us to override hardcoded exchange-urls with ones read from
# config (i.e., resolved at runtime rather than compile-time)
add_compile_definitions(CCAPI_EXPOSE_INTERNAL)
# Enable ccapi services
add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
# Enable ccapi exchanges
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_COIN_FUTURES)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_US)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_USDS_FUTURES)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_COINBASE)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_DERIBIT)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_OKX)
set(CCAPI_LOG_LEVEL
"Warn"
CACHE STRING "<Fatal|Error|Warn|Info|Debug|Trace> Log level for ccapi")
string(TOUPPER "${CCAPI_LOG_LEVEL}" _ccapi_log_level_upper)
add_compile_definitions("CCAPI_ENABLE_LOG_${_ccapi_log_level_upper}")
# ** Binance **
add_compile_definitions(CCAPI_BINANCE_URL_REST_BASE="https://api.binance.com")
add_compile_definitions(BINANCE_INSTRUMENTS_PATH="/api/v3/exchangeInfo")
add_compile_definitions(BINANCE_PRICE_STATS_PATH="/api/v3/ticker/24hr")
# ** Binance US **
add_compile_definitions(BINANCE_US_INSTRUMENTS_PATH="/api/v3/exchangeInfo")
add_compile_definitions(BINANCE_US_PRICE_STATS_PATH="/api/v3/ticker/24hr")
# ** Binance USDS Futures **
add_compile_definitions(CCAPI_BINANCE_USDS_FUTURES_URL_REST_BASE="https://dapi.binance.com")
add_compile_definitions(BINANCE_USDS_FUTURES_INSTRUMENTS_PATH="/dapi/v1/exchangeInfo")
add_compile_definitions(BINANCE_USDS_FUTURES_PRICE_STATS_PATH="/dapi/v1/ticker/24hr")
# ** Deribit **
add_compile_definitions(DERIBIT_INSTRUMENT_PATH="/api/v2/public/get_instrument")
add_compile_definitions(DERIBIT_INSTRUMENTS_PATH="/api/v2/public/get_instruments")
add_compile_definitions(DERIBIT_COMBOS_PATH="/api/v2/public/get_combos")
add_compile_definitions(DERIBIT_TICKER_PATH="/api/v2/public/ticker")
add_compile_definitions(DERIBIT_CURRENCIES_METHOD="public/get_currencies")
add_compile_definitions(DERIBIT_INSTRUMENT_METHOD="public/get_instrument")
add_compile_definitions(DERIBIT_INSTRUMENTS_METHOD="public/get_instruments")
add_compile_definitions(DERIBIT_COMBO_DETAILS_METHOD="public/get_combo_details")
add_compile_definitions(DERIBIT_COMBOS_METHOD="public/get_combos")
# ** Okx **
add_compile_definitions(OKX_INSTRUMENTS_PATH="/api/v5/public/instruments")
add_compile_definitions(OKX_UNDERLYING_PATH="/api/v5/public/underlying")
endif()
# flags
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")
# subdirs
if (BUILD_SPARKD)
add_subdirectory(src/server/sparkd)
add_subdirectory(src/data_files)
endif()
add_subdirectory(src/server/sparkd)
add_subdirectory(src/lib)
if (BUILD_ADMIN_WEB_APP)
add_subdirectory(src/Spark.Admin.WebApp)
endif()
if(BUILD_DOCS)
add_subdirectory(doc/user)
endif()
add_subdirectory(src/web)
add_subdirectory(doc/user)
if(BUILD_SDK)
add_subdirectory(src/sdk)
endif()
add_subdirectory(src/data_files)
if(BUILD_SPARKD)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/server
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/server/sparkd/sparkd ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/data_files ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/lib/libspark.so ${CMAKE_BINARY_DIR}/server
COMMAND
ln ARGS -sf
${EXTERNALS_ROOT}/lib/Release/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0
${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libACE-5.7.5.so ${CMAKE_BINARY_DIR}/server
COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/server/plugins
COMMENT "Creating server runtime layout"
DEPENDS sparkd data_files_dir)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/server
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/server/sparkd/sparkd ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/web ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/data_files ${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/lib/libspark.so ${CMAKE_BINARY_DIR}/server
COMMAND
ln ARGS -sf
${EXTERNALS_ROOT}/lib/Release/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0
${CMAKE_BINARY_DIR}/server
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libACE-5.7.5.so ${CMAKE_BINARY_DIR}/server
COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/server/plugins
COMMENT "Creating server runtime layout"
DEPENDS sparkd data_files_dir)
add_custom_target(server_layout ALL DEPENDS ${CMAKE_BINARY_DIR}/server)
install(
DIRECTORY "${CMAKE_BINARY_DIR}/server/plugins"
DESTINATION "${SPARK_INSTALL_PREFIX}/bin")
install(
FILES
"${SPARK_LIB}/libACE-5.7.5.so"
"${SPARK_LIB}/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0"
DESTINATION "${SPARK_INSTALL_PREFIX}/bin")
endif()
add_custom_target(server_layout ALL DEPENDS ${CMAKE_BINARY_DIR}/server)
endif()
-438
View File
@@ -1,438 +0,0 @@
{
"version": 4,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"configurePresets": [
{
"name": "spark",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build/${presetName}",
"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++20 /D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600"
},
"cacheVariables": {
"APP_DATA_DIR": "${dollar}{APPDATA}/bts",
"APP_DATA_DIR_OVERRIDE": "${dollar}{SPARK_DATA_DIR}",
"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": "20",
"CMAKE_SHARED_LINKER_FLAGS_DEBUG": "/DEBUG",
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "/OPT:REF /OPT:ICF /LTCG",
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
"EXTERNALS_ROOT": "${sourceDir}/externals/windows",
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf",
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0;${sourceDir}/build/$<CONFIG>/bin/net7.0-windows",
"EXPORT_MD_CONSUMER": {
"type": "BOOL",
"value": "ON"
},
"SHARED_MEMORY_PREFIX": "spark"
}
},
{
"name": "sparkd",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"platform": "",
"APP_DATA_DIR": "${dollar}{HOME}/sparkdata",
"APP_DATA_DIR_OVERRIDE": "${dollar}{SPARKD_DATA_DIR}",
"CMAKE_BUILD_WITH_INSTALL_RPATH": {
"type": "BOOL",
"value": "ON"
},
"CMAKE_CXX_STANDARD": "20",
"CMAKE_INSTALL_RPATH": ".",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}/sparkd",
"CMAKE_EXE_LINKER_FLAGS": "-Wno-undef",
"EXTERNALS_ROOT": "${sourceDir}/externals/linux",
"BUILD_SDK": {
"type": "BOOL",
"value": "OFF"
},
"BUILD_ADMIN_WEB_APP": {
"type": "BOOL",
"value": "ON"
},
"SHARED_MEMORY_PREFIX": "sparkd"
}
},
{
"name": "sparkd-debug",
"inherits": "sparkd",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": {
"type": "BOOL",
"value": "ON"
},
"CCAPI_LOG_LEVEL": "Info",
"CONFIG_DEFAULTS_PATH": "config/profiles/md_dev/*.conf;config/profiles/default/*.conf"
}
},
{
"name": "sparkd-release",
"inherits": "sparkd",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CCAPI_LOG_LEVEL": "Warn",
"CONFIG_DEFAULTS_PATH": "config/profiles/md_prod/*.conf;config/profiles/default/*.conf"
}
},
{
"name": "sparkd-debug-clang",
"inherits": "sparkd-debug",
"displayName": "Sparkd (Debug | Clang)",
"description": "Debug build compiled w/ clang",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG"
}
},
{
"name": "sparkd-debug-gcc",
"inherits": "sparkd-debug",
"displayName": "Sparkd (Debug | Gcc)",
"description": "Debug build compiled w/ gcc",
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -Wno-stringop-overread -DDEBUG"
}
},
{
"name": "sparkd-release-clang",
"inherits": "sparkd-release",
"displayName": "Sparkd (Release | Clang)",
"description": "Release build compiled w/ clang",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3"
}
},
{
"name": "sparkd-release-gcc",
"inherits": "sparkd-release",
"displayName": "Sparkd (Release | Gcc)",
"description": "Release build compiled w/ gcc",
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-stringop-overflow --std=c++20 -fdiagnostics-color -Wno-stringop-overread -Wno-maybe-uninitialized -fno-omit-frame-pointer -DNDEBUG -O3"
}
},
{
"name": "spark-api-server-windows",
"inherits": "spark",
"displayName": "Spark Api Server (Windows)",
"cacheVariables": {
"APP_DATA_DIR_OVERRIDE": "${dollar}{SPARK_API_SERVER_DATA_DIR}",
"SHARED_MEMORY_PREFIX": "spark_api_server"
}
},
{
"name": "spark-api-server-linux",
"inherits": "sparkd",
"displayName": "Spark Api Server (Linux)",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"APP_DATA_DIR_OVERRIDE": "${dollar}{SPARK_API_SERVER_DATA_DIR}",
"BUILD_ADMIN_WEB_APP": {
"type": "BOOL",
"value": "OFF"
},
"BUILD_SPARKD": {
"type": "BOOL",
"value": "OFF"
},
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf",
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0",
"EXPORT_MD_CONSUMER": {
"type": "BOOL",
"value": "ON"
}
}
},
{
"name": "sparkd-publish",
"inherits": "sparkd-release-gcc",
"displayName": "Publish",
"description": "Production build compiled w/ gcc and ready to ship"
},
{
"name": "sparkd-ccapi-diag",
"inherits": "sparkd-debug-clang",
"displayName": "Debug (ccapi diag)",
"description": "Debug build w/ ccapi log level 'Trace'",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CCAPI_LOG_LEVEL": "Trace"
}
},
{
"name": "data-stream-suite-windows",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"inherits": "spark",
"displayName": "Data Stream Suite (Windows)",
"description": "Data Stream utils ported over from Edge",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"APP_DATA_DIR": "${dollar}{APPDATA}/bts/DataStream",
"APP_DATA_DIR_OVERRIDE": "${dollar}{DATA_STREAM_DATA_DIR}",
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf;config/profiles/data_stream/*.conf",
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0;${sourceDir}/build/$<CONFIG>/bin/net7.0-windows;${sourceDir}/build/$<CONFIG>/bin/net8.0",
"SHARED_MEMORY_PREFIX": "data_stream"
}
},
{
"name": "data-stream-suite-linux",
"displayName": "Data Stream Suite (Linux)",
"description": "Data Stream utils ported over from Edge",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"inherits": "sparkd",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"APP_DATA_DIR": "${dollar}{HOME}/.local/share/DataStream",
"APP_DATA_DIR_OVERRIDE": "${dollar}{DATA_STREAM_DATA_DIR}",
"BUILD_ADMIN_WEB_APP": {
"type": "BOOL",
"value": "OFF"
},
"BUILD_SDK": {
"type": "BOOL",
"value": "OFF"
},
"BUILD_SPARKD": {
"type": "BOOL",
"value": "OFF"
},
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG",
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"CONFIG_DEFAULTS_PATH": "config/profiles/default/*.conf;config/profiles/data_stream/*.conf",
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0;${sourceDir}/build/$<CONFIG>/bin/net8.0",
"EXPORT_MD_CONSUMER": {
"type": "BOOL",
"value": "ON"
},
"SHARED_MEMORY_PREFIX": "data_stream"
}
}
],
"buildPresets": [
{
"name": "spark",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"hidden": true
},
{
"name": "spark-debug",
"displayName": "Spark (Debug)",
"inherits": "spark",
"configurePreset": "spark",
"configuration": "Debug"
},
{
"name": "spark-release",
"displayName": "Spark (Release)",
"inherits": "spark",
"configurePreset": "spark",
"configuration": "Release"
},
{
"name": "sparkd",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"hidden": true,
"targets": [
"data_files_dir",
"admin_web_app_bundle",
"install",
"libspark",
"rapidjson_project",
"server_layout",
"sparkd"
]
},
{
"name": "sparkd-debug-clang",
"configurePreset": "sparkd-debug-clang",
"displayName": "Sparkd (Debug | Clang)",
"inherits": "sparkd"
},
{
"name": "sparkd-debug-gcc",
"configurePreset": "sparkd-debug-gcc",
"displayName": "Sparkd (Debug | Gcc)",
"inherits": "sparkd"
},
{
"name": "sparkd-release-clang",
"configurePreset": "sparkd-release-clang",
"displayName": "Sparkd (Release | Clang)",
"inherits": "sparkd"
},
{
"name": "sparkd-release-gcc",
"configurePreset": "sparkd-release-gcc",
"displayName": "Sparkd (Release | Gcc)",
"inherits": "sparkd"
},
{
"name": "spark-api-server-windows",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"hidden": true,
"configurePreset": "spark-api-server-windows"
},
{
"name": "spark-api-server-windows-debug",
"displayName": "Spark Api Server (Windows | Debug)",
"inherits": "spark-api-server-windows",
"configuration": "Debug"
},
{
"name": "spark-api-server-windows-release",
"displayName": "Spark Api Server (Windows | Release)",
"inherits": "spark-api-server-windows",
"configuration": "Release"
},
{
"name": "spark-api-server-linux",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"hidden": true,
"configurePreset": "spark-api-server-linux"
},
{
"name": "spark-api-server-linux-debug",
"inherits": "spark-api-server-linux",
"displayName": "Spark Api Server (Linux | Debug)",
"configuration": "Debug"
},
{
"name": "spark-api-server-linux-release",
"inherits": "spark-api-server-linux",
"displayName": "Spark Api Server (Linux | Release)",
"configuration": "Release"
},
{
"name": "sparkd-publish",
"configurePreset": "sparkd-publish",
"displayName": "Publish",
"inherits": "sparkd",
"targets": "install"
},
{
"name": "sparkd-ccapi-diag",
"configurePreset": "sparkd-ccapi-diag",
"displayName": "Debug (ccapi diag)",
"inherits": "sparkd"
},
{
"name": "data-stream-suite-windows-debug",
"displayName": "Data Stream Suite (Windows | Debug)",
"configurePreset": "data-stream-suite-windows",
"configuration": "Debug"
},
{
"name": "data-stream-suite-windows-release",
"displayName": "Data Stream Suite (Windows | Release)",
"configurePreset": "data-stream-suite-windows",
"configuration": "Release"
},
{
"name": "data-stream-suite-linux-debug",
"displayName": "Data Stream Suite (Linux | Debug)",
"configurePreset": "data-stream-suite-linux",
"configuration": "Debug"
},
{
"name": "data-stream-suite-linux-release",
"displayName": "Data Stream Suite (Linux | Release)",
"configurePreset": "data-stream-suite-linux",
"configuration": "Release"
}
]
}
-83
View File
@@ -1,83 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
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_core", "src\client\spark_core\spark_core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_websocket", "src\client\spark_websocket\spark_websocket.csproj", "{3201359D-C071-4089-9EDE-B04D759F1508}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api_server", "src\client\spark_api_server\spark_api_server.csproj", "{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "spark_test", "src\client\spark_test\spark_test.csproj", "{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Console", "src\client\Spark.Console\Spark.Console.csproj", "{89D666E6-B500-498F-B026-4D167F68ADFC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
MinSizeRel|x64 = MinSizeRel|x64
Release|x64 = Release|x64
RelWithDebInfo|x64 = RelWithDebInfo|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{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}.MinSizeRel|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.MinSizeRel|x64.Build.0 = 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}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.Build.0 = Release|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}.MinSizeRel|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.MinSizeRel|x64.Build.0 = 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}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.RelWithDebInfo|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.Build.0 = Release|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|x64.ActiveCfg = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Debug|x64.Build.0 = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|x64.ActiveCfg = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.MinSizeRel|x64.Build.0 = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|x64.ActiveCfg = Release|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.Release|x64.Build.0 = Release|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|x64.ActiveCfg = Debug|x64
{EFC9FC4D-E92B-4C6D-9B97-26D38EAA118D}.RelWithDebInfo|x64.Build.0 = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|x64.ActiveCfg = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Debug|x64.Build.0 = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|x64.ActiveCfg = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.MinSizeRel|x64.Build.0 = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|x64.ActiveCfg = Release|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.Release|x64.Build.0 = Release|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|x64.ActiveCfg = Debug|x64
{89D666E6-B500-498F-B026-4D167F68ADFC}.RelWithDebInfo|x64.Build.0 = Debug|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
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32630.192
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpreaderFrontEnd", "SpreaderFrontEnd\SpreaderFrontEnd.csproj", "{28EE9ABE-BBA6-4587-8BEB-3B0CD979ED22}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{28EE9ABE-BBA6-4587-8BEB-3B0CD979ED22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28EE9ABE-BBA6-4587-8BEB-3B0CD979ED22}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28EE9ABE-BBA6-4587-8BEB-3B0CD979ED22}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28EE9ABE-BBA6-4587-8BEB-3B0CD979ED22}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3E2EF0DA-32BB-4A7A-9089-B132E1677AA7}
EndGlobalSection
EndGlobal
@@ -0,0 +1,36 @@
using System;
using System.Linq;
namespace SpreaderFrontEnd {
public class Book : IEquatable<Book> {
public Book(BookSide bids = null, BookSide asks = null) {
this.bids = bids ?? new BookSide();
this.asks = asks ?? new BookSide();
}
public BookSide bids { get; }
public BookSide asks { get; }
public Book Clone() {
return new Book(
new BookSide(bids.levels.ToList()),
new BookSide(asks.levels.ToList()));
}
public bool Equals(Book other) {
return other != null && other.bids.Equals(bids) && other.asks.Equals(asks);
}
public override bool Equals(object obj) {
return Equals(obj as Book);
}
public override int GetHashCode() {
return HashCodeHelper.combine(bids.GetHashCode(), asks.GetHashCode());
}
public override string ToString() {
return $"bid: {bids} | ask: {asks}";
}
}
}
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace SpreaderFrontEnd {
public class BookSide : IEquatable<BookSide> {
public BookSide() {
levels = new List<PriceLevel>();
}
public BookSide(IEnumerable<PriceLevel> levels) {
this.levels = levels?.ToList() ?? new List<PriceLevel>();
}
public IList<PriceLevel> levels { get; }
public BookSide Clone() {
return new BookSide(levels.ToList());
}
public bool Equals(BookSide other) {
return other != null && levels.SequenceEqual(other.levels);
}
public override bool Equals(object obj) {
return Equals(obj as BookSide);
}
public override int GetHashCode() {
return levels.Select(l => l.GetHashCode()).Skip(1).Aggregate(
levels[0].GetHashCode(), HashCodeHelper.combine);
}
public override string ToString() {
return string.Join("; ", levels);
}
}
}
@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SpreaderFrontEnd {
public class LegCursor {
public LegCursor(int leg_size, IList<PriceLevel> levels) {
this.leg_size = leg_size;
this.levels = levels;
}
/// <summary>
/// The [signed] quantity of this leg in the SpreaderContract to which it belongs
/// </summary>
public int leg_size { get; }
/// <summary>
/// The [unsigned] quantity of this leg in the SpreaderContract to which it belongs
/// </summary>
public int leg_size_abs {
get {
return Math.Abs(leg_size);
}
}
/// <summary>
/// The price levels of the underlying BookSide
/// </summary>
public IList<PriceLevel> levels { get; }
/// <summary>
/// The index of the current level. When <see cref="consume_unit_qty(uint, out List{PriceLevel})"/>
/// is called, quantity consumption begins at this level. Once this level's quantity is fully
/// consumed, <see cref="cursor"/> is incremented, and <see cref="curr_level_consumed_qty"/>
/// is reset to 0.
/// </summary>
public int cursor { get; private set; }
/// <summary>
/// The quantity that has been consumed at the current level (i.e., the level at index
/// <see cref="cursor"/>)
/// </summary>
public uint curr_level_consumed_qty { get; private set; }
/// <summary>
/// Consumes the specified quantity of units at the best available price(s)
/// </summary>
/// <param name="unit_qty">
/// The unit quantity to consume
/// </param>
/// <returns>True if the entire quantity is consumed, otherwise false.</returns>
public bool consume_unit_qty(uint unit_qty, out List<PriceLevel> consumed_levels) {
consumed_levels = new List<PriceLevel>();
uint marg_qty = (uint)(unit_qty * leg_size_abs);
var consumed_qty = _consume_raw_qty(marg_qty, ref consumed_levels);
Debug.Assert(consumed_qty % leg_size_abs == 0);
uint consumed_units = (uint)(consumed_qty / leg_size_abs);
return consumed_units == unit_qty;
}
/// <summary>
/// Gets the number of units (raw_quantity / leg_size_abs) available at the best price
/// </summary>
public PriceLevel curr_synth_level() {
if (cursor >= levels.Count) {
return PriceLevel.empty;
}
var curr_level = levels[cursor];
Debug.Assert(curr_level.qty >= curr_level_consumed_qty);
var curr_level_rem_qty = curr_level.qty - curr_level_consumed_qty;
if (curr_level_rem_qty >= leg_size_abs) {
return new PriceLevel(
price: curr_level.price * leg_size_abs,
qty: (uint)(curr_level_rem_qty / leg_size_abs));
}
double unit_cost = curr_level.price * curr_level_rem_qty;
var unit_rem = leg_size_abs - curr_level_rem_qty;
for (int i = cursor + 1; i < levels.Count; i++) {
curr_level = levels[i];
if (curr_level.qty >= unit_rem) {
unit_cost += curr_level.price * unit_rem;
return new PriceLevel(price: unit_cost, qty: 1);
}
unit_cost += curr_level.price * curr_level.qty;
unit_rem -= curr_level.qty;
}
return PriceLevel.empty;
}
/// <summary>
/// Consumes as much of the specified [raw] quantity as possible
/// </summary>
/// <returns>
/// The quantity that was actually consumed
/// </returns>
uint _consume_raw_qty(uint raw_qty, ref List<PriceLevel> dest) {
if (levels == null || cursor >= levels.Count) {
return 0;
}
var curr_level = levels[cursor];
// Cursor should be incremented when curr_level_consumed_qty == levels[cursor].qty
// (i.e., curr_level.qty should never be less than curr_level_consumed_qty)
Debug.Assert(curr_level.qty > curr_level_consumed_qty);
var curr_level_qty_rem = curr_level.qty - curr_level_consumed_qty;
if (curr_level_qty_rem > raw_qty) {
curr_level_consumed_qty += raw_qty;
dest.Add(new PriceLevel(price: curr_level.price, qty: raw_qty));
return raw_qty;
}
// The input qty is greater than the qty that remains at this level. Consume the rest on
// the next level.
cursor++;
curr_level_consumed_qty = 0;
dest.Add(new PriceLevel(price: curr_level.price, qty: curr_level_qty_rem));
return curr_level_qty_rem + _consume_raw_qty(raw_qty - curr_level_qty_rem, ref dest);
}
}
}
@@ -0,0 +1,44 @@
using System;
namespace SpreaderFrontEnd {
public struct PriceLevel : IEquatable<PriceLevel> {
public PriceLevel(double price, uint qty) {
this.price = price;
this.qty = qty;
}
public static PriceLevel empty {
get {
return new PriceLevel(double.NaN, 0);
}
}
public double price { get; }
public uint qty { get; }
public PriceLevel subtract_qty(uint value) {
System.Diagnostics.Debug.Assert(value <= qty);
return new PriceLevel(price, qty - value);
}
public PriceLevel add_qty(uint value) {
return new PriceLevel(price, qty + value);
}
public override string ToString() {
return $"{price} ({qty})";
}
public bool Equals(PriceLevel other) {
return qty == other.qty && price.Equals(other.price);
}
public override bool Equals(object obj) {
return obj is PriceLevel other && Equals(other);
}
public override int GetHashCode() {
return HashCodeHelper.combine(price.GetHashCode(), qty.GetHashCode());
}
}
}
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace SpreaderFrontEnd {
public static class SpreaderBookCalculator {
public static Book compute_spreader_book(
SpreaderContract contract, IEnumerable<Book> leg_books) {
if (contract == null) {
throw new ArgumentNullException(nameof(contract));
}
if (leg_books == null) {
throw new ArgumentNullException(nameof(leg_books));
}
var leg_book_list = leg_books as IList<Book> ?? leg_books.ToList();
var synth_book = new SyntheticBook(contract, leg_book_list);
return synth_book.to_book();
}
public static BookSide compute_spreader_book_side(
SpreaderContract contract, IList<Book> leg_books, bool is_bid) {
Debug.Assert(contract.spread_legs.Count == leg_books.Count);
var leg_cursors = leg_books.Select((b, i) => new LegCursor(
contract.spread_legs[i].qty,
contract.spread_legs[i].qty < 0 == is_bid ? b.asks.levels : b.bids.levels)).ToList();
var level_qty = leg_cursors.Select(lc => lc.curr_synth_level().qty).Min();
var result = new BookSide();
while (level_qty > 0) {
double level_price = 0;
for (int i = 0; i < leg_cursors.Count; i++) {
var lc = leg_cursors[i];
bool did_consume = lc.consume_unit_qty(level_qty, out var consumed_levels);
Debug.Assert(did_consume);
var leg_cost = consumed_levels.Select(l => l.price * l.qty).Sum() / level_qty;
if (lc.leg_size < 0) {
level_price -= leg_cost;
} else {
level_price += leg_cost;
}
}
result.levels.Add(new PriceLevel(price: level_price, qty: level_qty));
level_qty = leg_cursors.Select(lc => lc.curr_synth_level().qty).Min();
}
return result;
}
}
}
@@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace SpreaderFrontEnd {
class SyntheticBook {
public SyntheticBook(SpreaderContract contract, IList<Book> leg_books) {
bids = new SyntheticBookSide(contract, leg_books, true);
asks = new SyntheticBookSide(contract, leg_books, false);
}
public SyntheticBookSide bids { get; }
public SyntheticBookSide asks { get; }
public Book to_book() {
return new Book(bids: bids.to_book_side(), asks: asks.to_book_side());
}
}
}
@@ -0,0 +1,28 @@
using System.Collections;
using System.Collections.Generic;
namespace SpreaderFrontEnd {
class SyntheticBookSide : IEnumerable<PriceLevel> {
readonly SpreaderContract _contract;
readonly IList<Book> _leg_books;
readonly bool _is_bid;
public SyntheticBookSide(SpreaderContract contract, IList<Book> leg_books, bool is_bid) {
_contract = contract;
_leg_books = leg_books;
_is_bid = is_bid;
}
public BookSide to_book_side() {
return new BookSide(this);
}
public IEnumerator<PriceLevel> GetEnumerator() {
return new SyntheticBookSideEnumerator(_contract, _leg_books, _is_bid);
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
}
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Collections;
namespace SpreaderFrontEnd {
class SyntheticBookSideEnumerator : IEnumerator<PriceLevel> {
readonly List<LegCursor> _leg_cursors;
PriceLevel _current;
uint _level_qty;
public SyntheticBookSideEnumerator(
SpreaderContract contract, IList<Book> leg_books, bool is_bid) {
Debug.Assert(contract.spread_legs.Count == leg_books.Count);
_leg_cursors = new List<LegCursor>(leg_books.Count);
for (int i = 0; i < leg_books.Count; i++) {
_leg_cursors.Add(new LegCursor(
contract.spread_legs[i].qty,
contract.spread_legs[i].qty < 0 == is_bid ?
leg_books[i].asks.levels : leg_books[i].bids.levels));
}
}
public PriceLevel Current => _current;
object IEnumerator.Current => _current;
public void Dispose() { }
public bool MoveNext() {
_level_qty = _leg_cursors.Select(lc => lc.curr_synth_level().qty).Min();
if (_level_qty == 0) {
return false;
}
double level_price = 0;
for (int i = 0; i < _leg_cursors.Count; i++) {
var lc = _leg_cursors[i];
bool did_consume = lc.consume_unit_qty(_level_qty, out var consumed_levels);
Debug.Assert(did_consume);
var leg_cost = consumed_levels.Select(l => l.price * l.qty).Sum() / _level_qty;
if (lc.leg_size < 0) {
level_price -= leg_cost;
} else {
level_price += leg_cost;
}
}
_current = new PriceLevel(price: level_price, qty: _level_qty);
return true;
}
public void Reset() {
for (int i = 0; i < _leg_cursors.Count; i++) {
var lc = _leg_cursors[i];
_leg_cursors[i] = new LegCursor(lc.leg_size, lc.levels);
}
}
}
}
@@ -0,0 +1,8 @@
namespace SpreaderFrontEnd {
static class HashCodeHelper {
// Copied from https://referencesource.microsoft.com/#System.Numerics/System/Numerics/HashCodeHelper.cs
public static int combine(int h1, int h2) {
return (((h1 << 5) + h1) ^ h2);
}
}
}
+744
View File
@@ -0,0 +1,744 @@
using System.Windows.Forms;
namespace SpreaderFrontEnd
{
partial class LegControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this._combobox_security = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this._textbox_quote_qho_length = new System.Windows.Forms.TextBox();
this._textbox_quote_insidemarketdistance_towarddistance = new System.Windows.Forms.TextBox();
this._textbox_quote_conditional_ticks = new System.Windows.Forms.TextBox();
this._textbox_quote_throttle_outsideticks = new System.Windows.Forms.TextBox();
this._textbox_quote_throttle_insideticks = new System.Windows.Forms.TextBox();
this._textbox_quote_showqty_qty = new System.Windows.Forms.TextBox();
this.label11 = new System.Windows.Forms.Label();
this._checkbox_quote_insidemarketdistance = new System.Windows.Forms.CheckBox();
this.label10 = new System.Windows.Forms.Label();
this._checkbox_quote_conditional = new System.Windows.Forms.CheckBox();
this.label9 = new System.Windows.Forms.Label();
this.label8 = new System.Windows.Forms.Label();
this._checkbox_quote_throttle = new System.Windows.Forms.CheckBox();
this.label7 = new System.Windows.Forms.Label();
this._checkbox_quote_showqty = new System.Windows.Forms.CheckBox();
this.label6 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this._textbox_prehedge_payless_paylessticks = new System.Windows.Forms.TextBox();
this._textbox_prehedge_payup_payupticks = new System.Windows.Forms.TextBox();
this._textbox_prehedge_payup_threshold = new System.Windows.Forms.TextBox();
this._textbox_prehedge_payless_threshold = new System.Windows.Forms.TextBox();
this.label13 = new System.Windows.Forms.Label();
this.label14 = new System.Windows.Forms.Label();
this.label15 = new System.Windows.Forms.Label();
this._checkbox_prehedge_payup = new System.Windows.Forms.CheckBox();
this.label16 = new System.Windows.Forms.Label();
this._checkbox_prehedge_payless = new System.Windows.Forms.CheckBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this._textbox_posthedge_sizebasedcross_crossticks = new System.Windows.Forms.TextBox();
this._textbox_posthedge_sizebasedcross_threshold = new System.Windows.Forms.TextBox();
this._textbox_posthedge_timesbasedcross_crossticks = new System.Windows.Forms.TextBox();
this._textbox_posthedge_timesbasedcross_timems = new System.Windows.Forms.TextBox();
this._textbox_posthedge_ticksawaycross_crossticks = new System.Windows.Forms.TextBox();
this._textbox_posthedge_ticksawaycross_threshold = new System.Windows.Forms.TextBox();
this.label20 = new System.Windows.Forms.Label();
this.label21 = new System.Windows.Forms.Label();
this._checkbox_posthedge_sizebasedcross = new System.Windows.Forms.CheckBox();
this.label12 = new System.Windows.Forms.Label();
this.label17 = new System.Windows.Forms.Label();
this.label18 = new System.Windows.Forms.Label();
this._checkbox_posthedge_timebasedcross = new System.Windows.Forms.CheckBox();
this.label19 = new System.Windows.Forms.Label();
this._checkbox_posthedge_ticksawaycross = new System.Windows.Forms.CheckBox();
this._textbox_leg_qty = new System.Windows.Forms.TextBox();
this._checkbox_leg_enablequoting = new System.Windows.Forms.CheckBox();
this._textbox_leg_leanqtyfactor = new System.Windows.Forms.TextBox();
this._combobox_mdtype = new System.Windows.Forms.ComboBox();
this._textbox_leg_price_mult = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this._label_leanqty_factor = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
this.SuspendLayout();
//
// _combobox_security
//
this._combobox_security.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this._combobox_security.FormattingEnabled = true;
this._combobox_security.Location = new System.Drawing.Point(157, 15);
this._combobox_security.Name = "_combobox_security";
this._combobox_security.Size = new System.Drawing.Size(100, 23);
this._combobox_security.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(16, 23);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(49, 15);
this.label1.TabIndex = 1;
this.label1.Text = "Security";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(16, 58);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 15);
this.label2.TabIndex = 2;
this.label2.Text = "Quantity";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(16, 128);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(89, 15);
this.label3.TabIndex = 3;
this.label3.Text = "Enable Quoting";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(16, 198);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(98, 15);
this.label5.TabIndex = 5;
this.label5.Text = "Market Data Type";
//
// groupBox1
//
this.groupBox1.Controls.Add(this._textbox_quote_qho_length);
this.groupBox1.Controls.Add(this._textbox_quote_insidemarketdistance_towarddistance);
this.groupBox1.Controls.Add(this._textbox_quote_conditional_ticks);
this.groupBox1.Controls.Add(this._textbox_quote_throttle_outsideticks);
this.groupBox1.Controls.Add(this._textbox_quote_throttle_insideticks);
this.groupBox1.Controls.Add(this._textbox_quote_showqty_qty);
this.groupBox1.Controls.Add(this.label11);
this.groupBox1.Controls.Add(this._checkbox_quote_insidemarketdistance);
this.groupBox1.Controls.Add(this.label10);
this.groupBox1.Controls.Add(this._checkbox_quote_conditional);
this.groupBox1.Controls.Add(this.label9);
this.groupBox1.Controls.Add(this.label8);
this.groupBox1.Controls.Add(this._checkbox_quote_throttle);
this.groupBox1.Controls.Add(this.label7);
this.groupBox1.Controls.Add(this._checkbox_quote_showqty);
this.groupBox1.Controls.Add(this.label6);
this.groupBox1.ForeColor = System.Drawing.Color.Black;
this.groupBox1.Location = new System.Drawing.Point(12, 238);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(265, 369);
this.groupBox1.TabIndex = 6;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Quote";
//
// _textbox_quote_qho_length
//
this._textbox_quote_qho_length.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_quote_qho_length.Location = new System.Drawing.Point(145, 28);
this._textbox_quote_qho_length.Name = "_textbox_quote_qho_length";
this._textbox_quote_qho_length.Size = new System.Drawing.Size(100, 23);
this._textbox_quote_qho_length.TabIndex = 6;
//
// _textbox_quote_insidemarketdistance_towarddistance
//
this._textbox_quote_insidemarketdistance_towarddistance.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_quote_insidemarketdistance_towarddistance.Location = new System.Drawing.Point(145, 314);
this._textbox_quote_insidemarketdistance_towarddistance.Name = "_textbox_quote_insidemarketdistance_towarddistance";
this._textbox_quote_insidemarketdistance_towarddistance.Size = new System.Drawing.Size(100, 23);
this._textbox_quote_insidemarketdistance_towarddistance.TabIndex = 15;
//
// _textbox_quote_conditional_ticks
//
this._textbox_quote_conditional_ticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_quote_conditional_ticks.Location = new System.Drawing.Point(145, 250);
this._textbox_quote_conditional_ticks.Name = "_textbox_quote_conditional_ticks";
this._textbox_quote_conditional_ticks.Size = new System.Drawing.Size(100, 23);
this._textbox_quote_conditional_ticks.TabIndex = 13;
//
// _textbox_quote_throttle_outsideticks
//
this._textbox_quote_throttle_outsideticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_quote_throttle_outsideticks.Location = new System.Drawing.Point(145, 186);
this._textbox_quote_throttle_outsideticks.Name = "_textbox_quote_throttle_outsideticks";
this._textbox_quote_throttle_outsideticks.Size = new System.Drawing.Size(100, 23);
this._textbox_quote_throttle_outsideticks.TabIndex = 11;
//
// _textbox_quote_throttle_insideticks
//
this._textbox_quote_throttle_insideticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_quote_throttle_insideticks.Location = new System.Drawing.Point(145, 156);
this._textbox_quote_throttle_insideticks.Name = "_textbox_quote_throttle_insideticks";
this._textbox_quote_throttle_insideticks.Size = new System.Drawing.Size(100, 23);
this._textbox_quote_throttle_insideticks.TabIndex = 10;
//
// _textbox_quote_showqty_qty
//
this._textbox_quote_showqty_qty.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_quote_showqty_qty.Location = new System.Drawing.Point(145, 92);
this._textbox_quote_showqty_qty.Name = "_textbox_quote_showqty_qty";
this._textbox_quote_showqty_qty.Size = new System.Drawing.Size(100, 23);
this._textbox_quote_showqty_qty.TabIndex = 8;
//
// label11
//
this.label11.AutoSize = true;
this.label11.Location = new System.Drawing.Point(45, 322);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(93, 15);
this.label11.TabIndex = 16;
this.label11.Text = "Toward Distance";
//
// _checkbox_quote_insidemarketdistance
//
this._checkbox_quote_insidemarketdistance.AutoSize = true;
this._checkbox_quote_insidemarketdistance.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_quote_insidemarketdistance.Location = new System.Drawing.Point(15, 288);
this._checkbox_quote_insidemarketdistance.Name = "_checkbox_quote_insidemarketdistance";
this._checkbox_quote_insidemarketdistance.Size = new System.Drawing.Size(131, 19);
this._checkbox_quote_insidemarketdistance.TabIndex = 14;
this._checkbox_quote_insidemarketdistance.Text = "Inside Market Dist.";
this._checkbox_quote_insidemarketdistance.UseVisualStyleBackColor = true;
this._checkbox_quote_insidemarketdistance.CheckedChanged += new System.EventHandler(this._checkbox_quote_insidemarketdistance_CheckedChanged);
//
// label10
//
this.label10.AutoSize = true;
this.label10.Location = new System.Drawing.Point(47, 258);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(33, 15);
this.label10.TabIndex = 14;
this.label10.Text = "Ticks";
//
// _checkbox_quote_conditional
//
this._checkbox_quote_conditional.AutoSize = true;
this._checkbox_quote_conditional.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_quote_conditional.Location = new System.Drawing.Point(15, 224);
this._checkbox_quote_conditional.Name = "_checkbox_quote_conditional";
this._checkbox_quote_conditional.Size = new System.Drawing.Size(88, 19);
this._checkbox_quote_conditional.TabIndex = 12;
this._checkbox_quote_conditional.Text = "Conditional";
this._checkbox_quote_conditional.UseVisualStyleBackColor = true;
this._checkbox_quote_conditional.CheckedChanged += new System.EventHandler(this._checkbox_quote_conditional_CheckedChanged);
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(45, 194);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(77, 15);
this.label9.TabIndex = 12;
this.label9.Text = "Outside Ticks";
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(45, 164);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(67, 15);
this.label8.TabIndex = 11;
this.label8.Text = "Inside Ticks";
//
// _checkbox_quote_throttle
//
this._checkbox_quote_throttle.AutoSize = true;
this._checkbox_quote_throttle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_quote_throttle.Location = new System.Drawing.Point(15, 130);
this._checkbox_quote_throttle.Name = "_checkbox_quote_throttle";
this._checkbox_quote_throttle.Size = new System.Drawing.Size(72, 19);
this._checkbox_quote_throttle.TabIndex = 9;
this._checkbox_quote_throttle.Text = "Throttle";
this._checkbox_quote_throttle.UseVisualStyleBackColor = true;
this._checkbox_quote_throttle.CheckedChanged += new System.EventHandler(this._checkbox_quote_throttle_CheckedChanged);
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(45, 100);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(53, 15);
this.label7.TabIndex = 9;
this.label7.Text = "Quantity";
//
// _checkbox_quote_showqty
//
this._checkbox_quote_showqty.AutoSize = true;
this._checkbox_quote_showqty.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_quote_showqty.Location = new System.Drawing.Point(15, 66);
this._checkbox_quote_showqty.Name = "_checkbox_quote_showqty";
this._checkbox_quote_showqty.Size = new System.Drawing.Size(108, 19);
this._checkbox_quote_showqty.TabIndex = 7;
this._checkbox_quote_showqty.Text = "Show Quantity";
this._checkbox_quote_showqty.UseVisualStyleBackColor = true;
this._checkbox_quote_showqty.CheckedChanged += new System.EventHandler(this._checkbox_quote_showqty_CheckedChanged);
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(15, 36);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(121, 15);
this.label6.TabIndex = 6;
this.label6.Text = "Queue Holder Length";
//
// groupBox2
//
this.groupBox2.Controls.Add(this._textbox_prehedge_payless_paylessticks);
this.groupBox2.Controls.Add(this._textbox_prehedge_payup_payupticks);
this.groupBox2.Controls.Add(this._textbox_prehedge_payup_threshold);
this.groupBox2.Controls.Add(this._textbox_prehedge_payless_threshold);
this.groupBox2.Controls.Add(this.label13);
this.groupBox2.Controls.Add(this.label14);
this.groupBox2.Controls.Add(this.label15);
this.groupBox2.Controls.Add(this._checkbox_prehedge_payup);
this.groupBox2.Controls.Add(this.label16);
this.groupBox2.Controls.Add(this._checkbox_prehedge_payless);
this.groupBox2.Location = new System.Drawing.Point(13, 626);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(264, 234);
this.groupBox2.TabIndex = 7;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Pre-Hedge";
//
// _textbox_prehedge_payless_paylessticks
//
this._textbox_prehedge_payless_paylessticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_prehedge_payless_paylessticks.Location = new System.Drawing.Point(144, 90);
this._textbox_prehedge_payless_paylessticks.Name = "_textbox_prehedge_payless_paylessticks";
this._textbox_prehedge_payless_paylessticks.Size = new System.Drawing.Size(100, 23);
this._textbox_prehedge_payless_paylessticks.TabIndex = 18;
//
// _textbox_prehedge_payup_payupticks
//
this._textbox_prehedge_payup_payupticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_prehedge_payup_payupticks.Location = new System.Drawing.Point(144, 187);
this._textbox_prehedge_payup_payupticks.Name = "_textbox_prehedge_payup_payupticks";
this._textbox_prehedge_payup_payupticks.Size = new System.Drawing.Size(100, 23);
this._textbox_prehedge_payup_payupticks.TabIndex = 21;
//
// _textbox_prehedge_payup_threshold
//
this._textbox_prehedge_payup_threshold.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_prehedge_payup_threshold.Location = new System.Drawing.Point(144, 156);
this._textbox_prehedge_payup_threshold.Name = "_textbox_prehedge_payup_threshold";
this._textbox_prehedge_payup_threshold.Size = new System.Drawing.Size(100, 23);
this._textbox_prehedge_payup_threshold.TabIndex = 20;
//
// _textbox_prehedge_payless_threshold
//
this._textbox_prehedge_payless_threshold.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_prehedge_payless_threshold.Location = new System.Drawing.Point(144, 59);
this._textbox_prehedge_payless_threshold.Name = "_textbox_prehedge_payless_threshold";
this._textbox_prehedge_payless_threshold.Size = new System.Drawing.Size(100, 23);
this._textbox_prehedge_payless_threshold.TabIndex = 17;
//
// label13
//
this.label13.AutoSize = true;
this.label13.Location = new System.Drawing.Point(44, 98);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(74, 15);
this.label13.TabIndex = 14;
this.label13.Text = "Payless Ticks";
//
// label14
//
this.label14.AutoSize = true;
this.label14.Location = new System.Drawing.Point(44, 195);
this.label14.Name = "label14";
this.label14.Size = new System.Drawing.Size(69, 15);
this.label14.TabIndex = 12;
this.label14.Text = "Payup Ticks";
//
// label15
//
this.label15.AutoSize = true;
this.label15.Location = new System.Drawing.Point(44, 164);
this.label15.Name = "label15";
this.label15.Size = new System.Drawing.Size(59, 15);
this.label15.TabIndex = 11;
this.label15.Text = "Threshold";
//
// _checkbox_prehedge_payup
//
this._checkbox_prehedge_payup.AutoSize = true;
this._checkbox_prehedge_payup.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_prehedge_payup.Location = new System.Drawing.Point(15, 129);
this._checkbox_prehedge_payup.Name = "_checkbox_prehedge_payup";
this._checkbox_prehedge_payup.Size = new System.Drawing.Size(64, 19);
this._checkbox_prehedge_payup.TabIndex = 19;
this._checkbox_prehedge_payup.Text = "Pay Up";
this._checkbox_prehedge_payup.UseVisualStyleBackColor = true;
this._checkbox_prehedge_payup.CheckedChanged += new System.EventHandler(this._checkbox_prehedge_payup_CheckedChanged);
//
// label16
//
this.label16.AutoSize = true;
this.label16.Location = new System.Drawing.Point(44, 67);
this.label16.Name = "label16";
this.label16.Size = new System.Drawing.Size(59, 15);
this.label16.TabIndex = 9;
this.label16.Text = "Threshold";
//
// _checkbox_prehedge_payless
//
this._checkbox_prehedge_payless.AutoSize = true;
this._checkbox_prehedge_payless.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_prehedge_payless.Location = new System.Drawing.Point(15, 32);
this._checkbox_prehedge_payless.Name = "_checkbox_prehedge_payless";
this._checkbox_prehedge_payless.Size = new System.Drawing.Size(71, 19);
this._checkbox_prehedge_payless.TabIndex = 16;
this._checkbox_prehedge_payless.Text = "Pay Less";
this._checkbox_prehedge_payless.UseVisualStyleBackColor = true;
this._checkbox_prehedge_payless.CheckedChanged += new System.EventHandler(this._checkbox_prehedge_payless_CheckedChanged);
//
// groupBox3
//
this.groupBox3.Controls.Add(this._textbox_posthedge_sizebasedcross_crossticks);
this.groupBox3.Controls.Add(this._textbox_posthedge_sizebasedcross_threshold);
this.groupBox3.Controls.Add(this._textbox_posthedge_timesbasedcross_crossticks);
this.groupBox3.Controls.Add(this._textbox_posthedge_timesbasedcross_timems);
this.groupBox3.Controls.Add(this._textbox_posthedge_ticksawaycross_crossticks);
this.groupBox3.Controls.Add(this._textbox_posthedge_ticksawaycross_threshold);
this.groupBox3.Controls.Add(this.label20);
this.groupBox3.Controls.Add(this.label21);
this.groupBox3.Controls.Add(this._checkbox_posthedge_sizebasedcross);
this.groupBox3.Controls.Add(this.label12);
this.groupBox3.Controls.Add(this.label17);
this.groupBox3.Controls.Add(this.label18);
this.groupBox3.Controls.Add(this._checkbox_posthedge_timebasedcross);
this.groupBox3.Controls.Add(this.label19);
this.groupBox3.Controls.Add(this._checkbox_posthedge_ticksawaycross);
this.groupBox3.Location = new System.Drawing.Point(13, 882);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(264, 319);
this.groupBox3.TabIndex = 8;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Post-Hedge";
//
// _textbox_posthedge_sizebasedcross_crossticks
//
this._textbox_posthedge_sizebasedcross_crossticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_posthedge_sizebasedcross_crossticks.Location = new System.Drawing.Point(144, 276);
this._textbox_posthedge_sizebasedcross_crossticks.Name = "_textbox_posthedge_sizebasedcross_crossticks";
this._textbox_posthedge_sizebasedcross_crossticks.Size = new System.Drawing.Size(100, 23);
this._textbox_posthedge_sizebasedcross_crossticks.TabIndex = 30;
//
// _textbox_posthedge_sizebasedcross_threshold
//
this._textbox_posthedge_sizebasedcross_threshold.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_posthedge_sizebasedcross_threshold.Location = new System.Drawing.Point(144, 246);
this._textbox_posthedge_sizebasedcross_threshold.Name = "_textbox_posthedge_sizebasedcross_threshold";
this._textbox_posthedge_sizebasedcross_threshold.Size = new System.Drawing.Size(100, 23);
this._textbox_posthedge_sizebasedcross_threshold.TabIndex = 29;
//
// _textbox_posthedge_timesbasedcross_crossticks
//
this._textbox_posthedge_timesbasedcross_crossticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_posthedge_timesbasedcross_crossticks.Location = new System.Drawing.Point(144, 182);
this._textbox_posthedge_timesbasedcross_crossticks.Name = "_textbox_posthedge_timesbasedcross_crossticks";
this._textbox_posthedge_timesbasedcross_crossticks.Size = new System.Drawing.Size(100, 23);
this._textbox_posthedge_timesbasedcross_crossticks.TabIndex = 27;
//
// _textbox_posthedge_timesbasedcross_timems
//
this._textbox_posthedge_timesbasedcross_timems.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_posthedge_timesbasedcross_timems.Location = new System.Drawing.Point(144, 152);
this._textbox_posthedge_timesbasedcross_timems.Name = "_textbox_posthedge_timesbasedcross_timems";
this._textbox_posthedge_timesbasedcross_timems.Size = new System.Drawing.Size(100, 23);
this._textbox_posthedge_timesbasedcross_timems.TabIndex = 26;
//
// _textbox_posthedge_ticksawaycross_crossticks
//
this._textbox_posthedge_ticksawaycross_crossticks.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_posthedge_ticksawaycross_crossticks.Location = new System.Drawing.Point(144, 88);
this._textbox_posthedge_ticksawaycross_crossticks.Name = "_textbox_posthedge_ticksawaycross_crossticks";
this._textbox_posthedge_ticksawaycross_crossticks.Size = new System.Drawing.Size(100, 23);
this._textbox_posthedge_ticksawaycross_crossticks.TabIndex = 24;
//
// _textbox_posthedge_ticksawaycross_threshold
//
this._textbox_posthedge_ticksawaycross_threshold.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_posthedge_ticksawaycross_threshold.Location = new System.Drawing.Point(144, 58);
this._textbox_posthedge_ticksawaycross_threshold.Name = "_textbox_posthedge_ticksawaycross_threshold";
this._textbox_posthedge_ticksawaycross_threshold.Size = new System.Drawing.Size(100, 23);
this._textbox_posthedge_ticksawaycross_threshold.TabIndex = 23;
//
// label20
//
this.label20.AutoSize = true;
this.label20.Location = new System.Drawing.Point(44, 284);
this.label20.Name = "label20";
this.label20.Size = new System.Drawing.Size(65, 15);
this.label20.TabIndex = 17;
this.label20.Text = "Cross Ticks";
//
// label21
//
this.label21.AutoSize = true;
this.label21.Location = new System.Drawing.Point(44, 254);
this.label21.Name = "label21";
this.label21.Size = new System.Drawing.Size(59, 15);
this.label21.TabIndex = 16;
this.label21.Text = "Threshold";
//
// _checkbox_posthedge_sizebasedcross
//
this._checkbox_posthedge_sizebasedcross.AutoSize = true;
this._checkbox_posthedge_sizebasedcross.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_posthedge_sizebasedcross.Location = new System.Drawing.Point(15, 220);
this._checkbox_posthedge_sizebasedcross.Name = "_checkbox_posthedge_sizebasedcross";
this._checkbox_posthedge_sizebasedcross.Size = new System.Drawing.Size(117, 19);
this._checkbox_posthedge_sizebasedcross.TabIndex = 28;
this._checkbox_posthedge_sizebasedcross.Text = "Size Based Cross";
this._checkbox_posthedge_sizebasedcross.UseVisualStyleBackColor = true;
this._checkbox_posthedge_sizebasedcross.CheckedChanged += new System.EventHandler(this._checkbox_posthedge_sizebasedcross_CheckedChanged);
//
// label12
//
this.label12.AutoSize = true;
this.label12.Location = new System.Drawing.Point(44, 96);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(65, 15);
this.label12.TabIndex = 14;
this.label12.Text = "Cross Ticks";
//
// label17
//
this.label17.AutoSize = true;
this.label17.Location = new System.Drawing.Point(44, 190);
this.label17.Name = "label17";
this.label17.Size = new System.Drawing.Size(65, 15);
this.label17.TabIndex = 12;
this.label17.Text = "Cross Ticks";
//
// label18
//
this.label18.AutoSize = true;
this.label18.Location = new System.Drawing.Point(44, 160);
this.label18.Name = "label18";
this.label18.Size = new System.Drawing.Size(57, 15);
this.label18.TabIndex = 11;
this.label18.Text = "Time(ms)";
//
// _checkbox_posthedge_timebasedcross
//
this._checkbox_posthedge_timebasedcross.AutoSize = true;
this._checkbox_posthedge_timebasedcross.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_posthedge_timebasedcross.Location = new System.Drawing.Point(15, 126);
this._checkbox_posthedge_timebasedcross.Name = "_checkbox_posthedge_timebasedcross";
this._checkbox_posthedge_timebasedcross.Size = new System.Drawing.Size(122, 19);
this._checkbox_posthedge_timebasedcross.TabIndex = 25;
this._checkbox_posthedge_timebasedcross.Text = "Time Based Cross";
this._checkbox_posthedge_timebasedcross.UseVisualStyleBackColor = true;
this._checkbox_posthedge_timebasedcross.CheckedChanged += new System.EventHandler(this._checkbox_posthedge_timebasedcross_CheckedChanged);
//
// label19
//
this.label19.AutoSize = true;
this.label19.Location = new System.Drawing.Point(44, 66);
this.label19.Name = "label19";
this.label19.Size = new System.Drawing.Size(59, 15);
this.label19.TabIndex = 9;
this.label19.Text = "Threshold";
//
// _checkbox_posthedge_ticksawaycross
//
this._checkbox_posthedge_ticksawaycross.AutoSize = true;
this._checkbox_posthedge_ticksawaycross.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this._checkbox_posthedge_ticksawaycross.Location = new System.Drawing.Point(15, 32);
this._checkbox_posthedge_ticksawaycross.Name = "_checkbox_posthedge_ticksawaycross";
this._checkbox_posthedge_ticksawaycross.Size = new System.Drawing.Size(119, 19);
this._checkbox_posthedge_ticksawaycross.TabIndex = 22;
this._checkbox_posthedge_ticksawaycross.Text = "Ticks Away Cross";
this._checkbox_posthedge_ticksawaycross.UseVisualStyleBackColor = true;
this._checkbox_posthedge_ticksawaycross.CheckedChanged += new System.EventHandler(this._checkbox_posthedge_ticksawaycross_CheckedChanged);
//
// _textbox_leg_qty
//
this._textbox_leg_qty.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_leg_qty.Location = new System.Drawing.Point(157, 50);
this._textbox_leg_qty.Name = "_textbox_leg_qty";
this._textbox_leg_qty.Size = new System.Drawing.Size(100, 23);
this._textbox_leg_qty.TabIndex = 1;
this._textbox_leg_qty.Tag = "Double";
//
// _checkbox_leg_enablequoting
//
this._checkbox_leg_enablequoting.AutoSize = true;
this._checkbox_leg_enablequoting.Location = new System.Drawing.Point(157, 129);
this._checkbox_leg_enablequoting.Name = "_checkbox_leg_enablequoting";
this._checkbox_leg_enablequoting.Size = new System.Drawing.Size(15, 14);
this._checkbox_leg_enablequoting.TabIndex = 3;
this._checkbox_leg_enablequoting.UseVisualStyleBackColor = true;
//
// _textbox_leg_leanqtyfactor
//
this._textbox_leg_leanqtyfactor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_leg_leanqtyfactor.Location = new System.Drawing.Point(157, 155);
this._textbox_leg_leanqtyfactor.Name = "_textbox_leg_leanqtyfactor";
this._textbox_leg_leanqtyfactor.Size = new System.Drawing.Size(100, 23);
this._textbox_leg_leanqtyfactor.TabIndex = 4;
//
// _combobox_mdtype
//
this._combobox_mdtype.AutoCompleteCustomSource.AddRange(new string[] {
"Merged",
"Direct"});
this._combobox_mdtype.FormattingEnabled = true;
this._combobox_mdtype.Location = new System.Drawing.Point(157, 190);
this._combobox_mdtype.Name = "_combobox_mdtype";
this._combobox_mdtype.Size = new System.Drawing.Size(100, 23);
this._combobox_mdtype.TabIndex = 5;
//
// _textbox_leg_price_mult
//
this._textbox_leg_price_mult.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this._textbox_leg_price_mult.Location = new System.Drawing.Point(157, 85);
this._textbox_leg_price_mult.Name = "_textbox_leg_price_mult";
this._textbox_leg_price_mult.Size = new System.Drawing.Size(100, 23);
this._textbox_leg_price_mult.TabIndex = 2;
this._textbox_leg_price_mult.Tag = "Double";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(16, 93);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(87, 15);
this.label4.TabIndex = 10;
this.label4.Text = "Price Multiplier";
//
// _label_leanqty_factor
//
this._label_leanqty_factor.AutoSize = true;
this._label_leanqty_factor.Location = new System.Drawing.Point(16, 163);
this._label_leanqty_factor.Name = "_label_leanqty_factor";
this._label_leanqty_factor.Size = new System.Drawing.Size(90, 15);
this._label_leanqty_factor.TabIndex = 4;
this._label_leanqty_factor.Text = "Lean Qty Factor";
//
// LegControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.Controls.Add(this._textbox_leg_price_mult);
this.Controls.Add(this.label4);
this.Controls.Add(this._combobox_mdtype);
this.Controls.Add(this._textbox_leg_leanqtyfactor);
this.Controls.Add(this._checkbox_leg_enablequoting);
this.Controls.Add(this._textbox_leg_qty);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.label5);
this.Controls.Add(this._label_leanqty_factor);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this._combobox_security);
this.Name = "LegControl";
this.Size = new System.Drawing.Size(291, 1220);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ComboBox _combobox_security;
private Label label1;
private Label label2;
private Label label3;
private Label label5;
private GroupBox groupBox1;
private Label label6;
private Label label11;
private CheckBox _checkbox_quote_insidemarketdistance;
private Label label10;
private CheckBox _checkbox_quote_conditional;
private Label label9;
private Label label8;
private CheckBox _checkbox_quote_throttle;
private Label label7;
private CheckBox _checkbox_quote_showqty;
private GroupBox groupBox2;
private Label label13;
private Label label14;
private Label label15;
private CheckBox _checkbox_prehedge_payup;
private Label label16;
private CheckBox _checkbox_prehedge_payless;
private GroupBox groupBox3;
private Label label20;
private Label label21;
private CheckBox _checkbox_posthedge_sizebasedcross;
private Label label12;
private Label label17;
private Label label18;
private CheckBox _checkbox_posthedge_timebasedcross;
private Label label19;
private CheckBox _checkbox_posthedge_ticksawaycross;
private TextBox _textbox_leg_qty;
private CheckBox _checkbox_leg_enablequoting;
private TextBox _textbox_leg_leanqtyfactor;
private ComboBox _combobox_mdtype;
private TextBox _textbox_quote_insidemarketdistance_towarddistance;
private TextBox _textbox_quote_conditional_ticks;
private TextBox _textbox_quote_throttle_outsideticks;
private TextBox _textbox_quote_throttle_insideticks;
private TextBox _textbox_quote_showqty_qty;
private TextBox _textbox_prehedge_payless_paylessticks;
private TextBox _textbox_prehedge_payup_payupticks;
private TextBox _textbox_prehedge_payup_threshold;
private TextBox _textbox_prehedge_payless_threshold;
private TextBox _textbox_posthedge_sizebasedcross_crossticks;
private TextBox _textbox_posthedge_sizebasedcross_threshold;
private TextBox _textbox_posthedge_timesbasedcross_crossticks;
private TextBox _textbox_posthedge_timesbasedcross_timems;
private TextBox _textbox_posthedge_ticksawaycross_crossticks;
private TextBox _textbox_posthedge_ticksawaycross_threshold;
private TextBox _textbox_quote_qho_length;
private TextBox _textbox_leg_price_mult;
private Label label4;
private Label _label_leanqty_factor;
}
}
@@ -0,0 +1,305 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
namespace SpreaderFrontEnd {
// UI control that represents a spreader leg. This is hidden within the MainSpreaderForm
public partial class LegControl : UserControl {
private SpreaderLegContract _leg_contract = new SpreaderLegContract();
private IEnumerable<string> _securities = new List<string>();
public LegControl() {
InitializeComponent();
}
public void initialize(IEnumerable<string> securities, SpreaderLegContract? leg_contract) {
_securities = securities;
_leg_contract = leg_contract ?? new SpreaderLegContract();
_populate_ui();
}
#region Data -> UI
private void _populate_ui() {
_populate_basic();
_populate_quote();
_populate_prehedge();
_populate_posthedge();
_initialize_enablement();
_assign_events();
}
void _assign_events() {
foreach (System.Reflection.FieldInfo fi in GetType().GetFields(BindingFlags.NonPublic
| BindingFlags.Public
| BindingFlags.Instance)) {
if (fi.FieldType == typeof(TextBox)) {
object? val = fi.GetValue(this);
if (val != null) {
TextBox? textbox = val as TextBox;
if (textbox != null) {
textbox.TextChanged += Textbox_TextChanged;
textbox.EnabledChanged += Textbox_EnabledChanged;
}
}
}
}
}
private void Textbox_EnabledChanged(object? sender, EventArgs e) {
}
private void Textbox_TextChanged(object? sender, EventArgs e) {
if (sender != null && sender is TextBox) {
TextBox? tb = sender as TextBox;
if (tb == null)
return;
if ("Double".Equals(tb.Tag)) {
double res;
bool parsed = Double.TryParse(tb.Text, out res);
tb.ForeColor = parsed ? Color.Black : Color.Red;
} else {
UInt32 res;
bool parsed = UInt32.TryParse(tb.Text, out res);
tb.ForeColor = parsed ? Color.Black : Color.Red;
}
}
}
void _populate_basic() {
// security
_combobox_security.Items.Clear();
List<string> securities_plus_empty = new List<string>(_securities);
securities_plus_empty.Add(String.Empty);
_combobox_security.Items.AddRange(securities_plus_empty.ToArray());
_combobox_security.Text = _leg_contract.security;
// qty etc
_textbox_leg_qty.Text = _leg_contract.qty.ToString();
_textbox_leg_price_mult.Text = _leg_contract.price_mult.ToString();
_checkbox_leg_enablequoting.Checked = _leg_contract.enable_quoting;
_textbox_leg_leanqtyfactor.Text = _leg_contract.lean_qty_factor.ToString();
_combobox_mdtype.Text = _leg_contract.md_type.ToString();
}
void _populate_quote() {
Debug.Assert(_leg_contract.quote_params != null);
var qp = _leg_contract.quote_params;
_textbox_quote_qho_length.Text = qp.qho_length.ToString();
// show qty
_checkbox_quote_showqty.Checked = qp.show_qty != null;
if (qp.show_qty != null) {
_checkbox_quote_showqty.Checked = true;
_textbox_quote_showqty_qty.Text = qp.show_qty.show_qty.ToString();
}
// throttle
_checkbox_quote_throttle.Checked = qp.throttle != null;
if (qp.throttle != null) {
_textbox_quote_throttle_insideticks.Text = qp.throttle.inside_ticks.ToString();
_textbox_quote_throttle_outsideticks.Text = qp.throttle.outside_ticks.ToString();
}
// conditional
_checkbox_quote_conditional.Checked = qp.conditional != null;
if (qp.conditional != null) {
_textbox_quote_conditional_ticks.Text = qp.conditional.ticks.ToString();
}
// inside market dist.
_checkbox_quote_insidemarketdistance.Checked = qp.inside_market_distance != null;
if (qp.inside_market_distance != null) {
_textbox_quote_insidemarketdistance_towarddistance.Text = qp.inside_market_distance.ToString();
}
}
void _populate_prehedge() {
var ph = _leg_contract.pre_hedge_params;
// payless
_checkbox_prehedge_payless.Checked = ph.payless != null;
if (ph.payless != null) {
_textbox_prehedge_payless_threshold.Text = ph.payless.threshold.ToString();
_textbox_prehedge_payless_paylessticks.Text = ph.payless.payless_ticks.ToString();
}
// payup
_checkbox_prehedge_payup.Checked = ph.payup != null;
if (ph.payup != null) {
_textbox_prehedge_payup_threshold.Text = ph.payup.threshold.ToString();
_textbox_prehedge_payup_payupticks.Text = ph.payup.payup_ticks.ToString();
}
}
void _populate_posthedge() {
var ph = _leg_contract.post_hedge_params;
_checkbox_posthedge_ticksawaycross.Checked = ph.ticks_away_cross != null;
// ticks away cross
if (ph.ticks_away_cross != null) {
_textbox_posthedge_ticksawaycross_threshold.Text = ph.ticks_away_cross.threshold.ToString();
_textbox_posthedge_ticksawaycross_crossticks.Text = ph.ticks_away_cross.cross_ticks.ToString();
}
//time based cross
_checkbox_posthedge_timebasedcross.Checked = ph.time_based_cross != null;
if (ph.time_based_cross != null) {
_textbox_posthedge_timesbasedcross_timems.Text = ph.time_based_cross.time_ms.ToString();
_textbox_posthedge_timesbasedcross_crossticks.Text = ph.time_based_cross.cross_ticks.ToString();
}
// size based cross
_checkbox_posthedge_sizebasedcross.Checked = ph.size_based_cross != null;
if (ph.size_based_cross != null) {
_textbox_posthedge_sizebasedcross_threshold.Text = ph.size_based_cross.threshold.ToString();
_textbox_posthedge_sizebasedcross_crossticks.Text = ph.size_based_cross.ToString();
}
}
// forces checkbox events so that the text boxes connected to it are enabled/disabled
private void _initialize_enablement() {
_checkbox_quote_showqty_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_quote_throttle_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_quote_conditional_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_quote_insidemarketdistance_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_prehedge_payless_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_prehedge_payup_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_posthedge_ticksawaycross_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_posthedge_timebasedcross_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
_checkbox_posthedge_sizebasedcross_CheckedChanged(_checkbox_quote_showqty, new EventArgs());
}
#endregion
#region UI -> Data
public ParsedUIData<SpreaderLegContract> get_data() {
SpreaderLegContract rv = new SpreaderLegContract();
try {
// top part
rv.security = _combobox_security.Text;
rv.qty = Int32.Parse(_textbox_leg_qty.Text);
rv.price_mult = Double.Parse(_textbox_leg_price_mult.Text);
rv.enable_quoting = _checkbox_leg_enablequoting.Checked;
rv.lean_qty_factor = Double.Parse(_textbox_leg_leanqtyfactor.Text);
rv.md_type = SpreaderLegContract.MDType.Merged;
// Quote
rv.quote_params = new SpreaderLegContract.QuoteParams();
rv.quote_params.qho_length = String.IsNullOrEmpty(_textbox_quote_qho_length.Text) ? 0 :
UInt32.Parse(_textbox_quote_qho_length.Text);
rv.quote_params.show_qty = null;
if (_checkbox_quote_showqty.Checked) {
rv.quote_params.show_qty = new SpreaderLegContract.QuoteParams.ShowQty();
rv.quote_params.show_qty.show_qty = UInt32.Parse(_textbox_quote_showqty_qty.Text);
}
rv.quote_params.throttle = null;
if (_checkbox_quote_throttle.Checked) {
rv.quote_params.throttle = new SpreaderLegContract.QuoteParams.Throttle();
rv.quote_params.throttle.inside_ticks = UInt32.Parse(_textbox_quote_throttle_insideticks.Text);
rv.quote_params.throttle.outside_ticks = UInt32.Parse(_textbox_quote_throttle_outsideticks.Text);
}
rv.quote_params.conditional = null;
if (_checkbox_quote_conditional.Checked) {
rv.quote_params.conditional = new SpreaderLegContract.QuoteParams.Conditional();
rv.quote_params.conditional.ticks = Int32.Parse(_textbox_quote_conditional_ticks.Text);
}
rv.quote_params.inside_market_distance = null;
if (_checkbox_quote_insidemarketdistance.Checked) {
rv.quote_params.inside_market_distance = new SpreaderLegContract.QuoteParams.InsideMarketDistance();
rv.quote_params.inside_market_distance.toward_distance =
UInt32.Parse(_textbox_quote_insidemarketdistance_towarddistance.Text);
}
//Pre-Hedge
rv.pre_hedge_params = new SpreaderLegContract.PreHedgeParams();
rv.pre_hedge_params.payless = null;
if (_checkbox_prehedge_payless.Checked) {
rv.pre_hedge_params.payless = new SpreaderLegContract.PreHedgeParams.PayLess();
rv.pre_hedge_params.payless.threshold = UInt32.Parse(_textbox_prehedge_payless_threshold.Text);
rv.pre_hedge_params.payless.payless_ticks =
UInt32.Parse(_textbox_prehedge_payless_paylessticks.Text);
}
rv.pre_hedge_params.payup = null;
if (_checkbox_prehedge_payup.Checked) {
rv.pre_hedge_params.payup = new SpreaderLegContract.PreHedgeParams.PayUp();
rv.pre_hedge_params.payup.threshold = UInt32.Parse(_textbox_prehedge_payup_threshold.Text);
rv.pre_hedge_params.payup.payup_ticks = UInt32.Parse(_textbox_prehedge_payup_payupticks.Text);
}
//Post-Hedge
rv.post_hedge_params = new SpreaderLegContract.PostHedgeParams();
rv.post_hedge_params.ticks_away_cross = null;
if (_checkbox_posthedge_ticksawaycross.Checked) {
rv.post_hedge_params.ticks_away_cross = new SpreaderLegContract.PostHedgeParams.TicksAwayCross();
rv.post_hedge_params.ticks_away_cross.threshold = UInt32.Parse(_textbox_posthedge_ticksawaycross_threshold.Text);
rv.post_hedge_params.ticks_away_cross.cross_ticks = UInt32.Parse(_textbox_posthedge_ticksawaycross_crossticks.Text);
}
rv.post_hedge_params.time_based_cross = null;
if (_checkbox_posthedge_timebasedcross.Checked) {
rv.post_hedge_params.time_based_cross = new SpreaderLegContract.PostHedgeParams.TimeBasedCross();
rv.post_hedge_params.time_based_cross.time_ms =
UInt32.Parse(_textbox_posthedge_timesbasedcross_timems.Text);
rv.post_hedge_params.time_based_cross.cross_ticks =
UInt32.Parse(_textbox_posthedge_timesbasedcross_crossticks.Text);
}
rv.post_hedge_params.size_based_cross = null;
if (_checkbox_posthedge_sizebasedcross.Checked) {
rv.post_hedge_params.size_based_cross = new SpreaderLegContract.PostHedgeParams.SizedBasedCross();
rv.post_hedge_params.size_based_cross.threshold = UInt32.Parse(_textbox_posthedge_sizebasedcross_threshold.Text);
rv.post_hedge_params.size_based_cross.cross_ticks = UInt32.Parse(_textbox_posthedge_sizebasedcross_crossticks.Text);
}
}
catch(Exception ex) {
return new ParsedUIData<SpreaderLegContract>(null, true, ex.Message);
}
return new ParsedUIData<SpreaderLegContract>(rv, false, String.Empty);
}
#endregion
public SpreaderLegContract get_contract() {
return null;
}
#region Checkbox Check Change Events
private void _checkbox_quote_showqty_CheckedChanged(object sender, EventArgs e) {
_textbox_quote_showqty_qty.Enabled = _checkbox_quote_showqty.Checked;
}
private void _checkbox_quote_throttle_CheckedChanged(object sender, EventArgs e) {
_textbox_quote_throttle_insideticks.Enabled = _checkbox_quote_throttle.Checked;
_textbox_quote_throttle_outsideticks.Enabled = _checkbox_quote_throttle.Checked;
}
private void _checkbox_quote_conditional_CheckedChanged(object sender, EventArgs e) {
_textbox_quote_conditional_ticks.Enabled = _checkbox_quote_conditional.Checked;
}
private void _checkbox_quote_insidemarketdistance_CheckedChanged(object sender, EventArgs e) {
_textbox_quote_insidemarketdistance_towarddistance.Enabled = _checkbox_quote_insidemarketdistance.Checked;
}
private void _checkbox_prehedge_payless_CheckedChanged(object sender, EventArgs e) {
_textbox_prehedge_payless_threshold.Enabled = _checkbox_prehedge_payless.Checked;
_textbox_prehedge_payless_paylessticks.Enabled = _checkbox_prehedge_payless.Checked;
}
private void _checkbox_prehedge_payup_CheckedChanged(object sender, EventArgs e) {
_textbox_prehedge_payup_threshold.Enabled = _checkbox_prehedge_payup.Checked;
_textbox_prehedge_payup_payupticks.Enabled = _checkbox_prehedge_payup.Checked;
}
private void _checkbox_posthedge_ticksawaycross_CheckedChanged(object sender, EventArgs e) {
_textbox_posthedge_ticksawaycross_threshold.Enabled = _checkbox_posthedge_ticksawaycross.Checked;
_textbox_posthedge_ticksawaycross_crossticks.Enabled = _checkbox_posthedge_ticksawaycross.Checked;
}
private void _checkbox_posthedge_timebasedcross_CheckedChanged(object sender, EventArgs e) {
_textbox_posthedge_timesbasedcross_timems.Enabled = _checkbox_posthedge_timebasedcross.Checked;
_textbox_posthedge_timesbasedcross_crossticks.Enabled = _checkbox_posthedge_timebasedcross.Checked;
}
private void _checkbox_posthedge_sizebasedcross_CheckedChanged(object sender, EventArgs e) {
_textbox_posthedge_sizebasedcross_threshold.Enabled = _checkbox_posthedge_sizebasedcross.Checked;
_textbox_posthedge_sizebasedcross_crossticks.Enabled = _checkbox_posthedge_sizebasedcross.Checked;
}
#endregion
}
}
@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,152 @@
using System.Windows.Forms;
namespace SpreaderFrontEnd
{
partial class MainSpreaderForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this._button_ok = new System.Windows.Forms.Button();
this._button_cancel = new System.Windows.Forms.Button();
this._label_spreader_name = new System.Windows.Forms.Label();
this._textbox_spreader_name = new System.Windows.Forms.TextBox();
this._legcontrol1 = new SpreaderFrontEnd.LegControl();
this._legcontrol2 = new SpreaderFrontEnd.LegControl();
this._legcontrol3 = new SpreaderFrontEnd.LegControl();
this._legcontrol4 = new SpreaderFrontEnd.LegControl();
this._legcontrol5 = new SpreaderFrontEnd.LegControl();
this.SuspendLayout();
//
// _button_ok
//
this._button_ok.Location = new System.Drawing.Point(1231, 1306);
this._button_ok.Name = "_button_ok";
this._button_ok.Size = new System.Drawing.Size(120, 33);
this._button_ok.TabIndex = 4;
this._button_ok.Text = "OK";
this._button_ok.UseVisualStyleBackColor = false;
this._button_ok.Click += new System.EventHandler(this._button_ok_Click);
//
// _button_cancel
//
this._button_cancel.Location = new System.Drawing.Point(1380, 1306);
this._button_cancel.Name = "_button_cancel";
this._button_cancel.Size = new System.Drawing.Size(121, 33);
this._button_cancel.TabIndex = 5;
this._button_cancel.Text = "Cancel";
this._button_cancel.UseVisualStyleBackColor = false;
this._button_cancel.Click += new System.EventHandler(this._button_cancel_Click);
//
// _label_spreader_name
//
this._label_spreader_name.AutoSize = true;
this._label_spreader_name.Location = new System.Drawing.Point(22, 28);
this._label_spreader_name.Name = "_label_spreader_name";
this._label_spreader_name.Size = new System.Drawing.Size(88, 15);
this._label_spreader_name.TabIndex = 6;
this._label_spreader_name.Text = "Spreader Name";
//
// _textbox_spreader_name
//
this._textbox_spreader_name.Location = new System.Drawing.Point(116, 25);
this._textbox_spreader_name.Name = "_textbox_spreader_name";
this._textbox_spreader_name.Size = new System.Drawing.Size(343, 23);
this._textbox_spreader_name.TabIndex = 0;
//
// _legcontrol1
//
this._legcontrol1.BackColor = System.Drawing.Color.White;
this._legcontrol1.Location = new System.Drawing.Point(22, 67);
this._legcontrol1.Name = "_legcontrol1";
this._legcontrol1.Size = new System.Drawing.Size(291, 1220);
this._legcontrol1.TabIndex = 1;
//
// _legcontrol2
//
this._legcontrol2.BackColor = System.Drawing.Color.White;
this._legcontrol2.Location = new System.Drawing.Point(319, 67);
this._legcontrol2.Name = "_legcontrol2";
this._legcontrol2.Size = new System.Drawing.Size(291, 1220);
this._legcontrol2.TabIndex = 2;
//
// _legcontrol3
//
this._legcontrol3.BackColor = System.Drawing.Color.White;
this._legcontrol3.Location = new System.Drawing.Point(616, 67);
this._legcontrol3.Name = "_legcontrol3";
this._legcontrol3.Size = new System.Drawing.Size(291, 1220);
this._legcontrol3.TabIndex = 3;
//
// _legcontrol4
//
this._legcontrol4.BackColor = System.Drawing.Color.White;
this._legcontrol4.Location = new System.Drawing.Point(913, 67);
this._legcontrol4.Name = "_legcontrol4";
this._legcontrol4.Size = new System.Drawing.Size(291, 1220);
this._legcontrol4.TabIndex = 4;
//
// _legcontrol5
//
this._legcontrol5.BackColor = System.Drawing.Color.White;
this._legcontrol5.Location = new System.Drawing.Point(1210, 67);
this._legcontrol5.Name = "_legcontrol5";
this._legcontrol5.Size = new System.Drawing.Size(291, 1220);
this._legcontrol5.TabIndex = 5;
//
// MainSpreaderForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1517, 1363);
this.Controls.Add(this._legcontrol5);
this.Controls.Add(this._legcontrol4);
this.Controls.Add(this._legcontrol3);
this.Controls.Add(this._legcontrol2);
this.Controls.Add(this._legcontrol1);
this.Controls.Add(this._textbox_spreader_name);
this.Controls.Add(this._label_spreader_name);
this.Controls.Add(this._button_cancel);
this.Controls.Add(this._button_ok);
this.Name = "MainSpreaderForm";
this.Text = "MainSpreaderForm";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Button _button_ok;
private Button _button_cancel;
private Label _label_spreader_name;
private TextBox _textbox_spreader_name;
private LegControl _legcontrol1;
private LegControl _legcontrol2;
private LegControl _legcontrol3;
private LegControl _legcontrol4;
private LegControl _legcontrol5;
}
}
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SpreaderFrontEnd {
// This is the main UI widget. It is passed a list of securities and a SpreaderContract.
// The SpreaderContract can be empty (which will be the case when creating a new spreader).
// It has 3 public facing members (other than the constructor),
// 2 events that tell whether OK or Cancel was hit, respectively,
// and get_spreader_contract that returns a ParsedUIData<SpreaderContract>
public partial class MainSpreaderForm : Form {
private IEnumerable<LegControl> _leg_controls;
public Action on_OK = () => { };
public Action on_cancel = () => { };
private readonly IEnumerable<string> _securities;
private SpreaderContract _spreader_contract;
public MainSpreaderForm(IEnumerable<string> securities,
SpreaderContract spreader_contract)
: base() {
InitializeComponent();
_leg_controls = new LegControl[] { _legcontrol1, _legcontrol2, _legcontrol3, _legcontrol4, _legcontrol5 };
_securities = securities;
System.Diagnostics.Debug.Assert(spreader_contract != null);
// System.Diagnostics.Debug.Assert(spreader_contract.spread_legs.Count() == SpreaderContract.max_nlegs);
_spreader_contract = spreader_contract;
_textbox_spreader_name.Text = _spreader_contract.name;
for (var i = 0; i < _leg_controls.Count(); i++) {
SpreaderLegContract? lc = i < _spreader_contract.spread_legs.Count() ?
_spreader_contract.spread_legs.ElementAt(i) : null;
_leg_controls.ElementAt(i).initialize(securities, lc);
}
}
public ParsedUIData<SpreaderContract> get_spreader_contract() {
if (String.IsNullOrEmpty(_textbox_spreader_name.Text)) {
return new ParsedUIData<SpreaderContract>(null, true, "Spreader name is not set");
}
List<SpreaderLegContract> leg_contracts = new List<SpreaderLegContract>();
uint i = 0;
foreach (LegControl lc in _leg_controls) {
i++;
var leg_res = lc.get_data();
if (leg_res.is_error) {
return new ParsedUIData<SpreaderContract>(null, true, $"Leg: {i} is not set correctly");
}
leg_contracts.Add(leg_res.ui_data);
}
IEnumerable<SpreaderLegContract> leg_contracts_rv =
leg_contracts.Where(l => !String.IsNullOrEmpty(l.security));
if (leg_contracts_rv.Count() <= 1) {
return new ParsedUIData<SpreaderContract>(
null, true, "Spreader needs at least 2 legs");
}
// check the number of legs
return new ParsedUIData<SpreaderContract>(
new SpreaderContract(_textbox_spreader_name.Text, leg_contracts_rv), false, String.Empty);
}
private void _button_ok_Click(object sender, EventArgs e) {
ParsedUIData<SpreaderContract> ui_data = get_spreader_contract();
if (ui_data.is_error) {
string err_txt = $"The following error happened \n{ui_data.error_txt}";
System.Windows.Forms.MessageBox.Show(err_txt, "Spreader Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
on_OK();
}
private void _button_cancel_Click(object sender, EventArgs e) {
on_cancel();
}
}
}
@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,20 @@
namespace SpreaderFrontEnd {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class ParsedUIData<T> {
public readonly T ui_data;
public readonly bool is_error;
public readonly string error_txt;
public ParsedUIData(T ui_data, bool is_error, string error_txt) {
this.ui_data = ui_data;
this.is_error = is_error;
this.error_txt = error_txt;
}
}
}
@@ -0,0 +1,18 @@
using System;
using System.Windows.Forms;
namespace SpreaderFrontEnd {
internal static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
SyntheticBookTest.run();
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new TestForm());
}
}
}
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpreaderFrontEnd
{
[Serializable]
// Represents a spreader contract (anologous ot the protobuf on the C++ side)
// We could have generated managed wrappers from the protobuf, but we did not want
// to make your build process complicated hence opted for this class.
// It is quite simply a wrapper around an enumeration of SpreaderLegContract
public class SpreaderContract
{
public static uint max_nlegs = 5;
public string name = String.Empty;
public IList<SpreaderLegContract> spread_legs = new List<SpreaderLegContract>();
public SpreaderContract(string name, IEnumerable<SpreaderLegContract> spread_legs)
{
this.name = name;
this.spread_legs = spread_legs.ToList();
}
public static SpreaderContract empty
{
get
{
return new SpreaderContract("UNNAMED",
Enumerable.Repeat<SpreaderLegContract>(new SpreaderLegContract(), 5));
}
}
}
}
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<LanguageVersion>7</LanguageVersion>
</PropertyGroup>
</Project>
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpreaderFrontEnd
{
[Serializable]
// Represents a single leg of the spreader. It is made up of
// 1. a main section consisting of the security, qty, price mult etc
// 2. Quote parameters
// 3. Pre-Hedge parameters
// 4. Post-Hedge parameters
// It maps pretty directly to the UI (LegControl)
public class SpreaderLegContract
{
public enum MDType {
Direct = 0,
Merged = 1,
}
public string security = String.Empty;
public int qty = 1;
public double price_mult = 1;
public bool enable_quoting = false;
public double lean_qty_factor = 1;
public MDType md_type = MDType.Direct;
public QuoteParams quote_params = new QuoteParams();
public PreHedgeParams pre_hedge_params = new PreHedgeParams();
public PostHedgeParams post_hedge_params = new PostHedgeParams();
public class QuoteParams
{
public class ShowQty {
public UInt32 show_qty = 1;
}
public class Throttle {
public UInt32 inside_ticks = 0;
public UInt32 outside_ticks = 0;
}
public class Conditional {
public Int32 ticks = 0;
}
public class InsideMarketDistance {
public UInt32 toward_distance = 0;
}
public UInt32 qho_length = 0;
public ShowQty? show_qty = null;
public Throttle? throttle = null;
public Conditional? conditional = null;
public InsideMarketDistance? inside_market_distance = null;
}
public class PreHedgeParams
{
public class PayLess {
public UInt32 threshold = 0;
public UInt32 payless_ticks = 0;
}
public class PayUp
{
public UInt32 threshold = 0;
public UInt32 payup_ticks = 0;
}
public PayLess? payless = null;
public PayUp? payup = null;
}
public class PostHedgeParams
{
public class TicksAwayCross {
public UInt32 threshold = 0;
public UInt32 cross_ticks = 0;
}
public class TimeBasedCross {
public UInt32 time_ms = 0;
public UInt32 cross_ticks = 0;
}
public class SizedBasedCross {
public UInt32 threshold = 0;
public UInt32 cross_ticks = 0;
}
public TicksAwayCross? ticks_away_cross = null;
public TimeBasedCross? time_based_cross = null;
public SizedBasedCross? size_based_cross = null;
}
}
}
+79
View File
@@ -0,0 +1,79 @@
using System.Windows.Forms;
namespace SpreaderFrontEnd
{
partial class TestForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this._button_launch_new = new System.Windows.Forms.Button();
this._button_load_existing = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// _button_launch_new
//
this._button_launch_new.Location = new System.Drawing.Point(96, 46);
this._button_launch_new.Name = "_button_launch_new";
this._button_launch_new.Size = new System.Drawing.Size(169, 26);
this._button_launch_new.TabIndex = 0;
this._button_launch_new.Text = "Launch New";
this._button_launch_new.UseVisualStyleBackColor = true;
this._button_launch_new.Click += new System.EventHandler(this._button_launch_new_Click);
//
// _button_load_existing
//
this._button_load_existing.Location = new System.Drawing.Point(96, 114);
this._button_load_existing.Name = "_button_load_existing";
this._button_load_existing.Size = new System.Drawing.Size(169, 26);
this._button_load_existing.TabIndex = 1;
this._button_load_existing.Text = "Load Existing";
this._button_load_existing.UseVisualStyleBackColor = true;
this._button_load_existing.Click += new System.EventHandler(this._button_load_existing_Click);
//
// TestForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(371, 213);
this.Controls.Add(this._button_load_existing);
this.Controls.Add(this._button_launch_new);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "TestForm";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Test Launcher";
this.ResumeLayout(false);
}
#endregion
private Button _button_launch_new;
private Button _button_load_existing;
}
}
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace SpreaderFrontEnd {
// Test class that demostrates how to use the MainSpreaderForm.
// It has 2 buttons. "Launch New" launches a brand new spreader (empty UI)
// while "Launch Existing" loads the MainSpreaderForm with an existing
// spreader (hard coded arbitrary values)
public partial class TestForm : Form {
private IEnumerable<string> _securities = new string[] {
"ZCG23",
"ZCH23",
"ZCJ23",
"ZCL23",
"ZCM23"
};
public TestForm() {
InitializeComponent();
}
private void _button_launch_new_Click(object sender, EventArgs e) {
_show_form(SpreaderContract.empty);
}
private void _button_load_existing_Click(object sender, EventArgs e) {
var sc = _generate_test_contract();
_show_form(sc);
}
private void _show_form(SpreaderContract spreader_contract) {
MainSpreaderForm f = new MainSpreaderForm(_securities, spreader_contract);
f.on_OK = () => {
MessageBox.Show("Received OK", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
f.Close();
};
f.on_cancel = () => {
MessageBox.Show("Received Cancel", "Cancel", MessageBoxButtons.OK, MessageBoxIcon.Warning);
f.Close();
};
f.ShowDialog();
}
private SpreaderContract _generate_test_contract() {
List<SpreaderLegContract> lcs = new List<SpreaderLegContract>();
for (uint i = 0; i < 3; i++) {
SpreaderLegContract lc = _generate_test_leg_contract(i);
lcs.Add(lc);
}
SpreaderContract sc = new SpreaderContract("TEST SPREADER", lcs);
return sc;
}
private SpreaderLegContract _generate_test_leg_contract(uint idx) {
SpreaderLegContract rv = new SpreaderLegContract();
rv.security = _securities.ElementAt(0);
rv.qty = 1;
rv.price_mult = 1;
rv.enable_quoting = true;
rv.lean_qty_factor = 2;
rv.md_type = SpreaderLegContract.MDType.Merged;
// quote
rv.quote_params = new SpreaderLegContract.QuoteParams();
rv.quote_params.qho_length = 0;
rv.quote_params.show_qty = new SpreaderLegContract.QuoteParams.ShowQty();
rv.quote_params.show_qty.show_qty = 10;
rv.quote_params.throttle = new SpreaderLegContract.QuoteParams.Throttle();
rv.quote_params.throttle.inside_ticks = 3;
rv.quote_params.throttle.outside_ticks = 2;
// pre hedge
rv.pre_hedge_params = new SpreaderLegContract.PreHedgeParams();
rv.pre_hedge_params.payless = new SpreaderLegContract.PreHedgeParams.PayLess();
rv.pre_hedge_params.payless.threshold = 1000;
rv.pre_hedge_params.payless.payless_ticks = 7;
rv.pre_hedge_params.payup = new SpreaderLegContract.PreHedgeParams.PayUp();
rv.pre_hedge_params.payup.threshold = 500;
rv.pre_hedge_params.payup.payup_ticks = 12;
// post hedge
rv.post_hedge_params = new SpreaderLegContract.PostHedgeParams();
rv.post_hedge_params.ticks_away_cross = new SpreaderLegContract.PostHedgeParams.TicksAwayCross();
rv.post_hedge_params.ticks_away_cross.threshold = 10;
rv.post_hedge_params.ticks_away_cross.cross_ticks = 3;
rv.post_hedge_params.time_based_cross = new SpreaderLegContract.PostHedgeParams.TimeBasedCross();
rv.post_hedge_params.time_based_cross.time_ms = 20;
rv.post_hedge_params.time_based_cross.cross_ticks = 5;
return rv;
}
}
};
@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,230 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
namespace SpreaderFrontEnd {
public static class SyntheticBookTest {
/// <summary>
/// Run synthetic book computation tests
/// </summary>
public static int run() {
// Seed the test with a standard butterfly spread. Leg size multipliers will be applied to
// each leg to generate more variations to test.
var legs = new List<SpreaderLegContract> {
new SpreaderLegContract() {
security = "Leg1Sec",
qty = 1
},
new SpreaderLegContract() {
security = "Leg2Sec",
qty = -2
},
new SpreaderLegContract() {
security = "Leg3Sec",
qty = 1
}
};
var leg_multipliers = new List<int> { 1, -1, 2, -2, 3, -3 };
var contract = new SpreaderContract("Test", legs);
// Define a book (seed) for each leg. Quantities will be added to each price level for each
// leg's book to generate more variations to test.
var leg1_book = new Book(
bids: new BookSide(levels: new List<PriceLevel> {
new PriceLevel(price: 3, qty: 10),
new PriceLevel(price: 2, qty: 4),
new PriceLevel(price: 1, qty: 6)
}),
asks: new BookSide(levels: new List<PriceLevel> {
new PriceLevel(price: 4, qty: 5),
new PriceLevel(price: 5, qty: 7),
new PriceLevel(price: 6, qty: 8)
}));
var leg2_book = new Book(
bids: new BookSide(levels: new List<PriceLevel> {
new PriceLevel(price: 3, qty: 1),
new PriceLevel(price: 2, qty: 7),
new PriceLevel(price: 1, qty: 2)
}),
asks: new BookSide(levels: new List<PriceLevel> {
new PriceLevel(price: 4, qty: 3),
new PriceLevel(price: 5, qty: 3),
new PriceLevel(price: 6, qty: 5)
}));
var leg3_book = new Book(
bids: new BookSide(levels: new List<PriceLevel> {
new PriceLevel(price: 3, qty: 2),
new PriceLevel(price: 2, qty: 1),
new PriceLevel(price: 1, qty: 8)
}),
asks: new BookSide(levels: new List<PriceLevel> {
new PriceLevel(price: 4, qty: 4),
new PriceLevel(price: 5, qty: 3),
new PriceLevel(price: 6, qty: 4)
}));
var level_qty_additions = new List<uint> { 1, 2, 3, 4 };
var leg_books = new List<Book> { leg1_book, leg2_book, leg3_book };
for (int i = 0; i < leg_multipliers.Count; i++) {
var leg_mult = leg_multipliers[i];
for (int j = 0; j < contract.spread_legs.Count; j++) {
// Apply leg mult
contract.spread_legs[j].qty *= leg_mult;
foreach (var lqa in level_qty_additions) {
foreach(var lb in leg_books) {
// Apply qty addition to bid-levels
for (int level_idx = 0; level_idx < lb.bids.levels.Count; level_idx++) {
var orig_level = lb.bids.levels[level_idx];
lb.bids.levels[level_idx] = orig_level.add_qty(lqa);
run(leg_books, contract);
// Subtract the qty that was just added so each qty addition is applied to
// the original level
lb.bids.levels[level_idx] = lb.bids.levels[level_idx].subtract_qty(lqa);
}
// Apply qty additions to ask-levels
for (int level_idx = 0; level_idx < lb.asks.levels.Count; level_idx++) {
var orig_level = lb.asks.levels[level_idx];
lb.asks.levels[level_idx] = orig_level.add_qty(lqa);
run(leg_books, contract);
// Subtract the qty that was just added so each qty addition is applied to
// the original level
lb.asks.levels[level_idx] = lb.asks.levels[level_idx].subtract_qty(lqa);
}
}
}
// Divide by leg_mult so the each mult is applied to the original leg
contract.spread_legs[j].qty /= leg_mult;
}
}
return 0;
}
public static void run(List<Book> leg_books, SpreaderContract contract) {
var synth_book = SpreaderBookCalculator.compute_spreader_book(contract, leg_books);
for (int i = 0; i < contract.spread_legs.Count; i++) {
Console.WriteLine($"Leg{i} (qty {contract.spread_legs[i].qty}): {leg_books[i]}");
}
Console.WriteLine($"Synthetic Book: {synth_book}");
var leg_book_tups = _to_leg_book_tuples(leg_books, contract);
var expected_book = _compute_synth_book(leg_book_tups);
Console.WriteLine($"Expected Book: {expected_book}");
Debug.Assert(expected_book.Equals(synth_book));
}
static List<Tuple<Book, int>> _to_leg_book_tuples(List<Book> leg_books, SpreaderContract contract) {
Debug.Assert(leg_books.Count == contract.spread_legs.Count);
var rv = new List<Tuple<Book, int>>();
for (int i = 0; i < leg_books.Count; i++) {
rv.Add(Tuple.Create(leg_books[i], contract.spread_legs[i].qty));
}
return rv;
}
static List<Tuple<BookSide, int>> _to_leg_book_side_tuples(List<Tuple<Book, int>> leg_books, bool is_bid) {
var leg_book_tups = new List<Tuple<BookSide, int>>();
for (int i = 0; i < leg_books.Count; i++) {
var leg_size = leg_books[i].Item2;
var leg_book = leg_books[i].Item1;
var is_buy_leg = leg_size > 0;
var leg_book_side = is_buy_leg == is_bid ? leg_book.bids : leg_book.asks;
leg_book_tups.Add(Tuple.Create(leg_book_side, leg_size));
}
return leg_book_tups;
}
static Book _compute_synth_book(List<Tuple<Book, int>> leg_books) {
var leg_bids = _to_leg_book_side_tuples(leg_books, true);
var leg_asks = _to_leg_book_side_tuples(leg_books, false);
var synth_bids = _compute_synth_book_side(leg_bids);
var synth_asks = _compute_synth_book_side(leg_asks);
return new Book(synth_bids, synth_asks);
}
// <summary>
// Computes the synthetic book in a simple/unoptimized way, to ensure correctness. Books
// generated by the 'optimized' routine, which will be used in practice, should match those
// generated by this one.
// </summary>
static BookSide _compute_synth_book_side(IEnumerable<Tuple<BookSide, int>> leg_books) {
// Clone the books so we can mutate them without changing the input 'leg_books'
var leg_books_list = leg_books.Select(lb => Tuple.Create(lb.Item1.Clone(), lb.Item2)).ToList();
var levels = new List<PriceLevel>();
var top_level = _get_top_level(leg_books_list);
while (top_level.qty > 0) {
levels.Add(top_level);
foreach (var lb in leg_books_list) {
_remove_qty_from_top(lb.Item1, (int)(top_level.qty * Math.Abs(lb.Item2)));
}
top_level = _get_top_level(leg_books_list);
}
return new BookSide(levels);
}
static PriceLevel _get_top_level(IEnumerable<Tuple<BookSide, int>> leg_books) {
var leg_sizes = leg_books.Select(lb => lb.Item2).ToList();
var top_levels = leg_books.Select(_get_top_level).ToList();
var qty = top_levels.Select(l => l.qty).Min();
if (qty == 0) {
return PriceLevel.empty;
}
double price = 0;
for (int i = 0; i < top_levels.Count; i++) {
var leg_price = top_levels[i].price;
var leg_size = leg_sizes[i];
if (leg_size < 0) {
price -= leg_price;
} else {
price += leg_price;
}
}
return new PriceLevel(price, qty);
}
static PriceLevel _get_top_level(Tuple<BookSide, int> leg_book) {
return _get_top_level(leg_book.Item1, leg_book.Item2);
}
static PriceLevel _get_top_level(BookSide book, int leg_size) {
if (book.levels.Count == 0) {
return PriceLevel.empty;
}
var first_level = book.levels.First();
var abs_leg_size = Math.Abs(leg_size);
if (first_level.qty >= abs_leg_size) {
return new PriceLevel(first_level.price * abs_leg_size, (uint)(first_level.qty / abs_leg_size));
}
double price = first_level.qty * first_level.price;
var qty_rem = abs_leg_size - first_level.qty;
for (int i = 1; i < book.levels.Count; i++) {
var level = book.levels[i];
if (level.qty >= qty_rem) {
price += qty_rem * level.price;
return new PriceLevel(price, 1);
}
price += level.qty * level.price;
qty_rem -= level.qty;
}
return PriceLevel.empty;
}
/// <summary>
/// Removes the specified quantity from the top of the book
/// </summary>
static void _remove_qty_from_top(BookSide book, int qty) {
var subtracted_qty = 0;
while (subtracted_qty < qty && book.levels.Count > 0) {
var first_level = book.levels[0];
var qty_to_subtract = qty - subtracted_qty;
if (first_level.qty > qty_to_subtract) {
first_level = first_level.subtract_qty((uint)qty_to_subtract);
book.levels[0] = first_level;
return;
}
book.levels.RemoveAt(0);
subtracted_qty += (int)first_level.qty;
}
}
}
}
@@ -0,0 +1,78 @@
using System;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace SpreaderFrontEnd
{
public class Utils
{
public static void bin_serialize<T>(T t, Stream str)
{
#pragma warning disable SYSLIB0011
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(str, t);
#pragma warning restore SYSLIB0011
}
public static T bin_deserialize<T>(Stream str)
{
#pragma warning disable SYSLIB0011
BinaryFormatter bf = new BinaryFormatter();
T rv = (T)bf.Deserialize(str);
#pragma warning restore SYSLIB0011
return rv;
}
public static T? basic_deep_clone<T>(T t)
{
try
{
MemoryStream str = new MemoryStream();
bin_serialize(t, str);
str.Position = 0;
return bin_deserialize<T>(str);
}
catch
{
return default(T);
}
}
public static object? CloneObject(object objSource)
{
//step : 1 Get the type of source object and create a new instance of that type
Type typeSource = objSource.GetType();
object? objTarget = Activator.CreateInstance(typeSource);
//Step2 : Get all the properties of source object type
PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
//Step : 3 Assign all source property to taget object 's properties
foreach (PropertyInfo property in propertyInfo)
{
//Check whether property can be written to
if (property.CanWrite)
{
//Step : 4 check whether property type is value type, enum or string type
if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(typeof(System.String)))
{
property.SetValue(objTarget, property.GetValue(objSource, null), null);
}
//else property type is object/complex types, so need to recursively call this method until the end of the tree is reached
else
{
object? objPropertyValue = property.GetValue(objSource, null);
if (objPropertyValue == null)
{
property.SetValue(objTarget, null, null);
}
else
{
property.SetValue(objTarget, CloneObject(objPropertyValue), null);
}
}
}
}
return objTarget;
}
}
}
@@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v6.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v6.0": {
"SpreaderFrontEnd/1.0.0": {
"runtime": {
"SpreaderFrontEnd.dll": {}
}
}
}
},
"libraries": {
"SpreaderFrontEnd/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}
@@ -0,0 +1,15 @@
{
"runtimeOptions": {
"tfm": "net6.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.0"
}
]
}
}
-12
View File
@@ -1,12 +0,0 @@
function(print_list var)
set(CMAKE_MESSAGE_INDENT "")
set(_var_str "")
foreach(item IN LISTS ${var})
set(_var_str "${_var_str}\n ${item}")
endforeach()
if ("${ARGN}" STREQUAL "VERBOSE")
message(VERBOSE "***${var}:${_var_str}")
else()
message("***${var}:${_var_str}")
endif()
endfunction()
-224
View File
@@ -1,224 +0,0 @@
[cmake]: https://cmake.org/
[cmake ext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools
[cmake presets]: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
[cpp ext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools
[clangd ext]: https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd
[dotnet]: https://dotnet.microsoft.com/en-us/download/dotnet
[ninja build]: https://ninja-build.org/
[ninja generator]: https://cmake.org/cmake/help/latest/generator/Ninja.html
[ninja multi-config generator]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html
[python]: https://www.python.org/
[py venv]: https://docs.python.org/3/library/venv.html
[visual studio]: https://visualstudio.microsoft.com/
[visual studio generator]: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html
# C++ Intellisense for Spark on Windows (VS Code)
**Steps**
1. Install the **[C++ extension][cpp ext]**
2. Install the **[CMake extension][cmake ext]**
3. Copy `c_cpp_properties.json` from this folder to `$workspaceFolder/.vscode/`
4. In the VS Code Command Palette, run **CMake: Select Configure Preset**, then
select '**spark**' from the dropdown
**Notes**
* Intellisense won't work for generated files/types until you build libspark
# C++ Intellisense for Sparkd on Linux (VS Code)
1. Install the **[CMake extension][cmake ext]**
2. Install the **[Clangd extension][clangd ext]**
3. (Optional) Install the **[C++ extension][cpp ext]** (*needed for debugging,
but intellisense should work without it*).
4. If the **[C++ extension][cpp ext]** is installed, disable its intellisense in
your workspace settings (*Clangd intellisense is better*)
```
"C_Cpp.intelliSenseEngine": "disabled"
```
5. In the VS Code Command Palette, run **CMake: Select Configure Preset**, then select the
**[preset][cmake presets]** you wish to build from the dropdown
* *The **Clang** presets may work best with the **Clangd** extension*
* *Intellisense won't work for generated files/types until you build libspark*
# Build Spark on Windows
### Dependencies
* **[CMake][cmake]** (version >= 3.23)
* **[Python][python]** (version >= 3.9)
* **[Visual Studio][visual studio]** (2022)
* **[Dotnet][dotnet]** (sdk version >= 7.0.0)
### References
* **[CMakePresets][cmake presets]**
* **[Visual Studio 17 2022 (CMake generator)][visual studio generator]**
* **[Python Virtual Environment][py venv]**
### Notes
* *Run commands from the repo root dir unless otherwise noted*
1. Set up the **[Python virtual environment][py venv]**<br>
```
# Create the virtual environment
python3 -m venv .venv
# Activate the virtual environment
.venv\bin\activate.bat
# Update pip
python -m pip install --upgrade pip
# Install packages
pip install -r requirements.txt
```
2. Build
* *Run commands in python virtual environment*
```
# Configure
cmake --preset spark
# Build Debug
cmake --build --preset spark-debug
dotnet build spark_client.sln --configuration Debug
# Build Release
cmake --build --preset spark-release
dotnet build spark_client.sln --configuration Release
```
# Build Sparkd on Linux
### **Dependencies**
* **[CMake][cmake]** (version >= 3.23)
* **[Ninja Build][ninja build]**
* **[Python][python]** (version >= 3.9)
### **References**
* **[CMakePresets][cmake presets]**
* **[Ninja (CMake generator)][ninja generator]**
* **[Python Virtual Environment][py venv]**
* **[Devcontainer](devcontainer)**
### Prerequisites
* Open repository in a VS Code [Devcontainer](../docker/sparkd/dev/README.md), or
create your own [docker container](../docker/sparkd/dev/README.md) in which to build
### Notes
* *Run commands from the repo root dir unless otherwise noted*<br>
1. Set up the **[Python virtual environment][py venv]**
```
# Create the virtual environment
python3 -m venv .venv
# Activate the virtual environment
. .venv/bin/activate
# Update pip
python -m pip install --upgrade pip
# Install packages
pip install -r requirements.txt
```
2. Build
* *Run commands in python virtual environment*
```
# Configure clang debug
cmake --preset sparkd-clang-debug
# Build clang debug
cmake --build --preset spark-clang-debug
# Configure gcc release
cmake --build --preset sparkd-gcc-release
# Build gcc release
cmake --build --preset sparkd-gcc-release
```
# Build Spark Api Server on Windows
### **Dependencies**
* **[CMake][cmake]** (version >= 3.23)
* **[Python][python]** (version >= 3.9)
* **[Visual Studio][visual studio]** (version)
* **[Dotnet][dotnet]** (sdk version >= 7.0.0)
### **References**
* **[CMakePresets][cmake presets]**
* **[Visual Studio 17 2022 (CMake generator)][visual studio generator]**
* **[Python Virtual Environment][py venv]**
### Notes
* *Run commands from the repo root dir unless otherwise noted*
1. Set up the **[Python Virtual Environment][py venv]**
```
# Create the virtual environment
python3 -m venv .venv
# Activate the virtual environment
.venv\bin\activate.bat
# Update pip
python -m pip install --upgrade pip
# Install packages
pip install -r requirements.txt
```
2. Build
* *Run in python virtual environment*
```
# Configure
cmake --preset spark-api-server-windows
# Build debug
cmake --build --preset spark-api-server-windows-debug
dotnet build Spark.Api.Server.sln --configuration Debug
# Build release
cmake --build --preset spark-api-server-windows-release
dotnet build Spark.Api.Server.sln --configuration Release
```
# Build Spark Api Server on Linux
### **Dependencies**
* **[CMake][cmake]** (version >= 3.23)
* **[Ninja Build][ninja build]**
* **[Python][python]** (version >= 3.9)
* **[Dotnet][dotnet]** (sdk version >= 7.0.0)
### **References**
* **[CMakePresets][cmake presets]**
* **[Ninja Multi-Config (CMake generator)][ninja multi-config generator]**
* **[Python Virtual Environment][py venv]**
### Prerequisites
* Open repository in a VS Code [Devcontainer](../docker/sparkd/dev/README.md), or
create your own [docker container](../docker/sparkd/dev/README.md) in which to build
### Notes
* *Run commands from the repo root dir unless otherwise noted*
1. Set up the **[Python Virtual Environment][py venv]**
```
# Create the virtual environment
python3 -m venv .venv
# Activate the virtual environment
. .venv/bin/activate
# Update pip
python -m pip install --upgrade pip
# Install packages
pip install -r requirements.txt
```
2. Build
* *Run in python virtual environment*
```
# Configure
cmake --preset spark-api-server-linux
# Build debug
cmake --build --preset spark-api-server-linux-debug
dotnet build Spark.Api.Server.sln --configuration Debug
# Build release
cmake --build --preset spark-api-server-linux-release
dotnet build Spark.Api.Server.sln --configuration Release
```
-27
View File
@@ -1,27 +0,0 @@
{
"version": 4,
"configurations": [
{
"name": "Windows",
"intelliSenseMode": "windows-msvc-x64",
"includePath": [
"${workspaceFolder}/src/",
"${workspaceFolder}/build/src/",
"${workspaceFolder}/externals/windows/include/"
],
"defines": ["_WIN32", "__x86_64__"],
"browse": {
"path": [
"${workspaceRoot}/src",
"${workspaceRoot}/build/src"
],
"limitSymbolsToIncludedHeaders": true
},
"cStandard": "c17",
"cppStandard": "c++17",
"configurationProvider": "ms-vscode.cmake-tools",
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.34.31933/bin/Hostx64/x64/cl.exe",
"mergeConfigurations": true
}
]
}
+1 -3
View File
@@ -46,7 +46,6 @@ function setup_build
assert_dir $repo_root
assert_dir $build_root
set compiler "$argv[1]"
set c_compiler (which cc)
set build_type "$argv[2]"
if test \( -z "$build_type" \) -o \( \( "$build_type" != debug \) -a \( "$build_type" != release \) \)
@@ -60,7 +59,6 @@ function setup_build
else
# set compiler_arg "/usr/lib/ccache/clang++"
set compiler_arg "clang++"
set c_compiler (which clang)
end
else if test "$build_type" = release
set build_type_arg Release
@@ -87,7 +85,7 @@ function setup_build
rm -rf "$build_dest"
mkdir -p "$build_dest"
cd "$build_dest"
cmake -G Ninja -DCMAKE_BUILD_TYPE=$build_type_arg -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_C_COMPILER=$c_compiler -DCMAKE_CXX_COMPILER=$compiler_arg $repo_root
cmake -G Ninja -DCMAKE_BUILD_TYPE=$build_type_arg -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_CXX_COMPILER=$compiler_arg $repo_root
end
# The while loop below removes arguments (via shift) as it parses them.
File renamed without changes.
@@ -1,941 +0,0 @@
{
"$schema": "vscode://schemas/color-theme",
"type": "dark",
"colors": {
"activityBar.background": "#111111",
"activityBar.border": "#111111",
"activityBar.foreground": "#888888",
"activityBarBadge.background": "#88cc44",
"activityBarBadge.foreground": "#222222",
"badge.background": "#88cc44",
"badge.foreground": "#222222",
"button.background": "#333333",
"button.foreground": "#888888",
"button.hoverBackground": "#222222",
"debugExceptionWidget.background": "#333333",
"debugExceptionWidget.border": "#222222",
"debugToolBar.background": "#111111",
"diffEditor.insertedTextBackground": "#ffdd440c",
"diffEditor.insertedTextBorder": "#ffdd44",
"diffEditor.removedTextBackground": "#88bbff0c",
"diffEditor.removedTextBorder": "#88bbff",
"dropdown.background": "#222222",
"dropdown.border": "#222222",
"dropdown.foreground": "#888888",
"editor.background": "#222222",
"editor.findMatchBackground": "#44446655",
"editor.findMatchHighlightBackground": "#444466aa",
"editor.foreground": "#ffffff",
"editor.hoverHighlightBackground": "#44446655",
"editor.inactiveSelectionBackground": "#44446655",
"editor.lineHighlightBackground": "#00000066",
"editor.lineHighlightBorder": "#00000000",
"editor.rangeHighlightBackground": "#333333",
"editor.selectionBackground": "#444466",
"editor.selectionHighlightBackground": "#44446655",
"editor.wordHighlightBackground": "#44446655",
"editor.wordHighlightStrongBackground": "#44446655",
"editorBracketMatch.background": "#222222",
"editorBracketMatch.border": "#666666",
"editorCodeLens.foreground": "#666666",
"editorCursor.foreground": "#ffffff",
"editorError.foreground": "#ee5500",
"editorGroup.border": "#111111",
"editorGroup.dropBackground": "#111111bb",
"editorGroupHeader.noTabsBackground": "#111111",
"editorGroupHeader.tabsBackground": "#111111",
"editorGroupHeader.tabsBorder": "#222222",
"editorGutter.addedBackground": "#ffdd44",
"editorGutter.background": "#222222",
"editorGutter.deletedBackground": "#88bbff",
"editorGutter.modifiedBackground": "#88bbff",
"editorHoverWidget.background": "#333333",
"editorHoverWidget.border": "#222222",
"editorIndentGuide.background": "#333333",
"editorLineNumber.foreground": "#555555",
"editorLink.activeForeground": "#bba0ff",
"editorMarkerNavigation.background": "#333333",
"editorMarkerNavigationError.background": "#88bbff",
"editorMarkerNavigationWarning.background": "#88bbff",
"editorOverviewRuler.addedForeground": "#ffdd44",
"editorOverviewRuler.border": "#222222",
"editorOverviewRuler.currentContentForeground": "#333333",
"editorOverviewRuler.deletedForeground": "#88bbff",
"editorOverviewRuler.errorForeground": "#88bbff",
"editorOverviewRuler.findMatchForeground": "#555555",
"editorOverviewRuler.incomingContentForeground": "#333333",
"editorOverviewRuler.infoForeground": "#bba0ff",
"editorOverviewRuler.modifiedForeground": "#88bbff",
"editorOverviewRuler.rangeHighlightForeground": "#333333",
"editorOverviewRuler.selectionHighlightForeground": "#555555",
"editorOverviewRuler.warningForeground": "#88bbff",
"editorOverviewRuler.wordHighlightForeground": "#333333",
"editorOverviewRuler.wordHighlightStrongForeground": "#555555",
"editorRuler.foreground": "#ffffff",
"editorSuggestWidget.background": "#333333",
"editorSuggestWidget.border": "#333333",
"editorSuggestWidget.foreground": "#888888",
"editorSuggestWidget.highlightForeground": "#ffffff",
"editorSuggestWidget.selectedBackground": "#666666",
"editorWarning.border": "#00000000",
"editorWarning.foreground": "#88bbff",
"editorWhitespace.foreground": "#333333",
"editorWidget.background": "#333333",
"editorWidget.border": "#333333",
"errorForeground": "#88bbff",
"extensionButton.prominentBackground": "#333333",
"extensionButton.prominentForeground": "#ffffff",
"extensionButton.prominentHoverBackground": "#555555",
"focusBorder": "#666666",
"foreground": "#ffffff",
"gitDecoration.modifiedResourceForeground": "#cccccc",
"gitDecoration.untrackedResourceForeground": "#cccccc",
"input.background": "#333333",
"input.border": "#333333",
"input.foreground": "#ffffff",
"input.placeholderForeground": "#555555",
"inputOption.activeBorder": "#555555",
"inputValidation.errorBackground": "#333333",
"inputValidation.errorBorder": "#88bbff",
"inputValidation.infoBackground": "#333333",
"inputValidation.infoBorder": "#bba0ff",
"inputValidation.warningBackground": "#333333",
"inputValidation.warningBorder": "#88bbff",
"list.activeSelectionBackground": "#111111",
"list.activeSelectionForeground": "#ffffff",
"list.dropBackground": "#111111bf",
"list.focusBackground": "#222222",
"list.focusForeground": "#ffffff",
"list.highlightForeground": "#ffffff",
"list.hoverBackground": "#333333",
"list.hoverForeground": "#ffffff",
"list.inactiveSelectionBackground": "#000000",
"list.inactiveSelectionForeground": "#ffffff",
"menu.background": "#333333",
"menu.foreground": "#ffffff",
"merge.border": "#222222",
"merge.currentContentBackground": "#333333",
"merge.currentHeaderBackground": "#555555",
"merge.incomingContentBackground": "#555555",
"merge.incomingHeaderBackground": "#666666",
"panel.background": "#111111",
"panel.border": "#111111",
"panelTitle.activeBorder": "#ffffff",
"panelTitle.activeForeground": "#ffffff",
"panelTitle.inactiveForeground": "#888888",
"peekView.border": "#222222",
"peekViewEditor.background": "#333333",
"peekViewEditor.matchHighlightBackground": "#555555",
"peekViewEditorGutter.background": "#333333",
"peekViewResult.background": "#333333",
"peekViewResult.fileForeground": "#888888",
"peekViewResult.lineForeground": "#888888",
"peekViewResult.matchHighlightBackground": "#555555",
"peekViewResult.selectionBackground": "#333333",
"peekViewResult.selectionForeground": "#ffffff",
"peekViewTitle.background": "#333333",
"peekViewTitleDescription.foreground": "#888888",
"peekViewTitleLabel.foreground": "#ffffff",
"pickerGroup.border": "#222222",
"pickerGroup.foreground": "#555555",
"progressBar.background": "#333333",
"scrollbar.shadow": "#191919",
"scrollbarSlider.activeBackground": "#ffffff12",
"scrollbarSlider.background": "#ffffff12",
"scrollbarSlider.hoverBackground": "#ffffff12",
"selection.background": "#2255aa",
"sideBar.background": "#111111",
"sideBar.border": "#111111",
"sideBar.foreground": "#888888",
"sideBarSectionHeader.background": "#111111",
"sideBarSectionHeader.foreground": "#666666",
"sideBarTitle.foreground": "#555555",
"statusBar.background": "#111111",
"statusBar.border": "#111111",
"statusBar.debuggingBackground": "#666666",
"statusBar.debuggingForeground": "#ffffff",
"statusBar.foreground": "#666666",
"statusBar.noFolderBackground": "#111111",
"statusBar.noFolderForeground": "#666666",
"statusBarItem.activeBackground": "#222222",
"statusBarItem.hoverBackground": "#222222",
"statusBarItem.prominentBackground": "#333333",
"statusBarItem.prominentHoverBackground": "#444444",
"tab.activeBackground": "#222222",
"tab.border": "#111111",
"tab.inactiveBackground": "#111111",
"tab.inactiveForeground": "#888888",
"tab.unfocusedActiveBorder": "#888888",
"tab.unfocusedActiveForeground": "#888888",
"tab.unfocusedInactiveForeground": "#888888",
"terminal.ansiBlack": "#333333",
"terminal.ansiBlue": "#88bbff",
"terminal.ansiBrightBlack": "#666666",
"terminal.ansiBrightBlue": "#88bbff",
"terminal.ansiBrightCyan": "#bba0ff",
"terminal.ansiBrightGreen": "#ffdd44",
"terminal.ansiBrightMagenta": "#88bbff",
"terminal.ansiBrightRed": "#88bbff",
"terminal.ansiBrightWhite": "#ffffff",
"terminal.ansiBrightYellow": "#88cc44",
"terminal.ansiCyan": "#bba0ff",
"terminal.ansiGreen": "#ffdd44",
"terminal.ansiMagenta": "#88bbff",
"terminal.ansiRed": "#88bbff",
"terminal.ansiWhite": "#ffffff",
"terminal.ansiYellow": "#88cc44",
"terminal.background": "#151515",
"terminal.foreground": "#ffffff",
"titleBar.activeBackground": "#111111",
"titleBar.activeForeground": "#888888",
"titleBar.inactiveBackground": "#111111",
"titleBar.inactiveForeground": "#555555",
"walkThrough.embeddedEditorBackground": "#111111",
"widget.shadow": "#111111",
//"activityBar.activeBorder": "#888888",
//"activityBar.dropBorder": "#888888",
//"activityBar.inactiveForeground": "#88888866",
//"banner.background": "#111111",
//"banner.foreground": "#ffffff",
//"banner.iconForeground": "#3794ff",
//"bookmarks.lineBackground": "#00000000",
//"bookmarks.lineBorder": "#00000000",
//"bookmarks.overviewRuler": "#157efb88",
//"breadcrumb.activeSelectionForeground": "#ffffff",
//"breadcrumb.background": "#222222",
//"breadcrumb.focusForeground": "#ffffff",
//"breadcrumb.foreground": "#ffffffcc",
//"breadcrumbPicker.background": "#333333",
//"button.secondaryBackground": "#3a3d41",
//"button.secondaryForeground": "#ffffff",
//"button.secondaryHoverBackground": "#45494e",
//"charts.blue": "#3794ff",
//"charts.foreground": "#ffffff",
//"charts.green": "#89d185",
//"charts.lines": "#ffffff80",
//"charts.orange": "#d18616",
//"charts.purple": "#b180d7",
//"charts.red": "#ee5500",
//"charts.yellow": "#88bbff",
//"checkbox.background": "#222222",
//"checkbox.border": "#222222",
//"checkbox.foreground": "#888888",
//"debugConsole.errorForeground": "#88bbff",
//"debugConsole.infoForeground": "#3794ff",
//"debugConsole.sourceForeground": "#ffffff",
//"debugConsole.warningForeground": "#88bbff",
//"debugConsoleInputIcon.foreground": "#ffffff",
//"debugIcon.breakpointCurrentStackframeForeground": "#ffcc00",
//"debugIcon.breakpointDisabledForeground": "#848484",
//"debugIcon.breakpointForeground": "#e51400",
//"debugIcon.breakpointStackframeForeground": "#89d185",
//"debugIcon.breakpointUnverifiedForeground": "#848484",
//"debugIcon.continueForeground": "#75beff",
//"debugIcon.disconnectForeground": "#f48771",
//"debugIcon.pauseForeground": "#75beff",
//"debugIcon.restartForeground": "#89d185",
//"debugIcon.startForeground": "#89d185",
//"debugIcon.stepBackForeground": "#75beff",
//"debugIcon.stepIntoForeground": "#75beff",
//"debugIcon.stepOutForeground": "#75beff",
//"debugIcon.stepOverForeground": "#75beff",
//"debugIcon.stopForeground": "#f48771",
//"debugTokenExpression.boolean": "#4e94ce",
//"debugTokenExpression.error": "#f48771",
//"debugTokenExpression.name": "#c586c0",
//"debugTokenExpression.number": "#b5cea8",
//"debugTokenExpression.string": "#ce9178",
//"debugTokenExpression.value": "#cccccc99",
//"debugView.exceptionLabelBackground": "#6c2022",
//"debugView.exceptionLabelForeground": "#ffffff",
//"debugView.stateLabelBackground": "#88888844",
//"debugView.stateLabelForeground": "#ffffff",
//"debugView.valueChangedHighlight": "#569cd6",
//"descriptionForeground": "#ffffffb3",
//"diffEditor.diagonalFill": "#cccccc33",
//"editor.findRangeHighlightBackground": "#3a3d4166",
//"editor.focusedStackFrameHighlightBackground": "#7abd7a4d",
//"editor.foldBackground": "#4444664d",
//"editor.inlineValuesBackground": "#ffc80033",
//"editor.inlineValuesForeground": "#ffffff80",
//"editor.linkedEditingBackground": "#ff00004d",
//"editor.snippetFinalTabstopHighlightBorder": "#525252",
//"editor.snippetTabstopHighlightBackground": "#7c7c7c4d",
//"editor.stackFrameHighlightBackground": "#ffff0033",
//"editor.symbolHighlightBackground": "#444466aa",
//"editorActiveLineNumber.foreground": "#c6c6c6",
//"editorBracketHighlight.foreground1": "#ffd700",
//"editorBracketHighlight.foreground2": "#da70d6",
//"editorBracketHighlight.foreground3": "#179fff",
//"editorBracketHighlight.foreground4": "#00000000",
//"editorBracketHighlight.foreground5": "#00000000",
//"editorBracketHighlight.foreground6": "#00000000",
//"editorBracketHighlight.unexpectedBracket.foreground": "#ff1212cc",
//"editorBracketPairGuide.activeBackground1": "#00000000",
//"editorBracketPairGuide.activeBackground2": "#00000000",
//"editorBracketPairGuide.activeBackground3": "#00000000",
//"editorBracketPairGuide.activeBackground4": "#00000000",
//"editorBracketPairGuide.activeBackground5": "#00000000",
//"editorBracketPairGuide.activeBackground6": "#00000000",
//"editorBracketPairGuide.background1": "#00000000",
//"editorBracketPairGuide.background2": "#00000000",
//"editorBracketPairGuide.background3": "#00000000",
//"editorBracketPairGuide.background4": "#00000000",
//"editorBracketPairGuide.background5": "#00000000",
//"editorBracketPairGuide.background6": "#00000000",
//"editorGhostText.foreground": "#ffffff56",
//"editorGutter.commentRangeForeground": "#c5c5c5",
//"editorGutter.foldingControlForeground": "#c5c5c5",
//"editorHint.foreground": "#eeeeeeb3",
//"editorHoverWidget.foreground": "#ffffff",
//"editorHoverWidget.highlightForeground": "#ffffff",
//"editorHoverWidget.statusBarBackground": "#3d3d3d",
//"editorIndentGuide.activeBackground": "#333333",
//"editorInfo.foreground": "#3794ff",
//"editorInlayHint.background": "#88cc4499",
//"editorInlayHint.foreground": "#222222cc",
//"editorInlayHint.parameterBackground": "#88cc4499",
//"editorInlayHint.parameterForeground": "#222222cc",
//"editorInlayHint.typeBackground": "#88cc4499",
//"editorInlayHint.typeForeground": "#222222cc",
//"editorLightBulb.foreground": "#ffcc00",
//"editorLightBulbAutoFix.foreground": "#75beff",
//"editorLineNumber.activeForeground": "#c6c6c6",
//"editorMarkerNavigationError.headerBackground": "#88bbff1a",
//"editorMarkerNavigationInfo.background": "#3794ff",
//"editorMarkerNavigationInfo.headerBackground": "#3794ff1a",
//"editorMarkerNavigationWarning.headerBackground": "#88bbff1a",
//"editorOverviewRuler.bracketMatchForeground": "#a0a0a0",
//"editorOverviewRuler.commonContentForeground": "#60606066",
//"editorOverviewRuler.unicodeForeground": "#d186167e",
//"editorPane.background": "#222222",
//"editorSuggestWidget.focusHighlightForeground": "#ffffff",
//"editorSuggestWidget.selectedForeground": "#ffffff",
//"editorSuggestWidgetStatus.foreground": "#88888880",
//"editorUnicodeHighlight.border": "#bd9b03",
//"editorUnnecessaryCode.opacity": "#000000aa",
//"editorWidget.foreground": "#ffffff",
//"extensionBadge.remoteBackground": "#88cc44",
//"extensionBadge.remoteForeground": "#222222",
//"extensionIcon.preReleaseForeground": "#1d9271",
//"extensionIcon.starForeground": "#ff8e00",
//"extensionIcon.verifiedForeground": "#3794ff",
//"gitDecoration.addedResourceForeground": "#81b88b",
//"gitDecoration.conflictingResourceForeground": "#e4676b",
//"gitDecoration.deletedResourceForeground": "#c74e39",
//"gitDecoration.ignoredResourceForeground": "#8c8c8c",
//"gitDecoration.renamedResourceForeground": "#73c991",
//"gitDecoration.stageDeletedResourceForeground": "#c74e39",
//"gitDecoration.stageModifiedResourceForeground": "#e2c08d",
//"gitDecoration.submoduleResourceForeground": "#8db9e2",
//"gitlens.closedAutolinkedIssueIconColor": "#a371f7",
//"gitlens.closedPullRequestIconColor": "#f85149",
//"gitlens.decorations.addedForegroundColor": "#81b88b",
//"gitlens.decorations.branchAheadForegroundColor": "#35b15e",
//"gitlens.decorations.branchBehindForegroundColor": "#b15e35",
//"gitlens.decorations.branchDivergedForegroundColor": "#d8af1b",
//"gitlens.decorations.branchMissingUpstreamForegroundColor": "#c74e39",
//"gitlens.decorations.branchUnpublishedForegroundColor": "#35b15e",
//"gitlens.decorations.branchUpToDateForegroundColor": "#888888",
//"gitlens.decorations.copiedForegroundColor": "#73c991",
//"gitlens.decorations.deletedForegroundColor": "#c74e39",
//"gitlens.decorations.ignoredForegroundColor": "#8c8c8c",
//"gitlens.decorations.modifiedForegroundColor": "#cccccc",
//"gitlens.decorations.renamedForegroundColor": "#73c991",
//"gitlens.decorations.untrackedForegroundColor": "#cccccc",
//"gitlens.gutterBackgroundColor": "#ffffff13",
//"gitlens.gutterForegroundColor": "#bebebe",
//"gitlens.gutterUncommittedForegroundColor": "#00bcf299",
//"gitlens.lineHighlightBackgroundColor": "#00bcf233",
//"gitlens.lineHighlightOverviewRulerColor": "#00bcf299",
//"gitlens.mergedPullRequestIconColor": "#a371f7",
//"gitlens.openAutolinkedIssueIconColor": "#3fb950",
//"gitlens.openPullRequestIconColor": "#3fb950",
//"gitlens.trailingLineBackgroundColor": "#00000000",
//"gitlens.trailingLineForegroundColor": "#99999959",
//"gitlens.unpublishedCommitIconColor": "#35b15e",
//"gitlens.unpulledChangesIconColor": "#b15e35",
//"gitlens.unpushlishedChangesIconColor": "#35b15e",
//"icon.foreground": "#c5c5c5",
//"inputOption.activeBackground": "#66666666",
//"inputOption.activeForeground": "#ffffff",
//"inputOption.hoverBackground": "#5a5d5e80",
//"interactive.activeCodeBorder": "#222222",
//"interactive.inactiveCodeBorder": "#000000",
//"keybindingLabel.background": "#8080802b",
//"keybindingLabel.border": "#33333399",
//"keybindingLabel.bottomBorder": "#44444499",
//"keybindingLabel.foreground": "#cccccc",
//"keybindingTable.headerBackground": "#ffffff0a",
//"keybindingTable.rowsBackground": "#ffffff0a",
//"list.deemphasizedForeground": "#8c8c8c",
//"list.errorForeground": "#f88070",
//"list.filterMatchBackground": "#444466aa",
//"list.focusHighlightForeground": "#ffffff",
//"list.focusOutline": "#666666",
//"list.invalidItemForeground": "#b89500",
//"list.warningForeground": "#cca700",
//"listFilterWidget.background": "#653723",
//"listFilterWidget.noMatchesOutline": "#be1100",
//"listFilterWidget.outline": "#00000000",
//"menu.selectionBackground": "#111111",
//"menu.selectionForeground": "#ffffff",
//"menu.separatorBackground": "#bbbbbb",
//"menubar.selectionBackground": "#ffffff1a",
//"menubar.selectionForeground": "#888888",
//"merge.commonContentBackground": "#60606029",
//"merge.commonHeaderBackground": "#60606066",
//"minimap.errorHighlight": "#ff1212b3",
//"minimap.findMatchHighlight": "#d18616",
//"minimap.foregroundOpacity": "#000000",
//"minimap.selectionHighlight": "#264f78",
//"minimap.selectionOccurrenceHighlight": "#676767",
//"minimap.unicodeHighlight": "#d18616",
//"minimap.warningHighlight": "#88bbff",
//"minimapGutter.addedBackground": "#587c0c",
//"minimapGutter.deletedBackground": "#94151b",
//"minimapGutter.modifiedBackground": "#0c7d9d",
//"minimapSlider.activeBackground": "#ffffff09",
//"minimapSlider.background": "#ffffff09",
//"minimapSlider.hoverBackground": "#ffffff09",
//"notebook.cellBorderColor": "#000000",
//"notebook.cellEditorBackground": "#111111",
//"notebook.cellInsertionIndicator": "#666666",
//"notebook.cellStatusBarItemHoverBackground": "#ffffff26",
//"notebook.cellToolbarSeparator": "#80808059",
//"notebook.focusedCellBorder": "#666666",
//"notebook.focusedEditorBorder": "#666666",
//"notebook.inactiveFocusedCellBorder": "#000000",
//"notebook.selectedCellBackground": "#000000",
//"notebook.selectedCellBorder": "#000000",
//"notebook.symbolHighlightBackground": "#ffffff0b",
//"notebookScrollbarSlider.activeBackground": "#ffffff12",
//"notebookScrollbarSlider.background": "#ffffff12",
//"notebookScrollbarSlider.hoverBackground": "#ffffff12",
//"notebookStatusErrorIcon.foreground": "#88bbff",
//"notebookStatusRunningIcon.foreground": "#ffffff",
//"notebookStatusSuccessIcon.foreground": "#89d185",
//"notificationCenterHeader.background": "#424242",
//"notificationLink.foreground": "#3794ff",
//"notifications.background": "#333333",
//"notifications.border": "#424242",
//"notifications.foreground": "#ffffff",
//"notificationsErrorIcon.foreground": "#ee5500",
//"notificationsInfoIcon.foreground": "#3794ff",
//"notificationsWarningIcon.foreground": "#88bbff",
//"panel.dropBorder": "#ffffff",
//"panelSection.border": "#111111",
//"panelSection.dropBackground": "#111111bb",
//"panelSectionHeader.background": "#80808033",
//"ports.iconRunningProcessForeground": "#88cc44",
//"problemsErrorIcon.foreground": "#ee5500",
//"problemsInfoIcon.foreground": "#3794ff",
//"problemsWarningIcon.foreground": "#88bbff",
//"quickInput.background": "#333333",
//"quickInput.foreground": "#ffffff",
//"quickInputList.focusBackground": "#111111",
//"quickInputList.focusForeground": "#ffffff",
//"quickInputTitle.background": "#ffffff1b",
//"sash.hoverBorder": "#666666",
//"scm.providerBorder": "#454545",
//"searchEditor.findMatchBackground": "#44446670",
//"searchEditor.textInputBorder": "#333333",
//"settings.checkboxBackground": "#222222",
//"settings.checkboxBorder": "#222222",
//"settings.checkboxForeground": "#888888",
//"settings.dropdownBackground": "#222222",
//"settings.dropdownBorder": "#222222",
//"settings.dropdownForeground": "#888888",
//"settings.dropdownListBorder": "#333333",
//"settings.focusedRowBackground": "#80808024",
//"settings.focusedRowBorder": "#ffffff1f",
//"settings.headerForeground": "#e7e7e7",
//"settings.modifiedItemIndicator": "#0c7d9d",
//"settings.numberInputBackground": "#333333",
//"settings.numberInputBorder": "#333333",
//"settings.numberInputForeground": "#ffffff",
//"settings.rowHoverBackground": "#80808012",
//"settings.textInputBackground": "#333333",
//"settings.textInputBorder": "#333333",
//"settings.textInputForeground": "#ffffff",
//"sideBar.dropBackground": "#111111bb",
//"sideBySideEditor.horizontalBorder": "#111111",
//"sideBySideEditor.verticalBorder": "#111111",
//"statusBar.debuggingBorder": "#111111",
//"statusBar.noFolderBorder": "#111111",
//"statusBarItem.compactHoverBackground": "#ffffff33",
//"statusBarItem.errorBackground": "#0066eb",
//"statusBarItem.errorForeground": "#ffffff",
//"statusBarItem.prominentForeground": "#666666",
//"statusBarItem.remoteBackground": "#88cc44",
//"statusBarItem.remoteForeground": "#222222",
//"statusBarItem.warningBackground": "#0066eb",
//"statusBarItem.warningForeground": "#ffffff",
//"symbolIcon.arrayForeground": "#ffffff",
//"symbolIcon.booleanForeground": "#ffffff",
//"symbolIcon.classForeground": "#ee9d28",
//"symbolIcon.colorForeground": "#ffffff",
//"symbolIcon.constantForeground": "#ffffff",
//"symbolIcon.constructorForeground": "#b180d7",
//"symbolIcon.enumeratorForeground": "#ee9d28",
//"symbolIcon.enumeratorMemberForeground": "#75beff",
//"symbolIcon.eventForeground": "#ee9d28",
//"symbolIcon.fieldForeground": "#75beff",
//"symbolIcon.fileForeground": "#ffffff",
//"symbolIcon.folderForeground": "#ffffff",
//"symbolIcon.functionForeground": "#b180d7",
//"symbolIcon.interfaceForeground": "#75beff",
//"symbolIcon.keyForeground": "#ffffff",
//"symbolIcon.keywordForeground": "#ffffff",
//"symbolIcon.methodForeground": "#b180d7",
//"symbolIcon.moduleForeground": "#ffffff",
//"symbolIcon.namespaceForeground": "#ffffff",
//"symbolIcon.nullForeground": "#ffffff",
//"symbolIcon.numberForeground": "#ffffff",
//"symbolIcon.objectForeground": "#ffffff",
//"symbolIcon.operatorForeground": "#ffffff",
//"symbolIcon.packageForeground": "#ffffff",
//"symbolIcon.propertyForeground": "#ffffff",
//"symbolIcon.referenceForeground": "#ffffff",
//"symbolIcon.snippetForeground": "#ffffff",
//"symbolIcon.stringForeground": "#ffffff",
//"symbolIcon.structForeground": "#ffffff",
//"symbolIcon.textForeground": "#ffffff",
//"symbolIcon.typeParameterForeground": "#ffffff",
//"symbolIcon.unitForeground": "#ffffff",
//"symbolIcon.variableForeground": "#75beff",
//"tab.activeForeground": "#ffffff",
//"tab.activeModifiedBorder": "#3399cc",
//"tab.inactiveModifiedBorder": "#3399cc80",
//"tab.lastPinnedBorder": "#585858",
//"tab.unfocusedActiveBackground": "#222222",
//"tab.unfocusedActiveModifiedBorder": "#3399cc80",
//"tab.unfocusedInactiveBackground": "#111111",
//"tab.unfocusedInactiveModifiedBorder": "#3399cc40",
//"terminal.border": "#111111",
//"terminal.dropBackground": "#111111bb",
//"terminal.selectionBackground": "#ffffff40",
//"testing.iconErrored": "#f14c4c",
//"testing.iconFailed": "#f14c4c",
//"testing.iconPassed": "#73c991",
//"testing.iconQueued": "#cca700",
//"testing.iconSkipped": "#848484",
//"testing.iconUnset": "#848484",
//"testing.message.error.decorationForeground": "#ee5500",
//"testing.message.error.lineBackground": "#ff000033",
//"testing.message.info.decorationForeground": "#ffffff80",
//"testing.peekBorder": "#ee5500",
//"testing.peekHeaderBackground": "#ee55001a",
//"testing.runAction": "#73c991",
//"textBlockQuote.background": "#7f7f7f1a",
//"textBlockQuote.border": "#007acc80",
//"textCodeBlock.background": "#0a0a0a66",
//"textLink.activeForeground": "#3794ff",
//"textLink.foreground": "#3794ff",
//"textPreformat.foreground": "#d7ba7d",
//"textSeparator.foreground": "#ffffff2e",
//"toolbar.activeBackground": "#63666750",
//"toolbar.hoverBackground": "#5a5d5e50",
//"tree.indentGuidesStroke": "#585858",
//"tree.tableColumnsBorder": "#cccccc20",
//"tree.tableOddRowsBackground": "#ffffff0a",
//"welcomePage.progress.background": "#333333",
//"welcomePage.progress.foreground": "#3794ff",
//"welcomePage.tileBackground": "#333333",
//"welcomePage.tileHoverBackground": "#3d3d3d",
//"welcomePage.tileShadow": "#111111",
//"activityBar.activeBackground": null,
//"activityBar.activeFocusBorder": null,
//"button.border": null,
//"contrastActiveBorder": null,
//"contrastBorder": null,
//"debugToolBar.border": null,
//"diffEditor.border": null,
//"dropdown.listBackground": null,
//"editor.findMatchBorder": null,
//"editor.findMatchHighlightBorder": null,
//"editor.findRangeHighlightBorder": null,
//"editor.rangeHighlightBorder": null,
//"editor.selectionForeground": null,
//"editor.selectionHighlightBorder": null,
//"editor.snippetFinalTabstopHighlightBackground": null,
//"editor.snippetTabstopHighlightBorder": null,
//"editor.symbolHighlightBorder": null,
//"editor.wordHighlightBorder": null,
//"editor.wordHighlightStrongBorder": null,
//"editorCursor.background": null,
//"editorError.background": null,
//"editorError.border": null,
//"editorGhostText.background": null,
//"editorGhostText.border": null,
//"editorGroup.emptyBackground": null,
//"editorGroup.focusedEmptyBorder": null,
//"editorGroupHeader.border": null,
//"editorHint.border": null,
//"editorInfo.background": null,
//"editorInfo.border": null,
//"editorOverviewRuler.background": null,
//"editorSuggestWidget.selectedIconForeground": null,
//"editorUnnecessaryCode.border": null,
//"editorWarning.background": null,
//"editorWidget.resizeBorder": null,
//"inputValidation.errorForeground": null,
//"inputValidation.infoForeground": null,
//"inputValidation.warningForeground": null,
//"list.activeSelectionIconForeground": null,
//"list.filterMatchBorder": null,
//"list.inactiveFocusBackground": null,
//"list.inactiveFocusOutline": null,
//"list.inactiveSelectionIconForeground": null,
//"menu.border": null,
//"menu.selectionBorder": null,
//"menubar.selectionBorder": null,
//"minimap.background": null,
//"notebook.cellHoverBackground": null,
//"notebook.focusedCellBackground": null,
//"notebook.inactiveSelectedCellBorder": null,
//"notebook.outputContainerBackgroundColor": null,
//"notebook.outputContainerBorderColor": null,
//"notificationCenter.border": null,
//"notificationCenterHeader.foreground": null,
//"notificationToast.border": null,
//"panelInput.border": null,
//"panelSectionHeader.border": null,
//"panelSectionHeader.foreground": null,
//"peekViewEditor.matchHighlightBorder": null,
//"quickInput.list.focusBackground": null,
//"quickInputList.focusIconForeground": null,
//"searchEditor.findMatchBorder": null,
//"sideBarSectionHeader.border": null,
//"tab.activeBorder": null,
//"tab.activeBorderTop": null,
//"tab.hoverBackground": null,
//"tab.hoverBorder": null,
//"tab.hoverForeground": null,
//"tab.unfocusedActiveBorderTop": null,
//"tab.unfocusedHoverBackground": null,
//"tab.unfocusedHoverBorder": null,
//"tab.unfocusedHoverForeground": null,
//"terminal.tab.activeBorder": null,
//"terminalCursor.background": null,
//"terminalCursor.foreground": null,
//"testing.message.info.lineBackground": null,
//"titleBar.border": null,
//"toolbar.hoverOutline": null,
//"welcomePage.background": null,
//"window.activeBorder": null,
//"window.inactiveBorder": null
},
"tokenColors": [
{
"scope": [
"variable.language.this"
],
"settings": {
"fontStyle": ""
}
},
{
"scope": "markup.bold",
"settings": {
"fontStyle": "bold"
}
},
{
"scope": [
"invalid",
"markup.italic",
"markup.quote"
],
"settings": {
"fontStyle": "italic"
}
},
{
"scope": "markup.underline",
"settings": {
"fontStyle": "underline"
}
},
{
"scope": [
"source.js.jsx punctuation.section.embedded",
"entity.name.tag",
"string.other.link.description.title",
"support.constant",
"support.variable",
"support.type",
"variable.other.class",
"support.class.builtin.js",
"support.class.console.js",
"meta.property-value",
"variable.parameter.keyframe-list",
"meta.at-rule.keyframes entity.name.function",
"expression.embedded.vue punctuation.definition"
],
"settings": {
"foreground": "#BBA0FF",
"fontStyle": ""
}
},
{
"scope": [
"entity.other.attribute-name.pseudo-class.css",
"entity.name.type.object.console",
"variable.language",
"variable.parameter.function.language.special.self.python",
"storage.type",
"entity.other.attribute-name.pseudo-element.css"
],
"settings": {
"foreground": "#BBA0FF",
"fontStyle": "italic"
}
},
{
"scope": [
"punctuation.definition.string.template"
],
"settings": {
"foreground": "#BBA0FF",
"fontStyle": "bold"
}
},
{
"scope": [
"entity.other.attribute-name.class.css",
"entity.other.attribute-name.parent-selector-suffix.css",
"entity.other.attribute-name.parent-selector-suffix.css punctuation.definition.entity.css",
"meta.definition.function",
"markup.underline.link",
"markup.inserted",
"meta.function-call",
"meta.instance.constructor",
"meta.attribute-with-value.class string",
"string.other.ref",
"string.other.restructuredtext.ref",
"variable.function",
"entity.name.type",
"entity.name.function",
"variable.other.object.property",
"punctuation.separator.key-value",
"meta.definition.function.js",
"support.class.component.js",
"entity.other.inherited-class",
"support.class",
"support.function.misc",
"support.function",
"entity.other.attribute-name.id.css",
"entity.other.attribute-name.id.css punctuation",
"entity.other.attribute-name.class.css punctuation",
"meta.function-call support.function.construct",
"entity.other.attribute-name"
],
"settings": {
"foreground": "#FFDD44"
}
},
{
"scope": "storage.type.function.arrow",
"settings": {
"foreground": "#FFDD44",
"fontStyle": ""
}
},
{
"scope": [
"entity.name.section",
"constant.numeric.line-number.match.find-in-files",
"markup.heading",
"markup.changed",
"meta.attribute-with-value.id string",
"string",
"punctuation.definition.string.begin",
"punctuation.definition.string.end",
"meta.attribute-selector"
],
"settings": {
"foreground": "#88CC44"
}
},
{
"scope": [
"keyword",
"keyword.control",
"constant",
"constant.numeric",
"constant.language",
"constant.other.property",
"constant.character.escape",
"comment keyword.codetag.notation",
"keyword.other.template.begin",
"keyword.other.template.end",
"markup.raw",
"markup.deleted",
"meta.property-list.css variable.other",
"entity.name.constant.preprocessor",
"meta.preprocessor",
"punctuation.section.embedded",
"punctuation.template-string.element.begin",
"punctuation.template-string.element.end",
"string.quoted.template punctuation.definition.string.begin",
"string.quoted.template punctuation.definition.string.end",
"meta.paragraph.markdown meta.dummy.line-break",
"meta.paragraph.markdown meta.hard-line-break.markdown",
"storage",
"storage.class.restructuredtext.ref",
"string.other.link.title",
"string.other.link.description",
"string.regexp punctuation.definition.string.begin",
"string.regexp punctuation.definition.string.end",
"variable.language.arguments",
"storage.modifier",
"keyword.operator.new",
"keyword.operator",
"keyword.operator.spread",
"punctuation.section.embedded.end.php source.php",
"support.function.construct",
"meta.at-rule.keyframes",
"meta.at-rule.keyframes entity.other.attribute-name"
],
"settings": {
"foreground": "#88BBFF"
}
},
{
"scope": [
"variable.other.substitution"
],
"settings": {
"foreground": "#88BBFF",
"fontStyle": "bold"
}
},
{
"scope": [
"meta.function-call meta.function-call.arguments",
"meta.function-call meta.arguments",
"meta.function-call meta.group",
"source.json meta.structure.dictionary",
"meta.object.member",
"punctuation.definition.group",
"string.unquoted.label",
"variable.other.member",
"entity.name.class",
"entity.name.namespace",
"constant.other",
"variable",
"variable.other",
"variable.other.constant.js",
"text.find-in-files",
"source",
"entity.name.type.module",
"source.sql support.function",
"support.other.namespace.php"
],
"settings": {
"foreground": "#FFFFFF",
"fontStyle": ""
}
},
{
"scope": [
"variable.parameter",
"parameters variable.function"
],
"settings": {
"foreground": "#FFFFFF",
"fontStyle": "italic"
}
},
{
"scope": [
"variable.other.property",
"support.variable.property",
"punctuation.separator.key-value",
"meta.object-literal.key",
"variable.other.object.property",
"variable.object.property",
"text.html.basic",
"text.html.vue-html",
"text.html.php",
"text.html.derivative",
"punctuation.definition.variable",
"punctuation.definition.keyword.scss",
"meta.jsx.children.js",
"meta.tag.attributes keyword.operator.assignment",
"support.type.vendored.property-name.css",
"support.type.property-name.json",
"variable.other.constant.property"
],
"settings": {
"foreground": "#BBBBCC"
}
},
{
"scope": "meta.property-name support.type",
"settings": {
"foreground": "#BBBBCC",
"fontStyle": ""
}
},
{
"scope": [
"keyword.other.substitution",
"keyword.operator.heading.restructuredtext",
"keyword.operator.table.row.restructuredtext",
"keyword.operator.table.data.restructuredtext",
"punctuation",
"markup.ignored",
"markup.untracked",
"meta.brace.round",
"meta.brace.square",
"meta.brace.curly",
"meta.delimiter.comma.js",
"meta.function-call.without-arguments.js",
"meta.function-call.method.without-arguments.js",
"source.scss",
"string source punctuation.section.embedded",
"punctuation.definition.tag.begin source",
"source.php"
],
"settings": {
"foreground": "#9999AA"
}
},
{
"scope": [
"comment",
"comment punctuation"
],
"settings": {
"foreground": "#888899",
"fontStyle": "italic"
}
},
{
"scope": "token.info-token",
"settings": {
"foreground": "#6796E6"
}
},
{
"scope": "token.warn-token",
"settings": {
"foreground": "#CD9731"
}
},
{
"scope": "token.error-token",
"settings": {
"foreground": "#F44747"
}
},
{
"scope": "token.debug-token",
"settings": {
"foreground": "#B267E6"
}
}
]
}
File renamed without changes.
File renamed without changes.
-41
View File
@@ -1,41 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Spark Client",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/build/Debug/bin/net6.0-windows/Spark.exe",
"cwd": "${workspaceFolder}/build/Debug/bin/net6.0-windows",
"enableStepFiltering": false,
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "Spark Test",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/build/Debug/bin/net6.0/sparkcmd.exe",
"args": ["test", "${input:test}"],
"cwd": "${workspaceFolder}/build/Debug/bin/net6.0-windows",
"enableStepFiltering": false,
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "Attach (.NET Core)",
"type": "coreclr",
"request": "attach"
}
],
"inputs": [
{
"id": "test",
"description": "The test(s) to run",
"type": "promptString"
}
]
}
-37
View File
@@ -1,37 +0,0 @@
{
"cmake.configureOnOpen": false,
"workbench.colorTheme": "Default Dark+",
"C_Cpp.intelliSenseEngine": "Disabled",
"files.associations": {
"*.js": "javascript",
"*.conf": "jsonc",
"array": "cpp",
"xtree": "cpp",
"chrono": "cpp",
"*.ipp": "cpp",
"optional": "cpp",
"regex": "cpp",
"system_error": "cpp",
"format": "cpp",
"future": "cpp",
"istream": "cpp",
"memory": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"variant": "cpp",
"xlocmes": "cpp",
"xlocmon": "cpp",
"xlocnum": "cpp",
"xloctime": "cpp",
"xutility": "cpp",
"xstring": "cpp",
"string": "cpp",
"cstdint": "cpp"
},
"files.exclude": {
"**/.g.cs": true,
"**/.g.i.cs": true
}
}
-44
View File
@@ -1,44 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Spark Client",
"type": "process",
"command": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Common7\\Tools\\VsDevCmd.bat",
"args": [
"-arch=x64",
"-host_arch=x64",
"&&",
"${workspaceRoot}\\tools\\buildspark.cmd"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "new",
"showReuseMessage": false,
"clear": false,
"close": false
}
},
{
"label": "Run Spark Client",
"type": "process",
"command": "${workspaceRoot}\\build\\Debug\\bin\\net6.0-windows\\Spark.exe",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"problemMatcher": []
}
]
}
+1
View File
@@ -0,0 +1 @@
set(sources /home/taha/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)
+2 -2
View File
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.5)
project(doc)
include(${CMAKE_SOURCE_DIR}/cmake/safe_dep_glob.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/Protobuf.cmake)
include(${CMAKE_SOURCE_DIR}/tools/safe_dep_glob.cmake)
include(${CMAKE_SOURCE_DIR}/tools/Protobuf.cmake)
# DEPENDENCIES
set(DOC_GLOBS
Submodule
+1
Submodule docker/linux added at 05967d0f18.
-141
View File
@@ -1,141 +0,0 @@
FROM ubuntu:latest
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=America/New_York
# light deps (should be quick to download/install)
RUN apt-get update && apt-get install -y \
ca-certificates \
curl \
gnupg \
liblttng-ust-dev \
libpcap0.8-dev \
locales \
ninja-build \
software-properties-common \
sqlite3 \
tzdata
# clang
RUN apt-get update && apt-get install -y \
clang-13 \
clang-format-13 \
clangd-13 \
clang-15 \
clang-format-15 \
clangd-15
# g++
RUN apt-get update && apt-get install -y \
g++-11 \
g++-12
# python
RUN apt-get update && apt-get install -y \
python3-pip \
python3-venv \
&& python3 -m pip install --upgrade pip
# dotnet
RUN apt-get update && apt-get install -y \
dotnet7
# ssh
RUN apt-get update && apt-get install -y \
libssh2-1-dev \
openssh-server
# cmake
RUN \
curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc 2> /dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" \
| tee /etc/apt/sources.list.d/kitware.list > /dev/null \
&& apt-get update \
&& rm /usr/share/keyrings/kitware-archive-keyring.gpg \
&& apt-get install -y kitware-archive-keyring \
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs)-rc main" \
| tee -a /etc/apt/sources.list.d/kitware.list >/dev/null \
&& apt-get install -y cmake
# node
ARG node_major=18
RUN mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$node_major.x nodistro main" \
| tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs
# ccache is done here so that ccache sees clang++ installed, not clang-10
RUN apt-get update && apt-get install -y \
ccache
# emumba (light deps)
RUN apt-get update && apt-get install -y \
build-essential \
doxygen \
python3-sphinx \
graphviz \
libgtest-dev \
libssl-dev \
rapidjson-dev \
zlib1g-dev \
pkg-config
# emumba (boost)
RUN apt-get update && apt-get install -y \
libboost-filesystem-dev \
libboost-program-options-dev \
libboost-test-dev \
libboost-date-time-dev
# dev utils
RUN apt-get update && apt-get install -y \
fish \
git-all \
sudo \
vim \
wget
# set up default executables (update-alternatives)
RUN \
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-13 100; \
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-13 100; \
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-13 100; \
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-13 100; \
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100; \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
# Add compiler symlinks for ccache
RUN \
ln -s /usr/bin/ccache /usr/local/bin/clang; \
ln -s /usr/bin/ccache /usr/local/bin/clang++; \
ln -s /usr/bin/ccache /usr/local/bin/clang-13; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-13; \
ln -s /usr/bin/ccache /usr/local/bin/clang-15; \
ln -s /usr/bin/ccache /usr/local/bin/clang++-15; \
ln -s /usr/bin/ccache /usr/local/bin/gcc; \
ln -s /usr/bin/ccache /usr/local/bin/g++; \
ln -s /usr/bin/ccache /usr/local/bin/gcc-11; \
ln -s /usr/bin/ccache /usr/local/bin/g++-11; \
ln -s /usr/bin/ccache /usr/local/bin/gcc-12; \
ln -s /usr/bin/ccache /usr/local/bin/g++-12
RUN locale-gen en_US.UTF-8
ARG docker_user="bts"
ARG docker_uid="1000"
ARG docker_pass="bts"
RUN \
groupadd -g "$docker_uid" "$docker_user" \
&& useradd \
-m \
-u "$docker_uid" \
-g "$docker_uid" \
-G sudo \
--password "$(openssl passwd -1 "$docker_pass")" \
"$docker_user"
-64
View File
@@ -1,64 +0,0 @@
[dev containers]: https://code.visualstudio.com/docs/devcontainers/containers
[dev containers ext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
[docker repo sparkd-dev]: https://hub.docker.com/repository/docker/bluetradingsystems/sparkd-dev/general
# Sparkd Dev Container
## How to create a VS Code [Dev Container][dev containers]
1. Make sure the **[Dev Containers][dev containers ext]** extension is installed
1. Make sure your Docker image is up to date
```
docker pull bluetradingsystems/sparkd-dev:latest
```
1. Copy **devcontainer.json** from this folder to **$workspaceFolder/.devcontainer/**.
1. In the VS Code Command Palette, run **Dev Containers: Reopen in Container**
---
## How to create a Sparkd Container in the terminal (without VS Code)
1. Make sure your Docker image is up to date
```
docker pull bluetradingsystems/sparkd-dev:latest
```
2. Start the container
```
# Replace <cont_name> with a name for the container. The container's
# "$HOME" dir will be mounted to "$HOME/.sparkd-dev/mounts/<cont_name> on
# the host
./start_docker.sh --container <cont_name> --mount-existing
```
* *Replace <cont_name> with a name for the container*
* *The container's `$HOME` dir will be mounted to
`$HOME/.sparkd-dev/mounts<cont_name>` on the host*<br>
* *Run: `./start_docker.sh --help` to see additional options*
3. *(Optional) Attach VS Code to the running container.*<br>
Run **Dev Containers: Attach to Running Container** from the command palette,
then select your container in the dropdown
---
## How to update the Docker image
1. Change the image by modifying the Dockerfile (don't tag arbitrary
images on your machine and push them to our repo on Docker Hub)
1. After modifying the Dockerfile, (re)build the image
```
# Run in this dir
docker build -t bluetradingsystems/sparkd-dev:latest .
```
***Note:** Your docker login must have write permissions to push to the
[sparkd-dev][docker repo sparkd-dev] repository*
2. Commit the changes to Dockerfile in git
3. Push the new image to Docker Hub
```
docker push bluetradingsystems/sparkd-dev:latest
```
***Note:** The image doesn't have to be on Docker Hub, we can simply build
it from scratch on our local machines (with the Dockerfile). However, this
takes time. It is significantly quicker to download a prebuilt image, so we
store it on a remote repository to save time when setting up a new dev
machine.*
-123
View File
@@ -1,123 +0,0 @@
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
if [[ ! -v XDG_CONFIG_HOME ]]; then
export XDG_CONFIG_HOME="$HOME/.config"
fi
export PATH="$HOME/.local/bin:$PATH"
-25
View File
@@ -1,25 +0,0 @@
if ! set -q XDG_CONFIG_HOME
set -g XDG_CONFIG_HOME "$HOME/.config"
end
set fish_config_home $XDG_CONFIG_HOME/fish
if test -f "$fish_config_home/aliases.fish"
source "$fish_config_home/aliases.fish"
end
# enable general colors and case insensitive search in 'less'
set -x LESS "$LESS -R -Q -I"
set -x LC_ALL en_US.UTF-8
# enable syntax highlighting in 'less'
# set highlight color scheme in 'less' (fg)(bg)
set -g LESS_TERMCAP_md (tput bold)(tput setaf 36)
set -g LESS_TERMCAP_me (tput sgr0)
set -g LESS_TERMCAP_so (tput setaf 232)(tput setab 49)
set -q TERM
if test $status != 0; or test $TERM = 'xterm'
set -g TERM 'xterm-256color'
end
# Fix impossible-to-see navy blue command text color
set fish_color_command F8F8F2
set -g PATH "$HOME/.local/bin" "$PATH"
-33
View File
@@ -1,33 +0,0 @@
{
"image": "bluetradingsystems/sparkd-dev:latest",
// Creates local dir to mount to HOME in docker
"initializeCommand": "mkdir -p ${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId}",
"hostRequirements": {
"memory": "4gb",
"storage": "6gb"
},
"postCreateCommand": "/home/bts/spark/docker/sparkd/dev/devcontainer_post_create.sh",
"containerUser": "bts",
"workspaceMount": "source=${localWorkspaceFolder},target=/home/bts/spark,type=bind",
"workspaceFolder": "/home/bts/spark",
"updateRemoteUserUID": true,
"shutdownAction": "none",
// Note: If running multiple containers on the same host, each must use a
// unique set of ports. Usually we just add 1000 to each port as needed. For
// example, if 8000-8003 is taken, go with 9000-9003, then 10000-10003, etc.
"runArgs": [
"--shm-size",
"2gb",
"-p",
"8000:8000",
"-p",
"8001:8001",
"-p",
"8002:8002",
"-p",
"8003:8003"
],
"mounts": [
"source=${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId},target=/home/bts,type=bind"
]
}
@@ -1,33 +0,0 @@
#!/usr/bin/env bash
this_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
repo_dir="$(cd "$this_dir" && git rev-parse --show-toplevel)"
tools_dir="$repo_dir/tools"
gen_tag="GENERATED BY $(basename "${BASH_SOURCE[0]}")"
function copy_if_not_exist() {
src="$1"
dest="$2"
if [[ ! -e "$src" ]]; then
echo "Unable to copy $src to $dest. Source file doesn't exist"
exit 1
fi
if [[ ! -e "$dest" ]]; then
cp "$src" "$dest"
fi
}
# Init bashrc
echo "Initializing bashrc"
copy_if_not_exist "$this_dir/bashrc" "$HOME/.bashrc"
# Init fish config
echo "Initializing fish config"
fish_cfg_dir="$HOME/.config/fish/"
mkdir -p "$fish_cfg_dir"
exec "$tools_dir/write_tag_block.sh" \
--tag "$gen_tag" \
--replace \
--in-place \
--file "$fish_cfg_dir/config.fish" \
--text "$(cat "$this_dir/config.fish")"
-250
View File
@@ -1,250 +0,0 @@
#!/usr/bin/env bash
function _exit() {
if [[ "$#" -gt 1 ]]; then
# When there are multiple args, the last arg is the exit code.
echo "${@:1:($# - 1)}"
exit "${@: -1}"
fi
echo "$1"
exit 0
}
help_text="\
Add or update a user's uid
This script is intended to be run in a Docker container as a means to obtain
file permissions in mounted directories owned by the specified UID.
Usage: set_user.sh [OPTIONS] USER UID
Positionals:
USER The name of the user
Options:
--user USER The name of the user (defaults to 'bts')
--uid UID The new uid to give USER (defaults to '1000')
--group GROUP The primary group to give USER (defaults to USER)
--gid GID The primary gid to give USER (defaults to UID)
--pass PASSWORD The password to give USER (defaults to USER, only applies
if USER hasn't been created yet)
--modify-existing Update UID/GID even if USER already exists
-h,--help Print this help message and exit
"
function _add_group() {
if [[ "$#" -ne 2 ]]; then
_exit "'_add_group' requires exactly 2 args (group, gid). Received $#." 1
fi
local group="$1"
local gid="$2"
# Check if gid already exists
local existing_group=""
existing_group="$(getent group "$gid" | cut -d : -f 1)"
if [[ -n "$existing_group" ]]; then
if [[ "$existing_group" != "$group" ]]; then
echo "\
The gid '$gid' is already in use by group '$existing_group' (will not rename \
the group)"
fi
return
fi
# Check if group with same name already exists
local existing_gid=""
existing_gid="$(getent group "$group" | cut -d : -f 3)"
if [[ -n "$existing_gid" ]]; then
# The group already exists. Only modify if --modify-existing was specified.
if [[ "$modify_existing" -eq 0 ]]; then
_exit "\
The group '$group' already exists with gid '$existing_gid'.
Specify --modify-existing to change the gid anyways." 1
fi
echo "Changing gid for group '$group' from '$existing_gid' to '$gid'"
groupmod -g "$gid" "$group"
else
# The group doesn't exist. Add it
echo "Adding group '$group:$gid'"
groupadd -g "$gid" "$group"
fi
}
function _add_user() {
local user="$1"
local uid="$2"
local group="$3"
local gid="$4"
local pass="$5"
if [[ "$#" -ne 5 ]]; then
_exit "'_add_user' requires exactly 5 args (user, uid, group, gid, pass). \
Received $#." 1
fi
# Check if uid is being used by another user
local existing_user=""
existing_user="$(getent passwd "$uid" | cut -d : -f 1)"
if [[ -n "$existing_user" ]]; then
if [[ "$existing_user" != "$user" ]]; then
_exit "The uid '$uid' is already in use by user '$existing_user'." 1
fi
echo "The user '$user' already has the specified uid '$uid'."
# Modify gid if necessary
local existing_gid=""
existing_gid="$(id -g "$user" 2> /dev/null)"
if [[ "$existing_gid" = "$gid" ]]; then
echo "The user '$user' already has the specified gid '$gid'."
return
fi
if [[ "$modify_existing" -eq 0 ]]; then
_exit "\
The user '$user' is associated with the primary group '$existing_gid'.
Specify --modify-existing to change the gid anyways." 1
fi
echo "Changing primary group for '$user' from '$existing_gid' to '$gid'."
usermod -g "$gid" "$user"
return
fi
# Check if user with same name already exists
local existing_uid=""
existing_uid="$(id -u "$user" 2> /dev/null)"
if [[ -n "$existing_uid" ]]; then
if [[ "$existing_uid" = "$uid" ]]; then
_exit "The user '$user' already has the specified uid '$uid'" 0
fi
if [[ "$modify_existing" -eq 0 ]]; then
_exit "\
User '$user' already exists with uid '$existing_uid'.
Specify --modify-existing to change the uid anyways." 1
fi
echo "Changing uid for user '$user' from '$existing_uid' to '$uid'"
if ! usermod -u "$uid" -g "$gid" "$user"; then
_exit "usermod exited with code $?" 1
fi
return
fi
# The user doesn't exist. Add it
echo "Adding user '$user:$uid' (group='$group:$gid', password='$pass')"
useradd -m -u "$uid" -g "$gid" -G sudo --password "$(openssl passwd -1 "$pass")" "$user"
}
function _update_fish_dir_perms() {
local user="$1"
local uid="$2"
local gid="$3"
# When a fish shell session starts, a temp dir named '/tmp/fish.<user>' is
# created with the user's current uid/gid. If such a dir exists for the
# specified USER, make sure the uid/gid match the new values.
fish_dir="/tmp/fish.$user"
if [[ -d "$fish_dir" ]]; then
perms="$uid:$gid"
existing_perms="$(stat -c %u:%g "$fish_dir")"
if [[ "$existing_perms" != "$perms" ]]; then
echo "Changing uid:gid for dir '$fish_dir' from '$existing_perms' to '$perms'"
chown -R "$perms" "$fish_dir"
fi
fi
}
user=""
group=""
pass=""
declare -i uid=0
declare -i gid=0
declare -i modify_existing=0
while [[ $# -gt 0 ]]; do
case "$1" in
--user)
if [[ -z "$2" ]]; then
_exit "USER (--user) must be non-empty" 1
elif [[ "$2" = "root" ]]; then
_exit "USER (--user) cannot be 'root'" 1
fi
user="$2"
shift 2
;;
--group)
if [[ -z "$2" ]]; then
_exit "GROUP (--group) must be non-empty" 1
elif [[ "$2" = "root" ]]; then
_exit "GROUP (--group) cannot be 'root'" 1
fi
group="$2"
shift 2
;;
--uid)
if [[ -z "$2" ]]; then
_exit "UID (--uid) must be non-empty" 1
fi
uid="$2"
shift 2
;;
--gid)
if [[ -z "$2" ]]; then
_exit "GID (--gid) must be non-empty" 1
fi
gid="$2"
shift 2
;;
--pass)
if [[ -z "$2" ]]; then
_exit "PASS (--pass) must be non-empty" 1
fi
pass="$2"
shift 2
;;
--modify-existing)
modify_existing=1
shift 1
;;
-h)
;&
--help)
_exit "$help_text" 0
;;
*)
if [[ -z "$1" ]]; then
_exit "Invalid positional argument '$1'" 1
elif [[ -z "$user" ]]; then
user="$1"
elif [[ -z "$uid" ]]; then
uid="$1"
else
_exit "Unexpected argument '$1'" 1
fi
shift 1
;;
esac
done
if [[ -z "$user" ]]; then
user="bts"
fi
if [[ $uid -eq 0 ]]; then
uid=1000
fi
# In general, a user's primary group/gid matches the user's name/uid.
# If group/gid args weren't specified, set them to name/uid.
if [[ -z "$group" ]]; then
group="$user"
fi
if [[ $gid -eq 0 ]]; then
gid=$uid
fi
if [[ -z "$pass" ]]; then
pass="$user"
fi
_add_group "$group" "$gid"
_add_user "$user" "$uid" "$group" "$gid" "$pass"
_update_fish_dir_perms "$user" "$uid" "$gid"
-230
View File
@@ -1,230 +0,0 @@
#!/usr/bin/env bash
function _exit() {
if [[ "$#" -gt 1 ]]; then
# When there are multiple args, the last arg is the exit code.
echo "${@:1:($# - 1)}"
exit "${@: -1}"
fi
echo "$1"
exit 0
}
help_text="\
Start a docker dev container
Usage: start_docker.sh [OPTIONS] image container
Positionals:
image The image to instantiate
container The name for the container
Options:
-u,--user USER The user to add in the container (defaults to 'bts')
-p,--pass PASS The password for USER in the container (defaults to USER)
-i,--image IMAGE The image to instantiate (defaults to 'bluetradingsystems/sparkd-dev:latest')
-c,--container CONT The name for the container
-m,--mount MOUNT The name for the folder (outside the container) to create/mount to the home
directory in the container. Mount folders are added here: $mount_prefix
--mount-existing Mount the specified dir even if it already exists
--port <cont_port>:<host_port> OR [<cont_port>:<host_port>,...] Port mapping(s). May be
specified multiple times.
-h,--help Print this help message and exit
"
mount_prefix="$HOME/.sparkd-dev/mounts"
declare docker_user=""
declare docker_pass=""
declare image_name=""
declare cont_name=""
declare mount_name=""
declare -i mount_existing=0
declare -a port_mappings=()
while [[ $# -gt 0 ]]; do
case "$1" in
-u)
;&
--user)
if [[ -z "$2" ]]; then
_exit "User (-u,--user) must be non-empty" 1
fi
docker_user="$2"
shift 2
;;
-p)
;&
--pass)
if [[ -z "$2" ]]; then
_exit "Password (-p,--pass) must be non-empty" 1
fi
docker_pass="$2"
shift 2
;;
-i)
;&
--image)
if [[ -n "$image_name" ]]; then
_exit "Unexpected argument '$1'" 1
elif [[ -z "$2" ]]; then
_exit "Image (-i,--image) must be non-empty" 1
fi
image_name="$2"
shift 2
;;
-c)
;&
--container)
if [[ -n "$cont_name" ]]; then
_exit "Unexpected argument '$1'" 1
elif [[ -z "$2" ]]; then
_exit "Container (-c,--container) must be non-empty" 1
fi
cont_name="$2"
shift 2
;;
--port)
# Parse port(s) arg, and append the result to 'port_mappings'
# Note: port(s) may be specified in bracketed notation:
# [a:b,c:d,...,y:z]
next_ports="$(echo "$2" | sed -e 's/\[//g' -e 's/\]//g' -e 's/,/ /g')"
if [[ "${#port_mappings[@]}" -gt 0 ]]; then
next_ports=" $next_ports"
fi
port_mappings+=("$next_ports")
shift 2
;;
-m)
;&
--mount)
if [[ -z "$2" ]]; then
echo "Mount (-m,--mount) must be non-empty"
fi
mount_name="$2"
shift 2
;;
--mount-existing)
mount_existing=1
shift 1
;;
-h)
;&
--help)
_exit "$help_text" 0
;;
*)
if [[ -z "$1" ]]; then
_exit "Invalid positional argument '$1'" "$help_text" 1
elif [[ -z "$image_name" ]]; then
image_name="$1"
elif [[ -z "$cont_name" ]]; then
cont_name="$1"
else
_exit "Unexpected argument '$1'" "$help_text" 1
fi
shift 1
;;
esac
done
if [[ -z "$image_name" ]]; then
image_name="bluetradingsystems/sparkd-dev:latest"
fi
host_name="$(hostname)"
if [[ -n "$cont_name" ]]; then
host_name="$host_name.$cont_name"
fi
if [[ -z "$mount_name" ]]; then
mount_name="$cont_name"
fi
if [[ -z "$mount_name" && -z "$cont_name" ]]; then
_exit "Please specify mount (-m,--mount) and/or container (-c,--container)" 1
fi
if [[ -z "$docker_user" ]]; then
docker_user="bts"
fi
if [[ "$docker_user" = "root" ]]; then
_exit "USER (--user) cannot be 'root'" 1
fi
cont_home="/home/$docker_user"
home_src="$mount_prefix/$mount_name"
home_tgt="$cont_home"
this_dir="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
repo_src="$(cd "$this_dir" && git rev-parse --show-toplevel)"
repo_tgt="$cont_home/spark"
working_dir="$cont_home"
if [[ $mount_existing -eq 0 && -e "$home_src" ]]; then
# Don't overwrite existing dir (might be mounted in another container)
_exit "Mount dir '$home_src' already exists (use --mount-existing to mount \
an existing directory)" 1
fi
mkdir -p "$home_src"
if [[ "${#port_mappings[@]}" -eq 0 ]]; then
port_mappings=("8000:8000" "8001:8001" "8002:8002" "8003:8003")
fi
# Adapt port_mappings into args for `docker run` by prepending "-p " to each
# item
declare -a docker_port_args=()
for port_mapping in "${port_mappings[@]}"; do
docker_port_args+=("-p $port_mapping")
done
echo "Starting container '$cont_name'
image_name : $image_name
cont_name : $cont_name
home_src : $home_src
home_tgt : $home_tgt
repo_src : $repo_src
repo_tgt : $repo_tgt
working dir : $working_dir
ports : ${port_mappings[*]}
"
# DON'T wrap $docker_port_args in quotes. We want bash to split args by
# whitespace
docker run \
--net bridge \
-h "$host_name" \
-e "TZ=America/New_York" \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
--name "$cont_name" \
-v "$home_src:$home_tgt" \
-v "$repo_src:$repo_tgt" \
-w "$working_dir" \
${docker_port_args[*]} \
--shm-size=4024m \
-t \
-i \
-d \
-e DISPLAY="$DISPLAY" \
"$image_name"
# Add user w/ same uid and gid as the current user outside of docker, so the
# user inside the docker has file permissions in the mounted dir.
docker_group="$docker_user"
docker_uid="$(id -u "$USER")"
docker_gid="$(id -g "$USER")"
if [[ -z "$docker_pass" ]]; then
docker_pass="$docker_user"
fi
docker exec -u root -it "$cont_name" "$repo_tgt/docker/sparkd/dev/set_user.sh" \
--user "$docker_user" \
--uid "$docker_uid" \
--group "$docker_group" \
--gid "$docker_gid" \
--pass "$docker_pass"
# Run same script VS Code runs to initialize the container
docker exec -u "$docker_user" -it "$cont_name" "$repo_tgt/docker/sparkd/dev/devcontainer_post_create.sh"
-64
View File
@@ -1,64 +0,0 @@
#!/usr/bin/env bash
function print_help_and_exit() {
cat <<EOF
Open a shell inside the docker container
Usage: docker_shell.sh [OPTIONS] [CONTAINER]
Options:
-u,--user The user to login with in the container (defaults to the current user)
-c,--container The container name (may also be specified as positional arg)
-h,--help Print this help message and exit
EOF
exit "$1"
}
declare docker_user=""
declare cont_name=""
while [[ $# -gt 0 ]]; do
case "$1" in
-u)
;&
--user)
if [[ -z "$2" ]]; then
echo "User (-u,--user) must be non-empty"
print_help_and_exit 1
fi
docker_user="$2"
shift 2
;;
-h)
;&
--help)
print_help_and_exit 0
;;
-c)
;&
--container)
shift 1
;&
*)
if [[ ! -z "$cont_name" ]]; then
echo "Unexpected argument '$1'"
print_help_and_exit 1
fi
cont_name="$1"
shift 1
;;
esac
done
if [[ -z "$cont_name" ]]; then
echo "Please specify the container ([-c,--container])"
print_help_and_exit 1
fi
if [[ -z "$docker_user" ]]; then
docker_user="$USER"
fi
docker exec -u "$docker_user" -it "$cont_name" bash
-233
View File
@@ -1,233 +0,0 @@
#!/usr/bin/env bash
mount_prefix="$HOME/.spark-dev/mounts"
function print_help_and_exit() {
cat <<EOF
Start a docker dev container
Usage: start_docker.sh [OPTIONS] image container
Positionals:
image The image to instantiate
container The name for the container
Options:
-u,--user USER The user to add in the container (defaults to the current user)
-p,--pass PASS The password for USER in the container (defaults to USER)
-i,--image IMAGE The image to instantiate
-c,--container CONT The name for the container
-m,--mount MOUNT The name for the folder (outside the container) to create/mount to the home
directory in the container. Mount folders are added here: $mount_prefix
--mount-existing Mount the specified dir even if it already exists
--port <cont_port>:<host_port> OR [<cont_port>:<host_port>,...] Port mapping(s). May be
specified multiple times.
-h,--help Print this help message and exit
EOF
exit "$1"
}
declare docker_user=""
declare docker_pass=""
declare image_name=""
declare cont_name=""
declare mount_name=""
declare -i mount_existing=0
declare -a port_mappings=()
while [[ $# -gt 0 ]]; do
case "$1" in
-u)
;&
--user)
if [[ -z "$2" ]]; then
echo "User (-u,--user) must be non-empty"
print_help_and_exit 1
fi
docker_user="$2"
shift 2
;;
-p)
;&
--pass)
if [[ -z "$2" ]]; then
echo "Password (-p,--pass) must be non-empty"
print_help_and_exit 1
fi
docker_pass="$2"
shift 2
;;
-i)
;&
--image)
if [[ -n "$image_name" ]]; then
echo "Unexpected argument '$1'"
print_help_and_exit 1
elif [[ -z "$2" ]]; then
echo "Image (-i,--image) must be non-empty"
print_help_and_exit 1
fi
image_name="$2"
shift 2
;;
-c)
;&
--container)
if [[ -n "$cont_name" ]]; then
echo "Unexpected argument '$1'"
print_help_and_exit 1
elif [[ -z "$2" ]]; then
echo "Container (-c,--container) must be non-empty"
print_help_and_exit 1
fi
cont_name="$2"
shift 2
;;
--port)
# Parse port(s) arg, and append the result to 'port_mappings'
# Note: port(s) may be specified in bracketed notation:
# [a:b,c:d,...,y:z]
next_ports="$(echo "$2" | sed -e 's/\[//g' -e 's/\]//g' -e 's/,/ /g')"
if [[ "${#port_mappings[@]}" -gt 0 ]]; then
next_ports=" $next_ports"
fi
port_mappings+=("$next_ports")
shift 2
;;
-m)
;&
--mount)
if [[ -z "$2" ]]; then
echo "Mount (-m,--mount) must be non-empty"
fi
mount_name="$2"
shift 2
;;
--mount-existing)
mount_existing=1
shift 1
;;
-h)
;&
--help)
print_help_and_exit 0
;;
*)
if [[ -z "$1" ]]; then
echo "Invalid positional argument '$1'"
print_help_and_exit 1
elif [[ -z "$image_name" ]]; then
image_name="$1"
elif [[ -z "$cont_name" ]]; then
cont_name="$1"
else
echo "Unexpected argument '$1'"
print_help_and_exit 1
fi
shift 1
;;
esac
done
if [[ -z "$image_name" ]]; then
image_name="bluetradingsystems/spark-crypto-dev"
fi
host_name="$(hostname)"
if [[ -n "$cont_name" ]]; then
host_name="$host_name.$cont_name"
fi
if [[ -z "$mount_name" ]]; then
mount_name="$cont_name"
fi
if [[ -z "$mount_name" && -z "$cont_name" ]]; then
echo "Please specify mount (-m,--mount) and/or container (-c,--container)"
print_help_and_exit 1
fi
if [[ -z "$docker_user" ]]; then
docker_user="$USER"
fi
home_src=$mount_prefix/$mount_name
home_tgt=$HOME
repo_src=$(git rev-parse --show-superproject-working-tree)
repo_tgt=$HOME/$(basename "$repo_src")
working_dir=$HOME
if [[ $mount_existing -eq 0 && -e "$home_src" ]]; then
# Don't overwrite existing dir (might be mounted in another container)
echo "Mount dir '$home_src' already exists (use --mount-existing to mount an existing directory)"
print_help_and_exit 1
fi
mkdir -p "$home_src"
if [[ "${#port_mappings[@]}" -eq 0 ]]; then
port_mappings=("8000:8000" "8001:8001" "8002:8002" "8003:8003")
fi
# Adapt port_mappings into args for `docker run` by prepending "-p " to each
# item
declare -a docker_port_args=()
for port_mapping in "${port_mappings[@]}"; do
docker_port_args+=("-p $port_mapping")
done
echo "Starting container '$cont_name'
image_name : $image_name
cont_name : $cont_name
home_src : $home_src
home_tgt : $home_tgt
repo_src : $repo_src
repo_tgt : $repo_tgt
working dir : $working_dir
ports : ${port_mappings[*]}
"
# DON'T wrap $docker_port_args in quotes. We want bash to split args by
# whitespace
docker run \
--net bridge \
-h "$host_name" \
-e "TZ=America/New_York" \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
--name "$cont_name" \
-v "$home_src:$home_tgt" \
-v "$repo_src:$repo_tgt" \
-w "$working_dir" \
${docker_port_args[*]} \
--shm-size=4024m \
-t \
-i \
-d \
-e DISPLAY="$DISPLAY" \
"$image_name" \
bash
# Add user w/ same uid and gid as the current user outside of docker, so the
# user inside the docker has file permissions in the mounted dir.
docker_group="$docker_user"
docker_user_uid="$(id -u "$USER")"
docker_user_gid="$(id -g "$USER")"
echo "Adding user in container '$cont_name'
name : $docker_user
uid : $docker_user_uid
gid : $docker_user_gid"
if [[ -z "$docker_pass" ]]; then
docker_pass="$docker_user"
echo "Giving user '$docker_user' a secure password: $docker_pass"
fi
docker exec -u root -it "$cont_name" groupadd -g "$docker_user_gid" "$docker_group"
docker exec -u root -it "$cont_name" useradd -u "$docker_user_uid" -g "$docker_user_gid" "$docker_user"
docker exec -u root -it "$cont_name" usermod --password "$(openssl passwd -1 "$docker_pass")" "$docker_user"
docker exec -u root -it "$cont_name" usermod -aG sudo "$docker_user"
docker exec -u root -it "$cont_name" "$repo_tgt/externals/src/emumba/install_emumba-deribit-connector.sh"
+1
Submodule docker/windows added at de7d40c09d.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.200",
"version": "2.1.508",
"rollForward": "latestMajor"
}
}
+2 -7
View File
@@ -1,22 +1,17 @@
astroid==2.7.3
autopep8==1.5.7
certifi==2023.5.7
charset-normalizer==3.1.0
cffi==1.14.6
colorama==0.4.4
idna==3.4
isort==5.9.3
lazy-object-proxy==1.6.0
mccabe==0.6.1
platformdirs==2.3.0
protobuf==4.21.12
protobuf==3.19.1
pybars3==0.9.7
pycodestyle==2.7.0
pycparser==2.20
pylint==2.10.2
PyMeta3==0.5.1
requests==2.31.0
termcolor==1.1.0
toml==0.10.2
urllib3==2.0.3
wrapt==1.12.1
yapf==0.31.0
+41
View File
@@ -0,0 +1,41 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sparkd", "src\server\sparkd\sparkd.vcxproj", "{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspark", "build\src\lib\libspark.vcxproj", "{502FD050-679A-3B50-B438-098500700919}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
MinSizeRel|x64 = MinSizeRel|x64
Release|x64 = Release|x64
RelWithDebInfo|x64 = RelWithDebInfo|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.Debug|x64.ActiveCfg = Debug|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.Debug|x64.Build.0 = Debug|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.MinSizeRel|x64.ActiveCfg = Release|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.MinSizeRel|x64.Build.0 = Release|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.Release|x64.ActiveCfg = Release|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.Release|x64.Build.0 = Release|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{BBBAFD38-312D-4A8D-9AF0-F2BDEE72CE6F}.RelWithDebInfo|x64.Build.0 = Release|x64
{502FD050-679A-3B50-B438-098500700919}.Debug|x64.ActiveCfg = Debug|x64
{502FD050-679A-3B50-B438-098500700919}.Debug|x64.Build.0 = Debug|x64
{502FD050-679A-3B50-B438-098500700919}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
{502FD050-679A-3B50-B438-098500700919}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
{502FD050-679A-3B50-B438-098500700919}.Release|x64.ActiveCfg = Release|x64
{502FD050-679A-3B50-B438-098500700919}.Release|x64.Build.0 = Release|x64
{502FD050-679A-3B50-B438-098500700919}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
{502FD050-679A-3B50-B438-098500700919}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6A7249D7-B40C-4656-9347-60072D0B8FDB}
EndGlobalSection
EndGlobal
+27 -24
View File
@@ -1,23 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
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", "{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}"
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}") = "Spark.Console", "src\client\Spark.Console\Spark.Console.csproj", "{387566C6-C6F6-412C-A30C-9855BBCB4816}"
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", "{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_sdk", "src\client\spark_sdk\spark_sdk.csproj", "{6963C314-83C4-4667-B0D0-C2F7AE208C29}"
ProjectSection(ProjectDependencies) = postProject
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40} = {9FA60215-26AF-3EB7-AB89-D4F4B126EF40}
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_websocket", "src\client\spark_websocket\spark_websocket.csproj", "{3201359D-C071-4089-9EDE-B04D759F1508}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api_server", "src\client\spark_api_server\spark_api_server.csproj", "{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -34,6 +37,14 @@ Global
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.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
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Debug|x64.ActiveCfg = Debug|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Debug|x64.Build.0 = Debug|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Release|x64.ActiveCfg = Release|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Release|x64.Build.0 = Release|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|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}.MinSizeRel|x64.ActiveCfg = Release|x64
@@ -58,6 +69,14 @@ Global
{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}.Release|x64.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
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.Debug|x64.ActiveCfg = Debug|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.Debug|x64.Build.0 = Debug|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.Release|x64.ActiveCfg = Release|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.Release|x64.Build.0 = Release|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
{A1B7276B-8F81-3D58-A22E-870AF28DF9B9}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|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}.MinSizeRel|x64.ActiveCfg = Release|x64
@@ -74,22 +93,6 @@ Global
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.Build.0 = Release|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.ActiveCfg = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.Build.0 = Debug|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.Build.0 = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.ActiveCfg = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.Build.0 = Debug|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.Build.0 = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.ActiveCfg = Release|x64
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1,37 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
class AdditiveInverse : IArithmeticExpression<double> {
readonly IArithmeticExpression expression;
public AdditiveInverse(IArithmeticExpression expression) =>
this.expression = expression;
public static AdditiveInverse<T> Create<T>(IArithmeticExpression<T> expression)
where T : INumber<T> =>
new(expression);
public double Evaluate(IDictionary<string, object?> env) =>
-evaluateArg(expression, nameof(expression), env);
static double evaluateArg(
IArithmeticExpression expr, string name, IDictionary<string, object?> env) {
var obj = expr.Evaluate(env);
return ConvertUtils.try_convert(expr.Evaluate(env), out double dbl) ? dbl :
throw new Exception(
$"Invalid AdditiveInverse. {name} is of type {obj?.GetType()} " +
$"(expected {typeof(double)})");
}
}
class AdditiveInverse<T> : IArithmeticExpression<T>
where T : INumber<T> {
readonly IArithmeticExpression<T> expression;
public AdditiveInverse(IArithmeticExpression<T> expression) =>
this.expression = expression;
public T Evaluate(IDictionary<string, object?> env) =>
-expression.Evaluate(env);
}
@@ -1,45 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
public static class ArithmeticExpressionExtensions {
public static IArithmeticExpression<TResult> Add<TLeft, TRight, TResult>(
this IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right)
where TLeft :
INumber<TLeft>,
IAdditionOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> =>
new Sum<TLeft, TRight, TResult>(left, right);
public static IArithmeticExpression<TResult> Subtract<TLeft, TRight, TResult>(
this IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right)
where TLeft :
INumber<TLeft>,
ISubtractionOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> =>
new Difference<TLeft, TRight, TResult>(left, right);
public static IArithmeticExpression<TResult> Multiply<TLeft, TRight, TResult>(
this IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right)
where TLeft :
INumber<TLeft>,
IMultiplyOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> =>
new Product<TLeft, TRight, TResult>(left, right);
public static IArithmeticExpression<TResult> Divide<TLeft, TRight, TResult>(
this IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right)
where TLeft :
INumber<TLeft>,
IDivisionOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> =>
new Quotient<TLeft, TRight, TResult>(left, right);
public static IArithmeticExpression<T> Negate<T>(this IArithmeticExpression<T> expression)
where T : INumber<T> =>
new AdditiveInverse<T>(expression);
}
@@ -1,98 +0,0 @@
%namespace Bts.ArithmeticExpressions
%partial
%visibility internal
%tokentype Token
%parsertype ArithmeticExpressionParserImpl
%union {
public int Integer;
public double Real;
public string Identifier;
public ImmutableList<IArithmeticExpression> Arguments;
public ImmutableList<Assignment> Assignments;
public IArithmeticExpression Argument;
public Assignment Assignment;
public ArithmeticProgram Program;
}
/* Constants */
%token INTEGER_CONSTANT REAL_CONSTANT
/* Arithmetic Operators */
%token ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUALS
/* Syntax */
%token PARENTHESIS_OPEN, PARENTHESIS_CLOSE, COMMA, IDENTIFIER
%left ADD SUBTRACT
%left MULTIPLY DIVIDE
%nonassoc EQUALS
%type <Argument> Argument
%type <Arguments> Arguments
%type <Assignment> Assignment
%type <Assignments> Assignments
%type <Program> Program
%%
Program :
Assignments {
$$ = new($1);
}
;
Assignments :
Assignment {
$$ = ImmutableList<Assignment>.Empty.Add($1);
}
| Assignments Assignment {
$$ = $1.Add($2);
}
;
Assignment :
IDENTIFIER EQUALS Argument {
$$ = new($1.Identifier, $3);
}
;
Argument :
IDENTIFIER PARENTHESIS_OPEN Arguments PARENTHESIS_CLOSE {
$$ = new Function($1.Identifier, $3);
}
| INTEGER_CONSTANT {
$$ = new IntegerConstant($1.Integer);
}
| REAL_CONSTANT {
$$ = new RealConstant($1.Real);
}
| IDENTIFIER {
$$ = new Variable($1.Identifier);
}
| SUBTRACT Argument {
$$ = $2.Negate();
}
| PARENTHESIS_OPEN Argument PARENTHESIS_CLOSE {
$$ = $2;
}
| Argument MULTIPLY Argument {
$$ = $1.Multiply($3);
}
| Argument DIVIDE Argument {
$$ = $1.Divide($3);
}
| Argument ADD Argument {
$$ = $1.Add($3);
}
| Argument SUBTRACT Argument {
$$ = $1.Subtract($3);
}
;
Arguments :
Argument {
$$ = ImmutableList<IArithmeticExpression>.Empty.Add($1);
}
| Arguments COMMA Argument {
$$ = $1.Add($3);
}
;
@@ -1,19 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Text;
partial class ArithmeticExpressionParserImpl {
public ArithmeticExpressionParserImpl() : base(null) { }
public ValueType Parse(Stream stream) {
Scanner = new ArithmeticExpressionScanner(stream);
Parse();
return CurrentSemanticValue;
}
public ValueType Parse(string str) {
var inputBuffer = Encoding.Default.GetBytes(str);
using var stream = new MemoryStream(inputBuffer);
return Parse(stream);
}
}
@@ -1,11 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System;
partial class ArithmeticExpressionScanner {
public override void yyerror(string format, params object[] args) {
base.yyerror(format, args);
Console.WriteLine(format, args);
Console.WriteLine();
}
}
@@ -1,70 +0,0 @@
%namespace Bts.ArithmeticExpressions
%scannertype ArithmeticExpressionScanner
%visibility internal
%tokentype Token
%option stack, minimize, parser, verbose, persistbuffer, noembedbuffers
Letter [a-zA-Z]
Identifier {Letter}({Letter}*[0-9]*_*)*
IntegerConstant -?[0-9]+
RealConstant -?[0-9]+\.[0-9]+
ParenthesisOpen \(
ParenthesisClose \)
Add \+
Subtract \-
Multiply \*
Divide /
Equals =
Comma ,
%%
{IntegerConstant} {
yylval.Integer = int.Parse(yytext);
return (int)Token.INTEGER_CONSTANT;
}
{RealConstant} {
yylval.Real = double.Parse(yytext);
return (int)Token.REAL_CONSTANT;
}
{Identifier} {
yylval.Identifier = yytext;
return (int)Token.IDENTIFIER;
}
{ParenthesisOpen} {
return (int)Token.PARENTHESIS_OPEN;
}
{ParenthesisClose} {
return (int)Token.PARENTHESIS_CLOSE;
}
{Add} {
return (int)Token.ADD;
}
{Subtract} {
return (int)Token.SUBTRACT;
}
{Multiply} {
return (int)Token.MULTIPLY;
}
{Divide} {
return (int)Token.DIVIDE;
}
{Equals} {
return (int)Token.EQUALS;
}
{Comma} {
return (int)Token.COMMA;
}
%%
@@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.24.3" />
<PackageReference Include="YaccLexTools" Version="1.2.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ExpressionCore\ExpressionCore.csproj" />
<ProjectReference Include="..\..\client\spark_core\spark_core.csproj" />
</ItemGroup>
<ItemGroup Label="ArithmeticExpression">
<Scanner Include="ArithmeticExpressionTokens.lex" />
<Parser Include="ArithmeticExpressionGrammar.y" />
</ItemGroup>
</Project>
@@ -1,21 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Collections.Immutable;
class ArithmeticProgram : IArithmeticProgram {
readonly ImmutableList<Assignment>? assignments;
public ArithmeticProgram(Assignment assignment) =>
assignments = ImmutableList<Assignment>.Empty.Add(assignment);
public ArithmeticProgram(ImmutableList<Assignment> assignments) =>
this.assignments = assignments;
IEnumerable<string> IArithmeticProgram.OutputIdentifiers =>
assignments.empty_if_null()
.Select(a => a.Identifier ?? throw new Exception("Identifier string is null"))
.Distinct();
IDictionary<string, object?> IArithmeticProgram.Evaluate(IDictionary<string, object?> env) =>
assignments.empty_if_null().Aggregate(env, (e, a) => a.Evaluate(e));
}
@@ -1,16 +0,0 @@
namespace Bts.ArithmeticExpressions;
using Bts.ExpressionCore;
public static class ArithmeticProgramParser {
public static IArithmeticProgram Parse(Stream expression) =>
new Parser().Parse(expression);
public static IArithmeticProgram Parse(string expression) =>
new Parser().Parse(expression);
class Parser : IParser<ArithmeticProgram> {
public ArithmeticProgram Parse(Stream expression) =>
new ArithmeticExpressionParserImpl().Parse(expression).Program;
}
}
@@ -1,24 +0,0 @@
namespace Bts.ArithmeticExpressions;
public class Assignment {
public Assignment(string? identifier, IArithmeticExpression? value) {
Identifier = identifier ?? throw new ArgumentNullException(nameof(identifier));
Value = value ?? throw new ArgumentNullException(nameof(identifier));
}
public string? Identifier { get; }
public IArithmeticExpression? Value { get; }
public IDictionary<string, object?> Evaluate(IDictionary<string, object?> env) {
if (Identifier is null) {
throw new InvalidOperationException("Identifier is null");
}
if (Value is null) {
throw new InvalidOperationException($"Value is null (Identifier '{Identifier}')");
}
env[Identifier] = Value.Evaluate(env) ?? throw new Exception(
$"{nameof(Assignment)}.{nameof(Value)} (of type '{Value.GetType()}') " +
$"evaluated to null (Identifier '{Identifier}')");
return env;
}
}
@@ -1,45 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
public class Difference : IArithmeticExpression<double> {
readonly IArithmeticExpression lhs;
readonly IArithmeticExpression rhs;
public Difference(IArithmeticExpression lhs, IArithmeticExpression rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
public static Difference<T, T, T> Create<T>(
IArithmeticExpression<T> left, IArithmeticExpression<T> right)
where T : INumber<T>, ISubtractionOperators<T, T, T> =>
new(left, right);
public double Evaluate(IDictionary<string, object?> env) =>
evaluateArg(lhs, nameof(lhs), env) - evaluateArg(rhs, nameof(rhs), env);
static double evaluateArg(
IArithmeticExpression expr, string name, IDictionary<string, object?> env) {
var obj = expr.Evaluate(env);
return ConvertUtils.try_convert(expr.Evaluate(env), out double dbl) ? dbl :
throw new Exception(
$"Invalid Difference. {name} is of type {obj?.GetType()} (expected {typeof(double)})");
}
}
public class Difference<TLeft, TRight, TResult> : IArithmeticExpression<TResult>
where TLeft : INumber<TLeft>, ISubtractionOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> {
readonly IArithmeticExpression<TLeft> left;
readonly IArithmeticExpression<TRight> right;
public Difference(IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right) {
this.left = left;
this.right = right;
}
public TResult Evaluate(IDictionary<string, object?> env) =>
left.Evaluate(env) - right.Evaluate(env);
}
@@ -1,208 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
class EvaluationEnvironment : IDictionary<string, object?>, IReadOnlyDictionary<string, object?> {
IDictionary<string, object?> outerEnv;
IDictionary<string, object?> innerEnv = new Dictionary<string, object?>();
int? count;
public EvaluationEnvironment(IDictionary<string, object?> initial) =>
outerEnv = initial;
public object? this[string key] {
get {
if (innerEnv.TryGetValue(key, out var rv)) {
return rv;
}
if (outerEnv.TryGetValue(key, out rv)) {
return rv;
}
throw new Exception($"Undefined identifier '{key}'");
}
set {
if (count.HasValue && !ContainsKey(key)) {
count = count.Value + 1;
innerEnv.Add(key, value);
return;
}
innerEnv[key] = value;
}
}
public IDictionary<string, object?> Result =>
innerEnv;
public ICollection<string> Keys =>
new KeyCollection(outerEnv, innerEnv);
public ICollection<object?> Values =>
new ValueCollection(outerEnv, innerEnv);
public int Count =>
count ??= countKeys(outerEnv, innerEnv);
public bool IsReadOnly => throw new NotImplementedException();
public bool ContainsKey(string key) =>
innerEnv.ContainsKey(key) || outerEnv.ContainsKey(key);
public bool TryGetValue(string key, [MaybeNullWhen(false)] out object? value) =>
innerEnv.TryGetValue(key, out value) || outerEnv.TryGetValue(key, out value);
public IEnumerator<KeyValuePair<string, object?>> GetEnumerator() {
foreach (var kv in innerEnv) {
yield return kv;
}
foreach (var kv in outerEnv.Except()) {
if (!innerEnv.ContainsKey(kv.Key)) {
yield return kv;
}
}
}
public void Add(string key, object? value) {
if (ContainsKey(key)) {
throw new ArgumentException(
$"An element with the same key ({key}) already exists", nameof(key));
}
innerEnv.Add(key, value);
}
public void Add(KeyValuePair<string, object?> item) =>
Add(item.Key, item.Value);
public void Clear() =>
throw new NotSupportedException();
public bool Contains(KeyValuePair<string, object?> item) =>
TryGetValue(item.Key, out var v) && Equals(v, item.Value);
public void CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex) {
foreach (var kv in innerEnv) {
array[arrayIndex++] = kv;
}
foreach (var kv in outerEnv) {
if (!innerEnv.ContainsKey(kv.Key)) {
array[arrayIndex++] = kv;
}
}
}
public bool Remove(string key) =>
throw new NotSupportedException();
public bool Remove(KeyValuePair<string, object?> item) =>
throw new NotSupportedException();
static int countKeys(IDictionary<string, object?> d1, IDictionary<string, object?> d2) =>
d1.Count > d2.Count ?
d1.Count + d2.Keys.WhereNot(d1.ContainsKey).Count() :
d2.Count + d1.Keys.WhereNot(d2.ContainsKey).Count();
IEnumerable<string> IReadOnlyDictionary<string, object?>.Keys => Keys;
IEnumerable<object?> IReadOnlyDictionary<string, object?>.Values => Values;
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
class KeyCollection : ICollection<string> {
readonly IDictionary<string, object?> outerEnv;
readonly IDictionary<string, object?> innerEnv;
public KeyCollection(
IDictionary<string, object?> outerEnv, IDictionary<string, object?> innerEnv) {
this.outerEnv = outerEnv;
this.innerEnv = innerEnv;
}
public int Count =>
countKeys(outerEnv, innerEnv);
public bool IsReadOnly => true;
public void Add(string item) =>
throw new NotSupportedException();
public void Clear() =>
throw new NotSupportedException();
public bool Contains(string item) =>
innerEnv.ContainsKey(item) || outerEnv.ContainsKey(item);
public void CopyTo(string[] array, int arrayIndex) {
foreach (var k in this) {
array[arrayIndex++] = k;
}
}
public IEnumerator<string> GetEnumerator() {
foreach (var k in innerEnv.Keys) {
yield return k;
}
foreach (var k in outerEnv.Keys) {
if (!innerEnv.ContainsKey(k)) {
yield return k;
}
}
}
public bool Remove(string item) =>
throw new NotSupportedException();
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
class ValueCollection : ICollection<object?> {
readonly IDictionary<string, object?> outerEnv;
readonly IDictionary<string, object?> innerEnv;
public ValueCollection(
IDictionary<string, object?> outerEnv, IDictionary<string, object?> innerEnv) {
this.outerEnv = outerEnv;
this.innerEnv = innerEnv;
}
public int Count =>
// Not a typo (obv, numValues == numKeys)
countKeys(outerEnv, innerEnv);
public bool IsReadOnly => true;
public void Add(object? item) =>
throw new NotSupportedException();
public void Clear() =>
throw new NotSupportedException();
public bool Contains(object? item) =>
innerEnv.Values.Contains(item) ||
outerEnv
.Where(kv => !innerEnv.ContainsKey(kv.Key))
.Select(kv => kv.Value)
.Contains(item);
public void CopyTo(object?[] array, int arrayIndex) {
foreach (var k in this) {
array[arrayIndex++] = k;
}
}
public IEnumerator<object?> GetEnumerator() {
foreach (var k in innerEnv.Values) {
yield return k;
}
foreach (var kv in outerEnv) {
if (!innerEnv.ContainsKey(kv.Key)) {
yield return kv.Value;
}
}
}
public bool Remove(object? item) =>
throw new NotSupportedException();
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
}
@@ -1,34 +0,0 @@
namespace Bts.ArithmeticExpressions;
using Spark.Core;
using System.Collections.Immutable;
using System.Data;
public class Function : IArithmeticExpression {
public Function(string? identifier, ImmutableList<IArithmeticExpression>? arguments) {
Identifier = identifier;
Arguments = arguments;
}
public string? Identifier { get; }
public ImmutableList<IArithmeticExpression>? Arguments { get; }
public object? Evaluate(IDictionary<string, object?> env) {
if (Identifier is null) {
throw new InvalidOperationException("Identifier is null");
}
if (Arguments is null) {
throw new InvalidOperationException("Arguments is null");
}
if (Identifier == "ifNull") {
throw new NotImplementedException("'ifNull' function not yet implemented");
}
var argVals = Arguments.Select(e => e.Evaluate(env)).ToArray();
var argTypes = Array.ConvertAll(argVals, v => v?.GetType() ?? typeof(object));
var method = typeof(Math).GetMethod(Identifier, argTypes) ??
throw new EvaluateException(
$"Failed to find method '{Identifier}({", ".join(argTypes)})' in {typeof(Math)}");
return method.Invoke(null, argVals);
}
}
@@ -1,720 +0,0 @@
// ==============================================================
// <auto-generated>
// This code automatically produced from an embedded resource.
// Do not edit this file, or it will become incompatible with
// the specification from which it was generated.
// </auto-generated>
// ==============================================================
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Globalization;
namespace QUT.GplexBuffers
{
// Code copied from GPLEX embedded resource
[Serializable]
internal class BufferException : Exception
{
public BufferException() { }
public BufferException(string message) : base(message) { }
public BufferException(string message, Exception innerException)
: base(message, innerException) { }
protected BufferException(SerializationInfo info, StreamingContext context)
: base(info, context) { }
}
internal abstract class ScanBuff
{
private string fileNm;
public const int EndOfFile = -1;
public const int UnicodeReplacementChar = 0xFFFD;
public bool IsFile { get { return (fileNm != null); } }
public string FileName { get { return fileNm; } set { fileNm = value; } }
public abstract int Pos { get; set; }
public abstract int Read();
public virtual void Mark() { }
public abstract string GetString(int begin, int limit);
public static ScanBuff GetBuffer(string source)
{
return new StringBuffer(source);
}
public static ScanBuff GetBuffer(IList<string> source)
{
return new LineBuffer(source);
}
#if (!NOFILES)
public static ScanBuff GetBuffer(Stream source)
{
return new BuildBuffer(source);
}
#if (!BYTEMODE)
public static ScanBuff GetBuffer(Stream source, int fallbackCodePage)
{
return new BuildBuffer(source, fallbackCodePage);
}
#endif // !BYTEMODE
#endif // !NOFILES
}
#region Buffer classes
// ==============================================================
// ===== Definitions for various ScanBuff derived classes ====
// ==============================================================
// =============== String input ================
// ==============================================================
/// <summary>
/// This class reads characters from a single string as
/// required, for example, by Visual Studio language services
/// </summary>
sealed class StringBuffer : ScanBuff
{
string str; // input buffer
int bPos; // current position in buffer
int sLen;
public StringBuffer(string source)
{
this.str = source;
this.sLen = source.Length;
this.FileName = null;
}
public override int Read()
{
if (bPos < sLen) return str[bPos++];
else if (bPos == sLen) { bPos++; return '\n'; } // one strike, see new line
else { bPos++; return EndOfFile; } // two strikes and you're out!
}
public override string GetString(int begin, int limit)
{
// "limit" can be greater than sLen with the BABEL
// option set. Read returns a "virtual" EOL if
// an attempt is made to read past the end of the
// string buffer. Without the guard any attempt
// to fetch yytext for a token that includes the
// EOL will throw an index exception.
if (limit > sLen) limit = sLen;
if (limit <= begin) return "";
else return str.Substring(begin, limit - begin);
}
public override int Pos
{
get { return bPos; }
set { bPos = value; }
}
public override string ToString() { return "StringBuffer"; }
}
// ==============================================================
// The LineBuff class contributed by Nigel Horspool,
// nigelh@cs.uvic.cs
// ==============================================================
sealed class LineBuffer : ScanBuff
{
IList<string> line; // list of source lines from a file
int numLines; // number of strings in line list
string curLine; // current line in that list
int cLine; // index of current line in the list
int curLen; // length of current line
int curLineStart; // position of line start in whole file
int curLineEnd; // position of line end in whole file
int maxPos; // max position ever visited in whole file
int cPos; // ordinal number of code in source
// Constructed from a list of strings, one per source line.
// The lines have had trailing '\n' characters removed.
public LineBuffer(IList<string> lineList)
{
line = lineList;
numLines = line.Count;
cPos = curLineStart = 0;
curLine = (numLines > 0 ? line[0] : "");
maxPos = curLineEnd = curLen = curLine.Length;
cLine = 1;
FileName = null;
}
public override int Read()
{
if (cPos < curLineEnd)
return curLine[cPos++ - curLineStart];
if (cPos++ == curLineEnd)
return '\n';
if (cLine >= numLines)
return EndOfFile;
curLine = line[cLine];
curLen = curLine.Length;
curLineStart = curLineEnd + 1;
curLineEnd = curLineStart + curLen;
if (curLineEnd > maxPos)
maxPos = curLineEnd;
cLine++;
return curLen > 0 ? curLine[0] : '\n';
}
// To speed up searches for the line containing a position
private int cachedPosition;
private int cachedIxdex;
private int cachedLineStart;
// Given a position pos within the entire source, the results are
// ix -- the index of the containing line
// lstart -- the position of the first character on that line
private void findIndex(int pos, out int ix, out int lstart)
{
if (pos >= cachedPosition)
{
ix = cachedIxdex; lstart = cachedLineStart;
}
else
{
ix = lstart = 0;
}
while (ix < numLines)
{
int len = line[ix].Length + 1;
if (pos < lstart + len) break;
lstart += len;
ix++;
}
cachedPosition = pos;
cachedIxdex = ix;
cachedLineStart = lstart;
}
public override string GetString(int begin, int limit)
{
if (begin >= maxPos || limit <= begin) return "";
int endIx, begIx, endLineStart, begLineStart;
findIndex(begin, out begIx, out begLineStart);
int begCol = begin - begLineStart;
findIndex(limit, out endIx, out endLineStart);
int endCol = limit - endLineStart;
string s = line[begIx];
if (begIx == endIx)
{
// the usual case, substring all on one line
return (endCol <= s.Length) ?
s.Substring(begCol, endCol - begCol)
: s.Substring(begCol) + "\n";
}
// the string spans multiple lines, yuk!
StringBuilder sb = new StringBuilder();
if (begCol < s.Length)
sb.Append(s.Substring(begCol));
for (; ; )
{
sb.Append("\n");
s = line[++begIx];
if (begIx >= endIx) break;
sb.Append(s);
}
if (endCol <= s.Length)
{
sb.Append(s.Substring(0, endCol));
}
else
{
sb.Append(s);
sb.Append("\n");
}
return sb.ToString();
}
public override int Pos
{
get { return cPos; }
set
{
cPos = value;
findIndex(cPos, out cLine, out curLineStart);
// cLine should be the *next* line after curLine.
curLine = (cLine < numLines ? line[cLine++] : "");
curLineEnd = curLineStart + curLine.Length;
}
}
public override string ToString() { return "LineBuffer"; }
}
#if (!NOFILES)
// ==============================================================
// ===== class BuildBuff : for unicode text files ========
// ==============================================================
class BuildBuffer : ScanBuff
{
// Double buffer for char stream.
class BufferElement
{
StringBuilder bldr = new StringBuilder();
StringBuilder next = new StringBuilder();
int minIx;
int maxIx;
int brkIx;
bool appendToNext;
internal BufferElement() { }
internal int MaxIndex { get { return maxIx; } }
// internal int MinIndex { get { return minIx; } }
internal char this[int index]
{
get
{
if (index < minIx || index >= maxIx)
throw new BufferException("Index was outside data buffer");
else if (index < brkIx)
return bldr[index - minIx];
else
return next[index - brkIx];
}
}
internal void Append(char[] block, int count)
{
maxIx += count;
if (appendToNext)
this.next.Append(block, 0, count);
else
{
this.bldr.Append(block, 0, count);
brkIx = maxIx;
appendToNext = true;
}
}
internal string GetString(int start, int limit)
{
if (limit <= start)
return "";
if (start >= minIx && limit <= maxIx)
if (limit < brkIx) // String entirely in bldr builder
return bldr.ToString(start - minIx, limit - start);
else if (start >= brkIx) // String entirely in next builder
return next.ToString(start - brkIx, limit - start);
else // Must do a string-concatenation
return
bldr.ToString(start - minIx, brkIx - start) +
next.ToString(0, limit - brkIx);
else
throw new BufferException("String was outside data buffer");
}
internal void Mark(int limit)
{
if (limit > brkIx + 16) // Rotate blocks
{
StringBuilder temp = bldr;
bldr = next;
next = temp;
next.Length = 0;
minIx = brkIx;
brkIx = maxIx;
}
}
}
BufferElement data = new BufferElement();
int bPos; // Postion index in the StringBuilder
BlockReader NextBlk; // Delegate that serves char-arrays;
private string EncodingName
{
get
{
StreamReader rdr = NextBlk.Target as StreamReader;
return (rdr == null ? "raw-bytes" : rdr.CurrentEncoding.BodyName);
}
}
public BuildBuffer(Stream stream)
{
FileStream fStrm = (stream as FileStream);
if (fStrm != null) FileName = fStrm.Name;
NextBlk = BlockReaderFactory.Raw(stream);
}
#if (!BYTEMODE)
public BuildBuffer(Stream stream, int fallbackCodePage)
{
FileStream fStrm = (stream as FileStream);
if (fStrm != null) FileName = fStrm.Name;
NextBlk = BlockReaderFactory.Get(stream, fallbackCodePage);
}
#endif
/// <summary>
/// Marks a conservative lower bound for the buffer,
/// allowing space to be reclaimed. If an application
/// needs to call GetString at arbitrary past locations
/// in the input stream, Mark() is not called.
/// </summary>
public override void Mark() { data.Mark(bPos - 2); }
public override int Pos
{
get { return bPos; }
set { bPos = value; }
}
/// <summary>
/// Read returns the ordinal number of the next char, or
/// EOF (-1) for an end of stream. Note that the next
/// code point may require *two* calls of Read().
/// </summary>
/// <returns></returns>
public override int Read()
{
//
// Characters at positions
// [data.offset, data.offset + data.bldr.Length)
// are available in data.bldr.
//
if (bPos < data.MaxIndex)
{
// ch0 cannot be EOF
return (int)data[bPos++];
}
else // Read from underlying stream
{
// Experimental code, blocks of page size
char[] chrs = new char[4096];
int count = NextBlk(chrs, 0, 4096);
if (count == 0)
return EndOfFile;
else
{
data.Append(chrs, count);
return (int)data[bPos++];
}
}
}
public override string GetString(int begin, int limit)
{
return data.GetString(begin, limit);
}
public override string ToString()
{
return "StringBuilder buffer, encoding: " + this.EncodingName;
}
}
// =============== End ScanBuff-derived classes ==================
internal delegate int BlockReader(char[] block, int index, int number);
// A delegate factory, serving up a delegate that
// reads a block of characters from the underlying
// encoded stream, via a StreamReader object.
//
internal static class BlockReaderFactory
{
public static BlockReader Raw(Stream stream)
{
return delegate(char[] block, int index, int number)
{
byte[] b = new byte[number];
int count = stream.Read(b, 0, number);
int i = 0;
int j = index;
for (; i < count; i++, j++)
block[j] = (char)b[i];
return count;
};
}
#if (!BYTEMODE)
public static BlockReader Get(Stream stream, int fallbackCodePage)
{
Encoding encoding;
int preamble = Preamble(stream);
if (preamble != 0) // There is a valid BOM here!
encoding = Encoding.GetEncoding(preamble);
else if (fallbackCodePage == -1) // Fallback is "raw" bytes
return Raw(stream);
else if (fallbackCodePage != -2) // Anything but "guess"
encoding = Encoding.GetEncoding(fallbackCodePage);
else // This is the "guess" option
{
int guess = new Guesser(stream).GuessCodePage();
stream.Seek(0, SeekOrigin.Begin);
if (guess == -1) // ==> this is a 7-bit file
encoding = Encoding.ASCII;
else if (guess == 65001)
encoding = Encoding.UTF8;
else // ==> use the machine default
encoding = Encoding.Default;
}
StreamReader reader = new StreamReader(stream, encoding);
return reader.Read;
}
static int Preamble(Stream stream)
{
int b0 = stream.ReadByte();
int b1 = stream.ReadByte();
if (b0 == 0xfe && b1 == 0xff)
return 1201; // UTF16BE
if (b0 == 0xff && b1 == 0xfe)
return 1200; // UTF16LE
int b2 = stream.ReadByte();
if (b0 == 0xef && b1 == 0xbb && b2 == 0xbf)
return 65001; // UTF8
//
// There is no unicode preamble, so we
// return denoter for the machine default.
//
stream.Seek(0, SeekOrigin.Begin);
return 0;
}
#endif // !BYTEMODE
}
#endif // !NOFILES
#endregion Buffer classes
// ==============================================================
// ============ class CodePageHandling =============
// ==============================================================
#if (!NOFILES)
public static class CodePageHandling
{
public static int GetCodePage(string option)
{
string command = option.ToUpperInvariant();
if (command.StartsWith("CodePage:", StringComparison.OrdinalIgnoreCase))
command = command.Substring(9);
try
{
if (command.Equals("RAW"))
return -1;
else if (command.Equals("GUESS"))
return -2;
else if (command.Equals("DEFAULT"))
return 0;
else if (char.IsDigit(command[0]))
return int.Parse(command, CultureInfo.InvariantCulture);
else
{
Encoding enc = Encoding.GetEncoding(command);
return enc.CodePage;
}
}
catch (FormatException)
{
Console.Error.WriteLine(
"Invalid format \"{0}\", using machine default", option);
}
catch (ArgumentException)
{
Console.Error.WriteLine(
"Unknown code page \"{0}\", using machine default", option);
}
return 0;
}
}
#region guesser
#if (!BYTEMODE)
// ==============================================================
// ============ Encoding Guesser =============
// ==============================================================
/// <summary>
/// This class provides a simple finite state automaton that
/// scans the file looking for (1) valid UTF-8 byte patterns,
/// (2) bytes >= 0x80 which are not part of a UTF-8 sequence.
/// The method then guesses whether it is UTF-8 or maybe some
/// local machine default encoding. This works well for the
/// various Latin encodings.
/// </summary>
internal class Guesser
{
ScanBuff buffer;
public int GuessCodePage() { return Scan(); }
const int maxAccept = 10;
const int initial = 0;
const int eofNum = 0;
const int goStart = -1;
const int INITIAL = 0;
const int EndToken = 0;
#region user code
/*
* Reads the bytes of a file to determine if it is
* UTF-8 or a single-byte code page file.
*/
public long utfX;
public long uppr;
#endregion user code
int state;
int currentStart = startState[0];
int code;
#region ScannerTables
static int[] startState = new int[] { 11, 0 };
#region CharacterMap
static sbyte[] map = new sbyte[256] {
/* '\0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* '\x10' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* '\x20' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* '0' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* '@' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 'P' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* '`' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 'p' */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* '\x80' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* '\x90' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* '\xA0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* '\xB0' */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* '\xC0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* '\xD0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* '\xE0' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* '\xF0' */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 };
#endregion
static sbyte[][] nextState = new sbyte[][] {
new sbyte[] {0, 0, 0, 0, 0, 0},
new sbyte[] {-1, -1, 10, -1, -1, -1},
new sbyte[] {-1, -1, -1, -1, -1, -1},
new sbyte[] {-1, -1, 8, -1, -1, -1},
new sbyte[] {-1, -1, 5, -1, -1, -1},
new sbyte[] {-1, -1, 6, -1, -1, -1},
new sbyte[] {-1, -1, 7, -1, -1, -1},
null,
new sbyte[] {-1, -1, 9, -1, -1, -1},
null,
null,
new sbyte[] {-1, 1, 2, 3, 4, 2}
};
[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
// Reason for suppression: cannot have self-reference in array initializer.
static Guesser()
{
nextState[7] = nextState[2];
nextState[9] = nextState[2];
nextState[10] = nextState[2];
}
int NextState()
{
if (code == ScanBuff.EndOfFile)
return eofNum;
else
return nextState[state][map[code]];
}
#endregion
public Guesser(System.IO.Stream file) { SetSource(file); }
public void SetSource(System.IO.Stream source)
{
this.buffer = new BuildBuffer(source);
code = buffer.Read();
}
int Scan()
{
for (; ; )
{
int next;
state = currentStart;
while ((next = NextState()) == goStart)
code = buffer.Read();
state = next;
code = buffer.Read();
while ((next = NextState()) > eofNum)
{
state = next;
code = buffer.Read();
}
if (state <= maxAccept)
{
#region ActionSwitch
#pragma warning disable 162
switch (state)
{
case eofNum:
switch (currentStart)
{
case 11:
if (utfX == 0 && uppr == 0) return -1; /* raw ascii */
else if (uppr * 10 > utfX) return 0; /* default code page */
else return 65001; /* UTF-8 encoding */
break;
}
return EndToken;
case 1: // Recognized '{Upper128}', Shortest string "\xC0"
case 2: // Recognized '{Upper128}', Shortest string "\x80"
case 3: // Recognized '{Upper128}', Shortest string "\xE0"
case 4: // Recognized '{Upper128}', Shortest string "\xF0"
uppr++;
break;
case 5: // Recognized '{Utf8pfx4}{Utf8cont}', Shortest string "\xF0\x80"
uppr += 2;
break;
case 6: // Recognized '{Utf8pfx4}{Utf8cont}{2}', Shortest string "\xF0\x80\x80"
uppr += 3;
break;
case 7: // Recognized '{Utf8pfx4}{Utf8cont}{3}', Shortest string "\xF0\x80\x80\x80"
utfX += 3;
break;
case 8: // Recognized '{Utf8pfx3}{Utf8cont}', Shortest string "\xE0\x80"
uppr += 2;
break;
case 9: // Recognized '{Utf8pfx3}{Utf8cont}{2}', Shortest string "\xE0\x80\x80"
utfX += 2;
break;
case 10: // Recognized '{Utf8pfx2}{Utf8cont}', Shortest string "\xC0\x80"
utfX++;
break;
default:
break;
}
#pragma warning restore 162
#endregion
}
}
}
} // end class Guesser
#endif // !BYTEMODE
#endregion
#endif // !NOFILES
// End of code copied from embedded resource
}
@@ -1,19 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
public interface IArithmeticExpression {
IArithmeticExpression Add(IArithmeticExpression factor) => new Sum(this, factor);
IArithmeticExpression Divide(IArithmeticExpression other) => new Quotient(this, other);
IArithmeticExpression Multiply(IArithmeticExpression other) => new Product(this, other);
IArithmeticExpression Subtract(IArithmeticExpression other) => new Difference(this, other);
IArithmeticExpression Negate() => new AdditiveInverse(this);
object? Evaluate(IDictionary<string, object?> env);
}
public interface IArithmeticExpression<T> : IArithmeticExpression where T : INumber<T> {
new T Evaluate(IDictionary<string, object?> env);
object? IArithmeticExpression.Evaluate(IDictionary<string, object?> env) =>
Evaluate(env);
}
@@ -1,7 +0,0 @@
namespace Bts.ArithmeticExpressions;
public interface IArithmeticProgram {
IEnumerable<string> OutputIdentifiers { get; }
IDictionary<string, object?> Evaluate(IDictionary<string, object?> env);
}
@@ -1,11 +0,0 @@
namespace Bts.ArithmeticExpressions;
class IntegerConstant : IArithmeticExpression<int> {
readonly int value;
public IntegerConstant(int value) =>
this.value = value;
public int Evaluate(IDictionary<string, object?> env) =>
value;
}
@@ -1,45 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
class Product : IArithmeticExpression<double> {
readonly IArithmeticExpression left;
readonly IArithmeticExpression right;
public Product(IArithmeticExpression left, IArithmeticExpression right) {
this.left = left;
this.right = right;
}
public static Product<T, T, T> Create<T>(
IArithmeticExpression<T> left, IArithmeticExpression<T> right)
where T : INumber<T>, IMultiplyOperators<T, T, T> =>
new(left, right);
public double Evaluate(IDictionary<string, object?> env) =>
evaluateArg(left, nameof(left), env) * evaluateArg(right, nameof(right), env);
static double evaluateArg(
IArithmeticExpression expr, string name, IDictionary<string, object?> env) {
var obj = expr.Evaluate(env);
return ConvertUtils.try_convert(expr.Evaluate(env), out double dbl) ? dbl :
throw new Exception(
$"Invalid Product. {name} is of type {obj?.GetType()} (expected {typeof(double)})");
}
}
class Product<TLeft, TRight, TResult> : IArithmeticExpression<TResult>
where TLeft : INumber<TLeft>, IMultiplyOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> {
readonly IArithmeticExpression<TLeft> left;
readonly IArithmeticExpression<TRight> right;
public Product(IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right) {
this.left = left;
this.right = right;
}
public TResult Evaluate(IDictionary<string, object?> env) =>
left.Evaluate(env) * right.Evaluate(env);
}
@@ -1,45 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
class Quotient : IArithmeticExpression<double> {
readonly IArithmeticExpression left;
readonly IArithmeticExpression right;
public Quotient(IArithmeticExpression left, IArithmeticExpression right) {
this.left = left;
this.right = right;
}
public static Quotient<T, T, T> Create<T>(
IArithmeticExpression<T> left, IArithmeticExpression<T> right)
where T : INumber<T>, IDivisionOperators<T, T, T> =>
new(left, right);
public double Evaluate(IDictionary<string, object?> env) =>
evaluateArg(left, nameof(left), env) / evaluateArg(right, nameof(right), env);
static double evaluateArg(
IArithmeticExpression expr, string name, IDictionary<string, object?> env) {
var obj = expr.Evaluate(env);
return ConvertUtils.try_convert(expr.Evaluate(env), out double dbl) ? dbl :
throw new Exception(
$"Invalid Quotient. {name} is of type {obj?.GetType()} (expected {typeof(double)})");
}
}
class Quotient<TLeft, TRight, TResult> : IArithmeticExpression<TResult>
where TLeft : INumber<TLeft>, IDivisionOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> {
readonly IArithmeticExpression<TLeft> left;
readonly IArithmeticExpression<TRight> right;
public Quotient(IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right) {
this.left = left;
this.right = right;
}
public TResult Evaluate(IDictionary<string, object?> env) =>
left.Evaluate(env) / right.Evaluate(env);
}
@@ -1,11 +0,0 @@
namespace Bts.ArithmeticExpressions;
class RealConstant : IArithmeticExpression<double> {
readonly double value;
public RealConstant(double value) =>
this.value = value;
public double Evaluate(IDictionary<string, object?> env) =>
value;
}
@@ -1,884 +0,0 @@
// ==============================================================
// <auto-generated>
// This code automatically produced from an embedded resource.
// Do not edit this file, or it will become incompatible with
// the specification from which it was generated.
// </auto-generated>
// ==============================================================
// Gardens Point Parser Generator
// Copyright (c) Wayne Kelly, QUT 2005-2010
// (see accompanying GPPGcopyright.rtf)
using System;
using System.Text;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;
namespace QUT.Gppg {
/// <summary>
/// Abstract class for GPPG shift-reduce parsers.
/// Parsers generated by GPPG derive from this base
/// class, overriding the abstract Initialize() and
/// DoAction() methods.
/// </summary>
/// <typeparam name="TValue">Semantic value type</typeparam>
/// <typeparam name="TSpan">Location type</typeparam>
#if EXPORT_GPPG
public abstract class ShiftReduceParser<TValue, TSpan>
#else
internal abstract class ShiftReduceParser<TValue, TSpan>
#endif
where TSpan : IMerge<TSpan>, new() {
private AbstractScanner<TValue, TSpan> scanner;
/// <summary>
/// The abstract scanner for this parser.
/// </summary>
protected AbstractScanner<TValue, TSpan> Scanner {
get { return scanner; }
set { scanner = value; }
}
/// <summary>
/// Constructor for base class
/// </summary>
/// <param name="scanner">Scanner instance for this parser</param>
protected ShiftReduceParser( AbstractScanner<TValue, TSpan> scanner ) {
this.scanner = scanner;
}
// ==============================================================
// TECHNICAL EXPLANATION.
// Why the next two fields are not exposed via properties.
// ==============================================================
// These fields are of the generic parameter types, and are
// frequently instantiated as struct types in derived classes.
// Semantic actions are defined in the derived classes and refer
// to instance fields of these structs. In such cases the code
// "get_CurrentSemanticValue().myField = blah;" will fail since
// the getter pushes the value of the field, not the reference.
// So, in the presence of properties, gppg would need to encode
// such field accesses as ...
// "tmp = get_CurrentSemanticValue(); // Fetch value
// tmp.myField = blah; // update
// set_CurrentSemanticValue(tmp); " // Write update back.
// There is no issue if TValue is restricted to be a ref type.
// The same explanation applies to scanner.yylval.
// ==============================================================
/// <summary>
/// The current value of the "$$" symbolic variable in the parser
/// </summary>
[SuppressMessage( "Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields" )]
protected TValue CurrentSemanticValue;
/// <summary>
/// The current value of the "@$" symbolic variable in the parser
/// </summary>
[SuppressMessage( "Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields" )]
protected TSpan CurrentLocationSpan;
protected int NextToken;
private TSpan LastSpan;
private State FsaState;
private bool recovering;
private int tokensSinceLastError;
private PushdownPrefixState<State> StateStack = new PushdownPrefixState<State>();
private PushdownPrefixState<TValue> valueStack = new PushdownPrefixState<TValue>();
private PushdownPrefixState<TSpan> locationStack = new PushdownPrefixState<TSpan>();
/// <summary>
/// The stack of semantic value (YYSTYPE) values.
/// </summary>
protected PushdownPrefixState<TValue> ValueStack { get { return valueStack; } }
/// <summary>
/// The stack of location value (YYLTYPE) varlues.
/// </summary>
protected PushdownPrefixState<TSpan> LocationStack { get { return locationStack; } }
private int errorToken;
private int endOfFileToken;
private string[] nonTerminals;
private State[] states;
private Rule[] rules;
/// <summary>
/// Initialization method to allow derived classes
/// to insert the rule list into this base class.
/// </summary>
/// <param name="rules">The array of Rule objects</param>
protected void InitRules( Rule[] rules ) { this.rules = rules; }
/// <summary>
/// Initialization method to allow derived classes to
/// insert the states table into this base class.
/// </summary>
/// <param name="states">The pre-initialized states table</param>
protected void InitStates( State[] states ) { this.states = states; }
/// <summary>
/// OBSOLETE FOR VERSION 1.4.0
/// </summary>
/// <param name="size"></param>
protected void InitStateTable( int size ) { states = new State[size]; }
/// <summary>
/// Initialization method to allow derived classes
/// to insert the special value for the error and EOF tokens.
/// </summary>
/// <param name="err">The error state ordinal</param>
/// <param name="end">The EOF stat ordinal</param>
protected void InitSpecialTokens( int err, int end ) {
errorToken = err;
endOfFileToken = end;
}
/// <summary>
/// Initialization method to allow derived classes to
/// insert the non-terminal symbol names into this base class.
/// </summary>
/// <param name="names">Non-terminal symbol names</param>
protected void InitNonTerminals( string[] names ) { nonTerminals = names; }
#region YYAbort, YYAccept etcetera.
[Serializable]
[SuppressMessage( "Microsoft.Design", "CA1064:ExceptionsShouldBePublic" )]
// Reason for FxCop message suppression -
// This exception cannot escape from the local context
private class AcceptException : Exception {
internal AcceptException() { }
protected AcceptException( SerializationInfo i, StreamingContext c ) : base( i, c ) { }
}
[Serializable]
[SuppressMessage( "Microsoft.Design", "CA1064:ExceptionsShouldBePublic" )]
// Reason for FxCop message suppression -
// This exception cannot escape from the local context
private class AbortException : Exception {
internal AbortException() { }
protected AbortException( SerializationInfo i, StreamingContext c ) : base( i, c ) { }
}
[Serializable]
[SuppressMessage( "Microsoft.Design", "CA1064:ExceptionsShouldBePublic" )]
// Reason for FxCop message suppression -
// This exception cannot escape from the local context
private class ErrorException : Exception {
internal ErrorException() { }
protected ErrorException( SerializationInfo i, StreamingContext c ) : base( i, c ) { }
}
// The following methods are only called from within
// a semantic action. The thrown exceptions can never
// propagate outside the ShiftReduceParser class in
// which they are nested.
/// <summary>
/// Force parser to terminate, returning "true"
/// </summary>
protected static void YYAccept() { throw new AcceptException(); }
/// <summary>
/// Force parser to terminate, returning "false"
/// </summary>
protected static void YYAbort() { throw new AbortException(); }
/// <summary>
/// Force parser to terminate, returning
/// "false" if error recovery fails.
/// </summary>
protected static void YYError() { throw new ErrorException(); }
/// <summary>
/// Check if parser in error recovery state.
/// </summary>
protected bool YYRecovering { get { return recovering; } }
#endregion
/// <summary>
/// Abstract base method. ShiftReduceParser calls this
/// to initialize the base class data structures. Concrete
/// parser classes must override this method.
/// </summary>
protected abstract void Initialize();
/// <summary>
/// Main entry point of the Shift-Reduce Parser.
/// </summary>
/// <returns>True if parse succeeds, else false for
/// unrecoverable errors</returns>
public bool Parse() {
Initialize(); // allow derived classes to instantiate rules, states and nonTerminals
NextToken = 0;
FsaState = states[0];
StateStack.Push( FsaState );
valueStack.Push( CurrentSemanticValue );
LocationStack.Push( CurrentLocationSpan );
while (true) {
#if TRACE_ACTIONS
Console.Error.WriteLine("Entering state {0} ", FsaState.number);
DisplayStack();
#endif
int action = FsaState.defaultAction;
if (FsaState.ParserTable != null) {
if (NextToken == 0) {
// We save the last token span, so that the location span
// of production right hand sides that begin or end with a
// nullable production will be correct.
LastSpan = scanner.yylloc;
NextToken = scanner.yylex();
#if TRACE_ACTIONS
Console.Error.WriteLine( "Reading: Next token is {0}", TerminalToString( NextToken ) );
#endif
}
#if TRACE_ACTIONS
else
Console.Error.WriteLine( "Next token is still {0}", TerminalToString( NextToken ) );
#endif
if (FsaState.ParserTable.ContainsKey( NextToken ))
action = FsaState.ParserTable[NextToken];
}
if (action > 0) // shift
{
Shift( action );
}
else if (action < 0) // reduce
{
try {
Reduce( -action );
if (action == -1) // accept
return true;
}
catch (AbortException) {
return false;
}
catch (AcceptException) {
return true;
}
catch (ErrorException) {
if (!ErrorRecovery())
return false;
else
throw; // Rethrow x, preserving information.
}
}
else if (action == 0 && !ErrorRecovery()) // error
return false;
}
}
private void Shift( int stateIndex ) {
#if TRACE_ACTIONS
Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken));
#endif
FsaState = states[stateIndex];
valueStack.Push( scanner.yylval );
StateStack.Push( FsaState );
LocationStack.Push( scanner.yylloc );
if (recovering) {
if (NextToken != errorToken)
tokensSinceLastError++;
if (tokensSinceLastError > 5)
recovering = false;
}
if (NextToken != endOfFileToken)
NextToken = 0;
}
private void Reduce( int ruleNumber ) {
#if TRACE_ACTIONS
DisplayRule(ruleNumber);
#endif
Rule rule = rules[ruleNumber];
int rhLen = rule.RightHandSide.Length;
//
// Default actions for unit productions.
//
if (rhLen == 1) {
CurrentSemanticValue = valueStack.TopElement(); // Default action: $$ = $1;
CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1;
}
else if (rhLen == 0) {
// Create a new blank value.
// Explicit semantic action may mutate this value
CurrentSemanticValue = default( TValue );
// The location span for an empty production will start with the
// beginning of the next lexeme, and end with the finish of the
// previous lexeme. This gives the correct behaviour when this
// nonsense value is used in later Merge operations.
CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ?
scanner.yylloc.Merge( LastSpan ) :
default( TSpan ));
}
else {
// Default action: $$ = $1;
CurrentSemanticValue = valueStack[LocationStack.Depth - rhLen];
// Default action "@$ = @1.Merge(@N)" for location info.
TSpan at1 = LocationStack[LocationStack.Depth - rhLen];
TSpan atN = LocationStack[LocationStack.Depth - 1];
CurrentLocationSpan =
((at1 != null && atN != null) ? at1.Merge( atN ) : default( TSpan ));
}
DoAction( ruleNumber );
for (int i = 0; i < rule.RightHandSide.Length; i++) {
StateStack.Pop();
valueStack.Pop();
LocationStack.Pop();
}
FsaState = StateStack.TopElement();
if (FsaState.Goto.ContainsKey( rule.LeftHandSide ))
FsaState = states[FsaState.Goto[rule.LeftHandSide]];
StateStack.Push( FsaState );
valueStack.Push( CurrentSemanticValue );
LocationStack.Push( CurrentLocationSpan );
}
/// <summary>
/// Execute the selected action from array.
/// Must be overriden in derived classes.
/// </summary>
/// <param name="actionNumber">Index of the action to perform</param>
protected abstract void DoAction( int actionNumber );
private bool ErrorRecovery() {
bool discard;
if (!recovering) // if not recovering from previous error
ReportError();
if (!FindErrorRecoveryState())
return false;
//
// The interim fix for the "looping in error recovery"
// artifact involved moving the setting of the recovering
// bool until after invalid tokens have been discarded.
//
ShiftErrorToken();
discard = DiscardInvalidTokens();
recovering = true;
tokensSinceLastError = 0;
return discard;
}
private void ReportError() {
StringBuilder errorMsg = new StringBuilder();
errorMsg.AppendFormat( "Syntax error, unexpected {0}", TerminalToString( NextToken ) );
if (FsaState.ParserTable.Count < 7) {
bool first = true;
foreach (int terminal in FsaState.ParserTable.Keys) {
if (first)
errorMsg.Append( ", expecting " );
else
errorMsg.Append( ", or " );
errorMsg.Append( TerminalToString( terminal ) );
first = false;
}
}
scanner.yyerror( errorMsg.ToString() );
}
private void ShiftErrorToken() {
int old_next = NextToken;
NextToken = errorToken;
Shift( FsaState.ParserTable[NextToken] );
#if TRACE_ACTIONS
Console.Error.WriteLine("Entering state {0} ", FsaState.number);
#endif
NextToken = old_next;
}
private bool FindErrorRecoveryState() {
while (true) // pop states until one found that accepts error token
{
if (FsaState.ParserTable != null &&
FsaState.ParserTable.ContainsKey( errorToken ) &&
FsaState.ParserTable[errorToken] > 0) // shift
return true;
#if TRACE_ACTIONS
Console.Error.WriteLine("Error: popping state {0}", StateStack.TopElement().number);
#endif
StateStack.Pop();
valueStack.Pop();
LocationStack.Pop();
#if TRACE_ACTIONS
DisplayStack();
#endif
if (StateStack.IsEmpty()) {
#if TRACE_ACTIONS
Console.Error.WriteLine("Aborting: didn't find a state that accepts error token");
#endif
return false;
}
else
FsaState = StateStack.TopElement();
}
}
private bool DiscardInvalidTokens() {
int action = FsaState.defaultAction;
if (FsaState.ParserTable != null) {
// Discard tokens until find one that works ...
while (true) {
if (NextToken == 0) {
#if TRACE_ACTIONS
Console.Error.Write("Reading a token: ");
#endif
NextToken = scanner.yylex();
}
#if TRACE_ACTIONS
Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken));
#endif
if (NextToken == endOfFileToken)
return false;
if (FsaState.ParserTable.ContainsKey( NextToken ))
action = FsaState.ParserTable[NextToken];
if (action != 0)
return true;
else {
#if TRACE_ACTIONS
Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken));
#endif
NextToken = 0;
}
}
}
else if (recovering && tokensSinceLastError == 0) {
//
// Boolean recovering is not set until after the first
// error token has been shifted. Thus if we get back
// here with recovering set and no tokens read we are
// looping on the same error recovery action. This
// happens if current_state.ParserTable is null because
// the state has an LR(0) reduction, but not all
// lookahead tokens are valid. This only occurs for
// error productions that *end* on "error".
//
// This action discards tokens one at a time until
// the looping stops. Another attack would be to always
// use the LALR(1) table if a production ends on "error"
//
#if TRACE_ACTIONS
Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken));
#endif
if (NextToken == endOfFileToken)
return false;
NextToken = 0;
return true;
}
else
return true;
}
/// <summary>
/// Traditional YACC method. Discards the next input token.
/// </summary>
[SuppressMessage( "Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin" )]
[SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin" )]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
protected void yyclearin() { NextToken = 0; }
/// <summary>
/// Tradional YACC method. Clear the "recovering" flag.
/// </summary>
[SuppressMessage( "Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok" )]
[SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok" )]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
protected void yyerrok() { recovering = false; }
/// <summary>
/// OBSOLETE FOR VERSION 1.4.0
/// Method used by derived types to insert new
/// state instances in the "states" array.
/// </summary>
/// <param name="stateNumber">index of the state</param>
/// <param name="state">data for the state</param>
protected void AddState( int stateNumber, State state ) {
states[stateNumber] = state;
state.number = stateNumber;
}
private void DisplayStack() {
Console.Error.Write( "State stack is now:" );
for (int i = 0; i < StateStack.Depth; i++)
Console.Error.Write( " {0}", StateStack[i].number );
Console.Error.WriteLine();
}
private void DisplayRule( int ruleNumber ) {
Console.Error.Write( "Reducing stack by rule {0}, ", ruleNumber );
DisplayProduction( rules[ruleNumber] );
}
private void DisplayProduction( Rule rule ) {
if (rule.RightHandSide.Length == 0)
Console.Error.Write( "/* empty */ " );
else
foreach (int symbol in rule.RightHandSide)
Console.Error.Write( "{0} ", SymbolToString( symbol ) );
Console.Error.WriteLine( "-> {0}", SymbolToString( rule.LeftHandSide ) );
}
/// <summary>
/// Abstract state class naming terminal symbols.
/// This is overridden by derived classes with the
/// name (or alias) to be used in error messages.
/// </summary>
/// <param name="terminal">The terminal ordinal</param>
/// <returns></returns>
protected abstract string TerminalToString( int terminal );
private string SymbolToString( int symbol ) {
if (symbol < 0)
return nonTerminals[-symbol - 1];
else
return TerminalToString( symbol );
}
/// <summary>
/// Return text representation of argument character
/// </summary>
/// <param name="input">The character to convert</param>
/// <returns>String representation of the character</returns>
protected static string CharToString( char input ) {
switch (input) {
case '\a': return @"'\a'";
case '\b': return @"'\b'";
case '\f': return @"'\f'";
case '\n': return @"'\n'";
case '\r': return @"'\r'";
case '\t': return @"'\t'";
case '\v': return @"'\v'";
case '\0': return @"'\0'";
default: return string.Format( CultureInfo.InvariantCulture, "'{0}'", input );
}
}
}
/// <summary>
/// Classes implementing this interface must supply a
/// method that merges two location objects to return
/// a new object of the same type.
/// GPPG-generated parsers have the default location
/// action equivalent to "@$ = @1.Merge(@N);" where N
/// is the right-hand-side length of the production.
/// </summary>
/// <typeparam name="TSpan">The Location type</typeparam>
#if EXPORT_GPPG
public interface IMerge<TSpan>
#else
internal interface IMerge<TSpan>
#endif
{
/// <summary>
/// Interface method that creates a location object from
/// the current and last object. Typically used to create
/// a location object extending from the start of the @1
/// object to the end of the @N object.
/// </summary>
/// <param name="last">The lexically last object to merge</param>
/// <returns>The merged location object</returns>
TSpan Merge( TSpan last );
}
/// <summary>
/// This is the default class that carries location
/// information from the scanner to the parser.
/// If you don't declare "%YYLTYPE Foo" the parser
/// will expect to deal with this type.
/// </summary>
#if EXPORT_GPPG
public class LexLocation : IMerge<LexLocation>
#else
[SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )]
internal class LexLocation : IMerge<LexLocation>
#endif
{
private int startLine; // start line
private int startColumn; // start column
private int endLine; // end line
private int endColumn; // end column
/// <summary>
/// The line at which the text span starts.
/// </summary>
public int StartLine { get { return startLine; } }
/// <summary>
/// The column at which the text span starts.
/// </summary>
public int StartColumn { get { return startColumn; } }
/// <summary>
/// The line on which the text span ends.
/// </summary>
public int EndLine { get { return endLine; } }
/// <summary>
/// The column of the first character
/// beyond the end of the text span.
/// </summary>
public int EndColumn { get { return endColumn; } }
/// <summary>
/// Default no-arg constructor.
/// </summary>
public LexLocation() { }
/// <summary>
/// Constructor for text-span with given start and end.
/// </summary>
/// <param name="sl">start line</param>
/// <param name="sc">start column</param>
/// <param name="el">end line </param>
/// <param name="ec">end column</param>
public LexLocation( int sl, int sc, int el, int ec ) { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; }
/// <summary>
/// Create a text location which spans from the
/// start of "this" to the end of the argument "last"
/// </summary>
/// <param name="last">The last location in the result span</param>
/// <returns>The merged span</returns>
public LexLocation Merge( LexLocation last ) { return new LexLocation( this.startLine, this.startColumn, last.endLine, last.endColumn ); }
}
/// <summary>
/// Abstract scanner class that GPPG expects its scanners to
/// extend.
/// </summary>
/// <typeparam name="TValue">Semantic value type YYSTYPE</typeparam>
/// <typeparam name="TSpan">Source location type YYLTYPE</typeparam>
#if EXPORT_GPPG
public abstract class AbstractScanner<TValue, TSpan>
#else
internal abstract class AbstractScanner<TValue, TSpan>
#endif
where TSpan : IMerge<TSpan> {
/// <summary>
/// Lexical value optionally set by the scanner. The value
/// is of the %YYSTYPE type declared in the parser spec.
/// </summary>
[SuppressMessage( "Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields" )]
[SuppressMessage( "Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval" )]
[SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval" )]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
// A field must be declared for this value of parametric type,
// since it may be instantiated by a value struct. If it were
// implemented as a property, machine generated code in derived
// types would not be able to select on the returned value.
#pragma warning disable 649
public TValue yylval; // Lexical value: set by scanner
#pragma warning restore 649
/// <summary>
/// Current scanner location property. The value is of the
/// type declared by %YYLTYPE in the parser specification.
/// </summary>
[SuppressMessage( "Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc" )]
[SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc" )]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
public virtual TSpan yylloc {
get { return default( TSpan ); } // Empty implementation allowing
set { /* skip */ } // yylloc to be ignored entirely.
}
/// <summary>
/// Main call point for LEX-like scanners. Returns an int
/// corresponding to the token recognized by the scanner.
/// </summary>
/// <returns>An int corresponding to the token</returns>
[SuppressMessage( "Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex" )]
[SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex" )]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
public abstract int yylex();
/// <summary>
/// Traditional error reporting provided by LEX-like scanners
/// to their YACC-like clients.
/// </summary>
/// <param name="format">Message format string</param>
/// <param name="args">Optional array of args</param>
[SuppressMessage( "Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror" )]
[SuppressMessage( "Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror" )]
// Reason for FxCop message suppression -
// This is a traditional name for YACC-like functionality
public virtual void yyerror( string format, params object[] args ) { }
}
/// <summary>
/// Encapsulated state for the parser.
/// Opaque to users, visible to the tool-generated code.
/// </summary>
#if EXPORT_GPPG
public class State
{
/// <summary>
/// The number of states in the automaton.
/// </summary>
public int number;
#else
internal class State {
/// <summary>
/// The index of this state in the states array.
/// </summary>
internal int number;
#endif
internal Dictionary<int, int> ParserTable; // Terminal -> ParseAction
internal Dictionary<int, int> Goto; // NonTerminal -> State;
internal int defaultAction; // = 0; // ParseAction
/// <summary>
/// State transition data for this state. Pairs of elements of the
/// goto array associate symbol ordinals with next state indices.
/// The actions array is passed to another constructor.
/// </summary>
/// <param name="actions">The action list</param>c
/// <param name="goToList">Next state data</param>
public State( int[] actions, int[] goToList )
: this( actions ) {
Goto = new Dictionary<int, int>();
for (int i = 0; i < goToList.Length; i += 2)
Goto.Add( goToList[i], goToList[i + 1] );
}
/// <summary>
/// Action data for this state. Pairs of elements of the
/// action array associate action ordinals with each of
/// those symbols that have actions in the current state.
/// </summary>
/// <param name="actions">The action array</param>
public State( int[] actions ) {
ParserTable = new Dictionary<int, int>();
for (int i = 0; i < actions.Length; i += 2)
ParserTable.Add( actions[i], actions[i + 1] );
}
/// <summary>
/// Set the default action for this state.
/// </summary>
/// <param name="defaultAction">Ordinal of the default action</param>
public State( int defaultAction ) {
this.defaultAction = defaultAction;
}
/// <summary>
/// Set the default action and the state transition table.
/// </summary>
/// <param name="defaultAction">The default action</param>
/// <param name="goToList">Transitions from this state</param>
public State( int defaultAction, int[] goToList )
: this( defaultAction ) {
Goto = new Dictionary<int, int>();
for (int i = 0; i < goToList.Length; i += 2)
Goto.Add( goToList[i], goToList[i + 1] );
}
}
/// <summary>
/// Rule representation at runtime.
/// </summary>
#if EXPORT_GPPG
public class Rule
#else
internal class Rule
#endif
{
internal int LeftHandSide; // symbol
internal int[] RightHandSide; // symbols
/// <summary>
/// Rule constructor. This holds the ordinal of
/// the left hand side symbol, and the list of
/// right hand side symbols, in lexical order.
/// </summary>
/// <param name="left">The LHS non-terminal</param>
/// <param name="right">The RHS symbols, in lexical order</param>
public Rule( int left, int[] right ) {
this.LeftHandSide = left;
this.RightHandSide = right;
}
}
/// <summary>
/// Stack utility for the shift-reduce parser.
/// GPPG parsers have three instances:
/// (1) The parser state stack, T = QUT.Gppg.State,
/// (2) The semantic value stack, T = TValue,
/// (3) The location stack, T = TSpan.
/// </summary>
/// <typeparam name="T"></typeparam>
#if EXPORT_GPPG
public class PushdownPrefixState<T>
#else
internal class PushdownPrefixState<T>
#endif
{
// Note that we cannot use the BCL Stack<T> class
// here as derived types need to index into stacks.
//
private T[] array = new T[8];
private int tos = 0;
/// <summary>
/// Indexer for values of the stack below the top.
/// </summary>
/// <param name="index">index of the element, starting from the bottom</param>
/// <returns>the selected element</returns>
public T this[int index] { get { return array[index]; } }
/// <summary>
/// The current depth of the stack.
/// </summary>
public int Depth { get { return tos; } }
internal void Push( T value ) {
if (tos >= array.Length) {
T[] newarray = new T[array.Length * 2];
System.Array.Copy( array, newarray, tos );
array = newarray;
}
array[tos++] = value;
}
internal T Pop() {
T rslt = array[--tos];
array[tos] = default( T );
return rslt;
}
internal T TopElement() { return array[tos - 1]; }
internal bool IsEmpty() { return tos == 0; }
}
}
@@ -1,45 +0,0 @@
namespace Bts.ArithmeticExpressions;
using System.Numerics;
class Sum : IArithmeticExpression<double> {
readonly IArithmeticExpression left;
readonly IArithmeticExpression right;
public Sum(IArithmeticExpression left, IArithmeticExpression right) {
this.left = left;
this.right = right;
}
public static Sum<T, T, T> Create<T>(
IArithmeticExpression<T> left, IArithmeticExpression<T> right)
where T : INumber<T>, IAdditionOperators<T, T, T> =>
new(left, right);
public double Evaluate(IDictionary<string, object?> env) =>
evaluateArg(left, nameof(left), env) + evaluateArg(right, nameof(right), env);
static double evaluateArg(
IArithmeticExpression expr, string name, IDictionary<string, object?> env) {
var obj = expr.Evaluate(env);
return ConvertUtils.try_convert(expr.Evaluate(env), out double dbl) ? dbl :
throw new Exception(
$"Invalid Sum. {name} is of type {obj?.GetType()} (expected {typeof(double)})");
}
}
class Sum<TLeft, TRight, TResult> : IArithmeticExpression<TResult>
where TLeft : INumber<TLeft>, IAdditionOperators<TLeft, TRight, TResult>
where TRight : INumber<TRight>
where TResult : INumber<TResult> {
readonly IArithmeticExpression<TLeft> left;
readonly IArithmeticExpression<TRight> right;
public Sum(IArithmeticExpression<TLeft> left, IArithmeticExpression<TRight> right) {
this.left = left;
this.right = right;
}
public TResult Evaluate(IDictionary<string, object?> env) =>
left.Evaluate(env) + right.Evaluate(env);
}
@@ -1,4 +0,0 @@
global using System;
global using System.Linq;
global using System.Collections.Generic;
global using System.Collections.Immutable;
Loaded 100 of 4202 files, more files were not shown because too many files have changed in this diff. Show more