Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbf1fad2dd | ||
|
|
1fbc1584e5 | ||
|
|
f5457e5ce4 | ||
|
|
5ba746fd59 | ||
|
|
ab5cb23062 | ||
|
|
f4b7fbe6b5 | ||
|
|
9901ef54d4 | ||
|
|
293c13e11d | ||
|
|
be4c69fad4 | ||
|
|
2c4dc8fbe5 | ||
|
|
4ea93bc386 | ||
|
|
1c6333b07a | ||
|
|
26d543af82 | ||
|
|
99b301ad6f | ||
|
|
9cbe83e1a4 | ||
|
|
59369e1b2b | ||
|
|
7c42e75ddd | ||
|
|
b453be40fe | ||
|
|
96709c8121 | ||
|
|
5de9f63665 | ||
|
|
6089b209d1 | ||
|
|
d7a12d0dd9 | ||
|
|
2f87fe31be | ||
|
|
5a9749d551 | ||
|
|
ea950c8786 | ||
|
|
30891bfb49 |
No files matched your search
@@ -1,10 +1 @@
|
||||
IndentWidth: 3
|
||||
BinPackArguments: true
|
||||
BinPackParameters: false
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
PenaltyReturnTypeOnItsOwnLine: 140
|
||||
---
|
||||
Language: Proto
|
||||
IndentWidth: 2
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-format": {
|
||||
"version": "5.1.225507",
|
||||
"commands": [
|
||||
"dotnet-format"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||
root = true
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
|
||||
#### Core EditorConfig Options ####
|
||||
|
||||
# Indentation and spacing
|
||||
indent_size = 3
|
||||
indent_style = space
|
||||
tab_width = 3
|
||||
|
||||
# New line preferences
|
||||
end_of_line = crlf
|
||||
insert_final_newline = true
|
||||
|
||||
#### .NET Coding Conventions ####
|
||||
|
||||
# Organize usings
|
||||
dotnet_separate_import_directive_groups = true
|
||||
dotnet_sort_system_directives_first = false
|
||||
file_header_template = unset
|
||||
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
dotnet_style_prefer_auto_properties = true:silent
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
|
||||
# Field preferences
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
|
||||
# Parameter preferences
|
||||
dotnet_code_quality_unused_parameters = all:suggestion
|
||||
|
||||
# Suppression preferences
|
||||
dotnet_remove_unnecessary_suppression_exclusions = none
|
||||
|
||||
#### C# Coding Conventions ####
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_elsewhere = false:silent
|
||||
csharp_style_var_for_built_in_types = false:silent
|
||||
csharp_style_var_when_type_is_apparent = false:silent
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:silent
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
|
||||
# Pattern matching preferences
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_prefer_not_pattern = true:suggestion
|
||||
csharp_style_prefer_pattern_matching = true:silent
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
|
||||
# Null-checking preferences
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
csharp_prefer_static_local_function = true:suggestion
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
|
||||
|
||||
# Code-block preferences
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||
|
||||
# 'using' directive preferences
|
||||
csharp_using_directive_placement = inside_namespace:silent
|
||||
|
||||
#### C# Formatting Rules ####
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_catch = false
|
||||
csharp_new_line_before_else = false
|
||||
csharp_new_line_before_finally = false
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = none
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#### Naming styles ####
|
||||
|
||||
# Naming rules
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# Symbol specifications
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
# user types
|
||||
dotnet_naming_symbols.user_types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.user_types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.user_types.required_modifiers =
|
||||
|
||||
# non_field_members
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# public symbols
|
||||
dotnet_naming_symbols.public_symbols.applicable_kinds = property,method,field,event,delegate
|
||||
dotnet_naming_symbols.public_symbols.applicable_accessibilities = public,internal
|
||||
|
||||
# parameters
|
||||
dotnet_naming_symbols.parameters.applicable_kinds = parameter
|
||||
dotnet_naming_symbols.parameters.applicable_accessibilities = public,internal,protected,private,protected_internal,private_internal
|
||||
|
||||
# private symbols
|
||||
dotnet_naming_symbols.private_symbols.applicable_kinds = property,method,field,event,delegate
|
||||
dotnet_naming_symbols.private_symbols.applicable_accessibilities = protected,private
|
||||
|
||||
# Naming styles
|
||||
|
||||
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.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 =
|
||||
dotnet_naming_style.user_types.word_separator =
|
||||
dotnet_naming_style.user_types.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.interface.required_prefix = I
|
||||
dotnet_naming_style.interface.required_suffix =
|
||||
dotnet_naming_style.interface.word_separator =
|
||||
dotnet_naming_style.interface.capitalization = pascal_case
|
||||
|
||||
# rules
|
||||
dotnet_naming_rule.user_types.symbols = user_types
|
||||
dotnet_naming_rule.user_types.style = user_types
|
||||
dotnet_naming_rule.user_types.severity = suggestion
|
||||
|
||||
dotnet_naming_rule.interfaces.symbols = interface
|
||||
dotnet_naming_rule.interfaces.style = interface_style
|
||||
dotnet_naming_rule.interfaces.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_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.parameters.symbols = parameters
|
||||
dotnet_naming_rule.parameters.style = snake_case
|
||||
dotnet_naming_rule.parameters.severity = suggestion
|
||||
@@ -1,53 +1,32 @@
|
||||
nohup.out
|
||||
build/
|
||||
.build_proxy/
|
||||
cmake-build-debug/
|
||||
.cache/
|
||||
.ipynb_checkpoints/
|
||||
.idea/
|
||||
.dir-locals.el
|
||||
*.pyc
|
||||
**.vscode
|
||||
.vs
|
||||
obj/
|
||||
*.csproj.user
|
||||
*.vspx
|
||||
*.psess
|
||||
msbuild.log
|
||||
*.orig
|
||||
vcxproj.user
|
||||
src/client/spark/Properties/launchSettings.json
|
||||
compile_commands.json
|
||||
.cquery_cached_index/
|
||||
.cache/*
|
||||
.clangd/*
|
||||
src/client/sparkcmd/Properties/launchSettings.json
|
||||
node_modules
|
||||
paket-files
|
||||
project.lock.json
|
||||
src/.clang-format
|
||||
src/server/sparkd/orderman/perf_analysis/data
|
||||
src/server/sparkd/orderman/perf_analysis/logs/
|
||||
src/server/sparkd/orderman/perf_analysis/trace_data/
|
||||
.fake
|
||||
*.fsx.lock
|
||||
*.code-workspace
|
||||
src/lib/orderman/perf_analysis/logs/latency_data/
|
||||
trace_data/
|
||||
/src/lib/orderman/perf_analysis/last_pretty_log.csv
|
||||
/src/lib/orderman/perf_analysis/log.csv
|
||||
/doc/user/public/*
|
||||
.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*/*
|
||||
.cache/
|
||||
nohup.out
|
||||
build/
|
||||
cmake-build-debug/
|
||||
.idea/
|
||||
.dir-locals.el
|
||||
*.pyc
|
||||
.vscode/*
|
||||
!.vscode/*.json
|
||||
.vs
|
||||
obj/
|
||||
*.csproj.user
|
||||
*.vspx
|
||||
*.psess
|
||||
msbuild.log
|
||||
*.orig
|
||||
vcxproj.user
|
||||
src/client/spark/Properties/launchSettings.json
|
||||
compile_commands.json
|
||||
.cquery_cached_index/
|
||||
src/client/sparkcmd/Properties/launchSettings.json
|
||||
node_modules
|
||||
paket-files
|
||||
project.lock.json
|
||||
src/server/sparkd/orderman/perf_analysis/data
|
||||
src/server/sparkd/orderman/perf_analysis/logs/
|
||||
src/server/sparkd/orderman/perf_analysis/trace_data/
|
||||
.fake
|
||||
*.fsx.lock
|
||||
src/lib/orderman/perf_analysis/logs/latency_data/
|
||||
trace_data/
|
||||
/src/lib/orderman/perf_analysis/last_pretty_log.csv
|
||||
/src/lib/orderman/perf_analysis/log.csv
|
||||
@@ -7,6 +7,3 @@
|
||||
[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
|
||||
@@ -5,9 +5,7 @@
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/src",
|
||||
"${workspaceRoot}/externals/linux/include"
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
@@ -15,16 +13,13 @@
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/src",
|
||||
"${workspaceRoot}/externals/linux/include"
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"compileCommands": "${workspaceFolder}/build/ninja_debug/compile_commands.json"
|
||||
"cppStandard": "c++17"
|
||||
},
|
||||
{
|
||||
"name": "Windows",
|
||||
@@ -35,6 +30,7 @@
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/linux/include/tensorflow/contrib/makefile/gen/proto",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
@@ -55,6 +51,7 @@
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/linux/include/tensorflow/contrib/makefile/gen/proto",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
@@ -79,6 +76,7 @@
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/linux/include/tensorflow/contrib/makefile/gen/proto",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
@@ -1,402 +1,319 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Spark Local",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"run",
|
||||
"test",
|
||||
"-a",
|
||||
"OutrightVanillaOrder"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/gcc/debug/server/",
|
||||
"environment": [
|
||||
{
|
||||
"name": "TZ",
|
||||
"value": "America/Chicago"
|
||||
}
|
||||
],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SparkVM Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"-a",
|
||||
"[ilink3]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "LD LIBRARY",
|
||||
"text": "set env LD_LIBRARY_PATH=.",
|
||||
"ignoreFailures": false
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/gcc/debug/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"run"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/ninja_debug/src/server/sparkd",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Client Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "SDK Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark_sdk.exe",
|
||||
"args": [
|
||||
"md",
|
||||
"GLBX",
|
||||
"Future",
|
||||
"CL",
|
||||
"CLZ9",
|
||||
"--user=bts",
|
||||
"--pass="
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Excel Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "C:/Program Files/Microsoft Office/Office14/EXCEL.EXE",
|
||||
"args": [
|
||||
"${workspaceRoot}/build/Debug/bin/net471/spark_excel-addin64-packed.xll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Tests",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/sparkcmd.exe",
|
||||
"args": [
|
||||
"test",
|
||||
"ApiUpdateTests"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Attach",
|
||||
"type": "clr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
},
|
||||
{
|
||||
"name": "Spreader Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[spreader]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin Service Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[admin_service]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limiter Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[limiter]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MD Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[algo]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SparkVM attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"MIMode": "gdb",
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"stopOnEntry": false,
|
||||
"pythonPath": "${config:python.pythonPath}",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {},
|
||||
"envFile": "${workspaceRoot}/.env",
|
||||
"args": [
|
||||
"DEBUG"
|
||||
],
|
||||
"debugOptions": [
|
||||
"WaitOnAbnormalExit",
|
||||
"WaitOnNormalExit",
|
||||
"RedirectOutput"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Remote Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/home/bts/vsdbg/vsdbg",
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"quoteArgs": true
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
},
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Remote Launch",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "/usr/bin/dotnet",
|
||||
"args": [
|
||||
"sparkcmd.dll",
|
||||
"test",
|
||||
"test_join_create_and_takeout_market"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/home/bts/vsdbg/vsdbg",
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"quoteArgs": true
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
},
|
||||
"justMyCode": false
|
||||
}
|
||||
]
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/ninja_debug/server/sparkd/sparkd",
|
||||
"args": ["run"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/ninja_debug/src/server/sparkd",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Client Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "SDK Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark_sdk.exe",
|
||||
"args": ["md","GLBX","Future","CL", "CLZ9", "--user=bts", "--pass="],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Excel Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "C:/Program Files/Microsoft Office/Office14/EXCEL.EXE",
|
||||
"args": ["${workspaceRoot}/build/Debug/bin/net471/spark_excel-addin64-packed.xll"],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Tests",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/sparkcmd.exe",
|
||||
"args": ["test","test_filter"],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Attach",
|
||||
"type": "clr",
|
||||
"request": "attach",
|
||||
"processId":"${command:pickProcess}"
|
||||
},
|
||||
{
|
||||
"name": "SparkVM Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/server/sparkd",
|
||||
"args": ["run"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": ["bts@sparkvm"],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TFTest ",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/sdk/examples/tf_test",
|
||||
"args": [
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/sdk/examples/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Spreader Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": ["test", "[spreader]"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": ["bts@sparkvm"],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin Service Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": ["test", "[admin_service]"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": ["bts@sparkvm"],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limiter Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": ["test", "[limiter]"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": ["bts@sparkvm"],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MD Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"args": ["test","AuthToken"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/ninja_debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": ["bts@sparkvm"],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SparkVM attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "/home/bts/spark/build/ninja_debug/src/server/sparkd/sparkd",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"MIMode": "gdb",
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": ["bts@sparkvm"],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"stopOnEntry": false,
|
||||
"pythonPath": "${config:python.pythonPath}",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {},
|
||||
"envFile": "${workspaceRoot}/.env",
|
||||
"args": [ "DEBUG" ],
|
||||
"debugOptions": [
|
||||
"WaitOnAbnormalExit",
|
||||
"WaitOnNormalExit",
|
||||
"RedirectOutput"
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -7,9 +7,9 @@
|
||||
"vector": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xstring": "cpp",
|
||||
"system_error": "cpp",
|
||||
"array": "cpp",
|
||||
"string_view": "cpp"
|
||||
"system_error": "cpp",
|
||||
"array": "cpp",
|
||||
"string_view": "cpp"
|
||||
"xutility": "cpp",
|
||||
"*.ipp": "cpp"
|
||||
}
|
||||
@@ -14,21 +14,24 @@
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"group": "build"
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "server_build",
|
||||
"label": "server_build",
|
||||
"type": "shell",
|
||||
"command": ".\\tools\\buildsparkd.cmd",
|
||||
"problemMatcher": {
|
||||
"base": "$gcc",
|
||||
"problemMatcher": {
|
||||
"base": "$gcc",
|
||||
"owner": "cpp",
|
||||
"fileLocation": [
|
||||
"relative",
|
||||
"${workspaceFolder}"
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"pattern": {
|
||||
"regexp": "(.?)(home)(.?)(bts)(.?)(spark)(.?)(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)",
|
||||
"regexp": "(.?)(home)(.?)(bts)(.?)(spark)(.?)(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)",
|
||||
"file": 8,
|
||||
"line": 9,
|
||||
"column": 10,
|
||||
@@ -46,18 +49,6 @@
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "linux build (Debug)",
|
||||
"type": "shell",
|
||||
"command": "cd build/ninja_debug; time ninja",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,94 +1,67 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(spark)
|
||||
|
||||
if(WIN32)
|
||||
set(platform "windows")
|
||||
else()
|
||||
set(platform "linux")
|
||||
endif()
|
||||
if (WIN32)
|
||||
set (platform "windows")
|
||||
else ()
|
||||
set (platform "linux")
|
||||
endif ()
|
||||
|
||||
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/${CMAKE_BUILD_TYPE}")
|
||||
set(BUILD_SDK OFF CACHE BOOL "Build the sdk")
|
||||
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/${CMAKE_BUILD_TYPE}")
|
||||
|
||||
include_directories(BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
|
||||
link_directories(${SPARK_LIB})
|
||||
include_directories (BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib ${TF_INCLUDE})
|
||||
link_directories (${SPARK_LIB})
|
||||
|
||||
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")
|
||||
if (WIN32)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
||||
/MP \
|
||||
/WX /wd4251 /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 \
|
||||
/DCURL_STATICLIB \
|
||||
/D_WINSOCK_DEPRECATED_NO_WARNINGS \
|
||||
/D__TBB_NO_IMPLICIT_LINKAGE \
|
||||
/DBOOST_ALL_NO_LIB \
|
||||
/D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600")
|
||||
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} /MT")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF /LTCG")
|
||||
|
||||
# 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 ".")
|
||||
else ()
|
||||
# so that sparkd looks for libspark.so in its directory
|
||||
set (CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set (CMAKE_INSTALL_RPATH ".")
|
||||
|
||||
# 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
|
||||
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_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wno-undef")
|
||||
add_subdirectory(src/server/sparkd)
|
||||
add_subdirectory(src/lib)
|
||||
add_subdirectory(src/web)
|
||||
add_subdirectory(doc/user)
|
||||
if(BUILD_SDK)
|
||||
add_subdirectory(src/sdk)
|
||||
endif()
|
||||
add_subdirectory(src/sdk)
|
||||
add_subdirectory(src/data_files)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/server
|
||||
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
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/sdk/examples/order_plugin_example.so ${CMAKE_BINARY_DIR}/server/plugins/
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/sdk/examples/ai_order_plugin_example.so ${CMAKE_BINARY_DIR}/server/plugins/
|
||||
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libtensorflow.so ${CMAKE_BINARY_DIR}/server/plugins
|
||||
|
||||
COMMENT "Creating server runtime layout"
|
||||
DEPENDS sparkd data_files_dir)
|
||||
DEPENDS sparkd data_files_dir)
|
||||
|
||||
add_custom_target(server_layout ALL DEPENDS ${CMAKE_BINARY_DIR}/server)
|
||||
endif()
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
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
|
||||
@@ -1,36 +0,0 @@
|
||||
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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,744 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,305 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<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>
|
||||
@@ -1,152 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<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>
|
||||
@@ -1,20 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<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>
|
||||
@@ -1,90 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
<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>
|
||||
@@ -1,230 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"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": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net6.0",
|
||||
"frameworks": [
|
||||
{
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "6.0.0"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.WindowsDesktop.App",
|
||||
"version": "6.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"FormattingOptions": {
|
||||
"NewLine": "\n",
|
||||
"UseTabs": false,
|
||||
"TabSize": 3,
|
||||
"IndentationSize": 3,
|
||||
"SpacingAfterMethodDeclarationName": false,
|
||||
"SpaceWithinMethodDeclarationParenthesis": false,
|
||||
"SpaceBetweenEmptyMethodDeclarationParentheses": false,
|
||||
"SpaceAfterMethodCallName": false,
|
||||
"SpaceWithinMethodCallParentheses": false,
|
||||
"SpaceBetweenEmptyMethodCallParentheses": false,
|
||||
"SpaceAfterControlFlowStatementKeyword": true,
|
||||
"SpaceWithinExpressionParentheses": false,
|
||||
"SpaceWithinCastParentheses": false,
|
||||
"SpaceWithinOtherParentheses": false,
|
||||
"SpaceAfterCast": false,
|
||||
"SpacesIgnoreAroundVariableDeclaration": false,
|
||||
"SpaceBeforeOpenSquareBracket": false,
|
||||
"SpaceBetweenEmptySquareBrackets": false,
|
||||
"SpaceWithinSquareBrackets": false,
|
||||
"SpaceAfterColonInBaseTypeDeclaration": true,
|
||||
"SpaceAfterComma": true,
|
||||
"SpaceAfterDot": false,
|
||||
"SpaceAfterSemicolonsInForStatement": true,
|
||||
"SpaceBeforeColonInBaseTypeDeclaration": true,
|
||||
"SpaceBeforeComma": false,
|
||||
"SpaceBeforeDot": false,
|
||||
"SpaceBeforeSemicolonsInForStatement": false,
|
||||
"SpacingAroundBinaryOperator": "single",
|
||||
"IndentBraces": false,
|
||||
"IndentBlock": true,
|
||||
"IndentSwitchSection": true,
|
||||
"IndentSwitchCaseSection": true,
|
||||
"LabelPositioning": "oneLess",
|
||||
"WrappingPreserveSingleLine": true,
|
||||
"WrappingKeepStatementsOnSingleLine": true,
|
||||
"NewLinesForBracesInTypes": false,
|
||||
"NewLinesForBracesInMethods": false,
|
||||
"NewLinesForBracesInProperties": false,
|
||||
"NewLinesForBracesInAccessors": false,
|
||||
"NewLinesForBracesInAnonymousMethods": false,
|
||||
"NewLinesForBracesInControlBlocks": false,
|
||||
"NewLinesForBracesInAnonymousTypes": false,
|
||||
"NewLinesForBracesInObjectCollectionArrayInitializers": false,
|
||||
"NewLinesForBracesInLambdaExpressionBody": false,
|
||||
"NewLineForElse": false,
|
||||
"NewLineForCatch": false,
|
||||
"NewLineForFinally": false,
|
||||
"NewLineForMembersInObjectInit": true,
|
||||
"NewLineForMembersInAnonymousTypes": true,
|
||||
"NewLineForClausesInQuery": true
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
FROM spark-crypto_18.04
|
||||
|
||||
RUN \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update \
|
||||
&& apt-get install -y \
|
||||
htop \
|
||||
locales \
|
||||
source-highlight \
|
||||
powerline \
|
||||
fonts-powerline
|
||||
|
||||
|
||||
# Hide these in the .docker directory to avoid conflicts with existing repos on
|
||||
# this computer (in case a parent dir, such as $HOME, is mounted inside a
|
||||
# container)
|
||||
ARG repo_root="/home/john/Documents/repos/.docker"
|
||||
|
||||
# Create dirs for public/private repos
|
||||
USER john
|
||||
RUN \
|
||||
mkdir -p $repo_root/public \
|
||||
&& mkdir -p $repo_root/private
|
||||
|
||||
|
||||
## Get latest fish (build from source)
|
||||
# 1) get build deps
|
||||
USER root
|
||||
RUN \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update \
|
||||
&& apt-get install -y software-properties-common
|
||||
RUN \
|
||||
apt-add-repository ppa:fish-shell/release-3 \
|
||||
&& sed -i "s/^# deb/deb/g" /etc/apt/sources.list
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get build-dep -y fish
|
||||
|
||||
|
||||
# 2) Clone repo
|
||||
USER john
|
||||
RUN \
|
||||
cd $repo_root/public \
|
||||
&& git clone https://github.com/fish-shell/fish-shell.git
|
||||
|
||||
RUN \
|
||||
cd $repo_root/public/fish-shell \
|
||||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_DOCS=0 .. \
|
||||
&& cmake --build .
|
||||
|
||||
# Switch to root, rather than running inline w/ sudo cmd, to avoid having to
|
||||
# enter a password
|
||||
USER root
|
||||
RUN \
|
||||
cd $repo_root/public/fish-shell/build \
|
||||
&& make install
|
||||
USER john
|
||||
|
||||
|
||||
## Get oh-my-fish
|
||||
RUN \
|
||||
cd $repo_root/public \
|
||||
&& git clone https://github.com/oh-my-fish/oh-my-fish.git
|
||||
|
||||
RUN \
|
||||
cd $repo_root/public/oh-my-fish \
|
||||
&& ./bin/install --noninteractive --yes
|
||||
|
||||
|
||||
## Get my fish config
|
||||
RUN \
|
||||
cd $repo_root/private \
|
||||
&& git clone https://github.com/johncolvin-og/myfishconfig
|
||||
|
||||
RUN \
|
||||
cd $repo_root/private/myfishconfig \
|
||||
&& cp src/config.fish /home/john/.config/fish/ \
|
||||
&& cp src/aliases.fish /home/john/.config/fish/ \
|
||||
&& cp -r src/functions /home/john/.config/fish/ \
|
||||
&& cp -r src/themes/johncolvin /home/john/.local/share/omf/themes/ \
|
||||
&& fish --command "omf theme johncolvin"
|
||||
|
||||
|
||||
## Get my bash config (back up existing)
|
||||
RUN \
|
||||
cd $repo_root/private \
|
||||
&& git clone https://github.com/johncolvin-og/mybashconfig \
|
||||
&& cd mybashconfig \
|
||||
&& cp src/* /home/john/
|
||||
|
||||
|
||||
# Get vim files/tools
|
||||
USER root
|
||||
RUN \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update \
|
||||
&& apt-get install -y curl
|
||||
USER john
|
||||
RUN curl -fLo home/john/.vim/autoload/plug.vim --create-dirs \
|
||||
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
|
||||
|
||||
|
||||
# Some fonts look sketchy if the language isn't set to english:
|
||||
# * The powerline git glyphs in the fish prompt are all displayed as question
|
||||
# marks.
|
||||
#
|
||||
# * The shell confuses the position of the cursor, so characters are left
|
||||
# around when they should have been cleared, and the cursor's home position
|
||||
# is pushed one or two places to the right.
|
||||
#
|
||||
# * Most likely, the bad cursor position is caused by some dependencies the
|
||||
# interpretation of escape sequences have on the language setting. At this
|
||||
# point I don't even care anymore (literally took 8 hours to figure this
|
||||
# out). I just know this shit is needed to make the prompt work correctly.
|
||||
USER root
|
||||
RUN locale-gen "en_US.UTF-8"
|
||||
USER john
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
RUN fc-cache -vf
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
set this_dir (realpath (dirname (status -f)))
|
||||
set image_working_dir (realpath "$this_dir/../..")
|
||||
|
||||
set image_name $argv[1]
|
||||
if test (count $argv) -eq 0
|
||||
set image_name_cmd "$this_dir/docker_image_name.fish"
|
||||
set image_name (eval $image_name_cmd)
|
||||
end
|
||||
|
||||
docker build \
|
||||
-f "$this_dir/Dockerfile" \
|
||||
-t "$image_name" \
|
||||
"$image_working_dir"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
if test (count $argv) -gt 0
|
||||
echo $argv
|
||||
exit 0
|
||||
end
|
||||
|
||||
set image_name_cmd (realpath (dirname (status -f)))"/docker_image_name.fish"
|
||||
set image_name (eval $image_name_cmd)
|
||||
echo $image_name
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
echo "$USER""s_"(basename (git rev-parse --show-toplevel))"-dev"
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
set inst_name $argv[1]
|
||||
if test (count $argv) -eq 0
|
||||
set script_dir (realpath (dirname (status -f)))
|
||||
set inst_name (eval $script_dir"/docker_container_name.fish")
|
||||
end
|
||||
|
||||
set working_dir (realpath (pwd))
|
||||
echo $inst_name
|
||||
docker exec -w $working_dir -it "$inst_name" bash
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
function print_help_and_exit
|
||||
echo "\
|
||||
Usage: setup_builds.sh [OPTIONS] compiler build-type
|
||||
|
||||
Positionals:
|
||||
gcc Compile with gcc
|
||||
clang Compile with clang
|
||||
debug Build debug
|
||||
release Build release
|
||||
|
||||
Options:
|
||||
--compiler <clang|gcc> Specify the compiler
|
||||
--type <debug|release> Specify the type of build
|
||||
-f,--force Overwrite existing build directories
|
||||
-h,--help Print this help message and exit
|
||||
|
||||
"
|
||||
exit $argv[1]
|
||||
end
|
||||
|
||||
function assert_dir
|
||||
if test ! -d "$argv[1]"
|
||||
if test -n "$argv[2]"
|
||||
echo "Invalid variable "$argv[2]": '"$argv[1]"' is not a directory"
|
||||
else
|
||||
echo "'"$argv[1]"' is not a directory"
|
||||
end
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
# common variables
|
||||
|
||||
set tools_path (realpath (dirname (status -f)))
|
||||
set spartan_path_cmd $tools_path/spartan_path.fish
|
||||
set repo_root (eval $spartan_path_cmd "repo-root")
|
||||
set build_root "$repo_root"/"build"
|
||||
mkdir -p "$build_root"
|
||||
|
||||
# Initialize the build directory. Expected arguments: <compiler>, <build_type>
|
||||
# Note: this method assumes the variables 'repot_root' and 'build_root' have
|
||||
# already been properly initialized
|
||||
function setup_build
|
||||
assert_dir $repo_root
|
||||
assert_dir $build_root
|
||||
set compiler "$argv[1]"
|
||||
set build_type "$argv[2]"
|
||||
|
||||
if test \( -z "$build_type" \) -o \( \( "$build_type" != debug \) -a \( "$build_type" != release \) \)
|
||||
print_help_and_exit 1
|
||||
end
|
||||
|
||||
if test "$build_type" = debug
|
||||
set build_type_arg Debug
|
||||
if test "$compiler" = gcc
|
||||
set compiler_arg "/usr/lib/ccache/g++"
|
||||
else
|
||||
# set compiler_arg "/usr/lib/ccache/clang++"
|
||||
set compiler_arg "clang++"
|
||||
end
|
||||
else if test "$build_type" = release
|
||||
set build_type_arg Release
|
||||
if test "$compiler" = gcc
|
||||
set compiler_arg "g++"
|
||||
else
|
||||
set compiler_arg "clang++"
|
||||
end
|
||||
end
|
||||
|
||||
if test \( -z "$compiler" \) -o \( \( "$compiler" != gcc \) -a \( "$compiler" != clang \) \)
|
||||
print_help_and_exit 1
|
||||
end
|
||||
|
||||
set build_dest $build_root"/"$compiler"/"$build_type
|
||||
|
||||
echo "Set up build: "$compiler" "$build_type
|
||||
|
||||
if test \( -z "$force" \) -a \( -d $build_dest \)
|
||||
echo "The build directory '"$build_dest"' already exists (use -f to overwrite)"
|
||||
return 1
|
||||
end
|
||||
|
||||
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_CXX_COMPILER=$compiler_arg $repo_root
|
||||
end
|
||||
|
||||
# The while loop below removes arguments (via shift) as it parses them.
|
||||
# Additional information that needs to be extracted from the arguments must be
|
||||
# done so before the loop is executed.
|
||||
|
||||
set i 1
|
||||
while test $i -le (count $argv)
|
||||
switch $argv[$i]
|
||||
case --compiler
|
||||
set i (math "$i + 1")
|
||||
set compiler $argv[$i]
|
||||
case clang
|
||||
set compiler clang
|
||||
case gcc
|
||||
set compiler gcc
|
||||
case --type
|
||||
set i (math "$i + 1")
|
||||
set build_type $argv[$i]
|
||||
case release
|
||||
set build_type release
|
||||
case debug
|
||||
set build_type debug
|
||||
case -f
|
||||
set force 1
|
||||
case --force
|
||||
set force 1
|
||||
case -h
|
||||
print_help_and_exit 0
|
||||
case --help
|
||||
print_help_and_exit 0
|
||||
case '*'
|
||||
print_help_and_exit 1
|
||||
end
|
||||
set i (math "$i + 1")
|
||||
end
|
||||
|
||||
echo "compiler in "$compiler
|
||||
echo "build type in "$build_type
|
||||
if test -n "$compiler"
|
||||
if test -n "$build_type"
|
||||
setup_build $compiler $build_type
|
||||
else
|
||||
# all builds for the specified compiler
|
||||
setup_build $compiler debug
|
||||
setup_build $compiler release
|
||||
end
|
||||
else if test -n "$build_type"
|
||||
# all builds for the specified build type
|
||||
setup_build gcc $build_type
|
||||
setup_build clang $build_type
|
||||
else
|
||||
# all builds
|
||||
setup_build gcc debug
|
||||
setup_build gcc release
|
||||
setup_build clang debug
|
||||
setup_build clang release
|
||||
end
|
||||
@@ -1,153 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
function print_help_and_exit
|
||||
echo "\
|
||||
Usage: setup_builds.sh [OPTIONS] compiler build-type
|
||||
|
||||
Positionals:
|
||||
gcc Compile with gcc
|
||||
clang Compile with clang
|
||||
debug Build debug
|
||||
release Build release
|
||||
|
||||
Options:
|
||||
--compiler <clang|gcc> Specify the compiler
|
||||
--type <debug|release> Specify the type of build
|
||||
-f,--force Overwrite existing build directories
|
||||
-h,--help Print this help message and exit
|
||||
|
||||
"
|
||||
exit $argv[1]
|
||||
end
|
||||
|
||||
function assert_dir
|
||||
if test ! -d "$argv[1]"
|
||||
if test -n "$argv[2]"
|
||||
echo "Invalid variable "$argv[2]": '"$argv[1]"' is not a directory"
|
||||
else
|
||||
echo "'"$argv[1]"' is not a directory"
|
||||
end
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
# common variables
|
||||
|
||||
#set tools_path (readlink -f (pwd))
|
||||
#set tools_path (cd (dirname (status --current-filename)); and pwd)
|
||||
set tools_path (realpath (dirname (status -f)))
|
||||
set spartan_path_cmd $tools_path/spartan_path.fish
|
||||
set repo_root (eval $spartan_path_cmd "repo-root")
|
||||
# Don't call 'spartan_path_cmd "build"' bc it returns specific build path
|
||||
# (i.e., for a particular compiler/build type), not the root build path
|
||||
# set build_root (eval $spartan_path_cmd "build")
|
||||
set build_root "$repo_root"/"build"
|
||||
mkdir -p "$build_root"
|
||||
|
||||
# Initialize the build directory. Expected arguments: <compiler>, <build_type>
|
||||
# Note: this method assumes the variables 'repot_root' and 'build_root' have
|
||||
# already been properly initialized
|
||||
function setup_build
|
||||
assert_dir $repo_root
|
||||
assert_dir $build_root
|
||||
set compiler "$argv[1]"
|
||||
set build_type "$argv[2]"
|
||||
|
||||
if test \( -z "$build_type" \) -o \( \( "$build_type" != "debug" \) -a \( "$build_type" != "release" \) \)
|
||||
print_help_and_exit 1
|
||||
end
|
||||
|
||||
if test "$build_type" = "debug"
|
||||
set build_type_arg "Debug"
|
||||
if test "$compiler" = "gcc"
|
||||
set compiler_arg "/usr/lib/ccache/g++"
|
||||
else
|
||||
set compiler_arg "/usr/lib/ccache/clang++"
|
||||
end
|
||||
else if test "$build_type" = "release"
|
||||
set build_type_arg "Release"
|
||||
if test "$compiler" = "gcc"
|
||||
set compiler_arg "g++"
|
||||
else
|
||||
set compiler_arg "clang++"
|
||||
end
|
||||
end
|
||||
|
||||
if test \( -z "$compiler" \) -o \( \( "$compiler" != "gcc" \) -a \( "$compiler" != "clang" \) \)
|
||||
print_help_and_exit 1
|
||||
end
|
||||
|
||||
set build_dest $build_root"/"$compiler"/"$build_type
|
||||
set conan_dest $repo_root"/conan/"$compiler"_"$build_type
|
||||
|
||||
echo "Set up build: "$compiler" "$build_type
|
||||
|
||||
if test \( -z "$force" \) -a \( -d $build_dest \)
|
||||
echo "The build directory '"$build_dest"' already exists (use -f to overwrite)"
|
||||
return 1
|
||||
end
|
||||
|
||||
rm -rf "$build_dest"
|
||||
mkdir -p "$build_dest"
|
||||
mkdir -p "$conan_dest"
|
||||
cd "$build_dest"
|
||||
conan install --build missing --profile $conan_dest $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.
|
||||
# Additional information that needs to be extracted from the arguments must be
|
||||
# done so before the loop is executed.
|
||||
|
||||
set i 1
|
||||
while test $i -le (count $argv)
|
||||
switch $argv[$i]
|
||||
case '--compiler'
|
||||
set i (math "$i + 1")
|
||||
set compiler $argv[$i]
|
||||
case 'clang'
|
||||
set compiler 'clang'
|
||||
case 'gcc'
|
||||
set compiler 'gcc'
|
||||
case '--type'
|
||||
set i (math "$i + 1")
|
||||
set build_type $argv[$i]
|
||||
case 'release'
|
||||
set build_type 'release'
|
||||
case 'debug'
|
||||
set build_type 'debug'
|
||||
case '-f'
|
||||
set force 1
|
||||
case '--force'
|
||||
set force 1
|
||||
case '-h'
|
||||
print_help_and_exit 0
|
||||
case '--help'
|
||||
print_help_and_exit 0
|
||||
case '*'
|
||||
print_help_and_exit 1
|
||||
end
|
||||
set i (math "$i + 1")
|
||||
end
|
||||
|
||||
echo "compiler in "$compiler
|
||||
echo "build type in "$build_type
|
||||
if test -n "$compiler"
|
||||
if test -n "$build_type"
|
||||
setup_build $compiler $build_type
|
||||
else
|
||||
# all builds for the specified compiler
|
||||
setup_build $compiler "debug"
|
||||
setup_build $compiler "release"
|
||||
end
|
||||
else if test -n "$build_type"
|
||||
# all builds for the specified build type
|
||||
setup_build "gcc" $build_type
|
||||
setup_build "clang" $build_type
|
||||
else
|
||||
# all builds
|
||||
setup_build "gcc" "debug"
|
||||
setup_build "gcc" "release"
|
||||
setup_build "clang" "debug"
|
||||
setup_build "clang" "release"
|
||||
end
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
#basename (git rev-parse --show-toplevel)
|
||||
|
||||
function print_help_and_exit
|
||||
echo "\
|
||||
Print paths to core parts of the repository
|
||||
Usage: sparkd_path.sh SUBCOMMAND
|
||||
|
||||
Subcommands:
|
||||
build Print build path
|
||||
repo-root Print repo root path
|
||||
|
||||
"
|
||||
exit $argv[1]
|
||||
end
|
||||
|
||||
function print_build_help_and_exit
|
||||
echo "\
|
||||
Print build path
|
||||
Usage: sparkd_path.sh build [OPTIONS] compiler build-type
|
||||
|
||||
Positionals:
|
||||
gcc Print gcc build path
|
||||
clang Print clang build path
|
||||
debug Print debug build path
|
||||
release Print release build path
|
||||
|
||||
Options:
|
||||
--compiler <clang|gcc> Specify the compiler
|
||||
--type <debug|release> Specify the type of build
|
||||
-h,--help Print this help message and exit
|
||||
|
||||
"
|
||||
exit $argv[1]
|
||||
end
|
||||
|
||||
function print_repo_root
|
||||
git rev-parse --show-toplevel
|
||||
end
|
||||
|
||||
function run_repo_root
|
||||
print_repo_root
|
||||
end
|
||||
|
||||
function run_build
|
||||
set compiler "gcc"
|
||||
set build_type "release"
|
||||
set i 1
|
||||
while test $i -lt (count $argv)
|
||||
switch $argv[$i]
|
||||
case '--compiler'
|
||||
set i (math "$i + 1")
|
||||
set compiler $argv[$i]
|
||||
case 'clang'
|
||||
set compiler 'clang'
|
||||
case 'gcc'
|
||||
set compiler 'gcc'
|
||||
case '--type'
|
||||
set i (math "$i + 1")
|
||||
set build_type $argv[$i]
|
||||
case 'release'
|
||||
set build_type 'release'
|
||||
case 'debug'
|
||||
set build_type 'debug'
|
||||
'-h'
|
||||
print_build_help_and_exit 0
|
||||
'--help'
|
||||
print_build_help_and_exit 0
|
||||
'*'
|
||||
print_build_help_and_exit 1
|
||||
end
|
||||
set i (math "$i + 1")
|
||||
end
|
||||
if test \( $compiler = "clang" \) -o \( $compiler = "gcc" \)
|
||||
set comp_path $compiler
|
||||
else
|
||||
print_build_help_and_exit 1
|
||||
end
|
||||
set src_root (print_repo_root)
|
||||
set build_root (readlink -f "$src_root""/build")
|
||||
set build_dest $build_root"/"$compiler"/"$build_type
|
||||
echo $build_dest
|
||||
end
|
||||
|
||||
if test "$argv[1]" = "repo-root"
|
||||
print_repo_root $argv[2..-1]
|
||||
else if test "$argv[1]" = "build"
|
||||
run_build $argv[2..-1]
|
||||
else
|
||||
print_help_and_exit 1
|
||||
end
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
set image_name $argv[1]
|
||||
set cont_name $argv[2]
|
||||
|
||||
if test (count $argv) -lt 2
|
||||
if test (count $argv) -lt 1
|
||||
set image_name_cmd (realpath (dirname (status -f)))"/docker_image_name.fish"
|
||||
set image_name (eval $image_name_cmd)
|
||||
end
|
||||
set cont_name_cmd (realpath (dirname (status -f)))"/docker_container_name.fish "$image_name
|
||||
set cont_name (eval $cont_name_cmd)
|
||||
end
|
||||
|
||||
set working_dir (realpath (pwd))
|
||||
|
||||
set home_path /home/john
|
||||
set repo_path (git rev-parse --show-toplevel)
|
||||
set repo_path_out /home/john/Documents/repos/bts/(basename $repo_path)
|
||||
set working_dir $repo_path_out
|
||||
|
||||
echo "starting docker instance '"$cont_name"' (image '"$image_name"')"
|
||||
echo "working dir "$working_dir
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
--net host \
|
||||
-h (hostname) \
|
||||
-e "TZ=America/New_York" \
|
||||
--cap-add=SYS_PTRACE \
|
||||
--security-opt seccomp=unconfined \
|
||||
--name $cont_name \
|
||||
-v $repo_path:$repo_path_out \
|
||||
-u (id -u $USER) \
|
||||
-w $working_dir \
|
||||
--shm-size=4024m \
|
||||
-t \
|
||||
-i \
|
||||
-d \
|
||||
-e DISPLAY="$DISPLAY" \
|
||||
"$image_name" \
|
||||
bash
|
||||
|
||||
@@ -1,513 +0,0 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Spark Local",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"run",
|
||||
"test",
|
||||
"-a",
|
||||
"OutrightVanillaOrder"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/gcc/debug/server/",
|
||||
"environment": [
|
||||
{
|
||||
"name": "TZ",
|
||||
"value": "America/Chicago"
|
||||
}
|
||||
],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SparkVM Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"-a",
|
||||
"[ilink3]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "LD LIBRARY",
|
||||
"text": "set env LD_LIBRARY_PATH=.",
|
||||
"ignoreFailures": false
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/gcc/debug/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"run"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}/build/gcc/debug/src/server/sparkd",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Client Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "SDK Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/spark_sdk.exe",
|
||||
"args": [
|
||||
"md",
|
||||
"GLBX",
|
||||
"Future",
|
||||
"CL",
|
||||
"CLZ9",
|
||||
"--user=bts",
|
||||
"--pass="
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Excel Launch",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "C:/Program Files/Microsoft Office/Office14/EXCEL.EXE",
|
||||
"args": [
|
||||
"${workspaceRoot}/build/Debug/bin/net471/spark_excel-addin64-packed.xll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Tests",
|
||||
"type": "clr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/build/Debug/bin/net471/sparkcmd.exe",
|
||||
"args": [
|
||||
"test",
|
||||
"ApiUpdateTests"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": true,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Client Attach",
|
||||
"type": "clr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
},
|
||||
{
|
||||
"name": "Spreader Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[spreader]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MD Synthetic Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[md][synthetic]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Spartan Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[spartan_md]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Matcher Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[matcher]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin Service Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/src/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[admin_service]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limiter Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/src/server/sparkd/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[limiter]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/src/server/sparkd/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "enable pretty-printer",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MD Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/bts/spark/build/gcc/debug/server/sparkd",
|
||||
"args": [
|
||||
"test",
|
||||
"[algo]"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server/",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"preLaunchTask": "",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
},
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Skip STL",
|
||||
"text": "skip -gfi /usr/include/c++/7/bits/*.h",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SparkVM attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "/home/bts/spark/build/gcc/debug/src/server/sparkd/sparkd",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"MIMode": "gdb",
|
||||
"pipeTransport": {
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"stopOnEntry": false,
|
||||
"python": "${command:python.interpreterPath}",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {},
|
||||
"envFile": "${workspaceRoot}/.env",
|
||||
"args": [
|
||||
"DEBUG"
|
||||
],
|
||||
"debugOptions": [
|
||||
"WaitOnAbnormalExit",
|
||||
"WaitOnNormalExit",
|
||||
"RedirectOutput"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Remote Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickRemoteProcess}",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/home/bts/vsdbg/vsdbg",
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"quoteArgs": true
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
},
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Remote Launch",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "/usr/bin/dotnet",
|
||||
"args": [
|
||||
"sparkcmd.dll",
|
||||
"test",
|
||||
"test_join_create_and_takeout_market"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/bts/spark/build/gcc/debug/server",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "c:\\program files\\git\\usr\\bin\\ssh.exe",
|
||||
"pipeArgs": [
|
||||
"bts@sparkvm"
|
||||
],
|
||||
"debuggerPath": "/home/bts/vsdbg/vsdbg",
|
||||
"pipeCwd": "${workspaceRoot}",
|
||||
"quoteArgs": true
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/home/bts/spark/": "${workspaceRoot}"
|
||||
},
|
||||
"justMyCode": false
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"list": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"vector": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xstring": "cpp",
|
||||
"system_error": "cpp",
|
||||
"array": "cpp",
|
||||
"string_view": "cpp",
|
||||
"xutility": "cpp",
|
||||
"*.ipp": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Touch CMakeLists.txt",
|
||||
"type": "process",
|
||||
"promptOnClose": false,
|
||||
"isBackground": true,
|
||||
"command": "touch",
|
||||
"args": ["${workspaceRoot}/CMakeLists.txt"],
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": false,
|
||||
"revealProblems": "onProblem",
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "build_configuration",
|
||||
"type": "pickString",
|
||||
"default": "debug",
|
||||
"description": "Configuration:",
|
||||
"options": ["debug", "release"]
|
||||
},
|
||||
{
|
||||
"id": "compiler",
|
||||
"type": "pickString",
|
||||
"default": "gcc",
|
||||
"description": "Compiler",
|
||||
"options": ["clang", "gcc"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/src",
|
||||
"${workspaceRoot}/externals/linux/include"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/src",
|
||||
"${workspaceRoot}/externals/linux/include"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"compileCommands": "${workspaceFolder}/build/ninja_debug/compile_commands.json"
|
||||
},
|
||||
{
|
||||
"name": "Windows",
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"includePath": [
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/build/src",
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/local/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include"
|
||||
],
|
||||
"defines": [
|
||||
"__linux__",
|
||||
"__x86_64__"
|
||||
],
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/build/src",
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/local/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/*"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
},
|
||||
{
|
||||
"name": "WindowsQuick",
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"includePath": [
|
||||
"${workspaceRoot}/src",
|
||||
"${workspaceRoot}/build/src",
|
||||
"${workspaceRoot}/build/ninja_debug/src",
|
||||
"${workspaceRoot}/externals/windows/include",
|
||||
"${workspaceRoot}/externals/linux/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu/c++/6",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/c++/6/backward",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/local/include",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include/x86_64-linux-gnu",
|
||||
"${workspaceRoot}/externals/windows/vscode/usr/include"
|
||||
],
|
||||
"defines": [
|
||||
"__linux__",
|
||||
"__x86_64__"
|
||||
],
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceRoot}/src"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": "${workspaceRoot}/.vscode/browse.vc.db"
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
public
|
||||
@@ -1,15 +0,0 @@
|
||||
# The URL the site will be built for
|
||||
base_url = "https://api.bluetradesys.com"
|
||||
|
||||
title = "BTS Spark API"
|
||||
description = "Documentation for the BTS Spark API"
|
||||
|
||||
compile_sass = true
|
||||
|
||||
highlight_code = true
|
||||
highlight_theme = "kronuz"
|
||||
insert_anchor_links = true
|
||||
build_search_index = true
|
||||
|
||||
[extra]
|
||||
author = "Blue Trading Systems"
|
||||
@@ -1,5 +0,0 @@
|
||||
+++
|
||||
title = "BTS Spark API"
|
||||
+++
|
||||
|
||||
This is index
|
||||
@@ -1,7 +0,0 @@
|
||||
+++
|
||||
title="Client API"
|
||||
redirect_to = "client/getting-started/overview/"
|
||||
sort_by="weight"
|
||||
+++
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title="Getting Started"
|
||||
sort_by="weight"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
+++
|
||||
title = "Install Prerequisites"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
# C#/.NET
|
||||
|
||||
We target [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) so you can use .NET Framework 4.6.1+ or .NET Core 2.0+. Simply add a reference to the [Spark Nuget package](https://www.nuget.org/packages/spark_sdk/) to get started.
|
||||
|
||||
```
|
||||
dotnet new console -lang c#
|
||||
dotnet add package spark_sdk
|
||||
dotnet build
|
||||
```
|
||||
|
||||
# C++
|
||||
|
||||
The easiest way to get started with C++ is to use the Spark Server SDK to develop your application. Follow the instructions to [download and install the Spark Server SDK](/server/getting-started/install) and open the client_sdk sample project. If you want to run your C++ Client SDK application on Windows [contact us](mailto://api@bluetradesys.com) to get the required headers and binaries.
|
||||
|
||||
# JavaScript
|
||||
|
||||
We use JavaScript internally with the Spark Client API over a websocket connection but the documentation and packaging isn't ready yet. If this is something you're interested in get in touch with us at [api@bluetradesys.com](mailto:api@bluetradesys.com).
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
+++
|
||||
title = "Overview"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
The Spark Client SDK is a high level command and control API which can be used to build scripts or integrate Spark into your existing ecosystem. The API is divided into several independent **"services"** responsible for different aspects of the system. A Service can define both [remote procedure call (RPC)](/client/getting-started/services#rpc) and incremental [streaming](/client/getting-started/services#streams) data.
|
||||
|
||||
The [Spark Desktop](https://www.bluetradingsystems.com/bts-spark/) is built on top of this API so you can be assured that it is complete and well tested.
|
||||
|
||||
Spark uses [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) as an interface definition language similar to [GRPC](https://grpc.io) but backed by our custom high-performance TCP protocol. We currently support C#/.NET and C++ <!--and Javascript--> but the architecture is designed for easy extension so contact us about your specific business needs.
|
||||
|
||||
## Orders
|
||||
|
||||
Use the [OrderService](/client/services/orderservice) to send and manage orders including native exchange orders, spreader orders, and custom Algo orders created using the [Spark Server SDK](https://api.bluetradesys.com/server/).
|
||||
|
||||
## Spreader
|
||||
|
||||
Use the [SyntheticSecurityService](/client/services/syntheticsecurityservice) to create and manage synthetic spreads. Once created these spreads show up in the security and market data feeds just like exchange listed spreads.
|
||||
|
||||
## Position
|
||||
|
||||
Use the [PositionService](/client/services/positionservice) to get your position and P&L reports or add fills manually to keep the Spark system up to date with an external system.
|
||||
|
||||
## Administration
|
||||
|
||||
Use the [AdminService](/client/services/adminservice) to manage users and control limits.
|
||||
|
||||
## Market Data
|
||||
|
||||
For .NET subscribe to market data though the high level MarketDataClient interface. From C++ or JavaScript use the MarketDataRelay service directly.
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
+++
|
||||
title = "Services"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
The Spark Client SDK uses [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) to define the interface for each service in a language independent manner. Services have both functions which return a single result and streams of data which return values continuously while subscribed. This page describes the mapping from the Protocol Buffer definition to the concrete definition in each supported language.
|
||||
|
||||
# ServiceContext
|
||||
|
||||
To connect your client to the Spark Server you need to get or create a `ServiceContext` instance. A `ServiceContext` represents a connection to the Spark Server and a background thread for handling messages on that connection. Generally there should be a single `ServiceContext` per process. All of the methods on the `ServiceContext` are safe thread safe.
|
||||
|
||||
Construct a ServiceContext by calling the default constructor. The ServiceContext will find the Spark Server by loading the server configuration over an HTTP connection. To determine the URL it will search the following locations and use the first one that is present.
|
||||
|
||||
* A command line argument `-configserver <url>`
|
||||
* An environment variable `BTSCONFIG`
|
||||
* `%APPDATA%/bts/conf/spark.conf` (Windows)
|
||||
* /sparkdata/conf/spark.conf (Linux)
|
||||
* $HOME/sparkdata/conf/spark.conf (Linux)
|
||||
|
||||
If your application is running on a system with the BTS Client installed this will probably work without any further configuration. If you plan to run your client application on a separate machine we recommend setting the `BTSCONFIG` environment variable.
|
||||
|
||||
<div class="info">
|
||||
<i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i>
|
||||
If you are using the Spark Server SDK to run a local copy of the Spark server set <p><strong>BTSCONFIG = http://localhost:9000/config/</strong></p>
|
||||
</div>
|
||||
|
||||
To get a proxy for a given service call ServiceContext.locate<T>("qualifier") where T is the type of the service and "qualifier" is an optional qualifier used to disambiguate between 2 instances of the same service. The locate call cannot fail but it may return a disconnected proxy. When you make a call on the proxy you should check the call result to see if the method call succeeded.
|
||||
|
||||
# RPC
|
||||
|
||||
Here is the OrderService reduced to a single method definition. A RPC method always takes exactly 1 argument and returns 1 value. In this example the `create_order` call takes a `Create` instance and returns a `Response`.
|
||||
|
||||
```C
|
||||
service OrderService {
|
||||
rpc create_order(Create) returns (Response);
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
The `Create` and `Response` types are also defined as protocol buffer messages. Each field can either be a primitive type another message or a list or map.
|
||||
|
||||
```C
|
||||
message Create {
|
||||
OrderDefinition new_order = 1;
|
||||
double price = 2;
|
||||
uint32 quantity = 3;
|
||||
}
|
||||
|
||||
message Response {
|
||||
uint32 order_key = 1;
|
||||
OrderError error_code = 2;
|
||||
string msg = 3;
|
||||
}
|
||||
```
|
||||
|
||||
Each RPC call generates both synchronous (blocking) and asynchronous variants. In C# the asynchronous calls have the `_async` suffix and return a `Task`. In C++ the call is overloaded to either return a value synchronously or accept a callback function to be called on the ServiceContext thread when the call completes. <!-- In Javascript only async methods returning a Promise are generated because it never makes sense to make a blocking call in the browser. -->
|
||||
|
||||
To call the resulting service locate a proxy using the [ServiceContext](#servicecontext) and then call `cancel_order` or `cancel_order_async`. If you are calling the Spark API from a GUI application you should always prefer the `_async` version of the calls.
|
||||
|
||||
|
||||
### C# example
|
||||
```c#
|
||||
var ctx = new ServiceContext();
|
||||
var orders = ctx.locate<OrderService>();
|
||||
var response =
|
||||
await orders.create_order_async(
|
||||
new Create { price = 2.25, quantity = 42 });
|
||||
if (response.success) {
|
||||
Console.WriteLine($"success: {response.value}");
|
||||
}
|
||||
else {
|
||||
Console.WriteLine($"Error: {response.error_message}");
|
||||
}
|
||||
```
|
||||
### C++ example
|
||||
```cpp
|
||||
auto ctx = ServiceContext{};
|
||||
auto orders = ctx.locate<OrderService>();
|
||||
Create c;
|
||||
c.set_price(2.25);
|
||||
c.set_quantity(42);
|
||||
// Instead of providing an _async method C++ uses overloading.
|
||||
// To make a syncronous call simply omit the callback
|
||||
orders.create_order(c, [=](const Result<Response>& response) {
|
||||
if(response.success()) {
|
||||
std::cout << "success.";
|
||||
}
|
||||
else {
|
||||
std::cout << "error: " << response.error_message();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
# Streams
|
||||
|
||||
Streams allow you to subscribe to live updating data. Each stream represents a changing collection of protocol buffer objects. Similar to a database row each item has an `id` which uniquely identifies it within the collection. Updates from the Spark server can add, remove or replace entries in the collection. Since only the changed items are sent over the wire the stream can remain responsive even when it represents a large collection.
|
||||
|
||||
Streams are implemented using the language bindings for [ReativeX](http://reactivex.io/) which provide utility functions to drill down to the specific data your application needs. In C# we provide both mutable and immutable versions of the generated data types (C++ users can rely on `const`).
|
||||
|
||||
When defined in a proto file streams use the `stream` keyword on the result type.
|
||||
```C
|
||||
service OrderService {
|
||||
...
|
||||
rpc fills (FillsSub) returns (stream Fill);
|
||||
}
|
||||
```
|
||||
|
||||
### C# example
|
||||
```c#
|
||||
var sc = new ServiceContext();
|
||||
var orders = sc.locate<OrderService>();
|
||||
var fills_observable = orders.subscribei_fills();
|
||||
var unsub = fills_observable.Subscribe(update => {
|
||||
Console.WriteLine(
|
||||
"Added {0} items, Removed {1} items, Updated {2} items. Total items {3}",
|
||||
update.added.Count(),
|
||||
update.removed.Count(),
|
||||
update.changes.Count(),
|
||||
update.all.Count());
|
||||
});
|
||||
|
||||
Thread.Sleep(TimeSpan.FromMinutes(5));
|
||||
unsub.Dispose();
|
||||
```
|
||||
### C++ Example
|
||||
```cpp
|
||||
#include "lib/api/public/ServiceContext.h"
|
||||
#include "lib/api/services/OrderService.client.pb.h"
|
||||
using namespace bts::api;
|
||||
ServiceContext ctx;
|
||||
auto orders = ctx.locate<orderman::OrderService>();
|
||||
auto unsub = orders.subscribe_fills().subscribe([](const auto& update) {
|
||||
std::cout
|
||||
<< "Added " << update.added().size() << " items, "
|
||||
<< "Removed " << update.removed().size() << " items, "
|
||||
<< "Updated " << update.updated().size() << " items, "
|
||||
<< "Total items " << update.all().size() << std::endl;
|
||||
});
|
||||
std::this_thread::sleep_for(std::chrono::minutes(5));
|
||||
```
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title="Samples"
|
||||
sort_by="weight"
|
||||
weight = 30
|
||||
+++
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
+++
|
||||
title = "AdminService"
|
||||
+++
|
||||
@@ -1,3 +0,0 @@
|
||||
+++
|
||||
title = "OrderService"
|
||||
+++
|
||||
@@ -1,3 +0,0 @@
|
||||
+++
|
||||
title = "PositionService"
|
||||
+++
|
||||
@@ -1,3 +0,0 @@
|
||||
+++
|
||||
title = "SyntheticService"
|
||||
+++
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title="Services"
|
||||
#sort_by="weight"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
+++
|
||||
title = "Market Data"
|
||||
+++
|
||||
|
||||
|
||||
Use the MarketDataService to subscribe enumerate all available securities.
|
||||
|
||||
```cs
|
||||
using System;
|
||||
using System.Threading;
|
||||
using bts.api;
|
||||
using bts.api.core;
|
||||
|
||||
namespace sample {
|
||||
class Program {
|
||||
static void Main(string[] args) {
|
||||
using var context = new ServiceContext();
|
||||
var md = context.locate<MarketDataService>();
|
||||
using var sub = md.subscribe_securities().Subscribe(update => {
|
||||
foreach (var security in update.added) {
|
||||
Console.WriteLine($"Added security {security.Id}: {security.Symbol}");
|
||||
}
|
||||
});
|
||||
|
||||
Thread.Sleep(TimeSpan.FromMinutes(5));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```cpp
|
||||
#include "lib/api/public/ServiceContext.h"
|
||||
#include "spark/lib/domain_model/Security.h"
|
||||
#include "lib/api/services/MarketDataService.client.pb.h"
|
||||
#include <thread>
|
||||
|
||||
using namespace bts::api;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
ServiceContext ctx;
|
||||
auto md_service = ctx.locate<bts::api::MarketDataService>();
|
||||
auto sub = md_service.subscribe_securities().subscribe([](const auto& update) {
|
||||
for (const auto& s : update.added()) {
|
||||
std::cout << "Added security: " << s->id() << ": " << s->symbol() << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::minutes(5));
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
@@ -1,24 +0,0 @@
|
||||
+++
|
||||
title="Algo API"
|
||||
redirect_to = "server/getting-started/overview/"
|
||||
sort_by="weight"
|
||||
+++
|
||||
|
||||
Getting Started
|
||||
- Install (docker, editor)
|
||||
- Downloading
|
||||
- Write your first algo
|
||||
- Testing
|
||||
|
||||
Reference
|
||||
- Subscriptions
|
||||
- Child Orders
|
||||
- Detaching
|
||||
- Attaching
|
||||
- ...
|
||||
|
||||
Samples
|
||||
- Iceberg
|
||||
- Pro-rata
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title="Getting Started"
|
||||
sort_by="weight"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 54 KiB |
@@ -1,138 +0,0 @@
|
||||
+++
|
||||
title = "Development"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
# Visual Studio Code
|
||||
|
||||
In this section we're going to use the Remote - Containers feature of <a href="https://code.visualstudio.com/" target="_blank">Visual Studio Code<i class="fa fa-fw fa-window-restore" aria-hidden="true"></i></a> to simplify the development experience. If you are using a different editor skip to the <a href="#other-editors">other editor</a> section below.
|
||||
|
||||
## Remote - Containers
|
||||
|
||||
The Visual Studio Code Remote containers extension allows it to run a complete development environment inside the Spark SDK Docker container. The editor UI runs as a thin client on your desktop and connects to a headless instance running inside the Spark SDK Docker environment. This configuration allows us to ship a pre-configured set of [Tasks](https://code.visualstudio.com/Docs/editor/tasks) for building and testing your code.
|
||||
|
||||
Start Visual Studio Code and click on the puzzle piece icon on the left-hand side to open the extensions panel. Use the search box at the top to find the "Remote - Containers" extension and install it.
|
||||
|
||||
<img src="../vscode_remote_containers.png" width="640" />
|
||||
|
||||
## Into the Code
|
||||
|
||||
Open the examples/algo_template directory using the File->Open Folder menu option. If you opted to add it to your path during install, you could run `code .` from your command prompt.
|
||||
|
||||
When the workspace opens, you should see a notification offering to let you re-open the workspace inside the container.
|
||||
|
||||
<img src="../vscode_notification.png" width="480" />
|
||||
|
||||
The first time you open the workspace inside the container it will take a few seconds to configure the spark_sdk docker container. While the workspace is open in Visual Studio Code the docker image will also be running in the background. The container will stop automatically when you close the editor.
|
||||
|
||||
Open algo_template.cpp from the file browser on the left or by pressing ctrl-p and typing the name. Each Algo is a standard C++ class which implements **IAlgoOrder**. Placing your cursor on IAlgoOrder and pressing F12 will take you to the IAlgoOrder.h header file where you can browse the API. To learn more about how an Algo is instantiated see the [Algo Initialization](/server/ref/initialization).
|
||||
|
||||
## Compiling
|
||||
|
||||
To build press "Ctrl+Shift+B". You should see the build output at the bottom of your screen. If the build was successful the resulting algo_template.so will be automatically copied to the plugins directory where it will be loaded by the Spark server process on start.
|
||||
|
||||
<img src="../compiled.png" width="640" />
|
||||
|
||||
## Debugging
|
||||
|
||||
To debug your Algo set a breakpoint (F9) and open the Debug panel (Ctrl+Shift+D) and choose "(gdb) Launch". This will launch the Spark Server inside the container with the debugger attached.
|
||||
|
||||
<img src="../gdb_launch.png" width="380" />
|
||||
|
||||
With sparkd running you can launch the Spark Client (spark_client.cmd) and it will connect to the running server. Log in with the user "bts" and no password and open a ladder. You can now select your Algo on the order type dropdown and activate it by clicking on a price on the ladder.
|
||||
|
||||
<img src="../myalgo.png" width="150" />
|
||||
|
||||
While sparkd is running you can also access the Spark Server Admin interface on [http://localhost:9000](http://localhost:9000). Use the same "bts" login to access the admin interface. Here you can manage user and account permissions and risk limits.
|
||||
|
||||
## Starting Spark Server
|
||||
|
||||
To start the Spark Server without attaching a debugger press "Ctrl+Shift+P" and select "Tasks: Run Task" and then "Start Sparkd" and "Never scan task output" This will open a new terminal where you can see any messages logged with the **Sdk** subsystem as well as any warnings or errors. To stop the Spark server simply kill the terminal (trash can icon) or run the "Stop Sparkd" task.
|
||||
|
||||
## Next Steps
|
||||
|
||||
If you would like to understand more about how Docker is working behind the scenes continue to the [next section](#other-editors). Otherwise, continue to [Algo Registration](/server/ref/registration) to learn how Algos are registered with the Spark.
|
||||
|
||||
<hr>
|
||||
|
||||
# Other Editors
|
||||
|
||||
In this section you will be more exposed to the details of how Docker works and how to compile and test your Algo using the command line.
|
||||
|
||||
## Docker
|
||||
|
||||
Spark Server is built and runs only on Linux so you need a Linux development environment to effectively develop plug-ins for it. Docker lets you take the spark_sdk.img disk image and run it inside a virtual Linux machine running on your Windows desktop.
|
||||
|
||||
First, some terminology. A Docker "image" is a disk image containing a complete filesystem. The spark_sdk.img file you imported earlier is an image. A Docker "container" is what you get when you get when you attach this image to a running Linux system. You can connect to a running container and use it to run commands like the C++ compiler or the Spark server. Directories from your local filesystem can be mapped into the Docker container when it starts so you can easily share files.
|
||||
|
||||
### Start
|
||||
|
||||
The first step is to start the spark_sdk Docker container with the examples directory mapped so we can compile the examples inside the container. In your command prompt cd to the *examples* directory that you unzipped from the spark_sdk.zip file. Then run the following command to start the container.
|
||||
|
||||
Windows Command Prompt:
|
||||
{% clipable() %}
|
||||
docker run --rm -it -v %CD%:/examples -u bts -w /examples --shm-size 2048m --name spark_sdk -h spark_sdk --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 9000:9000 -p 9001:9001 spark_sdk bash
|
||||
{% end %}
|
||||
|
||||
**Powershell** / Linux / Mac:
|
||||
{% clipable() %}
|
||||
docker run --rm -it -v ${PWD}:/examples -u bts -w /examples --shm-size 2048m --name spark_sdk -h spark_sdk --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 9000:9000 -p 9001:9001 spark_sdk bash
|
||||
{% end %}
|
||||
|
||||
### Attach
|
||||
|
||||
The container will remain as long as this prompt is open. You can attach an additional to the running container with the following command:
|
||||
{% clipable() %}
|
||||
docker exec -it spark_sdk bash
|
||||
{% end %}
|
||||
|
||||
## Compiling
|
||||
|
||||
Let's look at the algo_template sample first. All of the samples are laid out similarly with a `build.sh` script for compiling. As long as you are running build.sh inside the spark Docker container, it automatically copies the build output to /sparkbin/plugins/ where it needs to be to get loaded by the Spark server.
|
||||
|
||||
```
|
||||
bts@spark_sdk:/examples$ cd algo_template/
|
||||
bts@spark_sdk:/examples/algo_template$ ./build.sh
|
||||
algo_template.so copied to /sparkbin/plugins/
|
||||
Restart sparkd to see changes.
|
||||
```
|
||||
|
||||
## Starting Spark Server
|
||||
|
||||
To start the Spark server `cd /sparkbin/` and run `./sparkd run`. Press Ctrl+C to stop it.
|
||||
```
|
||||
bts@spark_sdk:/sparkbin$ ./sparkd run
|
||||
2019-10-25 16:21:09.383626|262552152803600|Gen|Warn |1 |main|132 |Run.cpp:53 |dev|
|
||||
------------------------------------ Sparkd launched --------------------------------
|
||||
```
|
||||
|
||||
You will see any Sdk log messages as well as any log messages at or above Warning level from other parts of the system. If you need additional diagnostic information more details logs are stored in /sparkdata/data/logging/log. These logs will be automatically deleted when you stop the Docker container.
|
||||
|
||||
With sparkd running you can launch the Spark Client (spark_client.cmd) and it will connect to the running server. Log in with the user "bts" and no password and open a ladder. You can now select your Algo on the order type dropdown and activate it by clicking on a price on the ladder.
|
||||
|
||||
<img src="../myalgo.png" width="150" />
|
||||
|
||||
While sparkd is running you can also access the Spark Server Admin interface on [http://localhost:9000](http://localhost:9000). Use the same "bts" login to access the admin interface. Here you can manage user and account permissions and risk limits.
|
||||
|
||||
## Debugging
|
||||
|
||||
You can debug your algo using gdb from the bash command prompt.
|
||||
|
||||
```bts@spark_sdk:/sparkbin$ gdb --args ./sparkd run
|
||||
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
|
||||
Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
...
|
||||
Reading symbols from ./sparkd...done.
|
||||
(gdb) break algo_template.cpp:45
|
||||
No source file named algo_template.cpp.
|
||||
Make breakpoint pending on future shared library load? (y or [n]) y
|
||||
Breakpoint 1 (algo_template.cpp:45) pending.
|
||||
(gdb) run
|
||||
Starting program: /sparkbin/sparkd run
|
||||
```
|
||||
|
||||
If your editor supports debugging over the ssh protocol you can start sshd from inside the container.
|
||||
|
||||
## Next
|
||||
|
||||
Continue to [Algo Registration](/server/ref/registration) to learn how Algos are registered with the Spark.
|
||||
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -1,88 +0,0 @@
|
||||
+++
|
||||
title = "Download SDK"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
## Request Access 🔑
|
||||
|
||||
To start using the Server SDK you will need to request access though our sales department. Please email <a href="mailto:api@bluetradesys.com">api@bluetradesys.com</a> or call <a href="tel:919-913-0850">(919) 913-0850</a> and we will provide download credentials.
|
||||
|
||||
## Download
|
||||
|
||||
Download the latest SDK image here: [spark_sdk.zip](https://api.bluetradesys.com/download/spark_sdk.zip)
|
||||
|
||||
Unzip that folder into a working directory. Inside you should see something like this:
|
||||
|
||||
```
|
||||
spark_sdk.img
|
||||
client/
|
||||
spark_client.cmd
|
||||
examples/
|
||||
```
|
||||
|
||||
## Import
|
||||
|
||||
Import the spark_sdk image into docker using the `docker load` command.
|
||||
{% clipable() %}
|
||||
docker load < spark_sdk.img
|
||||
{% end %}
|
||||
|
||||
<div class="info">
|
||||
<i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i>
|
||||
<strong>If you see this error it means Docker Desktop is not running:</strong>
|
||||
|
||||
|
||||
error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/images/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.
|
||||
</div>
|
||||
|
||||
Confirm that the import worked by running `docker images` which should list the new image.
|
||||
```
|
||||
c:\bts> docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
bluetradingsystems/spark_sdk latest e2be89436e73 4 hours ago 3.89GB
|
||||
```
|
||||
|
||||
<!--
|
||||
## Run
|
||||
|
||||
Start the docker container by running
|
||||
```
|
||||
docker run -d -v %CD%:/work --name spark_sdk --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8000:8000 -p 8001:8001 -p 8008:8008 bluetradingsytems/spark_sdk
|
||||
```
|
||||
<div class="linux">
|
||||
<i class="fa fa-linux fa-fw" aria-hidden="true"></i>
|
||||
If you are using Linux or Mac replace <strong>%CD%</strong> with <strong>$PWD</strong>.
|
||||
</div>
|
||||
|
||||
The first time you invoke `docker run` you may be prompted to "share" your filesystem with Docker. This usually works fine but if you run into trouble, see <a href="">Docker Desktop for Windows tips</a> on avoiding common problems.
|
||||
|
||||
## Success 🎉
|
||||
Docker is now running the spark SDK image. If you are on Windows or Mac it is running inside a virtual Linux machine. You can see that is is running by typing `docker ps` to list running docker containers. If you restart the Docker Desktop application you will need to start the spark_sdk image again using `docker start spark_sdk`.
|
||||
|
||||
You should now be able to access an admin interface at http://localhost:8008/ which will let you stop and start the spark server process.
|
||||
-->
|
||||
|
||||
## Update
|
||||
|
||||
To update your Spark SDK simply download an unzip a new [spark_sdk.zip](https://api.bluetradesys.com/download/spark_sdk.zip) and use `docker load < spark_sdk.img` to overwrite the old image with the new one.
|
||||
|
||||
To preserve the old image so you can go back to it later run `docker tag spark_sdk spark_sdk:your_custom_tag` before loading the new SDK image.
|
||||
|
||||
### Re-build the Dev Container
|
||||
|
||||
If you are using Visual Studio Code you also need to rebuild the dev-container so it picks up the new image.
|
||||
|
||||
#### Inside VSCode
|
||||
To re-build from inside Visual Studio Code. Click the 'Remote Explorer' icon on the left hand side.
|
||||
You should see your spark_sdk project listed under the Containers section. Right click on it and select **rebuild-container**.
|
||||
|
||||
#### Command Line
|
||||
To re-build from the command line run `docker ps -a` and find the row with the spark_sdk image.
|
||||
```
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
54d96cfa3888 spark_sdk "/bin/sh -c 'echo Co…" About a minute ago Up About a minute 127.0.0.1:9000-9001->9000-9001/tcp quizzical_lichterman
|
||||
```
|
||||
Then run `docker rm 54d96cfa3888` (use your container id instead of 54d96cfa3888) or `docker rm quizzical_lichterman` (use your container name).
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
@@ -1,57 +0,0 @@
|
||||
+++
|
||||
title = "Install Prerequisites"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
These instructions assume you are using Microsoft Windows but you should be able to follow them on a Linux or Mac with minor modifications.
|
||||
|
||||
{% linux() %}
|
||||
When there is a significant difference on non-Windows platforms it will be called out in a box like this one.
|
||||
{% end %}
|
||||
{% info() %}
|
||||
Tips or solutions to common problems will be highlighted in a box like this.
|
||||
{% end %}
|
||||
|
||||
The minimum hardware requirements for using the SDK are:
|
||||
- **12 GB** RAM (preferably 16 GB or more)
|
||||
- 4 CPU cores
|
||||
- 20 GB free hard disk space
|
||||
|
||||
The Spark SDK uses a tool called Docker to distribute all of the tools you need to build and test your trading algorithm ("Algo"). Once you have Docker installed you can download and import the Spark SDK image and be ready to start developing your Algo in a few minutes.
|
||||
|
||||
## Docker
|
||||
|
||||
Download and install <a href="https://www.docker.com/products/docker-desktop" target="_blank">Docker Desktop for Windows/Mac. <i class="fa fa-fw fa-window-restore" aria-hidden="true"></i></a>
|
||||
|
||||
<div class="linux">
|
||||
<i class="fa fa-linux fa-fw" aria-hidden="true"></i>
|
||||
If you are using Linux follow the <a href="https://docs.docker.com/install/#supported-platforms">official install instructions for Docker for your distribution.</a>
|
||||
</div>
|
||||
|
||||
During the install Docker may ask you to enable virtualization support and reboot.
|
||||
|
||||
Once Docker Desktop is installed and running it will create an icon in your system tray area that looks like the Docker logo.
|
||||

|
||||
|
||||
Right click on the tray icon and choose 'Settings' and choose the 'Advanced' tab.
|
||||
|
||||
Ensure that the docker image has 8192 MB of memory and at least 2 cores. Memory that you assign to the docker image will not be available to Windows/Mac while Docker is running. CPU cores are shared with the host OS. Since you are going to use this image to compile your Algo it makes sense to allow Docker to use all available cores.
|
||||
|
||||
<img src="../docker_config.png" width="640" >
|
||||
|
||||
## Sharing
|
||||
|
||||
You need to give Docker access to the Windows drive where your source code is kept.
|
||||
|
||||
Open Settings -> Shared Drives and check the drive where you intend to keep your Algo source code.
|
||||
|
||||
<div class="info">
|
||||
<i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i>
|
||||
If you run into trouble with drive sharing, see <a href="https://code.visualstudio.com/docs/remote/troubleshooting#_docker-desktop-for-windows-tips">Docker Desktop for Windows tips</a> on avoiding common problems.
|
||||
</div>
|
||||
|
||||
## Editor
|
||||
|
||||
The Server SDK includes a complete configuration for C++ development with the <a href="https://code.visualstudio.com/" target="_blank">Visual Studio Code <i class="fa fa-fw fa-window-restore" aria-hidden="true"></i></a> editor. If you are a new to C++ development on a Linux system we recommend you give this a try as it's the easiest way to get up and running quickly. Of course, If you have a different editor that you prefer we fully support that as well.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,44 +0,0 @@
|
||||
+++
|
||||
title = "Overview"
|
||||
weight = 0
|
||||
+++
|
||||
|
||||
Using the **Spark Server SDK**, users can create new order types ("Algos"). In this case, users implement the new functionality in C++, producing a shared library that is loaded at run time by our Spark Server.
|
||||
|
||||
If you are interested in accessing Spark server remotely, please see the [Spark Client SDK](/client/).
|
||||
|
||||
## Speed
|
||||
|
||||
The Spark platform offers a sub-10 microsecond socket to socket response times for algorithmic trading. With the **Spark Server SDK**, you can create your order types in high-performance C++ and load them into the Spark server.
|
||||
|
||||
Since your order is running inside the Spark Server, there is virtually no overhead allowing your algorithm to take full advantage of the speed Spark offers. Hosting a high-performance language like C++ directly in the Spark server process allows it to respond to the market thousands of times faster than an Algo built using a proprietary drag and drop tool.
|
||||
|
||||
|
||||
## Easy to Get Started
|
||||
|
||||
If you are not actively developing with C++, it can be time-consuming to set up a complete development environment from scratch. That is why we provide a full development environment out of the box with [Docker](https://docker.io) so you can download and try the Server SDK quickly and easily.
|
||||
|
||||
Docker works across Windows, macOS, and Linux, so you don't need to change your development environment to try the Spark API. Docker also ensures that all of the dependencies you need are packaged together in one image, so you know it will work out of the box, no matter the platform.
|
||||
|
||||
## Implementation
|
||||
|
||||
Creating a new Algo begins with implementing a standard C++ class derived from IAlgoOrder. Start from the [algo_template](/server/samples/template) example to get going quickly.
|
||||
|
||||
The first call your new Algo receives is [do_before_launch](/server/ref/initialization#before-launch), which is an opportunity to validate parameters and allocate any long-lived resources needed during execution. Next, it receives either [do_launch](/server/ref/initialization#launch-launch-attached) in the case of a new order or [do_launch_attached](/server/ref/initialization#launch-launch-attached) if the order is attaching to an existing order.
|
||||
|
||||
The Algo receives a reference to [IAlgoServices](/server/ref/subscriptions/), which is how it calls out to the Spark system. It will use [IAlgoServices](/server/ref/subscriptions/) to subscribe to market events, launch and control child orders, and communicate its state to the larger Spark system.
|
||||
|
||||
## Fully Integrated
|
||||
|
||||
When a Spark Server plugin is loaded, it registers its exposed Algos with the Spark Server though the [init_spark_plugin](/server/ref/registration) callback. This callback allows the Algo to describe the parameters it expects so they can be automatically entered in the [Spark Client](https://www.bluetradingsystems.com/bts-spark/).
|
||||
|
||||
<img src="../myalgo.png" width="150" />
|
||||
<img src="../paramsui.png" width="460" />
|
||||
|
||||
Compose your Algo with out of the box Algos in the [Spark Algo Studio](https://www.bluetradingsystems.com/news/155-bts-algo-studio-provides-algo-library-with-customization-functionality) to create new functionality on the fly.
|
||||
|
||||
<img src="../algostudio.png" width="548" /><br />
|
||||
<img src="../iced_algo.png" width="460" />
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 93 KiB |
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title="Reference"
|
||||
sort_by="weight"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
+++
|
||||
title = "Questions"
|
||||
weight = 40
|
||||
+++
|
||||
|
||||
## I need to make a call that might take a few seconds. What is the best way to do this?
|
||||
|
||||
Create a background thread in [do_before_launch](/server/ref/initialization#before-launch) or [do_launch](/server/ref/initialization#launch-launch-attached) to do the work. Use [on_timer](/server/ref/subscriptions#timer) to poll until the result is available.
|
||||
|
||||
## I don't see the header files in the .zip file. Where are they?
|
||||
|
||||
The SDK headers are baked into the docker image along with the build tools. Once you've loaded the image with `docker load < spark_sdk.img` you can run this command to copy them out to your local file system `docker run --rm -it -v $PWD:/out spark_sdk /bin/tar -cvf /out/headers.tar /sdk/include` This will copy the headers to the current directory in headers.tar. We still recommend doing the actual build inside the docker environment but having a copy of the headers can be useful for setting up your development environment.
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
+++
|
||||
title = "Initialization"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
Each Algo derives from IAlgoOrder and overrides virtual methods to receive callbacks from the Spark system.
|
||||
|
||||
|
||||
## Before Launch
|
||||
|
||||
When an order is activated by a user or by another Algo, the first call it receives is do_before_launch. This call happens outside of the latency-sensitive path, so it's the place to validate parameters and set up data structures that the Algo might need.
|
||||
|
||||
This call returns an OrderOpResult, which allows it to fail and return an error message to its creator. If a user created this order, this message is displayed in the [Activity Log](https://www.bluetradingsystems.com/docs/bts_spark/Help/#activity-log) and across the bottom of the ladder.
|
||||
|
||||
Every SDK Algo is a "Dynamic" Algo since it's parameters are defined during [registration](/server/ref/registration/). Use the `get_if<T>` helper to retrieve a named parameter from the `order_params` collection as a `std::option<T>`. If a parameter has a valid default value you can use `std::option::value_or(...)` to set default values for missing parameters. If a parameter *must* exist or must be within a certain valid range, return an error to the caller.
|
||||
|
||||
```cpp
|
||||
OrderOpResult MyAlgo::do_before_launch(IBeforeLaunchAlgoServices& serv) {
|
||||
auto& def = serv.definition();
|
||||
auto& params = def.custom_def().dynamic().order_params();
|
||||
auto mqi = get_if<uint32_t>(params, "Min Quantity");
|
||||
if (!mqi || mqi.value() == 0)
|
||||
return OrderOpResult{
|
||||
ORDER_ERROR_INVALID_ORDER_DEFINITON,
|
||||
"Min Quantity parameter must be defined and non zero"};
|
||||
}
|
||||
```
|
||||
|
||||
<div class="info">
|
||||
<i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i>
|
||||
The parameters are defined during <a href="/server/ref/registration/">registration</a> by the <a href="/server/ref/registration/#dynamicorderdescriptor">DynamicOrderDescriptor</a>.
|
||||
</div>
|
||||
|
||||
### IBeforeLaunchAlgoServices
|
||||
|
||||
IBeforeLaunchAlgoServices is passed to `do_before_launch` and allows the Algo to query its environment.
|
||||
|
||||
```cpp
|
||||
class IBeforeLaunchAlgoServices {
|
||||
public:
|
||||
// The OrderDefinition for this algo
|
||||
virtual api::orderman::OrderDefinition const &definition() const = 0;
|
||||
|
||||
// The security this algo is paramterized with (also available from
|
||||
// definition())
|
||||
virtual api::Security const &security() const = 0;
|
||||
|
||||
// The unique order key for this algo
|
||||
virtual OrderKey order_key() const = 0;
|
||||
|
||||
// The parent key for this algo's parent or null_order_key() if the
|
||||
// algo does not have a parent
|
||||
virtual OrderKey parent_order_key() const = 0;
|
||||
|
||||
// The security identified by k or nullptr if no such security exists
|
||||
virtual api::Security const *lookup_security(SecurityKey k) const = 0;
|
||||
|
||||
// Wheter this algo is being attached to an existing order.
|
||||
// If an algo does not support attaching it can return an error
|
||||
// if is_attaching() == true from do_before_launch.
|
||||
virtual bool is_attaching() const = 0;
|
||||
|
||||
// Build a child template that can later can be used to quickly
|
||||
// launch child orders. The reserve parameter indicates how many
|
||||
// orders should be created ahead of time, before they are
|
||||
// launched. This is usefull to remove the relatively expensive
|
||||
// order creation operation to a background thread.
|
||||
virtual ChildTemplate &
|
||||
make_child_template(api::orderman::OrderDefinition const &child_def,
|
||||
size_t reserve = 1) = 0;
|
||||
|
||||
// Get the current time
|
||||
virtual TimeStamp get_time() const;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## Launch / Launch Attached
|
||||
|
||||
Depending on the state of `is_attaching()` the next call will either be `do_launch` or `do_launch_attached`. The only difference is that in `do_launch_attached` the existing OrderKey and ChildState are provided.
|
||||
|
||||
`do_launch` and `do_launch_attached` are in the latency-sensitive path and should not do more work than needed. These functions get a reference to `IAlgoServices`, which is a superset of the functionality available on `IBeforeLaunchAlgoServices`. Most Algos should store a pointer or reference to this object for managing child orders (it has a stable address).
|
||||
|
||||
Now is the time to use `IAlgoServices` to subscribe to market events that are relevant to your Algo and create any child orders that need to exist at the start of your Algo. You can safely call IAlgoServices from any `IAlgoOrder` callback.
|
||||
|
||||
To learn more about subscribing to events see [subscriptions](/server/ref/subscriptions).
|
||||
|
||||
### Things to do in the launch callback
|
||||
☑ Store a reference to IAlgoServices
|
||||
☑ Subscribe to relevant market events
|
||||
☑ Launch a child order?
|
||||
|
||||
|
||||
## Update
|
||||
|
||||
If the user or parent Algo changes the order parameters (price, size, or the custom parameters defined during registration), Spark calls the `do_update` callback with the new parameters. It is up to the Algo to decide how to apply the new parameters to update the running state. It can do this by canceling, changing, or adding new child orders.
|
||||
|
||||
|
Before Width: | Height: | Size: 46 KiB |
@@ -1,88 +0,0 @@
|
||||
+++
|
||||
title = "Child Orders"
|
||||
weight = 30
|
||||
+++
|
||||
|
||||
Every Algo must, at some point, launch a child order to be useful. Each child order can be another Algo or regular exchange order. When the child order is updated or filled, those changes are also sent to the parent.
|
||||
|
||||
|
||||
# Templates
|
||||
|
||||
Since launching a child order is one of the most latency-sensitive things an Algo can do, the Server SDK enables you to create a child template. An order template prepares an order based on a known OrderDefinition and gets it ready to send on a background thread. When the Algo determines it is time to send the order, it only needs to provide the price and quantity to complete and send the order. If an Algo expects to send multiple child orders, it can reserve more than one. Preparing a child template is typically done in [do_before_launch](http://127.0.0.1:1111/server/ref/initialization/#before-launch) callback.
|
||||
|
||||
```cpp
|
||||
virtual ChildTemplate&
|
||||
IBeforeLaunchAlgoServices::make_child_template(
|
||||
api::orderman::OrderDefinition const &child_def,
|
||||
size_t reserve = 1);
|
||||
```
|
||||
|
||||
# Launch
|
||||
|
||||
IAlgoServices provides two overloads for launching child orders. By default, launching a child order automatically subscribes the Algo to its state changes.
|
||||
|
||||
Launch a child order from a template if you have one prepared. This is the fastest option.
|
||||
```cpp
|
||||
OrderKey IAlgoServices::launch_child(ChildTemplate&, Price, Quantity, bool subscribe = true);
|
||||
```
|
||||
Launch a child order by constructing an OrderDefinition as needed.
|
||||
```cpp
|
||||
OrderKey launch_child(OrderDefinition const &, Price, Quantity, bool subscribe = true);
|
||||
```
|
||||
|
||||
When a child is launched its `OrderKey` is returned to the caller. This ID can be used to update, cancel, or detach the child order.
|
||||
|
||||
## Update
|
||||
|
||||
To update an existing child order, call update_child and pass an Update. The Update type lets you change the price, size or the entire OrderDefinition. You only need to specify the fields that you intend to update so only set the price() field if that is what you are changing.
|
||||
|
||||
```cpp
|
||||
void IAlgoServices::update_child(OrderKey child, api::orderman::Update const &);
|
||||
```
|
||||
|
||||
## Cancel
|
||||
|
||||
To cancel an existing child order call `cancel_child`. When the order is canceled you will receive an update though the `on_child_change` callback.
|
||||
|
||||
```cpp
|
||||
void IAlgoServices::cancel_child(OrderKey child);
|
||||
```
|
||||
|
||||
## Detach
|
||||
|
||||
The lifetime of a child order is tied to its parent. If a parent is canceled or completed child orders are automatically stopped as well. If the Algo needs to launch an order that will continue after the Algo ends use `detach_child` to sever the connection. This order hierarchy can be viewed in the Spark [Order Book](https://www.bluetradingsystems.com/docs/bts_spark/Trading/#order-book).
|
||||
|
||||
```cpp
|
||||
void IAlgoServices::detach_child(OrderKey child);
|
||||
```
|
||||
To detach all children at once use `detach_all_children`.
|
||||
|
||||
```cpp
|
||||
void IAlgoServices::detach_all_children();
|
||||
```
|
||||
|
||||
# Child Updated
|
||||
|
||||
When a child order is updated the parent receives the `on_child_change` callback with an updated ChildState object.
|
||||
|
||||
```cpp
|
||||
void on_child_change(OrderKey, ChildState const &) override;
|
||||
|
||||
struct ChildState {
|
||||
Price price;
|
||||
Quantity quantity;
|
||||
Quantity total_fills;
|
||||
Price avg_price;
|
||||
Quantity last_fills;
|
||||
Price last_price;
|
||||
ChildStatus status;
|
||||
Quantity fills_at_attach_time;
|
||||
};
|
||||
```
|
||||
|
||||
<!--
|
||||
To talk about:
|
||||
- updating fills (update_fill_state)
|
||||
- handling child finished (unexpected cancel)
|
||||
-->
|
||||
|
||||
|
Before Width: | Height: | Size: 7.2 KiB |
@@ -1,92 +0,0 @@
|
||||
+++
|
||||
title = "Registration"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
When Spark Server starts, it loads all plugins listed in the /sparkbin/plugins directory and calls an exported function named `init_spark_plugin` which must have the following signature.
|
||||
|
||||
```cpp
|
||||
extern "C" void init_spark_plugin(bts::SparkServices &serv) { }
|
||||
```
|
||||
|
||||
The `init_spark_plugin` function registers the Algo with a DynamicOrderDescriptor. Once registered, the Algo appears in the [Spark ladder](https://www.bluetradingsystems.com/docs/bts_spark/Trading/#ladder) and the [Algo Studio](https://www.bluetradingsystems.com/docs/bts_spark/Trading/#algo-studio).
|
||||
|
||||
To register an Algo call `register_dynamic_algo_order` on the provided bts::SparkServices instance. This function takes the DynamicOrderDescriptor and a function that is called to construct the IAlgoOrder. A single init_spark_plugin can call register_dynamic_algo_order multiple times to register multiple Algos.
|
||||
|
||||
The DynamicOrderDescriptor must have a dynamic_order_type (name), or the registration will fail.
|
||||
|
||||
```cpp
|
||||
DynamicOrderDescriptor desc;
|
||||
desc.set_dynamic_order_type("My Algo");
|
||||
auto result =
|
||||
serv.register_dynamic_algo_order(
|
||||
desc, []() { return std::make_unique<MyAlgo>(); });
|
||||
if (result != bts::AlgoRegistrationResult::SUCCESS) {
|
||||
// Algo failed to register
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## DynamicOrderDescriptor
|
||||
|
||||
The DynamicOrderDescriptor describes the type of parameters that the Algo accepts. These inputs can come either from the user manually entering them or from a parent Algo. Spark Algos are composable, so one Algo can activate another. See [Child Orders](/server/ref/orders) for more on how to activate custom order types as child orders.
|
||||
|
||||
Add parameters to the DynamicOrderDescriptor by calling `add_param_desc()` and setting the name and parameter type.
|
||||
|
||||
```cpp
|
||||
*desc.add_param_desc() = param_bool("Enable Feature");
|
||||
*desc.add_param_desc() = param_uint32("Feature Quantity");
|
||||
```
|
||||
|
||||
The above parameters look like this when rendered in the Spark ladder.
|
||||
|
||||
<img src="../paramsui.png" width="460" />
|
||||
|
||||
And like this when viewed in the Spark order book.
|
||||
|
||||
<img src="../orderbook_truncated.png" width="988" />
|
||||
|
||||
Each descriptor can be one of the following types:
|
||||
```
|
||||
// Primitive
|
||||
int32
|
||||
uint32
|
||||
double
|
||||
string
|
||||
bool
|
||||
// Complex
|
||||
Order
|
||||
Array
|
||||
Struct
|
||||
```
|
||||
|
||||
**Currently the Spark UI only renders parameters with primitive types.** The complex types can only be provided by a parent order.
|
||||
|
||||
### Order
|
||||
|
||||
This parameter type indicates that another order type parameterizes this Algo. When the Algo needs to create a child order, it can use this parameter type to create a custom order type instead of defaulting to a limit order.
|
||||
|
||||
For example, an Algo might be designed to wait for a specific market condition before putting in an order. Instead of placing a limit order when the condition is met, the user can specify that it should an IceBerg order. The Algo doesn't need special logic to handle different child order types.
|
||||
|
||||
### Array
|
||||
|
||||
An array parameter is a collection of the same type of parameter. If your Algo needed to behave differently depending on a table of prices, you could send that list in though an array parameter.
|
||||
```cpp
|
||||
*desc.add_param_desc() =
|
||||
param_array("Price Points",
|
||||
param_double("unused").param_type());
|
||||
```
|
||||
|
||||
### Struct
|
||||
|
||||
A struct parameter is a set of named parameter types similar to the entire DynamicOrderDescriptor. The struct parameter type can be combined with the array type to handle tabular data.
|
||||
|
||||
```cpp
|
||||
*desc.add_param_desc() =
|
||||
param_array("Step Table",
|
||||
param_struct("", {
|
||||
param_uint32("Market Quantity"),
|
||||
param_uint32("Order Quantity")
|
||||
}).param_type());
|
||||
```
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
+++
|
||||
title = "Subscriptions"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
An Algo exists to observe changes in the market and respond to them. When the Algo is [launched](1/server/ref/initialization/#launch-launch-attached) it uses IAlgoServices to subscribe to the events it needs to operate. Each subscribe call is paired with a matching unsubscribe call, which takes the same argument to unsubscribe.
|
||||
|
||||
# Book
|
||||
|
||||
Subscribe to book updates for the specified security call use subscribe_book and unsubscribe book.
|
||||
```cpp
|
||||
// Subscribe to book updates for the specified security
|
||||
void IAlgoServices::subscribe_book(SecurityKey);
|
||||
void IAlgoServices::unsubscribe_book(SecurityKey);
|
||||
|
||||
// You implement
|
||||
virtual void on_book(SecurityKey, Book const &) override;
|
||||
```
|
||||
Get the `SecurityKey` of the current security using:
|
||||
```cpp
|
||||
services.subscribe_book(SecurityKey(algo_services().security().id()));
|
||||
```
|
||||
If your Algo needs to subscribe to other securities, their keys must be passed in as parameters.
|
||||
|
||||
|
||||
To get the details of a security use
|
||||
```cpp
|
||||
api::Security const* IBeforeLaunchAlgoServices::lookup_security(SecurityKey k) const = 0;
|
||||
```
|
||||
|
||||
# Timer
|
||||
To handle time-based logic, an Algo can subscribe to a common timer event that is invoked once every 10 milliseconds. Use the TimeStamp class from `bts_chrono.h` to efficiently handle time calculations.
|
||||
```cpp
|
||||
// Subscribe to a periodic 10ms timer
|
||||
void IAlgoServices::subscribe_timer();
|
||||
// You implement
|
||||
virtual void on_timer() override;
|
||||
```
|
||||
|
||||
# Ticker
|
||||
The status callback is called when the market for this security opens, closes, or has some other state transition.
|
||||
```cpp
|
||||
// Subscribe to trade ticker
|
||||
void IAlgoServices::subscribe_ticker(SecurityKey);
|
||||
// You implement
|
||||
void on_ticker(SecurityKey, TradeVector const&) override;
|
||||
```
|
||||
|
||||
# Trading Status
|
||||
|
||||
The status callback is called when the market for this security opens, closes, or has some other state transition.
|
||||
```cpp
|
||||
// Subscribe to security trading status
|
||||
void IAlgoServices::subscribe_status(SecurityKey);
|
||||
// You implement
|
||||
virtual void on_status(SecurityKey, co2::TradingStatus) override;
|
||||
```
|
||||
|
||||
# Child Orders
|
||||
|
||||
When an Algo launches a child order, it is subscribed to the changes on that child automatically. If the Algo unsubscribes from those changes, it can re-subscribe using this method.
|
||||
|
||||
```cpp
|
||||
// Subscribe to child order updates for the specified child order.
|
||||
void IAlgoServices::subscribe_child_change(OrderKey);
|
||||
// You implement
|
||||
virtual void on_child_change(OrderKey, ChildState const &) override;
|
||||
```
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
+++
|
||||
title="Samples"
|
||||
sort_by="weight"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
+++
|
||||
title = "Join"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
|
||||
Join starts working N ticks away from the market (usually) and then watches for the opposite inside to become same side inside market; if there is then enough size on that market, it will join.
|
||||
|
||||
<div class="info">
|
||||
<i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i>
|
||||
This sample is part of the Server SDK examples included in the <a href="/server/getting-started/download/">spark_sdk.zip download</a>.
|
||||
</div>
|
||||
|
||||
```cpp
|
||||
#include "spark/lib/config/config.h"
|
||||
#include "spark/lib/config/protos/system.pb.h"
|
||||
#include "spark/lib/domain_model/Security.h"
|
||||
#include "spark/lib/orderman/orders/server/IAlgoOrder.h"
|
||||
#include "spark/lib/orderman/orders/server/IAlgoServices.h"
|
||||
#include "spark/lib/plugin/SparkServices.h"
|
||||
|
||||
#include "spark/lib/orderman/order_factory/IOrderFactory.h"
|
||||
#include "spark/lib/orderman/orderman_utils/Book.h"
|
||||
#include "spark/lib/orderman/orderman_utils/orderman_utils.h"
|
||||
#include "spark/lib/utils/PBUtils.h"
|
||||
|
||||
using namespace bts::api::orderman;
|
||||
using namespace bts::orderman;
|
||||
|
||||
namespace bts {
|
||||
namespace order_example {
|
||||
|
||||
// Join starts working N ticks away from the market (usually) and then
|
||||
// watches for the opposite inside to become same side inside market;
|
||||
// if there is then enough size on that market, it will join.
|
||||
class DynamicJoin : public IAlgoOrder {
|
||||
public:
|
||||
DynamicJoin();
|
||||
~DynamicJoin();
|
||||
|
||||
OrderOpResult do_before_launch(IBeforeLaunchAlgoServices &) override;
|
||||
void do_launch(IAlgoServices &) override;
|
||||
void do_launch_attached(IAlgoServices &, OrderKey, ChildState) override;
|
||||
void do_update(api::orderman::Update const &) override;
|
||||
void on_book(SecurityKey, Book const &) override;
|
||||
void on_child_change(OrderKey, ChildState const &) override;
|
||||
|
||||
private:
|
||||
enum class Status;
|
||||
struct PImpl;
|
||||
std::unique_ptr<PImpl> me;
|
||||
|
||||
IAlgoServices &algo_services() const;
|
||||
void try_to_join();
|
||||
};
|
||||
|
||||
// The three stages our algo goes through. We start by waiting to
|
||||
// observe the book for our security (WAITING_FOR_MD). Once we have a
|
||||
// book we use it to derive our target price and we continue to
|
||||
// monitor the book to see if we should join the market
|
||||
// (WAITING_TO_JOIN). Once the size and price constraints are met we
|
||||
// jump to the target price (JOINED). We remain in the JOINED state
|
||||
// until our order is filled or canceled.
|
||||
enum class DynamicJoin::Status { WAITING_FOR_MD, WAITING_TO_JOIN, JOINED };
|
||||
|
||||
// All state information needed for this algo
|
||||
struct DynamicJoin::PImpl {
|
||||
IAlgoServices *algo_services;
|
||||
Quantity min_quantity_to_join;
|
||||
Status status = Status::WAITING_FOR_MD;
|
||||
OrderKey child_key = null_order_key();
|
||||
ChildTemplate *child_template = nullptr;
|
||||
Book book_at_inception;
|
||||
Book last_book;
|
||||
};
|
||||
|
||||
DynamicJoin::DynamicJoin() : me(new PImpl()) {}
|
||||
DynamicJoin::~DynamicJoin() {}
|
||||
IAlgoServices &DynamicJoin::algo_services() const { return *me->algo_services; }
|
||||
|
||||
// This is called outside of the latency sensitive path
|
||||
// once. Expensive initialization should be done here, rather than
|
||||
// in do_launch()
|
||||
OrderOpResult DynamicJoin::do_before_launch(IBeforeLaunchAlgoServices &serv) {
|
||||
auto &def = serv.definition();
|
||||
bts_assert(def.has_custom_def());
|
||||
bts_assert(def.custom_def().has_dynamic());
|
||||
|
||||
// Validate our parameters, returning an error if we find a
|
||||
// problem. If an error is returned here the order will be
|
||||
// abandoned.
|
||||
auto ¶ms = def.custom_def().dynamic().order_params();
|
||||
auto mqi = get_if<uint32_t>(params, "Min Quantity");
|
||||
if (!mqi || mqi.value() == 0) {
|
||||
return OrderOpResult{
|
||||
ORDER_ERROR_INVALID_ORDER_DEFINITON,
|
||||
"Min Quantity parameter must be defined and non zero"};
|
||||
}
|
||||
|
||||
me->min_quantity_to_join = Quantity(mqi.value());
|
||||
|
||||
if (!serv.is_attaching()) {
|
||||
// If we are not attaching, create a child template so we can
|
||||
// quickly launch our child when the time comes.
|
||||
|
||||
// We will be sending a limit order with the same side,
|
||||
// security, trader, account, etc, as this algo order, so just
|
||||
// copy our definition to the child definition to start with.
|
||||
auto child_def = def;
|
||||
// Now add a limit order component to mark our child as a limit
|
||||
// order. Limit orders do not require any extra parameters
|
||||
// beyond those already inherited from this algo order
|
||||
// (i.e. beyond what we obtained through serv.definition()) so
|
||||
// we can just use a default constructed LimitOrderDefinition.
|
||||
*child_def.mutable_custom_def()->mutable_limit() = LimitOrderDefinition{};
|
||||
// Now just build the child template and cache it for future use
|
||||
me->child_template = &(serv.make_child_template(child_def));
|
||||
} else {
|
||||
// If we are attaching to an existing order then we do not need
|
||||
// to spawn a new child, so there is no need to setup a child
|
||||
// template
|
||||
}
|
||||
|
||||
// All is good, return a default constructed OrderOpResult which
|
||||
// indicates success.
|
||||
return {};
|
||||
}
|
||||
|
||||
// Called in the latency sensitive path, once, when the algo is first
|
||||
// launched.
|
||||
void DynamicJoin::do_launch(IAlgoServices &services) {
|
||||
// Cache our algo services
|
||||
me->algo_services = &services;
|
||||
|
||||
LOG(OrderMan, Diag, "Lauching DynamicJoin k: {} ",
|
||||
algo_services().order_key().value());
|
||||
|
||||
// Launch our child order
|
||||
me->child_key =
|
||||
services.launch_child(*me->child_template, algo_services().price(),
|
||||
algo_services().quantity());
|
||||
|
||||
// Subscribe to market data
|
||||
services.subscribe_book(SecurityKey(algo_services().security().id()));
|
||||
}
|
||||
|
||||
// Called in the latency sensitive path, once, when the algo is first
|
||||
// launched. In this case the algo is provided with an existing order
|
||||
// it is now responsible for managing.
|
||||
void DynamicJoin::do_launch_attached(IAlgoServices &services,
|
||||
OrderKey attached_order, ChildState st) {
|
||||
// The order was launched and attached to an existing order, with
|
||||
// key 'attached_order' and current state 'st'
|
||||
|
||||
// Cache our algo services
|
||||
me->algo_services = &services;
|
||||
|
||||
LOG(OrderMan, Diag,
|
||||
"Lauching DynamicJoin k: {} Attached to existing order: {}",
|
||||
algo_services().order_key().value(), attached_order.value());
|
||||
|
||||
// Cache the key of the attached order we will be managing
|
||||
me->child_key = attached_order;
|
||||
|
||||
// Subscribe to market data
|
||||
services.subscribe_book(SecurityKey(services.security().id()));
|
||||
|
||||
// Simulate a child change so we can update our own state to
|
||||
// reflect that of the child order we attached to. From this point
|
||||
// forward there is no distinction between an algo instance that
|
||||
// spawned a new child order and one that attached to an existing
|
||||
// order.
|
||||
on_child_change(attached_order, st);
|
||||
}
|
||||
|
||||
// Called when a human (or a supervising algo) updates a parameter for
|
||||
// this algo. The implementation validates the update and depending on
|
||||
// the validation outcome either applies the update or terminates the
|
||||
// algo.
|
||||
void DynamicJoin::do_update(api::orderman::Update const &update) {
|
||||
LOG(OrderMan, Diag, "DynamicJoin k: {} receiving update: {}",
|
||||
algo_services().order_key().value(), utils::pb::to_string(update));
|
||||
|
||||
// Validate update
|
||||
if (update.quantity() == 0) {
|
||||
// An invalid update has been detected so we terminate the
|
||||
// algo, signaling an error. Any child orders launched by
|
||||
// this algo will also be terminated.
|
||||
algo_services().terminate_error("Invalid update");
|
||||
return;
|
||||
}
|
||||
|
||||
// Updates have two parts, a standard part consisting of price and
|
||||
// size and present in all updates, and an optional part that is
|
||||
// specific to the algo in question. Below we check for the
|
||||
// existance of this optional part and validate if present.
|
||||
bool has_new_min_qty = false;
|
||||
if (update.has_custom()) {
|
||||
auto ¶ms = update.custom().dynamic().order_params();
|
||||
auto mqi = params.find("Min Quantity");
|
||||
|
||||
if (mqi == params.end() || mqi->second.as_uint32() == 0) {
|
||||
algo_services().terminate_error(
|
||||
"Minimum quantity to join must be greater than 0");
|
||||
return;
|
||||
}
|
||||
has_new_min_qty = true;
|
||||
me->min_quantity_to_join = Quantity(mqi->second.as_uint32());
|
||||
}
|
||||
|
||||
// Update is good, forward it to our child
|
||||
Update child_update;
|
||||
child_update.set_price(update.price());
|
||||
child_update.set_quantity(update.quantity());
|
||||
algo_services().update_child(me->child_key, child_update);
|
||||
|
||||
// Try to join again if conditions changed
|
||||
if (me->status == Status::WAITING_TO_JOIN && has_new_min_qty)
|
||||
try_to_join();
|
||||
}
|
||||
|
||||
// Called when the book for the specified security has changed
|
||||
void DynamicJoin::on_book(SecurityKey, Book const &b) {
|
||||
|
||||
// Cache the book, so we can reffer to it in the event of a
|
||||
// parameter change that might allow us to join
|
||||
me->last_book = b;
|
||||
|
||||
LOG(OrderMan, Diag, "DynamicJoin order {} on book. BID: {}@{} ASK: {}@{}",
|
||||
algo_services().order_key().value(), b.side(api::SIDE_BUY)[0].size(),
|
||||
b.side(api::SIDE_BUY)[0].price(), b.side(api::SIDE_SELL)[0].size(),
|
||||
b.side(api::SIDE_SELL)[0].price());
|
||||
|
||||
switch (me->status) {
|
||||
case Status::WAITING_FOR_MD: {
|
||||
|
||||
auto other_side =
|
||||
securities::other_side(algo_services().definition().side());
|
||||
auto &other_side_top = me->last_book.side(other_side)[0];
|
||||
|
||||
if (other_side_top.size() > 0) {
|
||||
// First time we get the opposite side market, we will use
|
||||
// this price as the target price for the join
|
||||
me->status = Status::WAITING_TO_JOIN;
|
||||
me->book_at_inception = b;
|
||||
LOG(OrderMan, Diag,
|
||||
"JoinOrder order {} receiving first book: {} Target: {}",
|
||||
algo_services().order_key().value(),
|
||||
me->min_quantity_to_join.value(), other_side_top.price());
|
||||
try_to_join();
|
||||
}
|
||||
} break;
|
||||
case Status::JOINED:
|
||||
// Nothing to do at this point
|
||||
break;
|
||||
case Status::WAITING_TO_JOIN:
|
||||
// Check if we reached the target and join if so
|
||||
try_to_join();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Given the current book, our target price and our min quantity
|
||||
// parameter, join if appropriate
|
||||
void DynamicJoin::try_to_join() {
|
||||
bts_assert(me->status == Status::WAITING_TO_JOIN);
|
||||
|
||||
auto my_side = algo_services().definition().side();
|
||||
auto other_side = securities::other_side(my_side);
|
||||
auto &my_side_psz = me->last_book.side(my_side)[0];
|
||||
auto &opposite_at_inception_psz = me->book_at_inception.side(other_side)[0];
|
||||
|
||||
if (my_side_psz.size() &&
|
||||
my_side_psz.size() >= me->min_quantity_to_join.value() &&
|
||||
securities::is_equal_or_better(
|
||||
my_side, Price(my_side_psz.price()),
|
||||
Price(opposite_at_inception_psz.price()))) {
|
||||
|
||||
// Time to update our child to join the market
|
||||
Update child_update;
|
||||
child_update.set_price(my_side_psz.price());
|
||||
child_update.set_quantity(algo_services().quantity().value());
|
||||
algo_services().update_child(me->child_key, child_update);
|
||||
me->status = Status::JOINED;
|
||||
|
||||
LOG(OrderMan, Diag, "DynamicJoin order {} joined: {}@{}",
|
||||
algo_services().order_key().value(),
|
||||
algo_services().quantity().value(), my_side_psz.price());
|
||||
|
||||
} else {
|
||||
LOG(OrderMan, Diag,
|
||||
"JoinOrder order {} still waiting to join. Order: {}@{} Top of "
|
||||
"the book: {}@{} Target: {}@{}",
|
||||
algo_services().order_key().value(),
|
||||
algo_services().quantity().value(), algo_services().price().value(),
|
||||
my_side_psz.size(), my_side_psz.price(),
|
||||
me->min_quantity_to_join.value(), opposite_at_inception_psz.price());
|
||||
}
|
||||
}
|
||||
|
||||
// Our child reported a change:
|
||||
void DynamicJoin::on_child_change(OrderKey, ChildState const &st) {
|
||||
// Our fill quantity and price is always a reflection of our
|
||||
// child's state
|
||||
algo_services().update_fill_state(st.total_fills, st.last_price);
|
||||
|
||||
switch (st.status) {
|
||||
case ChildStatus::WORKING:
|
||||
// Child order is still working, nothing to do
|
||||
return;
|
||||
case ChildStatus::COMPLETED:
|
||||
// Child order completed, we should also complete
|
||||
algo_services().complete();
|
||||
return;
|
||||
case ChildStatus::CANCELED:
|
||||
// Child order unexpectedly canceled, signal an error and
|
||||
// terminate
|
||||
algo_services().terminate_error("Unexpected child cancel");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This is called by the spark daemon at startup. In this call we
|
||||
// describe our algo's parameters and register a factory function to
|
||||
// create an instance of the algo.
|
||||
extern "C" void init_spark_plugin(bts::SparkServices &serv) {
|
||||
using namespace bts;
|
||||
|
||||
DynamicOrderDescriptor join_desc;
|
||||
|
||||
// Start by naming our order type
|
||||
join_desc.set_dynamic_order_type("dyn join");
|
||||
|
||||
// Now add a single unsigned int parameter, Min Quantity, that will
|
||||
// determine the minimum quantity that must exist in the book in
|
||||
// order for us to join the market.
|
||||
*join_desc.add_param_desc() = param_uint32("Min Quantity");
|
||||
|
||||
// Associate the descriptor with a builder function and register
|
||||
// that with the Spark server.
|
||||
auto result =
|
||||
serv.register_dynamic_algo_order(
|
||||
join_desc, []() { return std::make_unique<DynamicJoin>(); });
|
||||
|
||||
if (result != bts::AlgoRegistrationResult::SUCCESS) {
|
||||
// The join_desc has errors
|
||||
// Check the error log for more details
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace order_example
|
||||
} // namespace bts
|
||||
|
||||
```
|
||||
@@ -1,146 +0,0 @@
|
||||
+++
|
||||
title = "Template"
|
||||
weight = 5
|
||||
+++
|
||||
|
||||
A mostly blank Algo template that can be used as a jump-start for developing a new Algo.
|
||||
|
||||
<div class="info">
|
||||
<i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i>
|
||||
This sample is part of the Server SDK examples included in the <a href="/server/getting-started/download/">spark_sdk.zip download</a>.
|
||||
</div>
|
||||
|
||||
```cpp
|
||||
#include "spark/lib/config/config.h"
|
||||
#include "spark/lib/config/protos/system.pb.h"
|
||||
#include "spark/lib/domain_model/Security.h"
|
||||
#include "spark/lib/orderman/orders/algo/IAlgoOrder.h"
|
||||
#include "spark/lib/orderman/orders/algo/IAlgoServices.h"
|
||||
#include "spark/lib/plugin/SparkServices.h"
|
||||
|
||||
#include "spark/lib/orderman/order_factory/IOrderFactory.h"
|
||||
#include "spark/lib/orderman/orderman_utils/Book.h"
|
||||
#include "spark/lib/orderman/orderman_utils/orderman_utils.h"
|
||||
#include "spark/lib/utils/PBUtils.h"
|
||||
|
||||
using namespace bts::api::orderman;
|
||||
using namespace bts::orderman;
|
||||
|
||||
namespace bts {
|
||||
namespace order_example {
|
||||
|
||||
// MyAlgo is a blank IAlgoOrder which you can copy when starting a new Algo
|
||||
class MyAlgo : public IAlgoOrder {
|
||||
public:
|
||||
MyAlgo();
|
||||
~MyAlgo();
|
||||
|
||||
OrderOpResult do_before_launch(IBeforeLaunchAlgoServices &) override;
|
||||
void do_launch(IAlgoServices &) override;
|
||||
void do_launch_attached(IAlgoServices &, OrderKey, ChildState) override;
|
||||
void do_update(api::orderman::Update const &) override;
|
||||
void on_book(SecurityKey, Book const &) override;
|
||||
void on_child_change(OrderKey, ChildState const &) override;
|
||||
|
||||
private:
|
||||
IAlgoServices* algo_services;
|
||||
ChildTemplate *child_template = nullptr;
|
||||
OrderKey child_key = null_order_key();
|
||||
};
|
||||
|
||||
|
||||
MyAlgo::MyAlgo() : algo_services(nullptr) {}
|
||||
MyAlgo::~MyAlgo() {}
|
||||
|
||||
// This is called outside of the latency sensitive path.
|
||||
// Expensive initialization should be done here, rather than in do_launch()
|
||||
OrderOpResult MyAlgo::do_before_launch(IBeforeLaunchAlgoServices &serv) {
|
||||
LOG(Sdk,Info, "MyAlgo: do_before_launch");
|
||||
// If we are not attaching, create a child template so we can
|
||||
// quickly launch our child when the time comes.
|
||||
if (!serv.is_attaching()) {
|
||||
// We will be sending a limit order with the same side,
|
||||
// security, trader, account, etc, as this algo order, so just
|
||||
// copy our definition to the child definition to start with.
|
||||
auto child_def = serv.definition();
|
||||
// Now add a limit order component to mark our child as a limit
|
||||
// order. Limit orders do not require any extra parameters
|
||||
// beyond those already inherited from this algo order
|
||||
// (i.e. beyond what we obtained through serv.definition()) so
|
||||
// we can just use a default constructed LimitOrderDefinition.
|
||||
*child_def.mutable_custom_def()->mutable_limit() = LimitOrderDefinition{};
|
||||
// Now just build the child template and cache it for future use
|
||||
child_template = &(serv.make_child_template(child_def));
|
||||
}
|
||||
// Default constructed result is successful
|
||||
return {};
|
||||
}
|
||||
|
||||
// Called in the latency sensitive path, once, when the algo is first launched.
|
||||
// If the Algo is attaching to an existing order do_launch_attached is called instead.
|
||||
void MyAlgo::do_launch(IAlgoServices &services) {
|
||||
algo_services = &services;
|
||||
// Subscribe to book updates for this security
|
||||
services.subscribe_book(SecurityKey(services.security().id()));
|
||||
// Launch a child limit order
|
||||
child_key =
|
||||
services.launch_child(*child_template, services.price(), services.quantity());
|
||||
LOG(Sdk,Info, "MyAlgo: do_launch");
|
||||
}
|
||||
|
||||
// Called in the latency sensitive path, once, when the algo is first
|
||||
// launched. In this case the algo is provided with an existing order
|
||||
// it is now responsible for managing.
|
||||
void MyAlgo::do_launch_attached(IAlgoServices &services,
|
||||
OrderKey attached_order, ChildState st) {
|
||||
algo_services = &services;
|
||||
// Subscribe to book updates for this security
|
||||
services.subscribe_book(SecurityKey(services.security().id()));
|
||||
// Keep track of the child key
|
||||
child_key = attached_order;
|
||||
LOG(Sdk,Info, "MyAlgo: do_launch_attached");
|
||||
}
|
||||
|
||||
// Called when a human (or a supervising algo) updates a parameter for
|
||||
// this algo. The implementation validates the update and depending on
|
||||
// the validation outcome either applies the update or terminates the algo.
|
||||
void MyAlgo::do_update(api::orderman::Update const &update) {
|
||||
}
|
||||
|
||||
// Called when the book for the specified security has changed
|
||||
void MyAlgo::on_book(SecurityKey, Book const &b) {
|
||||
}
|
||||
|
||||
// Our child reported a change
|
||||
void MyAlgo::on_child_change(OrderKey, ChildState const &st) {
|
||||
}
|
||||
|
||||
// This is called by the spark daemon at startup. In this call we
|
||||
// describe our algo's parameters and register a factory function to
|
||||
// create an instance of the algo.
|
||||
extern "C" void init_spark_plugin(bts::SparkServices &serv) {
|
||||
using namespace bts;
|
||||
|
||||
DynamicOrderDescriptor desc;
|
||||
|
||||
// Start by naming our order type
|
||||
desc.set_dynamic_order_type("My Algo");
|
||||
|
||||
*desc.add_param_desc() = param_bool("Enable Feature");
|
||||
*desc.add_param_desc() = param_uint32("Feature Quantity");
|
||||
|
||||
// Associate the descriptor with a builder function and register
|
||||
// that with the Spark server.
|
||||
auto result =
|
||||
serv.register_dynamic_algo_order(
|
||||
desc, []() { return std::make_unique<MyAlgo>(); });
|
||||
|
||||
if (result != bts::AlgoRegistrationResult::SUCCESS) {
|
||||
// The desc has errors
|
||||
// Check the error log (/sparkdata/data/logging/log) for more details
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace order_example
|
||||
} // namespace bts
|
||||
```
|
||||
@@ -1,9 +0,0 @@
|
||||
#/bin/bash
|
||||
|
||||
# ../../externals/linux/bin/zola/zola build
|
||||
zola.exe build
|
||||
|
||||
rsync -avzL public/ bts@api.bluetradesys.com:/data/sdk/public/
|
||||
|
||||
rm -rf ./public/
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
html, body {
|
||||
font-size: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Source Sans Pro", "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
line-height: 1.6;
|
||||
// from http://www.heropatterns.com
|
||||
background-color: #0072a2;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%234b4b4b' fill-opacity='0.4'%3E%3Cpath opacity='.5' d='M96 95h4v1h-4v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9zm-1 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9z'/%3E%3Cpath d='M6 5V0H5v5H0v1h5v94h1V6h94V5H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
||||
|
||||
color: $foreground;
|
||||
|
||||
// for sticky footer
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $link-color;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid rgba(0, 124, 188, 0.25);
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1px solid $link-color;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
// totally taken from stripe
|
||||
&.button {
|
||||
outline: none;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0 14px;
|
||||
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .025em;
|
||||
color: #191919;
|
||||
text-decoration: none;
|
||||
transition: all .15s ease;
|
||||
border-bottom: none;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-1px);
|
||||
text-decoration: none;
|
||||
box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #f6f9fc;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
}
|
||||
|
||||
&.white {
|
||||
color: white;
|
||||
border-bottom-color: rgba(255, 255, 255, 0.25);
|
||||
|
||||
&:hover {
|
||||
border-bottom-color: white;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 1rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
p code, li code {
|
||||
// color: #e6e1dc;
|
||||
// background-color: #383838;
|
||||
color: #191919;
|
||||
background-color: #f5f5f5;
|
||||
white-space: pre-wrap;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
font-size: 0.85rem;
|
||||
font-family: monospace;
|
||||
// box-shadow: 0 1px 3px rgba(0,0,0,.1), 0 1px 1px rgba(0,0,0,.1), 0 2px 1px -1px rgba(0,0,0,.12);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
.documentation {
|
||||
padding: 3rem;
|
||||
display: flex;
|
||||
|
||||
&__sidebar {
|
||||
margin-right: 2rem;
|
||||
|
||||
ul {
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
> ul {
|
||||
> li {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.documentation__sidebar__title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0.25rem;
|
||||
|
||||
li {
|
||||
border-left: 1px solid $background;
|
||||
padding-left: 0.75rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
li.active a {
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid $link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&__content {
|
||||
width: 60%;
|
||||
// Same as the anchor absolute left to not overlap
|
||||
margin-left: 2rem;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
.zola-anchor {
|
||||
font-size: 1.25rem;
|
||||
visibility: hidden;
|
||||
margin-left: -2rem;
|
||||
text-decoration: none;
|
||||
border-bottom-color: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.zola-anchor {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 10px solid black;
|
||||
padding: 0.25rem 0.5rem;
|
||||
margin-left: 0;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
min-height: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
.documentation {
|
||||
flex-direction: column;
|
||||
padding: 2rem;
|
||||
|
||||
&__content {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&__sidebar {
|
||||
border-top: 1px solid $background;
|
||||
order: 1;
|
||||
margin-right: 0;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||