Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be68e006bf | ||
|
|
b1a1f83ea8 | ||
|
|
9495435780 | ||
|
|
e3d9b59759 | ||
|
|
eb0f6ae25a | ||
|
|
a9d72c22fb | ||
|
|
caf5463565 | ||
|
|
eb5290932f | ||
|
|
a0fb42f1cf | ||
|
|
a450d6447a | ||
|
|
db22dc2853 | ||
|
|
d042da8708 | ||
|
|
bed44db642 | ||
|
|
9c5ac2eb19 | ||
|
|
bec0e7dd15 | ||
|
|
9c7013082d | ||
|
|
80a9df9d73 | ||
|
|
7040af5545 | ||
|
|
fe8866118d | ||
|
|
d699f85784 | ||
|
|
0a797c0cfb |
No files matched your search
@@ -1,129 +0,0 @@
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Note installations that take a while (more than 10s)
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y ca-certificates
|
||||
RUN apt-get install -y ccache
|
||||
RUN apt-get install -y curl
|
||||
RUN apt-get install -y fish
|
||||
RUN apt-get install -y gdb
|
||||
# git-all: ~250s
|
||||
RUN apt-get install -y git-all
|
||||
RUN apt-get install -y gnupg
|
||||
# liblttng-ust-dev: ~30s
|
||||
RUN apt-get install -y liblttng-ust-dev
|
||||
RUN apt-get install -y libssh2-1-dev
|
||||
RUN apt-get install -y locales
|
||||
RUN apt-get install -y ninja-build
|
||||
# openssh-server: ~40s
|
||||
RUN apt-get install -y openssh-server
|
||||
RUN apt-get install -y pkg-config
|
||||
RUN apt-get install -y software-properties-common
|
||||
RUN apt-get install -y sudo
|
||||
RUN apt-get install -y tzdata
|
||||
RUN apt-get install -y vim
|
||||
RUN apt-get install -y zip
|
||||
|
||||
# Python: ~30s
|
||||
RUN apt-get install -y \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
&& python3 -m pip install --upgrade pip
|
||||
|
||||
# GCC
|
||||
ARG gcc_major=13
|
||||
RUN \
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y g++-$gcc_major
|
||||
|
||||
# Clang
|
||||
ARG clang_major=17
|
||||
RUN \
|
||||
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key 2> /dev/null \
|
||||
| gpg --dearmor - \
|
||||
| tee /usr/share/keyrings/llvm-snapshot.gpg > /dev/null \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-$clang_major main" \
|
||||
| tee -a "/etc/apt/sources.list.d/llvm.list" \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y \
|
||||
clang-$clang_major \
|
||||
clang-format-$clang_major \
|
||||
clangd-$clang_major
|
||||
|
||||
# CMake
|
||||
RUN \
|
||||
curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc 2> /dev/null \
|
||||
| gpg --dearmor - \
|
||||
| tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" \
|
||||
| tee /etc/apt/sources.list.d/kitware.list > /dev/null \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y cmake
|
||||
|
||||
# Dotnet
|
||||
RUN apt-get update && apt-get install -y dotnet7
|
||||
|
||||
# Node
|
||||
ARG node_major=18
|
||||
RUN mkdir -p /etc/apt/keyrings \
|
||||
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
|
||||
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$node_major.x nodistro main" \
|
||||
| tee /etc/apt/sources.list.d/nodesource.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y nodejs
|
||||
|
||||
# Emumba (deps)
|
||||
RUN apt-get update && apt-get -y install rapidjson-dev
|
||||
# Emumba
|
||||
COPY emumba /emumba
|
||||
RUN dpkg -i /emumba/emumba-deribit-connector-3.3.1-Linux.LICENSE_DISABLED.deb \
|
||||
&& rm -r /emumba
|
||||
|
||||
# Pcap
|
||||
RUN apt-get update && apt-get install -y libpcap0.8-dev
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
docker.io \
|
||||
docker-compose \
|
||||
docker-compose-v2
|
||||
|
||||
# Set up default executables (update-alternatives)
|
||||
RUN \
|
||||
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$clang_major 100; \
|
||||
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-$clang_major 100; \
|
||||
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-$clang_major 100; \
|
||||
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-$clang_major 100; \
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$gcc_major 100; \
|
||||
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-$gcc_major 100
|
||||
|
||||
# Add compiler symlinks for ccache
|
||||
RUN \
|
||||
ln -s /usr/bin/ccache /usr/local/bin/clang; \
|
||||
ln -s /usr/bin/ccache /usr/local/bin/clang++; \
|
||||
ln -s /usr/bin/ccache /usr/local/bin/clang-$clang_major; \
|
||||
ln -s /usr/bin/ccache /usr/local/bin/clang++-$clang_major; \
|
||||
ln -s /usr/bin/ccache /usr/local/bin/gcc; \
|
||||
ln -s /usr/bin/ccache /usr/local/bin/g++
|
||||
|
||||
RUN locale-gen en_US.UTF-8
|
||||
|
||||
ARG docker_user="bts"
|
||||
ARG docker_uid="1000"
|
||||
ARG docker_pass="bts"
|
||||
|
||||
RUN \
|
||||
groupadd -g "$docker_uid" "$docker_user" \
|
||||
&& useradd \
|
||||
-m \
|
||||
-u "$docker_uid" \
|
||||
-g "$docker_uid" \
|
||||
-G sudo \
|
||||
--password "$(openssl passwd -1 "$docker_pass")" \
|
||||
"$docker_user"
|
||||
|
||||
RUN usermod -aG docker "$docker_user"
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"dockerFile": "Dockerfile",
|
||||
// Creates local dir to mount to HOME in docker
|
||||
"initializeCommand": "mkdir -p ${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId}",
|
||||
"hostRequirements": {
|
||||
"memory": "4gb",
|
||||
"storage": "6gb"
|
||||
},
|
||||
"postCreateCommand": "/home/bts/spark/docker/sparkd/dev/devcontainer_post_create.sh",
|
||||
"containerUser": "bts",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/bts/spark,type=bind",
|
||||
"workspaceFolder": "/home/bts/spark",
|
||||
"updateRemoteUserUID": true,
|
||||
"shutdownAction": "none",
|
||||
// Note: If running multiple containers on the same host, each must use a
|
||||
// unique set of ports. Usually we just add 1000 to each port as needed. For
|
||||
// example, if 8000-8003 is taken, go with 9000-9003, then 10000-10003, etc.
|
||||
"runArgs": [
|
||||
"--shm-size",
|
||||
"2gb",
|
||||
"--network",
|
||||
"host"
|
||||
],
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId},target=/home/bts,type=bind",
|
||||
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
|
||||
],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"clangd.arguments": [
|
||||
"--compile-commands-dir=${workspaceFolder}/build/clang/debug"
|
||||
]
|
||||
},
|
||||
"extensions": [
|
||||
"eamodio.gitlens",
|
||||
"llvm-vs-code-extensions.vscode-clangd",
|
||||
"ms-vscode.cmake-tools",
|
||||
"ms-vscode.cpptools"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -42,7 +42,7 @@ trace_data/
|
||||
/.ignore
|
||||
*.rej
|
||||
.clangd/
|
||||
*CMakeDeps*.cmake
|
||||
*CMakeDeps.cmake
|
||||
/sniper.ipynb
|
||||
/src/.clang-format
|
||||
/src/server/sparkd/cmds/spartan/analysis/.ipynb_checkpoints
|
||||
@@ -50,4 +50,3 @@ trace_data/
|
||||
*.tmp/*
|
||||
/.venv*/*
|
||||
.cache/
|
||||
src/web/api/tsconfig.*.g.json
|
||||
+9
-3
@@ -1,6 +1,12 @@
|
||||
[submodule "externals"]
|
||||
path = externals
|
||||
url = git@bitbucket.org:bluetradesys/externals.git
|
||||
[submodule "vcpkg"]
|
||||
path = vcpkg
|
||||
url = https://github.com/microsoft/vcpkg.git
|
||||
[submodule "docker/linux"]
|
||||
path = docker/linux
|
||||
url = git@bitbucket.org:bluetradesys/linux_docker.git
|
||||
[submodule "docker/windows"]
|
||||
path = docker/windows
|
||||
url = git@bitbucket.org:bluetradesys/windows_docker.git
|
||||
[submodule "src/deribit-crypto-connector-demo-application"]
|
||||
path = src/deribit-crypto-connector-demo-application
|
||||
url = git@gitlab.com:cryptoexchanges1/deribit-crypto-connector-demo-application.git
|
||||
+77
-33
@@ -1,6 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(spark)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
if(WIN32)
|
||||
set(platform "windows")
|
||||
@@ -8,55 +7,100 @@ else()
|
||||
set(platform "linux")
|
||||
endif()
|
||||
|
||||
set(
|
||||
EXTERNALS_ROOT
|
||||
"${CMAKE_SOURCE_DIR}/externals/${platform}"
|
||||
CACHE
|
||||
STRING
|
||||
"External dependencies root folder (should contain folders: lib, bin, include")
|
||||
set(EXTERNALS_BIN "${EXTERNALS_ROOT}/bin")
|
||||
set(EXTERNALS_INCLUDE "${EXTERNALS_ROOT}/include")
|
||||
set(EXTERNALS_LIB "${EXTERNALS_ROOT}/lib/$<CONFIG>")
|
||||
set(BUILD_DOCS OFF CACHE BOOL "Build documentation")
|
||||
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(EXPORT_MD_CONSUMER OFF CACHE BOOL "Export (extern) C functions for MD consumer interop")
|
||||
if (WIN32)
|
||||
set(BUILD_SPARKD OFF CACHE BOOL "Build sparkd")
|
||||
set(BUILD_WEB OFF CACHE BOOL "Build the web server")
|
||||
else()
|
||||
set(BUILD_SPARKD ON CACHE BOOL "Build sparkd")
|
||||
set(BUILD_WEB ON CACHE BOOL "Build the web server")
|
||||
endif()
|
||||
set(BUILD_WEB ON CACHE BOOL "Build the web server")
|
||||
|
||||
include_directories(BEFORE SYSTEM ${EXTERNALS_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
|
||||
link_directories(${EXTERNALS_LIB})
|
||||
include_directories(BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
|
||||
link_directories(${SPARK_LIB})
|
||||
|
||||
add_compile_definitions(EXPORT_MD_CONSUMER="${EXPORT_MD_CONSUMER}")
|
||||
if(WIN32)
|
||||
# flags
|
||||
set(
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} \
|
||||
/MP \
|
||||
/WX /wd4251 /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 \
|
||||
/bigobj \
|
||||
/DCURL_STATICLIB \
|
||||
/D_WINSOCK_DEPRECATED_NO_WARNINGS \
|
||||
/D__TBB_NO_IMPLICIT_LINKAGE \
|
||||
/DBOOST_ALL_NO_LIB \
|
||||
/std:c++17 \
|
||||
/D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} /MT")
|
||||
set(
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
||||
"${CMAKE_SHARED_LINKER_FLAGS_RELEASE} \
|
||||
/DEBUG \
|
||||
/OPT:REF \
|
||||
/OPT:ICF \
|
||||
/LTCG")
|
||||
|
||||
# subdirs
|
||||
add_subdirectory(src/lib)
|
||||
else()
|
||||
# make sparkd look for libspark.so in its directory
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set(CMAKE_INSTALL_RPATH ".")
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install/${CMAKE_BUILD_TYPE}/sparkd")
|
||||
add_compile_definitions(SPARK_ENABLE_CCAPI)
|
||||
add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
|
||||
add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
|
||||
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_FTX)
|
||||
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE)
|
||||
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_DERIBIT)
|
||||
add_compile_definitions(CCAPI_ENABLE_LOG_WARN)
|
||||
|
||||
# flags
|
||||
set(
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
"${CMAKE_CXX_FLAGS_DEBUG} \
|
||||
-fPIC \
|
||||
-Wall \
|
||||
-pedantic \
|
||||
-Wextra \
|
||||
-Werror \
|
||||
-Wno-missing-braces \
|
||||
-Wno-ignored-qualifiers \
|
||||
--std=c++17 -fdiagnostics-color")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -DNDEBUG -O3")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wno-undef")
|
||||
|
||||
# subdirs
|
||||
if (BUILD_SPARKD)
|
||||
add_subdirectory(src/server/sparkd)
|
||||
add_subdirectory(src/data_files)
|
||||
endif()
|
||||
add_subdirectory(src/server/sparkd)
|
||||
add_subdirectory(src/lib)
|
||||
if (BUILD_WEB)
|
||||
add_subdirectory(src/web)
|
||||
endif()
|
||||
if(BUILD_DOCS)
|
||||
add_subdirectory(doc/user)
|
||||
endif()
|
||||
add_subdirectory(doc/user)
|
||||
if(BUILD_SDK)
|
||||
add_subdirectory(src/sdk)
|
||||
endif()
|
||||
add_subdirectory(src/data_files)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/server/sparkd/sparkd ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/web ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/data_files ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${CMAKE_BINARY_DIR}/src/lib/libspark.so ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND
|
||||
ln ARGS -sf
|
||||
${EXTERNALS_ROOT}/lib/Release/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0
|
||||
${CMAKE_BINARY_DIR}/server
|
||||
COMMAND ln ARGS -sf ${EXTERNALS_ROOT}/lib/Release/libACE-5.7.5.so ${CMAKE_BINARY_DIR}/server
|
||||
COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/server/plugins
|
||||
COMMENT "Creating server runtime layout"
|
||||
DEPENDS sparkd data_files_dir)
|
||||
|
||||
add_custom_target(server_layout ALL DEPENDS ${CMAKE_BINARY_DIR}/server)
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/externals/linux/lib/${CMAKE_BUILD_TYPE}/libACE-5.7.5.so" DESTINATION bin)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/externals/linux/lib/${CMAKE_BUILD_TYPE}/libOnixS.IceImpactMulticastPriceFeedHandlerCpp.so.3.16.0.0" DESTINATION bin)
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/externals/src/emumba/sparkd.lic" DESTINATION bin)
|
||||
endif()
|
||||
@@ -1,215 +0,0 @@
|
||||
{
|
||||
"version": 4,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 23,
|
||||
"patch": 0
|
||||
},
|
||||
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "spark",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"environment": {
|
||||
"SPARK_CMAKE_CXX_FLAGS": "/MP /WX /wd4250 /wd4251 /wd4244 /wd4267 /wd4355 /wd4275 /wd4345 /bigobj /EHsc /DCURL_STATICLIB /D_WINSOCK_DEPRECATED_NO_WARNINGS /D__TBB_NO_IMPLICIT_LINKAGE /DBOOST_ALL_NO_LIB /std:c++20 /D_SCL_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_CXX_FLAGS": "$env{SPARK_CMAKE_CXX_FLAGS}",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "$env{SPARK_CMAKE_CXX_FLAGS} /MTd",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "$env{SPARK_CMAKE_CXX_FLAGS} /MT",
|
||||
"CMAKE_CXX_STANDARD": "20",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_DEBUG": "/DEBUG",
|
||||
"CMAKE_SHARED_LINKER_FLAGS_RELEASE": "/OPT:REF /OPT:ICF /LTCG",
|
||||
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||
"EXTERNALS_ROOT": "${sourceDir}/externals/windows",
|
||||
"CONFIG_DEFAULTS_PATH": "config/defaults/*.conf",
|
||||
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0;${sourceDir}/build/$<CONFIG>/bin/net7.0-windows",
|
||||
"EXPORT_MD_CONSUMER": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"platform": "",
|
||||
"CMAKE_CXX_STANDARD": "20",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
|
||||
"CMAKE_EXE_LINKER_FLAGS": "-Wno-undef",
|
||||
"CONFIG_DEFAULTS_PATH": "config/defaults/*.conf",
|
||||
"EXTERNALS_ROOT": "${sourceDir}/externals/linux",
|
||||
"BUILD_SDK": {
|
||||
"type": "BOOL",
|
||||
"value": "OFF"
|
||||
},
|
||||
"BUILD_ADMIN_WEB_APP": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-debug",
|
||||
"inherits": "sparkd",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
},
|
||||
"CCAPI_LOG_LEVEL": "Info"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-release",
|
||||
"inherits": "sparkd",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CCAPI_LOG_LEVEL": "Warn"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-debug-clang",
|
||||
"inherits": "sparkd-debug",
|
||||
"displayName": "Sparkd (Debug | Clang)",
|
||||
"description": "Debug build compiled w/ clang",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "clang",
|
||||
"CMAKE_CXX_COMPILER": "clang++",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -DDEBUG"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-debug-gcc",
|
||||
"inherits": "sparkd-debug",
|
||||
"displayName": "Sparkd (Debug | Gcc)",
|
||||
"description": "Debug build compiled w/ gcc",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "gcc",
|
||||
"CMAKE_CXX_COMPILER": "g++",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -Wno-stringop-overread -DDEBUG"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-release-clang",
|
||||
"inherits": "sparkd-release",
|
||||
"displayName": "Sparkd (Release | Clang)",
|
||||
"description": "Release build compiled w/ clang",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "clang",
|
||||
"CMAKE_CXX_COMPILER": "clang++",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -fno-omit-frame-pointer -DNDEBUG -O3"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-release-gcc",
|
||||
"inherits": "sparkd-release",
|
||||
"displayName": "Sparkd (Release | Gcc)",
|
||||
"description": "Release build compiled w/ gcc",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "gcc",
|
||||
"CMAKE_CXX_COMPILER": "g++",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers -Wno-stringop-overflow --std=c++20 -fdiagnostics-color -Wno-stringop-overread -Wno-maybe-uninitialized -fno-omit-frame-pointer -DNDEBUG -O3"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "spark",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-debug",
|
||||
"displayName": "Spark (Debug)",
|
||||
"inherits": "spark",
|
||||
"configurePreset": "spark",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-release",
|
||||
"displayName": "Spark (Release)",
|
||||
"inherits": "spark",
|
||||
"configurePreset": "spark",
|
||||
"configuration": "Release"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-debug-clang",
|
||||
"configurePreset": "sparkd-debug-clang",
|
||||
"displayName": "Sparkd (Debug | Clang)",
|
||||
"inherits": "sparkd"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-debug-clang-j6",
|
||||
"configurePreset": "sparkd-debug-clang",
|
||||
"displayName": "Sparkd (Debug | Clang | jobs=6)",
|
||||
"inherits": "sparkd",
|
||||
"jobs": 6
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-debug-gcc",
|
||||
"configurePreset": "sparkd-debug-gcc",
|
||||
"displayName": "Sparkd (Debug | Gcc)",
|
||||
"inherits": "sparkd"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-release-clang",
|
||||
"configurePreset": "sparkd-release-clang",
|
||||
"displayName": "Sparkd (Release | Clang)",
|
||||
"inherits": "sparkd"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sparkd-release-gcc",
|
||||
"configurePreset": "sparkd-release-gcc",
|
||||
"displayName": "Sparkd (Release | Gcc)",
|
||||
"inherits": "sparkd"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/PackBasic.cmake)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
function(install_basic)
|
||||
set(_options)
|
||||
set(_one_value_args)
|
||||
set(_multi_value_args HEADERS)
|
||||
cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
|
||||
if (_ARGS_HEADERS)
|
||||
set(${PROJECT_NAME}_HEADERS ${_ARGS_HEADERS})
|
||||
else()
|
||||
file(
|
||||
GLOB_RECURSE ${PROJECT_NAME}_HEADERS
|
||||
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
*.h
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
FILE_SET HEADERS FILES ${${PROJECT_NAME}_HEADERS})
|
||||
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME}
|
||||
EXPORT ${PROJECT_NAME}Targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT ${PROJECT_NAME}Targets
|
||||
FILE ${PROJECT_NAME}Targets.cmake
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
|
||||
pack_basic()
|
||||
endfunction()
|
||||
@@ -1,36 +0,0 @@
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
function(pack_basic)
|
||||
find_package(Git QUIET)
|
||||
|
||||
if(GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE PROJECT_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT GIT_FOUND OR PROJECT_VERSION STREQUAL "")
|
||||
set(PROJECT_VERSION "0.0.0")
|
||||
endif()
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
configure_package_config_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
endfunction()
|
||||
@@ -1,12 +0,0 @@
|
||||
function(print_list var)
|
||||
set(CMAKE_MESSAGE_INDENT "")
|
||||
set(_var_str "")
|
||||
foreach(item IN LISTS ${var})
|
||||
set(_var_str "${_var_str}\n ${item}")
|
||||
endforeach()
|
||||
if ("${ARGN}" STREQUAL "VERBOSE")
|
||||
message(VERBOSE "***${var}:${_var_str}")
|
||||
else()
|
||||
message("***${var}:${_var_str}")
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -1,5 +1,5 @@
|
||||
set(Protobuf_PROTOC_EXECUTABLE "${EXTERNALS_BIN}/protoc")
|
||||
set(PROTOBUF_INCLUDE_DIRS "${EXTERNALS_INCLUDE}")
|
||||
set(Protobuf_PROTOC_EXECUTABLE "${SPARK_BIN}/protoc")
|
||||
set(PROTOBUF_INCLUDE_DIRS "${SPARK_INCLUDE}")
|
||||
set(PROTOBUF_STATIC_LIB "libprotobuf")
|
||||
|
||||
function(Protobuf_Generate_Cpp SRCS HDRS)
|
||||
@@ -106,9 +106,8 @@ function(Service_Compiler_Generate_Cpp SRCS HDRS)
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.client.pb.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.cc"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.server.pb.h"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/venv_exec.sh
|
||||
ARGS
|
||||
${Protobuf_PROTOC_EXECUTABLE}
|
||||
COMMAND
|
||||
"PYTHONPATH=${SPARK_PYTHON}" ${Protobuf_PROTOC_EXECUTABLE} ARGS
|
||||
--cpp_out=${CMAKE_BINARY_DIR}/src
|
||||
--plugin=protoc-gen-service=${CMAKE_SOURCE_DIR}/src/lib/api/service_compiler/plugin.py
|
||||
--service_out=lang=cpp,make_file_name=${ABS_FIL}:${CMAKE_BINARY_DIR}/src
|
||||
|
||||
@@ -46,7 +46,6 @@ function setup_build
|
||||
assert_dir $repo_root
|
||||
assert_dir $build_root
|
||||
set compiler "$argv[1]"
|
||||
set c_compiler (which cc)
|
||||
set build_type "$argv[2]"
|
||||
|
||||
if test \( -z "$build_type" \) -o \( \( "$build_type" != debug \) -a \( "$build_type" != release \) \)
|
||||
@@ -60,7 +59,6 @@ function setup_build
|
||||
else
|
||||
# set compiler_arg "/usr/lib/ccache/clang++"
|
||||
set compiler_arg "clang++"
|
||||
set c_compiler (which clang)
|
||||
end
|
||||
else if test "$build_type" = release
|
||||
set build_type_arg Release
|
||||
@@ -87,7 +85,7 @@ function setup_build
|
||||
rm -rf "$build_dest"
|
||||
mkdir -p "$build_dest"
|
||||
cd "$build_dest"
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=$build_type_arg -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_C_COMPILER=$c_compiler -DCMAKE_CXX_COMPILER=$compiler_arg $repo_root
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=$build_type_arg -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_CXX_COMPILER=$compiler_arg $repo_root
|
||||
end
|
||||
|
||||
# The while loop below removes arguments (via shift) as it parses them.
|
||||
|
||||
Submodule
+1
Submodule docker/linux added at 05967d0f18.
Submodule
+1
Submodule docker/windows added at de7d40c09d.
+1
-1
Submodule externals updated: 800873c856...99c440f568.
@@ -12,7 +12,6 @@ pycodestyle==2.7.0
|
||||
pycparser==2.20
|
||||
pylint==2.10.2
|
||||
PyMeta3==0.5.1
|
||||
termcolor==1.1.0
|
||||
toml==0.10.2
|
||||
wrapt==1.12.1
|
||||
yapf==0.31.0
|
||||
+15
-30
@@ -1,9 +1,11 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32922.545
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30114.105
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api", "src\client\spark_api\spark_api.csproj", "{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspark", "build\src\lib\libspark.vcxproj", "{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spark", "src\client\spark\Spark.csproj", "{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sparkcmd", "src\client\sparkcmd\sparkcmd.csproj", "{387566C6-C6F6-412C-A30C-9855BBCB4816}"
|
||||
@@ -11,13 +13,12 @@ EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_core", "src\client\spark_core\spark_core.csproj", "{6E449EB6-20AC-4FA6-B8D9-10F4BB7E1FEE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_sdk", "src\client\spark_sdk\spark_sdk.csproj", "{6963C314-83C4-4667-B0D0-C2F7AE208C29}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40} = {9FA60215-26AF-3EB7-AB89-D4F4B126EF40}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_test", "src\client\spark_test\spark_test.csproj", "{ECD78CC5-138F-4809-A764-2358C2AC2E82}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_websocket", "src\client\spark_websocket\spark_websocket.csproj", "{3201359D-C071-4089-9EDE-B04D759F1508}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "spark_api_server", "src\client\spark_api_server\spark_api_server.csproj", "{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -34,14 +35,14 @@ Global
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.Release|x64.Build.0 = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{DC9A8975-8211-4FC9-A9BA-C8B9D26AD481}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.Debug|x64.Build.0 = Debug|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.Release|x64.ActiveCfg = Release|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.Release|x64.Build.0 = Release|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{FDC3A021-386E-3A2C-A7EB-CBE94A95BE25}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Debug|x64.Build.0 = Debug|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Release|x64.ActiveCfg = Release|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.Release|x64.Build.0 = Release|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{9FA60215-26AF-3EB7-AB89-D4F4B126EF40}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.Debug|x64.Build.0 = Debug|x64
|
||||
{9A4D4D07-1AB6-4B2B-B111-A4F34D6C267E}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
@@ -82,22 +83,6 @@ Global
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.Release|x64.Build.0 = Release|x64
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{ECD78CC5-138F-4809-A764-2358C2AC2E82}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.Debug|x64.Build.0 = Debug|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.ActiveCfg = Release|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.Release|x64.Build.0 = Release|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{3201359D-C071-4089-9EDE-B04D759F1508}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Debug|x64.Build.0 = Debug|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.ActiveCfg = Release|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.Release|x64.Build.0 = Release|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{2B8C5D01-FF78-4BFA-B332-5E430586DAF9}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,55 +1,53 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<ComputerSpecificConfig>..\..\tools\override\$(computername).props</ComputerSpecificConfig>
|
||||
<SparkRoot>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\..))</SparkRoot>
|
||||
<SourceRoot>$([System.IO.Path]::GetFullPath($(SparkRoot)\src))</SourceRoot>
|
||||
<Externals>$(SparkRoot)\externals\windows</Externals>
|
||||
<DepotName>$([System.IO.Path]::GetFileName($([System.IO.Path]::GetFullPath($(SparkRoot)))))</DepotName>
|
||||
<ErrorReport>None</ErrorReport>
|
||||
<Prefer32Bit>False</Prefer32Bit>
|
||||
<Deterministic>true</Deterministic>
|
||||
<EnableDefaultContentItems>False</EnableDefaultContentItems>
|
||||
<ShowMissingItemTypes>false</ShowMissingItemTypes>
|
||||
<Configuration Condition="'$(configuration)'==''">Debug</Configuration>
|
||||
<EnablePreviewFeatures>true</EnablePreviewFeatures>
|
||||
<LangVersion>11</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Output">
|
||||
<BaseOutputPath>$(SparkRoot)\build\$(Configuration)</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\bin</OutputPath>
|
||||
<BaseIntermediateOutputPath>$(BaseOutputPath)\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<IntermediateOutputPath>$(BaseOutputPath)\obj\$(MSBuildProjectName)</IntermediateOutputPath>
|
||||
<ProtoOutputPath>$(BaseOutputPath)\obj\$(MSBuildProjectName)</ProtoOutputPath>
|
||||
<GenDir>$(BaseOutputPath)\gen\$(MSBuildProjectName)</GenDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import
|
||||
Project="$(ComputerSpecificConfig)"
|
||||
Condition="Exists($(ComputerSpecificConfig))" />
|
||||
|
||||
<PropertyGroup Label="ProtoBuf">
|
||||
<ProtocPluginBase>$(SparkRoot)\src\lib\api\service_compiler</ProtocPluginBase>
|
||||
<protoc>$(Externals)\bin\protoc.exe</protoc>
|
||||
<protogen>$(Externals)\bin\protogen.exe</protogen>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Proto2></Proto2>
|
||||
<Proto3>
|
||||
<OutBase>$(IntermediateOutputPath)\gen\%(relativedir)</OutBase>
|
||||
<OutCS>%(OutBase)%(FileName).cs</OutCS>
|
||||
<OutCSClient>%(OutBase)%(FileName).client.pb.cs</OutCSClient>
|
||||
<OutCSServer>%(OutBase)%(FileName).server.pb.cs</OutCSServer>
|
||||
<OutCSImmutable>%(OutBase)%(FileName).immutable.pb.cs</OutCSImmutable>
|
||||
<CompileOptions></CompileOptions>
|
||||
</Proto3>
|
||||
<Proto3Excel>
|
||||
<OutBase>$(IntermediateOutputPath)\gen\%(relativedir)</OutBase>
|
||||
<OutCSExcel>%(OutBase)%(FileName).excel.pb.cs</OutCSExcel>
|
||||
<CompileOptions></CompileOptions>
|
||||
</Proto3Excel>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
</Project>
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<ComputerSpecificConfig>..\..\tools\override\$(computername).props</ComputerSpecificConfig>
|
||||
<SparkRoot>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\..))</SparkRoot>
|
||||
<SourceRoot>$([System.IO.Path]::GetFullPath($(SparkRoot)\src))</SourceRoot>
|
||||
<Externals>$(SparkRoot)\externals\windows</Externals>
|
||||
<DepotName>$([System.IO.Path]::GetFileName($([System.IO.Path]::GetFullPath($(SparkRoot)))))</DepotName>
|
||||
<ErrorReport>None</ErrorReport>
|
||||
<Prefer32Bit>False</Prefer32Bit>
|
||||
<Deterministic>true</Deterministic>
|
||||
<EnableDefaultContentItems>False</EnableDefaultContentItems>
|
||||
<ShowMissingItemTypes>false</ShowMissingItemTypes>
|
||||
<Configuration Condition="'$(configuration)'==''">Debug</Configuration>
|
||||
<EnablePreviewFeatures>true</EnablePreviewFeatures>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Output">
|
||||
<BaseOutputPath>$(SparkRoot)\build\$(Configuration)</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\bin</OutputPath>
|
||||
<BaseIntermediateOutputPath>$(BaseOutputPath)\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<IntermediateOutputPath>$(BaseOutputPath)\obj\$(MSBuildProjectName)</IntermediateOutputPath>
|
||||
<GenDir>$(BaseOutputPath)\gen\$(MSBuildProjectName)</GenDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import
|
||||
Project="$(ComputerSpecificConfig)"
|
||||
Condition="Exists($(ComputerSpecificConfig))" />
|
||||
|
||||
<PropertyGroup Label="ProtoBuf">
|
||||
<ProtocPluginBase>$(SparkRoot)\src\lib\api\service_compiler</ProtocPluginBase>
|
||||
<protoc>$(Externals)\bin\protoc.exe</protoc>
|
||||
<protogen>$(Externals)\bin\protogen.exe</protogen>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Proto2></Proto2>
|
||||
<Proto3>
|
||||
<OutBase>$(IntermediateOutputPath)\gen\%(relativedir)</OutBase>
|
||||
<OutCS>%(OutBase)%(FileName).cs</OutCS>
|
||||
<OutCSClient>%(OutBase)%(FileName).client.pb.cs</OutCSClient>
|
||||
<OutCSServer>%(OutBase)%(FileName).server.pb.cs</OutCSServer>
|
||||
<OutCSImmutable>%(OutBase)%(FileName).immutable.pb.cs</OutCSImmutable>
|
||||
<CompileOptions></CompileOptions>
|
||||
</Proto3>
|
||||
<Proto3Excel>
|
||||
<OutBase>$(IntermediateOutputPath)\gen\%(relativedir)</OutBase>
|
||||
<OutCSExcel>%(OutBase)%(FileName).excel.pb.cs</OutCSExcel>
|
||||
<CompileOptions></CompileOptions>
|
||||
</Proto3Excel>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
</Project>
|
||||
@@ -52,7 +52,8 @@
|
||||
<Exec Command="set PYTHONPATH=$(SparkRoot)\.venv\Scripts\python" />
|
||||
<Exec
|
||||
Command="
|
||||
$(protoc) %* %(Proto3.FullPath) ^
|
||||
$(SparkRoot)\tools\build_protos.cmd ^
|
||||
%(Proto3.FullPath) ^
|
||||
--error_format=msvs ^
|
||||
--proto_path=$(SourceRoot) ^
|
||||
--plugin="protoc-gen-service=$(ProtocPluginBase)\plugin.cmd" ^
|
||||
|
||||
@@ -15,9 +15,7 @@ namespace mbts.spark {
|
||||
using mbts.ui.utility;
|
||||
using mbts.utils;
|
||||
|
||||
using Spark.Core;
|
||||
using Spark.Core.Collections;
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.ViewModel.Commands;
|
||||
|
||||
using System;
|
||||
@@ -35,15 +33,14 @@ namespace mbts.spark {
|
||||
class AnalyticsExpirationParametersVM : DisposableViewModelBase, IHandleRowSelection {
|
||||
readonly IBus _bus;
|
||||
readonly ObservableCollection<AnalyticsExpirationParameters> _parameters = new();
|
||||
readonly DeferrableAction _sync_visible_rows;
|
||||
readonly DeferrableActionWrapper _sync_visible_rows;
|
||||
readonly Property<AnalyticsExpirationParametersRowVM?> _copy_row_source;
|
||||
readonly Property<bool> _auto_copy_rolls_is_checked;
|
||||
readonly Property<bool> _auto_copy_rates_is_checked;
|
||||
readonly DelegateProperty<bool> _is_dirty;
|
||||
readonly ObservableHashSet<AnalyticsExpirationParametersRowVM> _selected_rows = new();
|
||||
readonly DeferrableAction _raise_selected_rows_changed;
|
||||
readonly DeferrableActionWrapper _raise_selected_rows_changed;
|
||||
readonly IRaiseCanExecuteChangedCommand _set_driver_to_nearest_exp_cmd;
|
||||
IList<string>? _pending_selected_symbols;
|
||||
|
||||
AnalyticsExpirationParametersMap? _parameter_map;
|
||||
(ICommand cmd, IDisposable can_exe_sub)? _smart_copy_roll_target_to_selection_cmd;
|
||||
@@ -66,7 +63,9 @@ namespace mbts.spark {
|
||||
_is_dirty = backing(nameof(is_dirty), () => rows.Any(r => r.is_dirty));
|
||||
|
||||
if (startup_data is not null) {
|
||||
_pending_selected_symbols = startup_data.selected_symbols;
|
||||
if (!startup_data.selected_symbols.is_null_or_empty()) {
|
||||
selected_symbols.AddRange(startup_data.selected_symbols);
|
||||
}
|
||||
auto_copy_rolls_is_checked = startup_data.auto_copy_rolls_is_checked;
|
||||
auto_copy_rates_is_checked = startup_data.auto_copy_rates_is_checked;
|
||||
}
|
||||
@@ -82,32 +81,32 @@ namespace mbts.spark {
|
||||
selected_rows_changed += _ => _set_driver_to_nearest_exp_cmd.RaiseCanExecuteChanged();
|
||||
|
||||
_dispose = Disposable.Create(
|
||||
_selected_rows.Subscribe((s, e) => _raise_selected_rows_changed.Invoke()),
|
||||
_selected_rows.Subscribe((s, e) => _raise_selected_rows_changed.execute()),
|
||||
ObservableAutoWrapper.connect(_parameters, rows, p => new(this, p), r => r.Dispose()),
|
||||
ObservableAutoWrapper.connect(
|
||||
non_options,
|
||||
explicit_drivers,
|
||||
sec => new ExpirationDriverImmutable(new() { Security = sec.to_api_sec_exp() })),
|
||||
rows.Subscribe((s, e) => _sync_visible_rows.Invoke()),
|
||||
rows.Subscribe((s, e) => _sync_visible_rows.execute()),
|
||||
_bus.subscribe(SparkTags.ExpirationParametersInputTag).OnDispatcher().Subscribe(
|
||||
CompositeObserver.create(
|
||||
Observer.Create<AnalyticsExpirationParametersMap>(_on_parameter_map),
|
||||
can_commit_observer.wrap<bool, AnalyticsExpirationParametersMap>(m => m is not null))),
|
||||
ObservableAutoWrapper.connect_item_hooks(selected_symbols, sym => {
|
||||
if (selected_symbol_ref_count.increment_adds_key(sym)) {
|
||||
_sync_visible_rows.Invoke();
|
||||
_sync_visible_rows.execute();
|
||||
}
|
||||
return Disposable.Create(() => {
|
||||
if (selected_symbol_ref_count.decrement_removes_key(sym)) {
|
||||
_sync_visible_rows.Invoke();
|
||||
_sync_visible_rows.execute();
|
||||
}
|
||||
});
|
||||
}),
|
||||
ObservableAutoWrapper.connect_item_hooks(
|
||||
rows, r => r.observe_is_dirty().Subscribe(_ => _is_dirty.refresh())),
|
||||
_is_dirty.observe_current(true).OnDispatcher().Subscribe(can_revert_observer),
|
||||
Disposable.wrap_collection(rows),
|
||||
Disposable.Create(() => {
|
||||
rows.DisposeAll();
|
||||
_smart_copy_roll_target_to_selection_cmd?.can_exe_sub?.Dispose();
|
||||
_smart_copy_riskless_rate_to_selection_cmd?.can_exe_sub?.Dispose();
|
||||
}));
|
||||
@@ -196,18 +195,10 @@ namespace mbts.spark {
|
||||
};
|
||||
|
||||
void _set_driver_to_nearest_exp(IEnumerable<AnalyticsExpirationParametersRowVM> rows) {
|
||||
Func<ExpirationDriverImmutable, bool> is_unexpired = (d) => {
|
||||
var st = d.Security.to_sec_exp().security_tuple.to_api_sec_tuple();
|
||||
var exp = d.Security.Expiration.date_time();
|
||||
return SecurityExpirationHelper.is_unexpired(st, exp);
|
||||
};
|
||||
foreach (var r in rows) {
|
||||
if (drivers
|
||||
.Where(d => d.HasSecurity && d.Security.Symbol == r.security.symbol)
|
||||
.Where(d => is_unexpired(d))
|
||||
.TryGetMinElement(
|
||||
d => (r.security.expiration - d.Security.Expiration.date_time()).Ticks.abs(),
|
||||
out var nearest_exp)) {
|
||||
if (drivers.Where(d => d.HasSecurity).TryGetMinElement(
|
||||
d => (r.security.expiration - d.Security.Expiration.date_time()).Ticks.abs(),
|
||||
out var nearest_exp)) {
|
||||
r.driver = nearest_exp;
|
||||
}
|
||||
}
|
||||
@@ -294,10 +285,10 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
symbols.sync_with(_parameters.Select(p => p.security.symbol).Distinct().Ordered());
|
||||
using var _ = _sync_visible_rows.defer();
|
||||
using var _ = _sync_visible_rows.defer_execution();
|
||||
if (is_first_update) {
|
||||
selected_symbols.sync_with(_pending_selected_symbols?.Intersect(symbols) ?? symbols);
|
||||
_pending_selected_symbols = null;
|
||||
// select all symbols on first update
|
||||
selected_symbols.sync_with(symbols);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
xmlns:u="clr-namespace:mbts.ui"
|
||||
xmlns:cv="clr-namespace:mbts.ui.converters"
|
||||
xmlns:shell="clr-namespace:mbts.ui.shell"
|
||||
Background="{u:BTSBrush UI.common_background}">
|
||||
Background="{StaticResource CommonBackground}">
|
||||
<UserControl.Resources>
|
||||
<cv:DoubleTextConverter x:Key="DoubleTextConverter" />
|
||||
<cv:DoubleTextConverter
|
||||
@@ -153,6 +153,7 @@
|
||||
SelectedItems="{Binding selected_symbols}"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="5,2,2,2"
|
||||
TextBlock.Foreground="Black"
|
||||
HeaderContent="Symbols"
|
||||
ShowSelectAll="True">
|
||||
<c:ComboCheckBox.HeaderContentTemplate>
|
||||
@@ -164,13 +165,19 @@
|
||||
|
||||
<WrapPanel>
|
||||
<TextBlock
|
||||
Margin="5,5,0,0" Foreground="{u:BTSBrush UI.default_text}" Text="Auto copy rolls:" />
|
||||
<CheckBox Margin="5,5,10,0" IsChecked="{Binding auto_copy_rolls_is_checked}" />
|
||||
Margin="5,5,0,0" Text="Auto copy rolls:" Style="{StaticResource TextBlock.Dark}" />
|
||||
<CheckBox
|
||||
Margin="5,5,10,0"
|
||||
IsChecked="{Binding auto_copy_rolls_is_checked}"
|
||||
Style="{StaticResource CheckBox.Dark}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<TextBlock
|
||||
Margin='0,5,0,0' Foreground="{u:BTSBrush UI.default_text}" Text="Auto copy rates:" />
|
||||
<CheckBox Margin="5,5,0,0" IsChecked="{Binding auto_copy_rates_is_checked}" />
|
||||
Margin='0,5,0,0' Text="Auto copy rates:" Style="{StaticResource TextBlock.Dark}" />
|
||||
<CheckBox
|
||||
Margin="5,5,0,0"
|
||||
IsChecked="{Binding auto_copy_rates_is_checked}"
|
||||
Style="{StaticResource CheckBox.Dark}" />
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
<c:DataGridEx
|
||||
@@ -415,7 +422,8 @@
|
||||
<DataTemplate>
|
||||
<TextBox
|
||||
Text="{Binding roll_target, Converter={StaticResource DoubleTextConverter}}"
|
||||
Margin="2" />
|
||||
Margin="2"
|
||||
Style="{StaticResource TextBox.Dark}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@@ -449,7 +457,8 @@
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox
|
||||
Text="{Binding riskless_rate, Converter={StaticResource RisklessRateConverter}}" />
|
||||
Text="{Binding riskless_rate, Converter={StaticResource RisklessRateConverter}}"
|
||||
Style="{StaticResource TextBox.Dark}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@@ -483,7 +492,8 @@
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox
|
||||
Text="{Binding settlement_price, Converter={StaticResource DoubleTextConverter}}" />
|
||||
Text="{Binding settlement_price, Converter={StaticResource DoubleTextConverter}}"
|
||||
Style="{StaticResource TextBox.Dark}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@@ -518,7 +528,8 @@
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox
|
||||
Text="{Binding delta_beta, Converter={StaticResource DoubleTextConverter}}" />
|
||||
Text="{Binding delta_beta, Converter={StaticResource DoubleTextConverter}}"
|
||||
Style="{StaticResource TextBox.Dark}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@@ -552,7 +563,9 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<DataGridTemplateColumn.CellEditingTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Text="{Binding vega_beta, Converter={StaticResource DoubleTextConverter}}" />
|
||||
<TextBox
|
||||
Text="{Binding vega_beta, Converter={StaticResource DoubleTextConverter}}"
|
||||
Style="{StaticResource TextBox.Dark}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellEditingTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace mbts.ui.shell {
|
||||
using mbts.ui.converters;
|
||||
using mbts.ui.extensions;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
@@ -5,8 +5,6 @@ namespace mbts.spark {
|
||||
using mbts.ui;
|
||||
using mbts.ui.shell;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace mbts.spark {
|
||||
|
||||
using mbts.analytics;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -42,12 +40,6 @@ namespace mbts.spark {
|
||||
exp_params_out_src.Subscribe(save_exp_params));
|
||||
|
||||
void save_exp_params(IEnumerable<AnalyticsExpirationParameters> exp_params) {
|
||||
Func<AnalyticsExpirationParameters, bool> is_unexpired = (p) => {
|
||||
var st = p.driver_security.security_tuple.to_api_sec_tuple();
|
||||
var exp = p.security.expiration;
|
||||
return SecurityExpirationHelper.is_unexpired(st, exp);
|
||||
};
|
||||
exp_params = exp_params.Where(t => is_unexpired(t));
|
||||
// listens to the commit tag and saves it
|
||||
Log.Gen.info($"AnalyticsParametersManager received commit req. count:{exp_params.Count()}");
|
||||
var to_save = new ExpirationParameterEntryList();
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace mbts.spark {
|
||||
|
||||
public SingleVolSurfaceRequestCalculator(int vs_id, IEnumerable<string> symbols,
|
||||
ThreadedBlackboard threaded_bb) {
|
||||
bts.Log.Gen.info($"SingleVolSurfaceRequestCalculator cons vs_id: {vs_id}");
|
||||
bts.Log.Gen.info($"SingleVolSurfaceRequestCalculator cons vs_id:{vs_id}");
|
||||
_vs_id = vs_id;
|
||||
_symbols = new HashSet<string>(symbols);
|
||||
_bb = threaded_bb;
|
||||
@@ -89,8 +89,8 @@ namespace mbts.spark {
|
||||
effective_req.cascade_up,
|
||||
effective_req.cascade_down);
|
||||
_timer.stop();
|
||||
bts.Log.Gen.info($"SingleVolSurfaceRequestCalculator._recompute_and_publish time: " +
|
||||
$"{_timer.lastIntervalTime}");
|
||||
bts.Log.Gen.info($"SingleVolSurfaceRequestCalculator._recompute_and_publish time:" +
|
||||
$"{_timer.lastIntervalTime} vs_output:{_last_output.log_string()}");
|
||||
_bb.post(SparkTags.VolSurfaceCalculationResponseTag(_vs_id),
|
||||
new VolSurfaceCalculationResponse(_last_output, effective_req.request_id));
|
||||
}
|
||||
|
||||
@@ -11,22 +11,18 @@ namespace mbts.analytics {
|
||||
// tags, into IReadOnlyDictionary of symbol vs data publsihed under one tag
|
||||
public class SymbolAggregationPublisher<TData> : IDisposable {
|
||||
private readonly ThreadedBlackboard _bb;
|
||||
private readonly SecurityType _sec_type;
|
||||
Func<string, ITag<TData>> _get_tag;
|
||||
// the tag on which the output will be published
|
||||
ITag<IReadOnlyDictionary<string, TData>> _out_tag;
|
||||
private readonly ITag<SystemContractData> _sc_data_tag;
|
||||
Func<string, ITag<TData>> _get_tag;
|
||||
ITag<IReadOnlyDictionary<string, TData>> _out_tag;
|
||||
private Dictionary<string, ITag<TData>> _tag_map =
|
||||
new Dictionary<string, ITag<TData>>();
|
||||
private HashSet<object> _obj_tags = new HashSet<object>();
|
||||
private bool _dirty = true;
|
||||
public SymbolAggregationPublisher(
|
||||
ThreadedBlackboard bb,
|
||||
SecurityType sec_type,
|
||||
Func<string, ITag<TData>> get_tag,
|
||||
ITag<IReadOnlyDictionary<string, TData>> out_tag) {
|
||||
_bb = bb;
|
||||
_sec_type = sec_type;
|
||||
_get_tag = get_tag;
|
||||
_out_tag = out_tag;
|
||||
_sc_data_tag = SparkTags.SystemContractsTag;
|
||||
@@ -52,20 +48,15 @@ namespace mbts.analytics {
|
||||
return;
|
||||
}
|
||||
foreach (var st in sc_data.sectup_map) {
|
||||
if (st.security_type != _sec_type) {
|
||||
continue;
|
||||
}
|
||||
// this is not correct since it is assuming symbol/name is
|
||||
// unique across securty_tuples
|
||||
string symbol = st.security_name;
|
||||
if (!_tag_map.ContainsKey(symbol)) {
|
||||
var tag = _get_tag(symbol);
|
||||
if (tag != null) {
|
||||
_tag_map.Add(symbol, tag);
|
||||
_obj_tags.Add(tag);
|
||||
_bb.subscribe(tag);
|
||||
_dirty = true;
|
||||
}
|
||||
var symbol_tag = _get_tag(symbol);
|
||||
_tag_map.Add(symbol, symbol_tag);
|
||||
_obj_tags.Add(symbol_tag);
|
||||
_bb.subscribe(symbol_tag);
|
||||
_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ using System.Collections;
|
||||
using mbts.spark;
|
||||
using System.DirectoryServices.ActiveDirectory;
|
||||
using Spark.Core.Protobuf;
|
||||
using mbts.ui;
|
||||
// using mbts.bb;
|
||||
|
||||
namespace mbts.spark {
|
||||
@@ -77,8 +76,7 @@ namespace mbts.spark {
|
||||
private HighPerformanceTimer _timer = new HighPerformanceTimer();
|
||||
|
||||
public VolSurfaceBusManager(bts.api.IBus bus,
|
||||
bts.api.analytics.AnalyticsService analytics_service,
|
||||
bts.api.orderman.OrderService order_service) {
|
||||
bts.api.analytics.AnalyticsService analytics_service) {
|
||||
bts.Log.Ui.info("VSBusManager cons tid:{VolSurfaceTroubleshootingFunctions.tid()}");
|
||||
_bus = bus;
|
||||
_bb = new ThreadedBlackboard("AW2", bus);
|
||||
@@ -103,16 +101,12 @@ namespace mbts.spark {
|
||||
_subs.Add(new AnalyticsParametersManager(bus, _analytics_service));
|
||||
_subs.Add(new ResourceAllocator(bus, _bb));
|
||||
_subs.Add(new SymbolAggregationPublisher<OptionDriverPriceMap>(
|
||||
_bb, SecurityType.Option, sym => SparkTags.OptionDriverBBOTag(sym),
|
||||
_bb, (sym) => SparkTags.OptionDriverBBOTag(sym),
|
||||
SparkTags.AllOptionDriverBBOTag));
|
||||
_subs.Add(new SymbolAggregationPublisher<OptionTheoInterpolationData>(
|
||||
_bb, SecurityType.Option, sym => SparkTags.SymbolInterpGreeksTag(sym),
|
||||
_bb, (sym) => SparkTags.SymbolInterpGreeksTag(sym),
|
||||
SparkTags.AllInterpGreeks));
|
||||
_subs.Add(new SymbolAggregationPublisher<ExpStrikeKeyedData<TheoPoint>>(
|
||||
_bb, SecurityType.Option, sym => SparkTags.TC2Tags.LiveTheosTag(sym),
|
||||
SparkTags.TC2Tags.AllLiveTheosTag));
|
||||
_subs.Add(new LiveTheoPublisher(_bb));
|
||||
_subs.Add(new InterpTheosServerPublisher(_bb, order_service));
|
||||
_subs.Add(new VolSurfaceInterpGreeksMultiplexer(_bb));
|
||||
// usage
|
||||
var list_sub = _bus.subscribe(SparkTags.VolSurfaceListTag).OnDispatcher().Subscribe(t => {
|
||||
@@ -144,74 +138,14 @@ namespace mbts.spark {
|
||||
var list_imm = new VolSurfaceUsageListImmutable(ulist);
|
||||
Log.Ui.info(list_imm.log_string());
|
||||
_bb.post(SparkTags.VolSurfaceUsageTag, list_imm);
|
||||
_spin_vss(list_imm);
|
||||
});
|
||||
_disps.Add(list_sub);
|
||||
// f(contract keyed theos, securities) -> id keyed theos
|
||||
// (so the newer UI controls can access theos vis sec keys)
|
||||
var theo_sub =
|
||||
_bus.subscribe(SparkTags.TC2Tags.AllLiveTheosTag)
|
||||
.CombineLatest(bus.subscribe(SparkTags.SystemContractsTag),
|
||||
(theos, sc_data) => (theos, sc_data)).Subscribe(
|
||||
tup => {
|
||||
var keyed_theos = _assemble_keyed_theos(tup.sc_data, tup.theos);
|
||||
_bus.post(SparkTags.KeyedTheos, keyed_theos);
|
||||
}
|
||||
);
|
||||
_disps.Add(theo_sub);
|
||||
}
|
||||
|
||||
static IReadOnlyDictionary<uint, VolSurfaceTheoPoint> _assemble_keyed_theos(
|
||||
SystemContractData sc_data,
|
||||
IReadOnlyDictionary<string, ExpStrikeKeyedData<TheoPoint>> theos) {
|
||||
if (sc_data is null || theos is null) {
|
||||
return new Dictionary<uint, VolSurfaceTheoPoint>(0);
|
||||
}
|
||||
|
||||
HighPerformanceTimer timer = new HighPerformanceTimer();
|
||||
timer.start();
|
||||
Dictionary<uint, VolSurfaceTheoPoint> rv = new Dictionary<uint, VolSurfaceTheoPoint>();
|
||||
foreach (var kv in theos) {
|
||||
var symbol = kv.Key;
|
||||
ExpStrikeKeyedData<TheoPoint> sym_theos = kv.Value;
|
||||
if (sym_theos == null)
|
||||
continue;
|
||||
foreach (var s_kv in sym_theos.get_data_linearly()) {
|
||||
DateTime exp = s_kv.first;
|
||||
double strike = s_kv.second;
|
||||
TheoPoint tp = s_kv.third;
|
||||
// TODO: fix exchange later
|
||||
Tuple<uint?, uint?> keys =
|
||||
sc_data.get_option_sec_id(Venue.Deribit, symbol, exp, strike);
|
||||
if (keys != null) {
|
||||
var c_key = keys.Item1;
|
||||
var p_key = keys.Item2;
|
||||
if (c_key.HasValue) {
|
||||
rv[c_key.Value] = new VolSurfaceTheoPoint(tp, true);
|
||||
}
|
||||
if (p_key.HasValue) {
|
||||
rv[p_key.Value] = new VolSurfaceTheoPoint(tp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
Log.Gen.info($"VolSurfaceBusManager keyed theos count: {rv.Count} " +
|
||||
$"time: {timer.lastIntervalTime}");
|
||||
return rv;
|
||||
}
|
||||
|
||||
public ThreadedBlackboard bb() {
|
||||
return _bb;
|
||||
}
|
||||
|
||||
void _spin_vss(VolSurfaceUsageListImmutable ulist) {
|
||||
foreach (var u in ulist.UsageList) {
|
||||
var vs_id = u.VsId;
|
||||
_bb.post(SparkTags.VolSurfaceActiveUITag(vs_id), true);
|
||||
}
|
||||
}
|
||||
|
||||
void _on_vs_usage_update(Update<VolSurfaceUsageListImmutable, int> update) {
|
||||
// TODO
|
||||
return;
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
|
||||
namespace mbts.analytics {
|
||||
using mbts.spark;
|
||||
|
||||
// TheoPoint (from edge) has both calls and puts in the same structure.
|
||||
// This shoudl dis-entangle that
|
||||
public class VolSurfaceTheoPoint {
|
||||
public readonly double theo = double.NaN;
|
||||
public readonly double delta = double.NaN;
|
||||
public readonly double driver = double.NaN;
|
||||
public VolSurfaceTheoPoint(TheoPoint tp, bool is_call) {
|
||||
if (tp != null) {
|
||||
theo = is_call ? tp.fwd_normalized_call : tp.fwd_normalized_put;
|
||||
delta = is_call ? tp.cdelta : tp.pdelta;
|
||||
driver = tp.driver;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
using mbts.user.settings;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class VolSurfaceDisplayGridColumn : IEquatable<VolSurfaceDisplayGridColumn> {
|
||||
public readonly Func<object, string> format;
|
||||
@@ -19,19 +18,16 @@
|
||||
VolSurfaceColumnSettings settings,
|
||||
Func<object, string> format = null,
|
||||
Func<string, object> parse = null,
|
||||
Func<object, bool, object> tick_move = null,
|
||||
IEqualityComparer<object> comparer = null) {
|
||||
Func<object, bool, object> tick_move = null) {
|
||||
this.settings = settings;
|
||||
this.format = format ?? (v => v?.ToString() ?? string.Empty);
|
||||
this.parse = parse ?? (v => v);
|
||||
this.tick_move = tick_move ?? ((v, is_up) => v);
|
||||
this.comparer = comparer ?? EqualityComparer<object>.Default;
|
||||
}
|
||||
|
||||
public string unique_col_name => settings.id;
|
||||
public string display_name => settings.display_name;
|
||||
public string group => settings.group;
|
||||
public IEqualityComparer<object> comparer { get; }
|
||||
|
||||
internal VolSurfaceColumnType type => settings.type;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
using mbts.user.settings;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
class VolSurfaceDisplayUtilities {
|
||||
public static TickDisplaySettings default_tick_display =>
|
||||
@@ -19,10 +18,6 @@
|
||||
default_tick_display.with(display_multiplier: 100);
|
||||
|
||||
public static double parse_double(object obj) {
|
||||
if (obj is null) {
|
||||
Log.Gen.warn("parse_double received null input (will return nan and continue)");
|
||||
return double.NaN;
|
||||
}
|
||||
Log.assert(obj is double);
|
||||
obj = obj ?? Double.NaN;
|
||||
double rv = obj is Double ? (double)obj : (Double.TryParse(obj.ToString(), out rv) ? rv : Double.NaN);
|
||||
@@ -54,31 +49,9 @@
|
||||
}
|
||||
|
||||
public static Func<object, bool, object> get_double_tickmove(TickFactors tick_factors, int tick_move) =>
|
||||
(data, is_up) => {
|
||||
if (data is not double dbl) {
|
||||
return data;
|
||||
}
|
||||
if (dbl.is_nan()) {
|
||||
return 0D;
|
||||
}
|
||||
return tick_factors.tick(dbl, is_up ? tick_move : -tick_move);
|
||||
};
|
||||
|
||||
public static IEqualityComparer<double> get_double_comparer(
|
||||
TickFactors tick_factors = null, double display_mult = double.NaN) {
|
||||
if (tick_factors is null) {
|
||||
return new TickFactors(10^7, 1).tick_equality_comparer();
|
||||
}
|
||||
// This equality comparer is used to compare actual values (not multiplied by
|
||||
// 'display_mult'), while the TickFactors are used to format the display value (multiplied
|
||||
// by 'display_mult'). Multiply the tick base by 'display_mult' so the equality comparison
|
||||
// is done with the correct number of decimal places.
|
||||
if (display_mult > 0 && Math.Log10(display_mult).is_int()) {
|
||||
tick_factors = tick_factors.with(
|
||||
tick_base: tick_factors.tick_base * display_mult);
|
||||
}
|
||||
return tick_factors.tick_equality_comparer();
|
||||
}
|
||||
(data, is_up) => data is double d_data ?
|
||||
tick_factors.tick(d_data, is_up ? tick_move : -tick_move) :
|
||||
data;
|
||||
|
||||
public static VolSurfaceDisplayGridColumn get_double_output_col(
|
||||
string group,
|
||||
@@ -140,10 +113,7 @@
|
||||
col_config,
|
||||
format: get_double_tostring(col_config.tick_factors, col_config.tick_display),
|
||||
parse: get_parse_double(col_config.tick_factors, col_config.tick_display),
|
||||
tick_move: get_double_tickmove(col_config.tick_factors, col_config.tick_move),
|
||||
comparer: get_double_comparer(
|
||||
col_config.tick_factors, col_config.tick_display.display_multiplier)
|
||||
.cast<double, object>());
|
||||
tick_move: get_double_tickmove(col_config.tick_factors, col_config.tick_move));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using mbts.analytics;
|
||||
using bts.api;
|
||||
using bts.collections;
|
||||
using System.Linq;
|
||||
using bts.api.orderman;
|
||||
using bts;
|
||||
|
||||
namespace mbts.spark {
|
||||
// Listens to the interp theos, decorates the data
|
||||
// and sends them over to the sparkd server
|
||||
public class InterpTheosServerPublisher : IDisposable {
|
||||
private readonly ThreadedBlackboard _bb;
|
||||
private readonly bts.api.orderman.OrderService _order_service;
|
||||
private HighPerformanceTimer _timer = new HighPerformanceTimer();
|
||||
|
||||
public InterpTheosServerPublisher(ThreadedBlackboard bb,
|
||||
bts.api.orderman.OrderService order_service) {
|
||||
bts.Log.Ui.info(
|
||||
$"InterpTheosServerPublisher cons tid:{VolSurfaceTroubleshootingFunctions.tid()}");
|
||||
_bb = bb;
|
||||
_order_service = order_service;
|
||||
_bb.subscribe(SparkTags.AllInterpGreeks);
|
||||
_bb.subscribe(SparkTags.SystemContractsTag);
|
||||
_bb.data_callback += _on_data;
|
||||
}
|
||||
|
||||
private void _on_data(object tag, object data) {
|
||||
if (tag.Equals(SparkTags.SystemContractsTag) ||
|
||||
tag.Equals(SparkTags.AllInterpGreeks)) {
|
||||
_publish_data();
|
||||
}
|
||||
}
|
||||
|
||||
private static IDictionary<UInt32, DriverMD> _get_drivers(
|
||||
IReadOnlyDictionary<string, OptionDriverPriceMap> driver_map,
|
||||
SystemContractData sc_data) {
|
||||
var rv = new Dictionary<UInt32, DriverMD>();
|
||||
foreach (var kv in driver_map) {
|
||||
rv.AddRange(
|
||||
SecurityNormalizer.normalize_drivers(kv.Value, sc_data).ToArray());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static IEnumerable<Tuple<SecurityImmutable, TheoPoint>> _get_theos(
|
||||
IReadOnlyDictionary<string, OptionTheoInterpolationData> theo_data,
|
||||
SystemContractData sc_data) {
|
||||
var rv = new List<Tuple<SecurityImmutable, TheoPoint>>();
|
||||
foreach (var kv in theo_data) {
|
||||
rv.AddRange(
|
||||
SecurityNormalizer.normalize_interp_theos(kv.Value, sc_data));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private void _publish_data() {
|
||||
SystemContractData sc_data = _bb.read_state(SparkTags.SystemContractsTag, null);
|
||||
IReadOnlyDictionary<string, OptionTheoInterpolationData> all_theos =
|
||||
_bb.read_state(SparkTags.AllInterpGreeks, null);
|
||||
IReadOnlyDictionary<string, OptionDriverPriceMap> all_drivers =
|
||||
_bb.read_state(SparkTags.AllOptionDriverBBOTag, null);
|
||||
if (sc_data == null || all_theos == null || all_drivers == null)
|
||||
return;
|
||||
_timer.start();
|
||||
IDictionary<UInt32, DriverMD> driver_map = _get_drivers(all_drivers, sc_data);
|
||||
IEnumerable<Tuple<SecurityImmutable, TheoPoint>> theo_map = _get_theos(all_theos, sc_data);
|
||||
// assemble it together and send it to the server
|
||||
var ptp_list = new List<bts.api.orderman.PrecomputedTheoPoint>();
|
||||
foreach (var tup in theo_map) {
|
||||
SecurityImmutable sec = tup.Item1;
|
||||
TheoPoint tp = tup.Item2;
|
||||
bool is_call = sec.Option.CallPut == PutOrCall.Call;
|
||||
var sec_id = sec.Id;
|
||||
DriverMD dmd = null;
|
||||
driver_map.TryGetValue(sec_id, out dmd);
|
||||
PrecomputedTheoPoint ptp = new PrecomputedTheoPoint();
|
||||
ptp.SecId = sec_id;
|
||||
ptp.Driver = tp.driver;
|
||||
ptp.DriverSecId = dmd != null && dmd.driver_security.HasValue ?
|
||||
dmd.driver_security.Value.Id : 0;
|
||||
ptp.Theo = is_call ? tp.call : tp.put;
|
||||
ptp.Delta = is_call ? tp.cdelta : tp.pdelta;
|
||||
ptp.Gamma = is_call ? tp.cgamma : tp.pgamma;
|
||||
ptp.Vega = is_call ? tp.cvega : tp.pvega;
|
||||
ptp.Theta = is_call ? tp.c_theta : tp.p_theta;
|
||||
ptp.Rho = Double.NaN;
|
||||
ptp_list.Add(ptp);
|
||||
}
|
||||
bts.api.orderman.PrecomputedTheos server_theos = new PrecomputedTheos();
|
||||
server_theos.Theos.AddRange(ptp_list);
|
||||
_timer.stop();
|
||||
var comp_time = _timer.lastIntervalTime;
|
||||
_timer.start();
|
||||
_order_service.set_precomputed_theos(server_theos);
|
||||
_timer.stop();
|
||||
var pub_time = _timer.lastIntervalTime;
|
||||
bts.Log.Gen.info($"InterpTheosServerPublisher._publish_data " +
|
||||
$"size: {server_theos.Theos.Count} comp_time: {comp_time} msecs " +
|
||||
$"pub_time: {pub_time}");
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
_bb.data_callback -= _on_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ using bts.api;
|
||||
using mbts.ui;
|
||||
using MathNet.Numerics.Providers.FourierTransform;
|
||||
using BCG;
|
||||
using System.Windows.Automation;
|
||||
using bts.collections;
|
||||
|
||||
namespace mbts.spark {
|
||||
// Publishes theos for all options (on the side, also publishes the theos for TC2)
|
||||
@@ -70,14 +68,19 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
private void _log_theos(SystemContractData sc_data,
|
||||
IReadOnlyDictionary<uint, GreeksTuple> greeks_map) {
|
||||
IReadOnlyDictionary<uint, GreeksTuple> greeks_map,
|
||||
DateTime? exp_filt = null) {
|
||||
string rv = "LiveTheosPublisher data: ";
|
||||
foreach (var kv in greeks_map) {
|
||||
var id = kv.Key;
|
||||
var g_tup = kv.Value;
|
||||
if (sc_data.sec_md_map.TryGetValue(id, out var smd)) {
|
||||
string sec_str = smd.ToString();
|
||||
rv += "\n" + $"id: {id} sec: {sec_str} greeks: {g_tup}";
|
||||
if (exp_filt == null ||
|
||||
(smd.security.security_type() == SecurityType.Option &&
|
||||
smd.security.Option.expiration_date().Equals(exp_filt.Value))) {
|
||||
string sec_str = smd.ToString();
|
||||
rv += "\n" + $"id: {id} sec: {sec_str} greeks: {g_tup}";
|
||||
}
|
||||
}
|
||||
}
|
||||
bts.Log.Gen.info(rv);
|
||||
@@ -131,7 +134,6 @@ namespace mbts.spark {
|
||||
return;
|
||||
}
|
||||
var k_theos = new Dictionary<SecurityStrike, TheoPoint>();
|
||||
// option spreads
|
||||
foreach (var kv in sc_data.strike_map) {
|
||||
foreach (SecurityStrike k in kv.Value) {
|
||||
var (call_id, put_id) = k.call_put_id;
|
||||
@@ -140,59 +142,26 @@ namespace mbts.spark {
|
||||
k_theos[k] = tp;
|
||||
// put it in the output map
|
||||
if (call_id.HasValue) {
|
||||
var normalized_theo = VolSurfaceCoreFunctions.normalize_theo(tp.call, tp.driver);
|
||||
res.Add(call_id.Value,
|
||||
new GreeksTuple(tp.vol, tp.driver, tp.call, tp.cdelta, tp.cgamma,
|
||||
tp.cvega, tp.c_theta, Double.NaN, normalized_theo));
|
||||
tp.cvega, tp.c_theta, Double.NaN));
|
||||
}
|
||||
if (put_id.HasValue) {
|
||||
var normalized_theo = VolSurfaceCoreFunctions.normalize_theo(tp.put, tp.driver);
|
||||
res.Add(put_id.Value,
|
||||
new GreeksTuple(tp.vol, tp.driver, tp.put, tp.pdelta, tp.pgamma,
|
||||
tp.pvega, tp.p_theta, Double.NaN, normalized_theo));
|
||||
tp.pvega, tp.p_theta, Double.NaN));
|
||||
}
|
||||
}
|
||||
}
|
||||
// futures
|
||||
var future_theos = _get_future_theos();
|
||||
res.AddRange(future_theos);
|
||||
// spreads, all option and future non tied spreads
|
||||
foreach (var spr in sc_data.spreads) {
|
||||
GreeksTuple gtup = StatelessSpreadCalculator.compute_non_tied_spread(spr.security, res);
|
||||
res.Add(spr.security.Id, gtup);
|
||||
}
|
||||
// copy and publish
|
||||
IReadOnlyDictionary<uint, GreeksTuple> res_ro = res;
|
||||
bts.Log.Gen.info($"LiveTheoPublisher._interp_and_publish posting " +
|
||||
$"count: {res_ro.Count}");
|
||||
$"count: {res_ro.Count}");
|
||||
_timer.stop();
|
||||
_logger.log(_log_id, _log_id, _timer.lastIntervalTime);
|
||||
_bb.post(SparkTags.Greeks, res_ro);
|
||||
// oh and those TC2 theos for comptability
|
||||
_publish_tc2_theos(k_theos);
|
||||
}
|
||||
|
||||
// If we do any rolls like SP for futures, it will be here
|
||||
IDictionary<UInt32, GreeksTuple> _get_future_theos() {
|
||||
var rv = new Dictionary<UInt32, GreeksTuple>();
|
||||
SystemContractData sc_data = _bb.read_state(SparkTags.SystemContractsTag);
|
||||
if (sc_data == null)
|
||||
return rv;
|
||||
foreach (var kv in sc_data.exp_map) {
|
||||
var id = kv.Value;
|
||||
SecurityMD sec_md;
|
||||
if (sc_data.sec_md_map.TryGetValue(id, out sec_md)) {
|
||||
if (sec_md.security.HasFuture) {
|
||||
SecurityExpiration exp = kv.Key;
|
||||
double pr = sec_md.md.fixing_price;
|
||||
rv.Add(sec_md.security.Id,
|
||||
new GreeksTuple(0, pr, pr, 1, 0, 0, 0, 0, pr));
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// recomputes and publishes them periodicially
|
||||
void _publish_future_theos() {
|
||||
if (DateTime.Now - _last_future_theos_published < _futures_theos_publish_period)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#nullable enable
|
||||
namespace mbts.spark {
|
||||
using bts.api;
|
||||
|
||||
using mbts.analytics;
|
||||
|
||||
using System;
|
||||
@@ -41,10 +39,5 @@ namespace mbts.spark {
|
||||
.SelectMany(kv => kv.Value.exp_price_map)
|
||||
.ToDictionaryCrushed(kv => kv.Key.to_vs_exp(), kv => kv.Value);
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<SecurityExpiration, DriverMD> get_price_map() {
|
||||
return new Dictionary<SecurityExpiration, DriverMD>(exp_price_map);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
namespace mbts.spark {
|
||||
using bts.api;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
// A lot of options data (migrated from edge) is not normalized
|
||||
// on the sec_id, but rather on a combination of symbol, exp, strike.
|
||||
// Additionally the exchange is missing. This class serves as that
|
||||
// one since point to resolve that.
|
||||
// (Over time we will normalize all the data and this wont be needed)
|
||||
public static class SecurityNormalizer {
|
||||
// f(option_exp:driver_md) -> (sec_id:driver_md)
|
||||
|
||||
public static IDictionary<UInt32, DriverMD> normalize_drivers(
|
||||
OptionDriverPriceMap driver_map, SystemContractData sc_data) {
|
||||
if (driver_map is null) {
|
||||
return new Dictionary<uint, DriverMD>(0);
|
||||
}
|
||||
Dictionary<UInt32, DriverMD> rv = new Dictionary<uint, DriverMD>();
|
||||
foreach (var kv in driver_map.get_price_map()) {
|
||||
var exp = kv.Key;
|
||||
var dmd = kv.Value;
|
||||
IEnumerable<SecurityMD> exp_secs = sc_data.get_securities(
|
||||
(sec_md) => {
|
||||
var s = sec_md.security;
|
||||
return s.security_type() == SecurityType.Option &&
|
||||
s.Symbol == driver_map.option_symbol &&
|
||||
s.earliest_expiration() == exp.expiration;
|
||||
}
|
||||
);
|
||||
foreach (var sec_md in exp_secs) {
|
||||
rv.Add(sec_md.security.Id, kv.Value);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static IEnumerable<Tuple<SecurityImmutable, TheoPoint>> normalize_interp_theos(
|
||||
OptionTheoInterpolationData symbol_theos, SystemContractData sc_data) {
|
||||
if (symbol_theos is null) {
|
||||
return Enumerable.Empty<Tuple<SecurityImmutable, TheoPoint>>();
|
||||
}
|
||||
var rv = new List<Tuple<SecurityImmutable, TheoPoint>>();
|
||||
foreach (DateTime exp in symbol_theos.get_expirations()) {
|
||||
Dictionary<double, Dictionary<double, TheoPoint>> exp_data =
|
||||
symbol_theos.get_expiration_data(exp);
|
||||
// exp_data is driver vs strike vs TP
|
||||
foreach (var exp_kv in exp_data) {
|
||||
foreach (var k_kv in exp_kv.Value) {
|
||||
double strike = k_kv.Key;
|
||||
TheoPoint tp = k_kv.Value;
|
||||
IEnumerable<SecurityMD> calls = sc_data.get_options(
|
||||
null, symbol_theos.symbol, exp, strike, PutOrCall.Call);
|
||||
IEnumerable<SecurityMD> puts = sc_data.get_options(
|
||||
null, symbol_theos.symbol, exp, strike, PutOrCall.Put);
|
||||
foreach (SecurityMD sec_md in calls) {
|
||||
rv.Add(Tuple.Create(sec_md.security, tp));
|
||||
}
|
||||
foreach (SecurityMD sec_md in puts) {
|
||||
rv.Add(Tuple.Create(sec_md.security, tp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -108,22 +107,6 @@ namespace mbts.spark {
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityImmutable? get_option_contract(
|
||||
Venue venue, string symbol, DateTime exp, double strike, PutOrCall cp) {
|
||||
var k_tup = get_option_sec_id(venue, symbol, exp, strike);
|
||||
if (k_tup != null) {
|
||||
var id = cp == PutOrCall.Call ? k_tup.Item1 : k_tup.Item2;
|
||||
if (id.HasValue) {
|
||||
var id_val = id.Value;
|
||||
SecurityMD sec_md;
|
||||
if (sec_md_map.TryGetValue(id_val, out sec_md)) {
|
||||
return sec_md.security;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tuple<uint?, uint?> get_option_sec_id(
|
||||
Venue venue, string symbol, DateTime exp, double strike) {
|
||||
var s_exp = new SecurityExpiration(venue, SecurityType.Option, symbol, exp);
|
||||
@@ -259,28 +242,5 @@ namespace mbts.spark {
|
||||
kv.Value.Count > 0).Select(kv => kv.Key.expiration);
|
||||
}
|
||||
|
||||
public IEnumerable<SecurityMD> spreads {
|
||||
get {
|
||||
return sec_md_map.Where(kv => kv.Value.security.HasSpread)
|
||||
.Select(kv => kv.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<SecurityMD> get_securities(Func<SecurityMD, bool> criteria) {
|
||||
return sec_md_map.Values.Where(sec_md => criteria(sec_md));
|
||||
}
|
||||
|
||||
public IEnumerable<SecurityMD> get_options(
|
||||
Venue? exchange, string option_name, DateTime? exp, double? strike, PutOrCall? cp) {
|
||||
return get_securities(sc => {
|
||||
var s = sc.security;
|
||||
return s.security_type() == SecurityType.Option &&
|
||||
(exchange == null || s.Exchange == exchange) &&
|
||||
(exp == null || s.earliest_expiration() == exp) &&
|
||||
(strike == null || s.strike() == strike) &&
|
||||
(cp == null || s.Option.CallPut == cp);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -63,27 +63,6 @@ namespace mbts.spark {
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static string log_string(this VolSurfaceCalculationRequest vs_req) {
|
||||
if (vs_req == null) {
|
||||
return "Null";
|
||||
}
|
||||
string action_str = String.Empty;
|
||||
foreach (var kv in vs_req.action_map) {
|
||||
action_str += $"exp: {kv.Key.ToString()} action: {kv.Value.ToString()}, ";
|
||||
}
|
||||
action_str = action_str.TrimEnd(',', ' ');
|
||||
return $"vs_inp: {vs_req.volsurface_input.log_string()}\nreq_id: {vs_req.request_id}\n" +
|
||||
$"action_map: {action_str}\nup: {vs_req.cascade_up} down: {vs_req.cascade_down}";
|
||||
}
|
||||
|
||||
public static string log_string(this VolSurfaceCalculationResponse resp) {
|
||||
if (resp == null) {
|
||||
return "Null";
|
||||
}
|
||||
return $"req_id: {resp.request_id} vs_output: " +
|
||||
$"{resp.volsurface_calculation_output.volsurface_input.log_string()}";
|
||||
}
|
||||
|
||||
private static string _trim_leading_char(string s, char c) {
|
||||
if (!s.is_null_or_empty() && s.EndsWith(c)) {
|
||||
return s.Remove(s.Length - 1, 1);
|
||||
@@ -92,12 +71,11 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
internal static string log_string(this VolSurfaceDisplayModel.DisplayModelData dm_data) {
|
||||
var vs_output = dm_data.vs_output;
|
||||
var exp_grid = dm_data.exp_grid;
|
||||
var vs_output_str = vs_output == null ? "NULL" : vs_output.volsurface_input.log_string();
|
||||
var exp_grid_str = exp_grid == null ? "NULL" : exp_grid.log_string();
|
||||
var rv = $"DisplayModelData\nvs_output:\n{vs_output_str}\n" +
|
||||
$"exp_grid\n{exp_grid_str}\n";
|
||||
string rv = String.Empty;
|
||||
string global_grid_str = dm_data.global_grid == null ? "Null" : dm_data.global_grid.log_string();
|
||||
rv += $"global_grid: {global_grid_str} \n";
|
||||
string exp_grid_str = dm_data.exp_grid == null ? "Null" : dm_data.exp_grid.log_string();
|
||||
rv += $"exp_grid: {exp_grid_str} \n";
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -113,19 +91,19 @@ namespace mbts.spark {
|
||||
}
|
||||
|
||||
internal static string log_string(this VolSurfaceDisplayGrid dgrid) {
|
||||
Func<IDictionary<string, object>, string> log_exp = (col_val_map) => {
|
||||
Func<IDictionary<string, object>, string> log_exp = (map) => {
|
||||
string rv = String.Empty;
|
||||
foreach (var kv in col_val_map) {
|
||||
foreach (var kv in map) {
|
||||
string val_string = kv.Value == null ? "Null" : kv.Value.ToString();
|
||||
rv += $"{kv.Key}: {val_string}, ";
|
||||
rv += $"{kv.Key}:{val_string},";
|
||||
}
|
||||
return _trim_leading_char(rv, ',');
|
||||
};
|
||||
string rv = String.Empty;
|
||||
foreach (var kv in dgrid.data_map) {
|
||||
rv += $"Exp: {kv.Key.expiration.ToShortDateString()} Data: {log_exp(kv.Value)}\n";
|
||||
rv += $"Exp:{kv.Key.expiration.ToShortDateString()} Data:{log_exp(kv.Value)},";
|
||||
}
|
||||
return rv;
|
||||
return _trim_leading_char(rv, ',');
|
||||
}
|
||||
|
||||
internal static string log_string(this OptionDriverPriceMap map) {
|
||||
@@ -260,15 +238,6 @@ namespace mbts.spark {
|
||||
return rv;
|
||||
}
|
||||
|
||||
internal static string log_string(this IPNLUnit p) {
|
||||
string rv = "IPNLUnit:";
|
||||
rv += $" account: {p.account} sec: {p.security.security_desc()} driver: {p.driver} theo: {p.theo} settle: {p.settle_price}" +
|
||||
$" start_pos: {p.start_long_pos - p.start_short_pos} day_pos: {p.day_long_pos - p.day_short_pos}" +
|
||||
$" start_pnl: {p.start_pnl} start_delta: {p.start_delta} start_vega: {p.start_vega}" +
|
||||
$" day_pnl: {p.day_pnl} day_delta: {p.day_delta} day_vega: {p.day_vega}";
|
||||
return rv;
|
||||
}
|
||||
|
||||
internal static int tid() {
|
||||
return System.Threading.Thread.CurrentThread.ManagedThreadId;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace mbts.spark {
|
||||
using System.Collections.Generic;
|
||||
|
||||
[ProtoContract]
|
||||
class VolSurfaceGraphSettings : IProtobuf<VolSurfaceGraphSettings> {
|
||||
class VolSurfaceGraphSettings : IEquatable<VolSurfaceGraphSettings>, ICloneable {
|
||||
public static VolSurfaceGraphSettings get_default() {
|
||||
return new VolSurfaceGraphSettings {
|
||||
put_control_points = new ScatterSeriesSettings {
|
||||
@@ -110,7 +110,7 @@ namespace mbts.spark {
|
||||
// }
|
||||
//}
|
||||
|
||||
public VolSurfaceGraphSettings Clone() =>
|
||||
public object Clone() =>
|
||||
ProtobufSerializationHelper.clone(this);
|
||||
|
||||
public bool Equals(VolSurfaceGraphSettings other) =>
|
||||
|
||||
@@ -6,10 +6,6 @@ using mbts.analytics;
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.utility;
|
||||
|
||||
using Spark.Core;
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Collections;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -55,7 +51,7 @@ namespace mbts.spark {
|
||||
var vs_removes = removed.Select(exp => exp.ToVSExp());
|
||||
|
||||
var true_removed = removed.Where(rmv => !vs_adds.Contains(rmv.ToVSExp()));
|
||||
var true_added = added.Except(vs_removes.Concat(_hidden_exps), v => v.ToVSExp());
|
||||
var true_added = added.Where(add => !vs_removes.Contains(add.ToVSExp()));
|
||||
var changed_calc_modes = added.Where(add => vs_removes.Contains(add.ToVSExp()));
|
||||
|
||||
foreach (var tr in true_removed) {
|
||||
@@ -65,10 +61,16 @@ namespace mbts.spark {
|
||||
}
|
||||
}
|
||||
|
||||
var comp = ComparerWrapper<object>.wrap_cast(
|
||||
NullCheckComparer.create<IExpirationBasedRow>(
|
||||
(r1, r2) => r1.expiration.CompareTo(r2.expiration)));
|
||||
visible_rows.InsertSorted(true_added, comp);
|
||||
foreach (var ta in true_added) {
|
||||
if (_hidden_exps.Contains(ta.ToVSExp()) ||
|
||||
!rows.TryGetFirst(r => r.expiration.expiration == ta.expiration, out var row)) {
|
||||
continue;
|
||||
}
|
||||
visible_rows.InsertSorted(row,
|
||||
Comparer<IExpirationBasedRow>.Create(
|
||||
(r1, r2) => r1.expiration.CompareTo(r2.expiration))
|
||||
.wrap<IExpirationBasedRow, object>());
|
||||
}
|
||||
|
||||
foreach (var ccm in changed_calc_modes) {
|
||||
int index = visible_rows
|
||||
|
||||
@@ -10,10 +10,6 @@ namespace mbts.spark {
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.utility;
|
||||
|
||||
using Spark.Analytics.View;
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -31,13 +27,13 @@ namespace mbts.spark {
|
||||
readonly LinearAxisVM _x_axis = new() { position = AxisPosition.BottomLeftToRight };
|
||||
readonly LinearAxisVM _y_axis = new() { position = AxisPosition.LeftBottomToTop };
|
||||
readonly Dictionary<SecurityExpiration, ExpGraphBounds> _expiration_graph_bounds;
|
||||
readonly VolSurfaceGraphSettings _settings;
|
||||
readonly ObservableCollection<VolSurfaceDisplayGridExpiration> _expirations = new();
|
||||
readonly Dictionary<VolSurfaceDisplayGridExpiration, SeriesSetVM> _expiration_series_cache = new();
|
||||
|
||||
VolSurfaceExpiration _md_exp;
|
||||
VolSurfaceDisplayGridExpiration _expiration;
|
||||
VolSurfaceDisplayGridExpiration _earliest_selected_expiration;
|
||||
VolSurfaceGraphSettings _settings;
|
||||
object _implied_vol_market_side = ImpliedVolHelper.None;
|
||||
bool _show_vol_path;
|
||||
|
||||
@@ -86,17 +82,13 @@ namespace mbts.spark {
|
||||
if (_model.get_active_settings() is not VolSurfaceSettings vss) {
|
||||
return null;
|
||||
}
|
||||
var vm = new VolSurfaceGraphSettingsVM(vss.core_settings.vol_surface_name);
|
||||
vm.load_from(_settings.Clone());
|
||||
vm.request_commit += commit;
|
||||
return new VolSurfaceGraphSettingsWindow {
|
||||
DataContext = vm
|
||||
};
|
||||
|
||||
void commit(VolSurfaceGraphSettings settings) {
|
||||
_settings = settings;
|
||||
_recreate_series();
|
||||
}
|
||||
// return new VolSurfaceGraphSettingsEditor {
|
||||
// DataContext = new VolSurfaceGraphSettingsEditorVM(vss.core_settings.vol_surface_name, ProtoBufSerializationHelper.clone_protobuf(_settings), settings => {
|
||||
// _settings = settings;
|
||||
// _recreate_series();
|
||||
// })
|
||||
// };
|
||||
return null;
|
||||
});
|
||||
graph_vm = new BTSGraphVM {
|
||||
plot_area_background = Colors.Transparent,
|
||||
@@ -125,7 +117,7 @@ namespace mbts.spark {
|
||||
})
|
||||
.BufferLatest(TimeSpan.FromSeconds(0.1))
|
||||
.OnDispatcher()
|
||||
.SelectSeries(series => Observable.Create<SeriesVM>(o => {
|
||||
.SelectManyInSeries(series => Observable.Create<SeriesVM>(o => {
|
||||
o.OnNext(null);
|
||||
return Disposable.Create(series
|
||||
.Select(svm => svm.points.Subscribe((s, e) => o.OnNext(svm)))
|
||||
@@ -193,20 +185,6 @@ namespace mbts.spark {
|
||||
static (double call_wing_start, double put_wing_start) _get_actual_wing_starts(VolCurveDisplayGraph disp_graph) =>
|
||||
disp_graph.all_points.Select(p => p.Item1).MinMax() ?? (double.NaN, double.NaN);
|
||||
|
||||
void _recreate_series() {
|
||||
/// 'graph_vm.series_set' is bound to '_expirations', so clearing and re-adding expirations
|
||||
/// in turn regenerates the series. '_expiration_series_cache' must
|
||||
/// be cleared as well, otherwise cached series vms would just be back to the collection
|
||||
/// ('graph_vm.series_set').
|
||||
var visible_exp = _earliest_selected_expiration;
|
||||
_expiration_series_cache.Clear();
|
||||
_expirations.SetItems(_model.get_ordered_expirations());
|
||||
foreach (var svm in graph_vm.series.OfType<SeriesSetVM>()) {
|
||||
svm.is_visible = svm.args.Equals(visible_exp);
|
||||
}
|
||||
_update();
|
||||
}
|
||||
|
||||
void _expirations_changed(IEnumerable<VolSurfaceDisplayGridExpiration> added, IEnumerable<VolSurfaceDisplayGridExpiration> removed) {
|
||||
_expirations.sync_with(_model.get_ordered_expirations());
|
||||
_update();
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
namespace mbts.spark {
|
||||
using mbts.ui;
|
||||
using mbts.ui.shell;
|
||||
|
||||
using System;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows.Input;
|
||||
|
||||
class VolGridCellVM : DisposableViewModelBase {
|
||||
readonly Property<object> _candidate_value;
|
||||
readonly Property<object> _committed_value;
|
||||
readonly Property<bool> _is_dirty;
|
||||
|
||||
public VolGridCellVM(string column_id) {
|
||||
this.column_id = column_id ?? throw new ArgumentNullException(nameof(column_id));
|
||||
_committed_value = backing<object>(nameof(committed_value));
|
||||
_candidate_value = backing<object>(nameof(candidate_value));
|
||||
_is_dirty = backing(nameof(is_dirty),
|
||||
_committed_value.observe_current(true)
|
||||
.CombineLatest(_candidate_value.observe_current(true))
|
||||
.Select(tup => !Equals(tup.First, tup.Second))
|
||||
.OnDispatcher());
|
||||
}
|
||||
|
||||
public string column_id { get; }
|
||||
|
||||
public object committed_value {
|
||||
get => _committed_value.Value;
|
||||
set => _committed_value.set(value);
|
||||
}
|
||||
|
||||
public object candidate_value {
|
||||
get => _candidate_value.Value;
|
||||
set => _candidate_value.set(value);
|
||||
}
|
||||
|
||||
public bool is_dirty => _is_dirty.Value;
|
||||
|
||||
public IObservable<object> observe_candidate(bool start_immediately = false) =>
|
||||
_candidate_value.observe_current(start_immediately);
|
||||
|
||||
public void revert() =>
|
||||
candidate_value = committed_value;
|
||||
|
||||
public override string ToString() =>
|
||||
$"column_id: {column_id}, committed: {committed_value}, candidate: {candidate_value}";
|
||||
}
|
||||
|
||||
class VolGridCellVM<T> : VolGridCellVM {
|
||||
public VolGridCellVM(string column_id) : base(column_id) { }
|
||||
|
||||
public VolGridCellVM(string column_id, T committed_value, T candidate_value) : base(column_id) {
|
||||
this.committed_value = committed_value;
|
||||
this.candidate_value = candidate_value;
|
||||
}
|
||||
|
||||
public new T committed_value {
|
||||
get => base.committed_value is T v ? v : default;
|
||||
set => base.committed_value = value;
|
||||
}
|
||||
|
||||
public new T candidate_value {
|
||||
get => base.candidate_value is T v ? v : default;
|
||||
set => base.candidate_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
class VolGridTickCellVM : VolGridCellVM {
|
||||
ICommand _tick_up_cmd;
|
||||
ICommand _tick_down_cmd;
|
||||
|
||||
public VolGridTickCellVM(string column_id) : base(column_id) { }
|
||||
|
||||
public event Action<bool> request_tick;
|
||||
|
||||
public ICommand tick_up_cmd =>
|
||||
_tick_up_cmd ??= new DelegateCommand(() =>
|
||||
request_tick?.Invoke(true));
|
||||
|
||||
public ICommand tick_down_cmd =>
|
||||
_tick_down_cmd ??= new DelegateCommand(() =>
|
||||
request_tick?.Invoke(false));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#nullable enable
|
||||
namespace mbts.spark.VolSurface {
|
||||
using System.Windows.Media;
|
||||
|
||||
readonly struct VolSurfaceCellState {
|
||||
public bool is_dirty => committed_text is not null;
|
||||
|
||||
public FormattedText? text { get; init; }
|
||||
public FormattedText? committed_text { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
#nullable enable
|
||||
namespace mbts.spark {
|
||||
using bts;
|
||||
|
||||
using mbts.ui.controls;
|
||||
using mbts.ui.shell;
|
||||
|
||||
using Spark.Core;
|
||||
|
||||
using System;
|
||||
|
||||
class VolSurfaceCellVM : DisposableViewModelBase {
|
||||
readonly Property<object?> _candidate_value;
|
||||
readonly Property<object?> _committed_value;
|
||||
readonly DelegateProperty<bool> _is_dirty;
|
||||
readonly DeferrableAction _refresh;
|
||||
|
||||
public VolSurfaceCellVM(
|
||||
VolSurfaceDisplayGridExpiration expiration, VolSurfaceDisplayGridColumn column) {
|
||||
this.column = column ?? throw new ArgumentNullException(nameof(column));
|
||||
this.expiration = expiration ?? throw new ArgumentNullException(nameof(expiration));
|
||||
_committed_value = backing<object?>(nameof(committed_value), column.comparer);
|
||||
_candidate_value = backing<object?>(nameof(candidate_value), column.comparer);
|
||||
_is_dirty = backing(
|
||||
nameof(is_dirty), () => !column.comparer.Equals(candidate_value, committed_value));
|
||||
_refresh = new(_is_dirty.refresh);
|
||||
_committed_value.Changed += on_committed_changed;
|
||||
_candidate_value.Changed += on_candidate_changed;
|
||||
_is_dirty.Changed += (o, n) => {
|
||||
Log.assert(o != n);
|
||||
Log.Ui.info(
|
||||
$"VolSurface '{expiration}.{column}' is_dirty changed to {n}. " +
|
||||
$"commited: {committed_value}; candidate: {candidate_value}");
|
||||
};
|
||||
|
||||
void on_committed_changed(object? oldval, object? newval) =>
|
||||
_is_dirty.refresh();
|
||||
|
||||
void on_candidate_changed(object? oldval, object? newval) =>
|
||||
_is_dirty.refresh();
|
||||
}
|
||||
|
||||
public event PropertyChange<object?>? candidate_value_changed {
|
||||
add => _candidate_value.Changed += value;
|
||||
remove => _candidate_value.Changed -= value;
|
||||
}
|
||||
|
||||
public VolSurfaceDisplayGridColumn column { get; }
|
||||
public string column_id => column.unique_col_name;
|
||||
public VolSurfaceDisplayGridExpiration expiration { get; }
|
||||
|
||||
public object? committed_value {
|
||||
get => _committed_value.Value;
|
||||
set => _committed_value.set(value);
|
||||
}
|
||||
|
||||
public object? candidate_value {
|
||||
get => _candidate_value.Value;
|
||||
set => _candidate_value.set(value);
|
||||
}
|
||||
|
||||
public bool is_dirty => _is_dirty.Value;
|
||||
|
||||
public IObservable<object?> observe_candidate(bool start_immediately = false) =>
|
||||
_candidate_value.observe_current(start_immediately);
|
||||
|
||||
public void reset(object? committed_value, object? candidate_value) {
|
||||
using var _ = _refresh.defer();
|
||||
this.committed_value = committed_value;
|
||||
this.candidate_value = candidate_value;
|
||||
}
|
||||
|
||||
public void revert() =>
|
||||
candidate_value = committed_value;
|
||||
|
||||
public override string ToString() =>
|
||||
$"column: {column}, committed: {committed_value}, candidate: {candidate_value}";
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ namespace mbts.spark.VolSurface {
|
||||
view.SetBinding(FrameworkElement.DataContextProperty, new Binding() {
|
||||
Converter = _data_context_converter
|
||||
});
|
||||
view.SetBinding(TextBlock.TextProperty, new Binding(nameof(VolSurfaceCellVM.candidate_value)) {
|
||||
view.SetBinding(TextBlock.TextProperty, new Binding(nameof(VolGridCellVM.candidate_value)) {
|
||||
Converter = ValueConverter.create(obj => model.format(obj))
|
||||
});
|
||||
return view;
|
||||
@@ -101,16 +101,16 @@ namespace mbts.spark.VolSurface {
|
||||
view.SetBinding(FrameworkElement.DataContextProperty, new Binding() {
|
||||
Converter = _data_context_converter
|
||||
});
|
||||
view.SetBinding(VolSurfaceCellView.CommittedValueProperty, new Binding(nameof(VolSurfaceCellVM.committed_value)) {
|
||||
view.SetBinding(VolSurfaceCellView.CommittedValueProperty, new Binding(nameof(VolGridCellVM.committed_value)) {
|
||||
Mode = BindingMode.OneWay,
|
||||
Converter = ValueConverter.create(obj => model.format(obj))
|
||||
});
|
||||
view.SetBinding(VolSurfaceCellView.CandidateValueProperty, new Binding(nameof(VolSurfaceCellVM.candidate_value)) {
|
||||
view.SetBinding(VolSurfaceCellView.CandidateValueProperty, new Binding(nameof(VolGridCellVM.candidate_value)) {
|
||||
Mode = BindingMode.TwoWay,
|
||||
Converter = ValueConverter.create<object, string>(obj => model.format(obj), obj => model.parse(obj))
|
||||
});
|
||||
view.SetBinding(VolSurfaceCellView.TickDownCommandProperty, new Binding(nameof(VolSurfaceTickCellVM.tick_down_cmd)));
|
||||
view.SetBinding(VolSurfaceCellView.TickUpCommandProperty, new Binding(nameof(VolSurfaceTickCellVM.tick_up_cmd)));
|
||||
view.SetBinding(VolSurfaceCellView.TickDownCommandProperty, new Binding(nameof(VolGridTickCellVM.tick_down_cmd)));
|
||||
view.SetBinding(VolSurfaceCellView.TickUpCommandProperty, new Binding(nameof(VolGridTickCellVM.tick_up_cmd)));
|
||||
var bd = new Border {
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||
VerticalAlignment = VerticalAlignment.Stretch,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#nullable enable
|
||||
namespace mbts.spark.VolSurface {
|
||||
using bts;
|
||||
using bts.collections;
|
||||
@@ -12,10 +11,6 @@ namespace mbts.spark.VolSurface {
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.utility;
|
||||
|
||||
using Spark.Core;
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Collections;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -30,20 +25,17 @@ namespace mbts.spark.VolSurface {
|
||||
class VolSurfaceGridVM : DisposableViewModelBase {
|
||||
readonly VolSurfaceVM _parent;
|
||||
readonly ObservableCollection<VolSurfaceDisplayGridExpiration> _expirations = new();
|
||||
readonly DeferrableAction _invalidate_rows;
|
||||
readonly DeferrableActionWrapper _invalidate_rows;
|
||||
readonly ColumnsModel _columns_model;
|
||||
|
||||
ISet<string> _hidden_columns;
|
||||
ISet<VolSurfaceExpiration>? _hidden_expirations;
|
||||
IDisposable? _shift_editor;
|
||||
ISet<VolSurfaceExpiration> _hidden_expirations;
|
||||
IDisposable _shift_editor;
|
||||
|
||||
public VolSurfaceGridVM(
|
||||
VolSurfaceVM vm,
|
||||
VolSurfaceDisplayModel model,
|
||||
ISet<string> hidden_columns,
|
||||
ISet<VolSurfaceExpiration> hidden_expirations) {
|
||||
Log.notnull(hidden_columns);
|
||||
Log.notnull(hidden_expirations);
|
||||
public VolSurfaceGridVM(VolSurfaceVM vm, VolSurfaceDisplayModel model,
|
||||
ISet<string> hidden_columns, ISet<VolSurfaceExpiration> hidden_expirations) {
|
||||
Log.assert(hidden_columns != null);
|
||||
Log.assert(hidden_expirations != null);
|
||||
_parent = vm;
|
||||
this.model = model;
|
||||
_columns_model = new(create_exp_column_view());
|
||||
@@ -71,31 +63,16 @@ namespace mbts.spark.VolSurface {
|
||||
};
|
||||
|
||||
_dispose = Disposable.Create(
|
||||
ObservableAutoWrapper.connect(_expirations, rows, row_factory),
|
||||
ObservableAutoWrapper.connect_item_hooks(rows, connect_row),
|
||||
ObservableAutoWrapper.connect(_expirations, rows, exp => new VolSurfaceRowVM(this, exp), row => row.Dispose()),
|
||||
sorted_visible_rows.bind(visible_rows),
|
||||
Disposable.Create(() => {
|
||||
this.model.on_candidate_grid_change -= _on_grid_updated;
|
||||
this.model.on_committed_grid_change -= _on_grid_updated;
|
||||
rows.DisposeAll(true);
|
||||
Disposable.dispose(rows);
|
||||
Disposable.dispose(ref _shift_editor);
|
||||
}),
|
||||
_columns_model);
|
||||
|
||||
VolSurfaceRowVM row_factory(VolSurfaceDisplayGridExpiration exp) =>
|
||||
new(this, exp);
|
||||
|
||||
IDisposable connect_row(VolSurfaceRowVM row) {
|
||||
row.request_calculate += request_recalc;
|
||||
return Disposable.Create(() => {
|
||||
row.request_calculate -= request_recalc;
|
||||
row.Dispose();
|
||||
});
|
||||
|
||||
void request_recalc() =>
|
||||
model.set_candidate_grid(current_grid);
|
||||
}
|
||||
|
||||
VolSurfaceColumn create_exp_column_view() {
|
||||
var filter = new ComboCheckBox();
|
||||
filter.SetResourceReference(FrameworkElement.StyleProperty, "ExpirationFilterDropDown");
|
||||
@@ -115,7 +92,7 @@ namespace mbts.spark.VolSurface {
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<IEnumerable<VolSurfaceDisplayGridExpiration>>? on_selection_changed;
|
||||
public event Action<IEnumerable<VolSurfaceDisplayGridExpiration>> on_selection_changed;
|
||||
|
||||
public VolSurfaceDisplayGrid current_grid { get; private set; }
|
||||
public VolSurfaceDisplayGrid committed_grid { get; private set; }
|
||||
@@ -141,7 +118,6 @@ namespace mbts.spark.VolSurface {
|
||||
.Select(group => new DIYGridSuperHeaderVM(group.Key, group.Count(), collapsed_content: _short_header(group.Key)))
|
||||
.ToList();
|
||||
|
||||
public ICommand populate_empty_exps_cmd => _parent.populate_empty_exps_cmd;
|
||||
public ICommand main_settings_cmd => _parent.main_settings_cmd;
|
||||
public ICommand advanced_settings_cmd => _parent.advanced_settings_cmd;
|
||||
public ICommand graph_settings_cmd => _parent.vol_curve_vm.settings_command;
|
||||
@@ -165,14 +141,13 @@ namespace mbts.spark.VolSurface {
|
||||
rows.select_exp().Except(visible_rows.select_exp());
|
||||
|
||||
public void invalidate_rows() =>
|
||||
_invalidate_rows.Invoke();
|
||||
_invalidate_rows.execute();
|
||||
|
||||
public IDisposable defer_invalidate_rows() =>
|
||||
_invalidate_rows.defer();
|
||||
_invalidate_rows.defer_execution();
|
||||
|
||||
public VolSurfaceColumn get_column(string id) =>
|
||||
columns.FirstOrDefault(c => c.id == id) as VolSurfaceColumn ??
|
||||
throw new InvalidOperationException($"Failed to find column '{id}'");
|
||||
columns.FirstOrDefault(c => c.id == id) as VolSurfaceColumn;
|
||||
|
||||
internal void signal_selection_changed() {
|
||||
var e = on_selection_changed;
|
||||
@@ -243,7 +218,7 @@ namespace mbts.spark.VolSurface {
|
||||
!_hidden_columns.Contains(column.unique_col_name);
|
||||
|
||||
void _on_grid_updated() {
|
||||
using var _ = _invalidate_rows.defer();
|
||||
using var _ = _invalidate_rows.defer_execution();
|
||||
var grid_new = model.get_active_grid();
|
||||
// add/remove columns
|
||||
var cols_new = grid_new.get_ordered_columns()
|
||||
@@ -268,7 +243,7 @@ namespace mbts.spark.VolSurface {
|
||||
}
|
||||
current_grid = grid_new;
|
||||
committed_grid = is_dirty ? model.get_committed_grid() : current_grid;
|
||||
_invalidate_rows.Invoke();
|
||||
_invalidate_rows.execute();
|
||||
}
|
||||
|
||||
void _launch_shift_editor(VolSurfaceDisplayGridColumn column, Action<double> commit_shift) {
|
||||
@@ -349,7 +324,7 @@ namespace mbts.spark.VolSurface {
|
||||
model.set_candidate_grid(current_grid);
|
||||
|
||||
class ColumnsModel : IDisposable {
|
||||
IDisposable? _dispose;
|
||||
IDisposable _dispose;
|
||||
|
||||
public ColumnsModel(VolSurfaceColumn row_header_col) {
|
||||
views_with_header_ro = ObservableAutoWrapper.create_read_only_wrapper(views_with_header);
|
||||
|
||||
@@ -8,8 +8,6 @@ namespace mbts.spark {
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.utility;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -81,7 +79,6 @@ namespace mbts.spark {
|
||||
|
||||
public bool is_input_cell => column?.type == VolSurfaceColumnType.ReadWriteTick;
|
||||
|
||||
public ICommand populate_empty_exps_cmd => _parent.populate_empty_exps_cmd;
|
||||
public ICommand main_settings_cmd => _parent.main_settings_cmd;
|
||||
public ICommand advanced_settings_cmd => _parent.advanced_settings_cmd;
|
||||
public ICommand grid_settings_cmd => _parent.grid_settings_cmd;
|
||||
|
||||
@@ -4,19 +4,22 @@ namespace mbts.spark.VolSurface {
|
||||
using mbts.ui.controls;
|
||||
using mbts.ui.shell;
|
||||
|
||||
using Spark.Core;
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows.Media;
|
||||
|
||||
public struct VolSurfaceCellState {
|
||||
public bool is_dirty => committed_text is not null;
|
||||
public FormattedText? text;
|
||||
public FormattedText? committed_text;
|
||||
}
|
||||
|
||||
class VolSurfaceRowVM : DisposableViewModelBase, ISelectable, IFormatCellsToClipboard, DIYGrid.IRowVM {
|
||||
readonly VolSurfaceGridVM _parent;
|
||||
readonly VolSurfaceDisplayGridExpiration _exp;
|
||||
readonly Dictionary<string, CellData> _cells = new();
|
||||
readonly DeferrableAction _request_calculate;
|
||||
|
||||
VolSurfaceRowContextMenuVM? _context_menu;
|
||||
bool _is_selected;
|
||||
@@ -24,7 +27,6 @@ namespace mbts.spark.VolSurface {
|
||||
public VolSurfaceRowVM(VolSurfaceGridVM parent, VolSurfaceDisplayGridExpiration exp) {
|
||||
_parent = parent;
|
||||
_exp = exp;
|
||||
_request_calculate = new(() => request_calculate?.Invoke());
|
||||
_dispose = Disposable.Create(() => {
|
||||
_cells.Values.DisposeAll();
|
||||
_cells.Clear();
|
||||
@@ -34,7 +36,6 @@ namespace mbts.spark.VolSurface {
|
||||
|
||||
public event Action<bool>? is_selected_changed;
|
||||
public event Action? invalidated;
|
||||
public event Action? request_calculate;
|
||||
|
||||
public VolSurfaceDisplayGridExpiration expiration => _exp;
|
||||
|
||||
@@ -51,14 +52,12 @@ namespace mbts.spark.VolSurface {
|
||||
public VolSurfaceRowContextMenuVM context_menu =>
|
||||
_context_menu ??= new(_parent, this);
|
||||
|
||||
public VolSurfaceCellVM get_cell(VolSurfaceDisplayGridColumn column) =>
|
||||
public VolGridCellVM get_cell(VolSurfaceDisplayGridColumn column) =>
|
||||
_cells.GetOrAdd(column.unique_col_name, _ => _create_cell(column)).vm;
|
||||
|
||||
public void invalidate() {
|
||||
using (_request_calculate.supress()) {
|
||||
foreach (var cell in _cells.Values) {
|
||||
_sync_cell(cell.vm);
|
||||
}
|
||||
foreach (var cell in _cells.Values) {
|
||||
_sync_cell(cell.vm);
|
||||
}
|
||||
invalidated?.Invoke();
|
||||
}
|
||||
@@ -80,15 +79,29 @@ namespace mbts.spark.VolSurface {
|
||||
CellData _create_cell(VolSurfaceDisplayGridColumn column) {
|
||||
var cell = column.type switch {
|
||||
VolSurfaceColumnType.ReadWriteTick => create_tick_cell(),
|
||||
_ => new VolSurfaceCellVM(_exp, column)
|
||||
_ => new VolGridCellVM(column.unique_col_name),
|
||||
};
|
||||
_sync_cell(cell);
|
||||
return new(cell, _connect_cell(cell));
|
||||
var dispose = cell.observe_candidate().DistinctUntilChanged().OnDispatcher()
|
||||
.Subscribe(value => {
|
||||
var curr = _parent.current_grid.read(expiration, column);
|
||||
if (Equals(value, curr)) {
|
||||
return;
|
||||
}
|
||||
var grid = _parent.current_grid;
|
||||
grid.write(expiration, column, value);
|
||||
_parent.model.set_candidate_grid(grid);
|
||||
});
|
||||
return new(cell, dispose);
|
||||
|
||||
VolSurfaceCellVM create_tick_cell() {
|
||||
var cell = new VolSurfaceTickCellVM(_exp, column);
|
||||
VolGridTickCellVM create_tick_cell() {
|
||||
var cell = new VolGridTickCellVM(column.unique_col_name);
|
||||
cell.request_tick += is_up => {
|
||||
var col = _parent.get_column(column.unique_col_name);
|
||||
if (col is null) {
|
||||
throw new InvalidOperationException(
|
||||
$"Failed to find column with id {column.unique_col_name}");
|
||||
}
|
||||
if (col.model?.tick_move is var tm) {
|
||||
cell.candidate_value = tm?.Invoke(cell.candidate_value, is_up);
|
||||
return;
|
||||
@@ -99,48 +112,23 @@ namespace mbts.spark.VolSurface {
|
||||
}
|
||||
}
|
||||
|
||||
void _sync_cell(VolSurfaceCellVM cell) {
|
||||
void _sync_cell(VolGridCellVM cell) {
|
||||
if (cell is null) {
|
||||
return;
|
||||
}
|
||||
using var _ = _request_calculate.supress();
|
||||
cell.reset(
|
||||
committed_value: _parent.committed_grid.read(_exp, cell.column_id),
|
||||
candidate_value: _parent.current_grid.read(_exp, cell.column_id));
|
||||
}
|
||||
|
||||
IDisposable? _connect_cell(VolSurfaceCellVM cell) {
|
||||
return cell.column.type switch {
|
||||
VolSurfaceColumnType.ReadWriteTick => connect_input(),
|
||||
_ => null
|
||||
};
|
||||
|
||||
IDisposable connect_input() {
|
||||
cell.candidate_value_changed += on_candidate_value_changed;
|
||||
return Disposable.Create(() =>
|
||||
cell.candidate_value_changed -= on_candidate_value_changed);
|
||||
|
||||
void on_candidate_value_changed(object? oldval, object? newval) {
|
||||
var curr = _parent.current_grid.read(expiration, cell.column);
|
||||
if (cell.column.comparer.Equals(newval, curr)) {
|
||||
return;
|
||||
}
|
||||
var grid = _parent.current_grid;
|
||||
grid.write(expiration, cell.column, newval);
|
||||
_request_calculate.Invoke();
|
||||
}
|
||||
}
|
||||
cell.committed_value = _parent.committed_grid.read(_exp, cell.column_id);
|
||||
cell.candidate_value = _parent.current_grid.read(_exp, cell.column_id);
|
||||
}
|
||||
|
||||
class CellData : IDisposable {
|
||||
IDisposable? _dispose;
|
||||
IDisposable _dispose;
|
||||
|
||||
public CellData(VolSurfaceCellVM vm, IDisposable? dispose) {
|
||||
public CellData(VolGridCellVM vm, IDisposable dispose) {
|
||||
this.vm = vm;
|
||||
_dispose = Disposable.Create(vm, dispose);
|
||||
}
|
||||
|
||||
public VolSurfaceCellVM vm { get; }
|
||||
public VolGridCellVM vm { get; }
|
||||
|
||||
public void Dispose() =>
|
||||
Disposable.dispose(ref _dispose);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#nullable enable
|
||||
namespace mbts.spark {
|
||||
using mbts.ui;
|
||||
using mbts.ui.controls;
|
||||
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
class VolSurfaceTickCellVM : VolSurfaceCellVM {
|
||||
ICommand? _tick_up_cmd;
|
||||
ICommand? _tick_down_cmd;
|
||||
|
||||
public VolSurfaceTickCellVM(
|
||||
VolSurfaceDisplayGridExpiration expiration, VolSurfaceDisplayGridColumn column)
|
||||
: base(expiration, column) { }
|
||||
|
||||
public event Action<bool>? request_tick;
|
||||
|
||||
public ICommand tick_up_cmd =>
|
||||
_tick_up_cmd ??= new DelegateCommand(() =>
|
||||
request_tick?.Invoke(true));
|
||||
|
||||
public ICommand tick_down_cmd =>
|
||||
_tick_down_cmd ??= new DelegateCommand(() =>
|
||||
request_tick?.Invoke(false));
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace mbts.spark {
|
||||
get => _core_settings.font_weight_override;
|
||||
set {
|
||||
using var _ = detect_property_change();
|
||||
_core_settings.with(font_weight_override: value.HasValue ? new(value) : null);
|
||||
_core_settings.with(font_weight_override: value.HasValue ? new NullableFontWeightProto(value) : null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using mbts.ui;
|
||||
using mbts.ui.controls.graph;
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace mbts.spark
|
||||
{
|
||||
class VolSurfaceGraphSettingsEditorVM
|
||||
{
|
||||
public VolSurfaceGraphSettingsEditorVM(string vol_surface_name, VolSurfaceGraphSettings settings, Action<VolSurfaceGraphSettings> commit) {
|
||||
this.vol_surface_name = vol_surface_name;
|
||||
_settings = settings;
|
||||
this.commit = new DelegateCommand(() => commit(_settings));
|
||||
}
|
||||
|
||||
private readonly VolSurfaceGraphSettings _settings;
|
||||
|
||||
public string vol_surface_name { get; private set; }
|
||||
|
||||
public VolSurfaceScatterSeriesSettingsVM implied_puts { get { return new VolSurfaceScatterSeriesSettingsVM(_settings.implied_puts); } }
|
||||
public VolSurfaceScatterSeriesSettingsVM implied_atm { get { return new VolSurfaceScatterSeriesSettingsVM(_settings.implied_atm); } }
|
||||
public VolSurfaceScatterSeriesSettingsVM implied_calls { get { return new VolSurfaceScatterSeriesSettingsVM(_settings.implied_calls); } }
|
||||
|
||||
public VolSurfaceScatterSeriesSettingsVM put_control_points { get { return new VolSurfaceScatterSeriesSettingsVM(_settings.put_control_points); } }
|
||||
public VolSurfaceScatterSeriesSettingsVM atm { get { return new VolSurfaceScatterSeriesSettingsVM(_settings.atm); } }
|
||||
public VolSurfaceScatterSeriesSettingsVM call_control_points { get { return new VolSurfaceScatterSeriesSettingsVM(_settings.call_control_points); } }
|
||||
|
||||
public VolSurfaceLineSeriesSettingsVM put_wing { get { return new VolSurfaceLineSeriesSettingsVM(_settings.put_wing); } }
|
||||
public VolSurfaceLineSeriesSettingsVM inner_curve { get { return new VolSurfaceLineSeriesSettingsVM(_settings.inner_curve); } }
|
||||
public VolSurfaceLineSeriesSettingsVM call_wing { get { return new VolSurfaceLineSeriesSettingsVM(_settings.call_wing); } }
|
||||
|
||||
public VolSurfaceLineSeriesSettingsVM vol_path { get { return new VolSurfaceLineSeriesSettingsVM(_settings.vol_path); } }
|
||||
|
||||
public ICommand commit { get; private set; }
|
||||
}
|
||||
|
||||
|
||||
class VolSurfaceScatterSeriesSettingsVM
|
||||
{
|
||||
public VolSurfaceScatterSeriesSettingsVM(ScatterSeriesSettings settings) {
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
private readonly ScatterSeriesSettings _settings;
|
||||
|
||||
public MarkerShape shape { get { return _settings.shape; } set { _settings.shape = value; } }
|
||||
public double size { get { return _settings.size; } set { _settings.size = value; } }
|
||||
public Color fill {
|
||||
get => _settings.fill;
|
||||
set => _settings.fill = value;
|
||||
}
|
||||
public Color stroke {
|
||||
get => _settings.stroke;
|
||||
set => _settings.stroke = value;
|
||||
}
|
||||
|
||||
public Array shapes { get { return Enum.GetValues(typeof(MarkerShape)); } }
|
||||
}
|
||||
|
||||
class VolSurfaceLineSeriesSettingsVM
|
||||
{
|
||||
public VolSurfaceLineSeriesSettingsVM(LineSeriesSettings settings) {
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
private readonly LineSeriesSettings _settings;
|
||||
|
||||
public Color color { get { return (Color)_settings.color; } set { _settings.color = (BTSColor)value; } }
|
||||
public double thickness { get { return _settings.stroke_thickness; } set { _settings.stroke_thickness = value; } }
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ namespace mbts.spark {
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.utility;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
using System;
|
||||
@@ -540,7 +539,7 @@ namespace mbts.spark {
|
||||
public ObservableCollection<VSSymbol> symbols { get; private set; }
|
||||
|
||||
public void Dispose() =>
|
||||
symbols.DisposeAll(true);
|
||||
Disposable.dispose(symbols);
|
||||
}
|
||||
|
||||
public class VSSymbolStructureVM : DisposableViewModelBase {
|
||||
@@ -551,11 +550,11 @@ namespace mbts.spark {
|
||||
_selected_driver_grid = backing<VSSymbolGridVM>(nameof(selected_driver_grid));
|
||||
settings.core_settings.master_slave_relationships ??= new List<VolSurfaceSymbolRelationship>();
|
||||
settings.core_settings.implied_vol_marketdata_relationships ??= new List<VolSurfaceSymbolRelationship>();
|
||||
_dispose = Disposable.Create(
|
||||
_dispose = new DisposableCombo(
|
||||
driver_grids.Subscribe((s, e) =>
|
||||
selected_driver_grid ??= driver_grids.FirstOrDefault()),
|
||||
bus.subscribe(SparkTags.ExpirationParametersInputTag).OnDispatcher().Subscribe(on_exp_params_input),
|
||||
Disposable.Create(() => driver_grids.DisposeAll(true)));
|
||||
bus.subscribe(SparkTags.ExpirationParametersInputTag).OnDispatcher().Subscribe(on_exp_params_input)) +
|
||||
new Action(() => Disposable.dispose(driver_grids));
|
||||
|
||||
void on_exp_params_input(AnalyticsExpirationParametersMap data) {
|
||||
var driver_map = data.get_option_driver_map();
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace mbts.spark {
|
||||
using mbts.ui.controls;
|
||||
using mbts.ui.shell;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.ViewModel.Commands;
|
||||
|
||||
using System;
|
||||
@@ -61,7 +60,6 @@ namespace mbts.spark {
|
||||
vol_terms_vm = new VolTermsGraphVM(_model, demux);
|
||||
|
||||
// command
|
||||
populate_empty_exps_cmd = new Command(() => { _model.populate_empty_expirations(); });
|
||||
_revert_cmd = new Command(o => _model.revert(), o => _model.is_dirty);
|
||||
_commit_cmd = new Command(o => _model.commit(), o => _model.is_dirty);
|
||||
load_previous_cmd = new Command(
|
||||
@@ -187,7 +185,6 @@ namespace mbts.spark {
|
||||
|
||||
public ICommand revert_cmd => _revert_cmd;
|
||||
public ICommand commit_cmd => _commit_cmd;
|
||||
public ICommand populate_empty_exps_cmd { get; }
|
||||
public ICommand main_settings_cmd => _main_settings_cmd;
|
||||
public ICommand advanced_settings_cmd => _advanced_settings_cmd;
|
||||
public ICommand grid_settings_cmd => _grid_settings_cmd;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
using mbts.ui.shell;
|
||||
|
||||
using Spark.Core;
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using mbts.analytics;
|
||||
using mbts.ui.controls;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
using System;
|
||||
@@ -127,20 +126,6 @@
|
||||
_log_bad_transition(_state, "set candidate grid");
|
||||
}
|
||||
|
||||
public void populate_empty_expirations() {
|
||||
bts.Log.Ui.info(String.Format("VolSurfaceDisplayModel.populate_expirations called with state: {0}",
|
||||
_state.ToString()));
|
||||
if (_state == DisplayModelState.Idle || _state == DisplayModelState.ResponseReady) {
|
||||
DisplayModelData curr_data = _get_current_data();
|
||||
VolSurfaceInput vs_inp =
|
||||
VolSurfaceDataFunctions.populate_empty_expirations(curr_data.vs_output.volsurface_input);
|
||||
_change_state(DisplayModelState.WaitingForCalcResponse);
|
||||
_bus.post(SparkTags.VolSurfaceCalculationRequestTag(_vs_id),
|
||||
new VolSurfaceCalculationRequest(vs_inp, _request_version_no++));
|
||||
} else
|
||||
_log_bad_transition(_state, "populate_expirations");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Globals
|
||||
@@ -160,7 +145,6 @@
|
||||
return (_committed_data != null && _committed_data.vs_output != null) ? _committed_data.vs_output.volsurface_input.surface_parameters.vol_time : DateTime.MinValue;
|
||||
}
|
||||
public void set_candidate_vol_time(DateTime vol_time) {
|
||||
bts.Log.Ui.info($"VolSurfaceDisplayModel.set_candidate_vol_time vs_id: {_vs_id} state: {_state.ToString()} vol_time: {vol_time}");
|
||||
if (_state == DisplayModelState.Idle || _state == DisplayModelState.ResponseReady) {
|
||||
DisplayModelData curr_data = _get_current_data();
|
||||
if (curr_data != null) {
|
||||
@@ -584,7 +568,9 @@
|
||||
private void _change_state(DisplayModelState new_state) {
|
||||
bool dirty_before = _translate_to_dirty(_state),
|
||||
dirty_after = _translate_to_dirty(new_state);
|
||||
bts.Log.Ui.info($"VolSurfaceDisplayModel._change_state vs_id: {_vs_id} {_state.ToString()}->{new_state.ToString()}");
|
||||
// mbts.Logger.log(bts.log.Level.Info, bts.log.Subsystem.ui,
|
||||
// String.Format("State change {0}->{1}", _state.ToString(), new_state.ToString()));
|
||||
bts.Log.Ui.info(String.Format("State change {0}->{1}", _state.ToString(), new_state.ToString()));
|
||||
_state = new_state;
|
||||
if (dirty_before != dirty_after && on_dirty_change != null) {
|
||||
_bus.post(SparkTags.VolSurfaceDirtyStateTag(_vs_id), dirty_after);
|
||||
@@ -627,8 +613,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
private void _log_bad_transition(DisplayModelState state, string action) {
|
||||
bts.Log.Ui.error($"VoLSurfaceDisplayModel bad_transaction vs_id: {_vs_id} {state}:{action}");
|
||||
private static void _log_bad_transition(DisplayModelState state, string action) {
|
||||
//mbts.Logger.log(bts.log.Level.Error, bts.log.Subsystem.ui, String.Format("{0}:{1}", state, action));
|
||||
bts.Log.Ui.error(String.Format("{0}:{1}", state, action));
|
||||
}
|
||||
|
||||
private static bool _translate_to_dirty(DisplayModelState state) {
|
||||
|
||||
@@ -172,18 +172,6 @@ namespace mbts.spark {
|
||||
return new(sec.Exchange, sec.ContractCase, sec.Symbol, exp_date, sec.Id);
|
||||
}
|
||||
|
||||
public static SecurityTuple security_tuple(this Security sec) {
|
||||
return security_tuple(new SecurityImmutable(sec));
|
||||
}
|
||||
|
||||
public static SecurityTuple security_tuple(this SecurityImmutable sec) {
|
||||
bts.api.SecurityTuple rv = new SecurityTuple();
|
||||
rv.Symbol = sec.Symbol;
|
||||
rv.Type = sec.security_type();
|
||||
rv.Venue = sec.Exchange;
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static ExpirationDriver to_exp_driver(this SecurityExpiration sec_exp) =>
|
||||
new() {
|
||||
Security = new() {
|
||||
|
||||
@@ -5,8 +5,6 @@ using bts.api.core;
|
||||
using bts.collections;
|
||||
using bts.utils;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
@@ -43,7 +41,7 @@ namespace mbts.spark {
|
||||
on_users = Observable.Return(DictionaryHelper.wrap_value(user.id, user.name));
|
||||
all_user_tuples = user.permissions == UserTuple.Permissions.Admin ?
|
||||
service.subscribei_admin_data()
|
||||
.Select(u => u.all.FirstOrNull())
|
||||
.Select(u => u.all.TryFirst())
|
||||
.Where(ad => ad.HasValue)
|
||||
.Select(ad => ad.Value.Users
|
||||
.Where(u => user.can_access_user_data(u.Id))
|
||||
@@ -52,14 +50,11 @@ namespace mbts.spark {
|
||||
.Table(UserTuple.key_fn)
|
||||
.Cache() :
|
||||
Observable.Return(TableUpdate<UserTuple, uint>.mk_empty(UserTuple.key_fn).with_added(new[] { user }));
|
||||
_dispose = Disposable.Create(
|
||||
all_user_tuples.Subscribe(t => bus.post(SparkTags.Users, t.state)),
|
||||
on_accounts.Subscribe(map => {
|
||||
_account_map = map;
|
||||
var account_tuple_map = MappedDictionary.create(map, (id, name) => new AccountTuple(id, name));
|
||||
bus.post(SparkTags.AccountsTag, account_tuple_map);
|
||||
}));
|
||||
bus.post(SparkTags.CurrentUser, user);
|
||||
_dispose = on_accounts.Subscribe(map => {
|
||||
_account_map = map;
|
||||
var account_tuple_map = MappedDictionary.create(map, (id, name) => new AccountTuple(id, name));
|
||||
bus.post(SparkTags.AccountsTag, account_tuple_map);
|
||||
});
|
||||
}
|
||||
|
||||
public IObservable<IReadOnlyDictionary<uint, string>> on_users { get; }
|
||||
@@ -81,7 +76,7 @@ namespace mbts.spark {
|
||||
}));
|
||||
|
||||
public AccountTuple? get_default_account() =>
|
||||
_account_map.Select(kv => new AccountTuple(kv.Key, kv.Value)).FirstOrNull();
|
||||
_account_map.Select(kv => new AccountTuple(kv.Key, kv.Value)).TryFirst();
|
||||
|
||||
public void Dispose() =>
|
||||
Disposable.dispose(ref _dispose);
|
||||
|
||||
@@ -10,8 +10,7 @@ namespace mbts.analytics {
|
||||
double gamma = double.NaN,
|
||||
double vega = double.NaN,
|
||||
double theta = double.NaN,
|
||||
double rho = double.NaN,
|
||||
double normalized_theo = double.NaN) {
|
||||
double rho = double.NaN) {
|
||||
this.vol = vol;
|
||||
this.driver = driver;
|
||||
this.theo = theo;
|
||||
@@ -20,7 +19,6 @@ namespace mbts.analytics {
|
||||
this.vega = vega;
|
||||
this.theta = theta;
|
||||
this.rho = rho;
|
||||
this.normalized_theo = normalized_theo;
|
||||
}
|
||||
|
||||
public static GreeksTuple empty => new();
|
||||
@@ -33,7 +31,6 @@ namespace mbts.analytics {
|
||||
public double vega { get; }
|
||||
public double theta { get; }
|
||||
public double rho { get; }
|
||||
public double normalized_theo { get; }
|
||||
|
||||
public bool Equals(GreeksTuple other) =>
|
||||
vol.Equals(other.vol) &&
|
||||
@@ -68,8 +65,7 @@ namespace mbts.analytics {
|
||||
double? gamma = null,
|
||||
double? vega = null,
|
||||
double? theta = null,
|
||||
double? rho = null,
|
||||
double? normalized_theo = null) =>
|
||||
double? rho = null) =>
|
||||
new(
|
||||
vol ?? greeks_tuple.vol,
|
||||
driver ?? greeks_tuple.driver,
|
||||
@@ -78,7 +74,12 @@ namespace mbts.analytics {
|
||||
gamma ?? greeks_tuple.gamma,
|
||||
vega ?? greeks_tuple.vega,
|
||||
theta ?? greeks_tuple.theta,
|
||||
rho ?? greeks_tuple.rho,
|
||||
normalized_theo ?? greeks_tuple.normalized_theo);
|
||||
rho ?? greeks_tuple.rho);
|
||||
|
||||
public static double normalized_theo(this in GreeksTuple greeks_tuple) =>
|
||||
greeks_tuple.theo / greeks_tuple.driver;
|
||||
|
||||
public static double normalized_delta(this in GreeksTuple greeks_tuple) =>
|
||||
greeks_tuple.delta / greeks_tuple.driver;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ namespace mbts {
|
||||
|
||||
using ProtoBuf;
|
||||
|
||||
using Spark.Core;
|
||||
using Spark.Core.Collections;
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
@@ -101,13 +100,17 @@ namespace mbts {
|
||||
|
||||
public static IComparer<SecurityExpiration> get_comparer(Properties prop) {
|
||||
return prop switch {
|
||||
Properties.Type => ComparerWrapper<SecurityExpiration>.wrap(s => s.security_type),
|
||||
Properties.Symbol => ComparerWrapper<SecurityExpiration>.wrap(s => s.symbol),
|
||||
Properties.Expiration => ComparerWrapper<SecurityExpiration>.wrap(s => s.expiration),
|
||||
Properties.Venue => ComparerWrapper<SecurityExpiration>.wrap(s => s.exchange),
|
||||
Properties.Id => ComparerWrapper<SecurityExpiration>.wrap(s => s.id),
|
||||
Properties.Type => wrap(s => s.security_type),
|
||||
Properties.Symbol => wrap(s => s.symbol),
|
||||
Properties.Expiration => wrap(s => s.expiration),
|
||||
Properties.Venue => wrap(s => s.exchange),
|
||||
Properties.Id => wrap(s => s.id).to_safe(),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
static IComparer<SecurityExpiration> wrap<T>(
|
||||
Func<SecurityExpiration, T> selector, IComparer<T>? comparer = null) =>
|
||||
(comparer ?? Comparer<T>.Default).wrap(selector);
|
||||
}
|
||||
|
||||
public static IComparer<SecurityExpiration> get_comparer(params Properties[] hierarchy) =>
|
||||
@@ -145,7 +148,7 @@ namespace mbts {
|
||||
!(x == y);
|
||||
|
||||
public override string ToString() =>
|
||||
$"{security_tuple} {SecurityFormatter.format_expiration(expiration)}";
|
||||
$"{security_tuple} {expiration.ToShortDateString()}";
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
@@ -186,6 +189,6 @@ namespace mbts {
|
||||
exchange ?? sec_exp.exchange, security_type ?? sec_exp.security_type,
|
||||
symbol ?? sec_exp.symbol,
|
||||
expiration ?? sec_exp.expiration,
|
||||
id.has_value ? id : sec_exp.id);
|
||||
id.has_value ? id.value : sec_exp.id);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ namespace mbts.analytics {
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return String.Format("{0} {1} {2}",
|
||||
return String.Format("{0} {1} {2}",
|
||||
security_type.ToString().ToUpper().First(), symbol, expiration.ToShortDateString());
|
||||
}
|
||||
|
||||
@@ -74,11 +74,6 @@ namespace mbts.analytics {
|
||||
int rv = expiration.CompareTo(other.expiration);
|
||||
return rv != 0 ? rv : symbol.CompareTo(other.symbol);
|
||||
}
|
||||
|
||||
public double diff_days(VolSurfaceExpiration exp_other) {
|
||||
TimeSpan ts = expiration - exp_other.expiration;
|
||||
return ts.TotalDays;
|
||||
}
|
||||
}
|
||||
|
||||
public static class VolSurfaceExpirationExtensions {
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
using mbts.co2;
|
||||
|
||||
namespace mbts.analytics {
|
||||
using Size = System.Single;
|
||||
public class VolSurfaceMDUnit : IEquatable<VolSurfaceMDUnit> {
|
||||
public readonly double bid_price, ask_price;
|
||||
public readonly Size bid_size, ask_size;
|
||||
public readonly uint bid_size, ask_size;
|
||||
public readonly double mark_price = double.NaN;
|
||||
private static VolSurfaceMDUnit _empty =
|
||||
new VolSurfaceMDUnit(Double.NaN, 0, Double.NaN, 0, Double.NaN);
|
||||
|
||||
public VolSurfaceMDUnit(double this_bid_price, Size this_bid_size,
|
||||
double this_ask_price, Size this_ask_size,
|
||||
public VolSurfaceMDUnit(double this_bid_price, uint this_bid_size,
|
||||
double this_ask_price, uint this_ask_size,
|
||||
double this_mark_price) {
|
||||
bid_price = this_bid_price;
|
||||
bid_size = this_bid_size;
|
||||
@@ -29,7 +28,7 @@ namespace mbts.analytics {
|
||||
|
||||
public VolSurfaceMDUnit(NativePriceSize bid, NativePriceSize ask,
|
||||
double mark_price)
|
||||
: this(bid.price, bid.size_f, ask.price, ask.size_f, mark_price) {
|
||||
: this(bid.price, bid.size, ask.price, ask.size, mark_price) {
|
||||
}
|
||||
|
||||
public bool is_two_sided() { return bid_size != 0 && ask_size != 0; }
|
||||
@@ -42,7 +41,7 @@ namespace mbts.analytics {
|
||||
}
|
||||
|
||||
public double get_weighted_mid_price(bool get_one_sided_mid = true) {
|
||||
Size sum_q = bid_size + ask_size;
|
||||
uint sum_q = bid_size + ask_size;
|
||||
if (sum_q == 0) {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
@@ -943,15 +943,7 @@ namespace mbts.analytics {
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region inverse contracts
|
||||
// Bitcoin contracts, for example, where the strike is in USD, and the theo
|
||||
// needs to be in terms of the underlying contract
|
||||
public static double normalize_theo(double theo, double fwd) {
|
||||
return fwd == 0 ? Double.NaN : (theo / fwd);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Other Pricing Utilities
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@ namespace mbts.analytics
|
||||
/// with default inputs
|
||||
public static VolSurfaceInput sync_input_expirations_to_master_list(VolSurfaceInput vs_input, IEnumerable<VolSurfaceExpiration> system_exp_list)
|
||||
{
|
||||
HashSet<VolSurfaceExpiration> vs_exp_map = new HashSet<VolSurfaceExpiration>(vs_input.surface_parameters.curve_parameters_map.Select(t => t.Item1)),
|
||||
sys_exp_map = new HashSet<VolSurfaceExpiration>(system_exp_list);
|
||||
var vs_exp_map = vs_input.surface_parameters.curve_parameters_map
|
||||
.empty_if_null().Select(t => t.Item1).ToHashSet();
|
||||
var sys_exp_map = system_exp_list.ToHashSet();
|
||||
sys_exp_map.difference(
|
||||
vs_exp_map,
|
||||
out HashSet<VolSurfaceExpiration> deleted_exps,
|
||||
@@ -680,60 +681,5 @@ namespace mbts.analytics
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Data copying
|
||||
|
||||
public static bool exp_has_input(VolSurfaceSettings vs_settings, VolCurveParameters exp_params) {
|
||||
if (exp_params == null || vs_settings == null)
|
||||
return false;
|
||||
double atm_vol = get_atm_vol(vs_settings, exp_params);
|
||||
double ref_fwd = exp_params.core_parameters.ref_forward;
|
||||
return !Double.IsNaN(atm_vol) && !Double.IsNaN(ref_fwd);
|
||||
}
|
||||
|
||||
public static VolSurfaceExpiration find_nearest_populated_exp(
|
||||
VolSurfaceInput vs_input, VolSurfaceExpiration vs_exp) {
|
||||
VolCurveParameters exp_params = get_curve_parameters(vs_input, vs_exp);
|
||||
if (exp_has_input(vs_input.surface_settings, exp_params))
|
||||
return vs_exp;
|
||||
VolSurfaceExpiration rv = null;
|
||||
double rv_diff_days = Double.MaxValue;
|
||||
foreach (var kv in vs_input.surface_parameters.curve_parameters_map) {
|
||||
var this_exp = kv.Item1;
|
||||
var this_exp_params = kv.Item2;
|
||||
if (exp_has_input(vs_input.surface_settings, this_exp_params)) {
|
||||
double this_exp_diff_days = Math.Abs(vs_exp.diff_days(this_exp));
|
||||
if (this_exp_diff_days < rv_diff_days) {
|
||||
rv = this_exp;
|
||||
rv_diff_days = this_exp_diff_days;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Copies the empty exps from closest neighbor
|
||||
public static VolSurfaceInput populate_empty_expirations(VolSurfaceInput vs_input) {
|
||||
VolSurfaceInput rv = Spark.Core.Protobuf.ProtobufSerializationHelper.clone(vs_input);
|
||||
rv.surface_parameters.curve_parameters_map.Clear();
|
||||
foreach (var kv in vs_input.surface_parameters.curve_parameters_map) {
|
||||
var vs_exp = kv.Item1;
|
||||
var exp_params = kv.Item2;
|
||||
if (!exp_has_input(vs_input.surface_settings, exp_params)) {
|
||||
VolSurfaceExpiration np_exp = find_nearest_populated_exp(vs_input, vs_exp);
|
||||
if (np_exp != null) {
|
||||
var np_exp_params = get_curve_parameters(vs_input, np_exp);
|
||||
if (np_exp_params != null) {
|
||||
exp_params = Spark.Core.Protobuf.ProtobufSerializationHelper.clone(np_exp_params);
|
||||
}
|
||||
}
|
||||
}
|
||||
rv.surface_parameters.curve_parameters_map.Add(
|
||||
new Tuple<VolSurfaceExpiration, VolCurveParameters>(vs_exp, exp_params));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -674,7 +674,7 @@ namespace mbts.analytics {
|
||||
var vol_time = VolSurfaceCoreFunctions.compute_vol_time(
|
||||
vs_input, vs_standard_time.server_time_utc);
|
||||
var exp_inp_data = vs_nonvol_input.get_option_exp_input();
|
||||
foreach (var (exp, curve_params) in vs_input.surface_parameters.curve_parameters_map) {
|
||||
foreach (var (exp, curve_params) in vs_input.surface_parameters.curve_parameters_map.empty_if_null()) {
|
||||
var time_shift = DoubleHelper.CoerceNaN(curve_params.core_parameters.time_shift);
|
||||
_compute_option_bizt(
|
||||
vs_input, exp, vol_time, time_shift, out var biz_yrs, out var biz_days_per_yr);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace Spark {
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
static class ConsoleInterop {
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern IntPtr GetConsoleWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool ShowWindow(IntPtr h_wnd, int n_cmd_show);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
internal static extern int FreeConsole();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using bts.api;
|
||||
|
||||
using mbts;
|
||||
using mbts.config;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -8,22 +8,22 @@ using mbts.ui;
|
||||
using mbts.ui.spark;
|
||||
using mbts.ui.utilities;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using bts.api.analytics;
|
||||
using BCG;
|
||||
|
||||
using Disposable = mbts.Disposable;
|
||||
|
||||
namespace bts {
|
||||
[Export(typeof(IShellDaemon))]
|
||||
class AnalyticsDaemon : IShellDaemon, IDisposable {
|
||||
private readonly IBus _bus;
|
||||
private readonly AnalyticsService _analytics_service;
|
||||
private readonly bts.api.orderman.OrderService _order_service;
|
||||
private readonly VolSurfaceBusManager _vs_manager;
|
||||
private readonly SpreadManager _spread_manager;
|
||||
private readonly SpreadCalculationSynchronizer _spread_calc;
|
||||
@@ -31,13 +31,11 @@ namespace bts {
|
||||
IDisposable _dispose;
|
||||
|
||||
[ImportingConstructor]
|
||||
public AnalyticsDaemon(IBus bus, AnalyticsService analytics_service,
|
||||
bts.api.orderman.OrderService order_service) {
|
||||
public AnalyticsDaemon(IBus bus, AnalyticsService analytics_service) {
|
||||
bts.Log.Gen.info("AnalyticsDaemon started");
|
||||
_bus = bus;
|
||||
_analytics_service = analytics_service;
|
||||
_order_service = order_service;
|
||||
_vs_manager = new VolSurfaceBusManager(_bus, _analytics_service, _order_service);
|
||||
_vs_manager = new VolSurfaceBusManager(_bus, _analytics_service);
|
||||
_spread_manager = new SpreadManager(_vs_manager.bb(), "xxx");
|
||||
_spread_calc = new SpreadCalculationSynchronizer(_vs_manager.bb());
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using bts.api;
|
||||
using bts.spark;
|
||||
|
||||
using mbts;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
@@ -7,8 +7,6 @@ using mbts;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
|
||||
@@ -11,7 +11,6 @@ using System.Reactive.Linq;
|
||||
|
||||
using SecurityKey = System.UInt32;
|
||||
using MDHandle = mbts.co2.FakeMDConsumerHandle;
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
namespace bts {
|
||||
//[Export(typeof(IShellDaemon))]
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace bts.daemons {
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -19,7 +17,7 @@ namespace bts.daemons {
|
||||
|
||||
[Export(typeof(IShellDaemon))]
|
||||
public sealed class FakeSymbolDriverDaemon : IShellDaemon, IDisposable {
|
||||
IDisposable? _dispose;
|
||||
IDisposable _dispose;
|
||||
|
||||
public FakeSymbolDriverDaemon(IBus bus) {
|
||||
int tid_counter = 1;
|
||||
@@ -70,7 +68,6 @@ namespace bts.daemons {
|
||||
double price,
|
||||
int size = 1,
|
||||
string account = "ACC A",
|
||||
uint account_id = 1,
|
||||
double? strike = null,
|
||||
PutOrCall? cp = null,
|
||||
double? theo = null
|
||||
@@ -84,11 +81,9 @@ namespace bts.daemons {
|
||||
price,
|
||||
theo ?? price + 10 * new Random().NextDouble(),
|
||||
account,
|
||||
account_id,
|
||||
true,
|
||||
DateTime.Now,
|
||||
"FakeTrader",
|
||||
1);
|
||||
"FakeTrader");
|
||||
return t1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,15 @@ using mbts.ui;
|
||||
using mbts.ui.spark;
|
||||
using mbts.ui.utilities;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
|
||||
using Disposable = mbts.Disposable;
|
||||
|
||||
namespace bts {
|
||||
[Export(typeof(IShellDaemon))]
|
||||
class GlobalAlertsDaemon : IShellDaemon, IDisposable {
|
||||
@@ -38,14 +39,13 @@ namespace bts {
|
||||
_notification_service = notification_service;
|
||||
_launcher = new ThreadedWindowLauncher(_window_name);
|
||||
_dispose = Disposable.Create(
|
||||
bus.subscribe(SparkTags.ShowGlobalAlertsTag).Subscribe(_ =>
|
||||
_launcher.show(_view_factory)),
|
||||
_hub.subscribe_default_settings().SubscribeEach(s =>
|
||||
Disposable.Create(s.alerts.trade_alerts
|
||||
.Where(t => t.is_enabled)
|
||||
.Select(a => _notification_service.link_to_trades(
|
||||
a.predicate.security_criteria, a.predicate.create(), a.sound))
|
||||
.ToList())));
|
||||
bus.subscribe(SparkTags.ShowGlobalAlertsTag)
|
||||
.Subscribe(_ => _launcher.show(_view_factory)),
|
||||
_hub.subscribe_default_settings()
|
||||
.SubscribeEach(s => new CompositeDisposable(
|
||||
s.alerts.trade_alerts.Where(t => t.is_enabled).Select(
|
||||
a => _notification_service.link_to_trades(
|
||||
a.predicate.security_criteria, a.predicate.create(), a.sound)))));
|
||||
}
|
||||
|
||||
Window _view_factory() {
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace bts {
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Data;
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -143,6 +142,6 @@ namespace bts {
|
||||
}
|
||||
|
||||
public void Dispose() =>
|
||||
_resources.DisposeAll(true);
|
||||
Disposable.dispose(_resources);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ using BCG;
|
||||
|
||||
using bts.api;
|
||||
using bts.api.synthetic;
|
||||
using bts.collections;
|
||||
using bts.md;
|
||||
using bts.utils;
|
||||
|
||||
@@ -11,8 +10,6 @@ using mbts.co2;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -30,38 +27,26 @@ namespace bts {
|
||||
IDisposable _dispose;
|
||||
Dictionary<uint, SecurityMD> _server_sec_map = new Dictionary<uint, SecurityMD>();
|
||||
Dictionary<uint, SecurityMD> _fake_sec_map = new Dictionary<uint, SecurityMD>();
|
||||
private readonly IList<IDisposable> _subs = new List<IDisposable>();
|
||||
|
||||
[ImportingConstructor]
|
||||
public MergedMDDaemon(IBus bus) {
|
||||
//TempTester.test_analytics();
|
||||
bts.Log.Gen.info("MergedMDDaemon started");
|
||||
_bus = bus;
|
||||
_subs.Add(_bus.subscribe(SparkTags.ServerSecuritiesTag).OnDispatcher().Subscribe(
|
||||
d => _on_server_sec_map(d)));
|
||||
_subs.Add(_bus.subscribe(SparkTags.FakeSecuritiesTag).OnDispatcher().Subscribe(
|
||||
d => _on_fake_sec_map(d)));
|
||||
// This is done periodically to remove expired contracts
|
||||
// (disabling it right now because we are not sure if deleting securities
|
||||
// works with the various UI windows)
|
||||
// _subs.Add(_bus.subscribe(SparkTags.SparkTimer).BufferLatest(TimeSpan.FromMinutes(1))
|
||||
// .Subscribe(t => _merge_and_post()));
|
||||
_bus.subscribe(SparkTags.ServerSecuritiesTag).OnDispatcher().Subscribe(
|
||||
d => _on_server_sec_map(d));
|
||||
_bus.subscribe(SparkTags.FakeSecuritiesTag).OnDispatcher().Subscribe(
|
||||
d => _on_fake_sec_map(d));
|
||||
}
|
||||
|
||||
private void _log_options(IReadOnlyDictionary<uint, SecurityMD> sec_map) {
|
||||
string rv = "MergedMDDaemon Options:\n";
|
||||
foreach (var kv in sec_map) {
|
||||
var sec = kv.Value.security;
|
||||
var md = kv.Value.md;
|
||||
ulong time = 0;
|
||||
NativePriceSize bid, ask;
|
||||
var has_md = md.get_bbo(ref time, out bid, out ask);
|
||||
if (sec.HasOption) {
|
||||
rv += $"id: {kv.Key} desc: {sec.security_desc()} sym: {sec.Symbol} " +
|
||||
$"exp: {sec.security_expiration()} " +
|
||||
$"k: {sec.Option.Strike} cp: {sec.Option.CallPut} " +
|
||||
$"bid: p: {bid.price} q: {bid.size} qf: {bid.size_f} ask: p: {ask.price} q: {ask.size} qf: {ask.size_f}" +
|
||||
"\n";
|
||||
$"k: {sec.Option.Strike} cp: {sec.Option.CallPut}" + "\n";
|
||||
}
|
||||
}
|
||||
Log.Gen.info(rv);
|
||||
@@ -69,27 +54,33 @@ namespace bts {
|
||||
|
||||
private void _on_server_sec_map(IReadOnlyDictionary<uint, SecurityMD> sec_map) {
|
||||
_log_options(sec_map);
|
||||
bts.Log.Gen.info(String.Format("MergedMDDaemon._on_server_sec_map sz: {0}", sec_map.Count()));
|
||||
bts.Log.Gen.info(String.Format("MergedMDDaemon._on_server_sec_map sz:{0}", sec_map.Count()));
|
||||
_server_sec_map = new Dictionary<uint, SecurityMD>(sec_map);
|
||||
_merge_and_post();
|
||||
}
|
||||
|
||||
private void _on_fake_sec_map(IReadOnlyDictionary<uint, SecurityMD> sec_map) {
|
||||
bts.Log.Gen.info(String.Format("MergedMDDaemon._on_fake_sec_map sz: {0}", sec_map.Count()));
|
||||
bts.Log.Gen.info(String.Format("MergedMDDaemon._on_fake_sec_map sz:{0}", sec_map.Count()));
|
||||
_fake_sec_map = new Dictionary<uint, SecurityMD>(sec_map);
|
||||
_merge_and_post();
|
||||
}
|
||||
|
||||
private void _merge_and_post() {
|
||||
Func<SecurityMD, bool> is_active = (sec_md) => {
|
||||
var sec = sec_md.security;
|
||||
return SecurityExpirationHelper.is_unexpired(sec);
|
||||
if (sec_md.security.HasFuture || sec_md.security.HasOption) {
|
||||
var exp = sec_md.security.security_expiration();
|
||||
if (exp.HasValue) {
|
||||
return exp.Value.Date >= DateTime.Now.Date.AddDays(-1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
var to_pub = _server_sec_map.Where(kv => is_active(kv.Value)).ToDictionary(kv => kv.Key, kv => kv.Value);
|
||||
foreach (var kv in _fake_sec_map) {
|
||||
to_pub[kv.Key] = kv.Value;
|
||||
}
|
||||
bts.Log.Gen.info(String.Format("MergedMDDaemon._merge_and_post sz: {0}", to_pub.Count()));
|
||||
bts.Log.Gen.info(String.Format("MergedMDDaemon._merge_and_post sz:{0}", to_pub.Count()));
|
||||
_bus.post(SparkTags.SecuritiesTag, to_pub);
|
||||
SystemContractData sc_data = new SystemContractData(to_pub);
|
||||
_bus.post(SparkTags.SystemContractsTag, sc_data);
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
using bts.api.orderman;
|
||||
using bts.spark;
|
||||
|
||||
using mbts;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
|
||||
@@ -10,8 +10,6 @@ using mbts.spark;
|
||||
using mbts.ui;
|
||||
using mbts.ui.spark;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
using bts.api;
|
||||
using mbts.ui;
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Reactive.Linq;
|
||||
using System.Collections.Generic;
|
||||
using mbts.spark;
|
||||
using bts.api.orderman;
|
||||
using bts.collections;
|
||||
using System.Linq;
|
||||
using Microsoft.Scripting.Utils;
|
||||
|
||||
namespace bts {
|
||||
[Export(typeof(IShellDaemon))]
|
||||
class RFQDaemon : IShellDaemon, IDisposable {
|
||||
private readonly IBus _bus;
|
||||
private readonly bts.api.orderman.OrderService _order_service;
|
||||
private List<IDisposable> _subs = new List<IDisposable>();
|
||||
|
||||
[ImportingConstructor]
|
||||
public RFQDaemon(IBus bus, bts.api.orderman.OrderService order_service) {
|
||||
bts.Log.Gen.info("RFQDaemon started");
|
||||
_bus = bus;
|
||||
_order_service = order_service;
|
||||
var d = bus.subscribe(SparkTags.RFQSend)
|
||||
.Subscribe(_handle_rfq);
|
||||
}
|
||||
|
||||
private void _handle_rfq(RFQRequestImmutable rfq) {
|
||||
bts.Log.Gen.info($"RFQDaemon._handle_rfq");
|
||||
_order_service.send_rfq(rfq);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
foreach (var d in _subs) {
|
||||
d.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
using mbts.spark;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
|
||||
@@ -13,7 +13,6 @@ namespace bts.daemons {
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Collections;
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -30,11 +29,10 @@ namespace bts.daemons {
|
||||
readonly OrderService _order_service;
|
||||
readonly ErrorReporter _error_reporter;
|
||||
readonly IBus _bus;
|
||||
readonly mbts.analytics.PNLReportCalculator _pnl_calc;
|
||||
|
||||
IReadOnlyDictionary<int, ReportImmutable> _report_parameters_map =
|
||||
new Dictionary<int, ReportImmutable>();
|
||||
IDisposable? _dispose;
|
||||
IDisposable _dispose;
|
||||
|
||||
[ImportingConstructor]
|
||||
public ReportDaemon(
|
||||
@@ -50,7 +48,6 @@ namespace bts.daemons {
|
||||
_error_reporter = error_reporter;
|
||||
_order_service = order_service;
|
||||
_report_calculators = new(mk_report_calculator);
|
||||
_pnl_calc = new PNLReportCalculator(bus);
|
||||
|
||||
_dispose = Disposable.Create(
|
||||
bus.subscribe(SparkTags.ReportBlackboardTags.Create).Subscribe(rp => _create_report(rp).ignore()),
|
||||
@@ -62,8 +59,7 @@ namespace bts.daemons {
|
||||
_bus.subscribe(SparkTags.SystemContractsTag).CombineLatest(
|
||||
_order_service.subscribe_fills(), _position_service.subscribe_manual_fills())
|
||||
.Subscribe(tup => _on_all_trade_data(tup.First, tup.Second, tup.Third)),
|
||||
_report_calculators,
|
||||
_pnl_calc);
|
||||
_report_calculators);
|
||||
|
||||
IDisposable mk_report_calculator(int id) {
|
||||
if (!_report_parameters_map.TryGetValue(id, out var r)) {
|
||||
@@ -160,8 +156,8 @@ namespace bts.daemons {
|
||||
|
||||
var fills_tl = fills_filtered.Select(
|
||||
f => new TradeLogRow(f, sc_data.sec_md_map[f.SecurityKey].security));
|
||||
var m_fills_tl = man_fills_filtered.Select(m => new TradeLogRow(
|
||||
m, sc_data.sec_md_map[m.SecurityKey].security, Fill.Types.FillKind.Standard));
|
||||
var m_fills_tl = man_fills_filtered.Select(
|
||||
m => new TradeLogRow(m, sc_data.sec_md_map[m.SecurityKey].security));
|
||||
var merged_fills = fills_tl.Concat(m_fills_tl).ToList();
|
||||
Log.Ui.info($"ReportDaemon posting {merged_fills.Count} trades");
|
||||
_bus.post(SparkTags.TradeLogTag, merged_fills);
|
||||
|
||||
@@ -5,8 +5,6 @@ using mbts;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using bts.api.core;
|
||||
using bts.metrics;
|
||||
|
||||
using mbts;
|
||||
using mbts.config;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Composition;
|
||||
using System.Linq;
|
||||
|
||||
@@ -52,9 +52,6 @@ namespace mbts.ui {
|
||||
EditDocumentGeometryKey = nameof(EditDocumentGeometryKey),
|
||||
VolCurveGeometryKey = nameof(VolCurveGeometryKey),
|
||||
FinancialGrowthGeometryKey = nameof(FinancialGrowthGeometryKey),
|
||||
MarketGeometryKey = nameof(MarketGeometryKey),
|
||||
RefreshGeometryKey = nameof(RefreshGeometryKey),
|
||||
FavoriteWindowGeometryKey = nameof(FavoriteWindowGeometryKey),
|
||||
GearGeometryKey = nameof(GearGeometryKey),
|
||||
HamburgerMenuGeometryKey = nameof(HamburgerMenuGeometryKey),
|
||||
HornGeometryKey = nameof(HornGeometryKey),
|
||||
@@ -63,7 +60,6 @@ namespace mbts.ui {
|
||||
LetterDKey = nameof(LetterDKey),
|
||||
MenuOrientationGeometryKey = nameof(MenuOrientationGeometryKey),
|
||||
OrdersGeometryKey = nameof(OrdersGeometryKey),
|
||||
PaperPlaneGeometryKey = nameof(PaperPlaneGeometryKey),
|
||||
PauseGeometryKey = nameof(PauseGeometryKey),
|
||||
PaymentGeometryKey = nameof(PaymentGeometryKey),
|
||||
PencilGeometryKey = nameof(PencilGeometryKey),
|
||||
@@ -81,9 +77,7 @@ namespace mbts.ui {
|
||||
|
||||
public static Geometry PlayGeometry => Geometry.Parse(get_geometric_path(PlayGeometryKey).FirstOrDefault() ?? string.Empty);
|
||||
|
||||
static readonly Pen _copy_boxes_pen = new Pen(
|
||||
BTSColors.UI.icon_foreground, 5.0.RoundLayoutValue())
|
||||
.frozen();
|
||||
static readonly Pen _copy_boxes_pen = new Pen(Brushes.Black, HighDpiExtensions.RoundLayoutValue(5)).frozen();
|
||||
|
||||
static readonly string base_uri = "pack://application:,,,/Images/Icons/";
|
||||
private static ResourceDictionary _resources = (ResourceDictionary)Application.LoadComponent(new Uri("/Images/Vector/Icons.xaml", UriKind.RelativeOrAbsolute));
|
||||
@@ -122,8 +116,8 @@ namespace mbts.ui {
|
||||
|
||||
|
||||
public static ImageSource DataCopy { get { return load_image("DataCopy.ico"); } }
|
||||
// public static ImageSource Refresh { get { return load_image("Refresh.png"); } }
|
||||
// public static ImageSource FavoriteWindow { get { return load_image("FavoriteWindow.png"); } }
|
||||
public static ImageSource Refresh { get { return load_image("Refresh.png"); } }
|
||||
public static ImageSource FavoriteWindow { get { return load_image("FavoriteWindow.png"); } }
|
||||
|
||||
public static ImageSource Browser => load_resource_and_freeze("Browser");
|
||||
|
||||
@@ -159,9 +153,6 @@ namespace mbts.ui {
|
||||
public static ImageSource Book { get { return load_resource_and_freeze("Book"); } }
|
||||
|
||||
public static ImageSource Orders => create_icon(OrdersGeometryKey);
|
||||
|
||||
public static ImageSource Refresh => create_icon(RefreshGeometryKey);
|
||||
public static ImageSource FavoriteWindow => create_icon(FavoriteWindowGeometryKey);
|
||||
public static ImageSource AddOrders { get { return load_resource_and_freeze("AddOrders"); } }
|
||||
public static ImageSource CancelOrders { get { return load_resource_and_freeze("CancelOrders"); } }
|
||||
public static ImageSource CancelBuys { get { return load_resource_and_freeze("CancelBuys"); } }
|
||||
@@ -212,7 +203,6 @@ namespace mbts.ui {
|
||||
public static ImageSource CopyBoxes => create_icon(CopyBoxesGeometryKey, null, _copy_boxes_pen);
|
||||
public static ImageSource CurrencyExchange => create_icon(CurrencyExchangeGeometryKey);
|
||||
public static ImageSource DataEdit => create_icon(DataEditGeometryKey);
|
||||
public static ImageSource DayFills => PNL;
|
||||
public static ImageSource Defrag { get { return load_resource_and_freeze("Defrag"); } }
|
||||
public static ImageSource DetachAlgos => create_icon_and_rotate(DetachAlgosKey, Brushes.Red);
|
||||
public static ImageSource Disk => create_icon(DiskGeometryKey);
|
||||
@@ -239,24 +229,17 @@ namespace mbts.ui {
|
||||
public static ImageSource Import => load_resource_and_freeze("Import");
|
||||
public static ImageSource Key => create_icon(KeyGeometryKey);
|
||||
public static ImageSource Knight { get { return load_resource_and_freeze("Knight"); } }
|
||||
public static ImageSource manual_fills => create_icon(DataEditGeometryKey);
|
||||
public static ImageSource Market => create_icon(MarketGeometryKey);
|
||||
public static ImageSource MenuOrientation => create_icon(MenuOrientationGeometryKey);
|
||||
public static ImageSource open_orders => Book;
|
||||
public static ImageSource options_view => Sheets;
|
||||
public static ImageSource paper_plane => create_icon(
|
||||
PaperPlaneGeometryKey, null, new(BTSColors.UI.icon_foreground, 2));
|
||||
public static ImageSource Pause => create_icon(PauseGeometryKey);
|
||||
public static ImageSource Payment => create_icon(PaymentGeometryKey);
|
||||
public static ImageSource Pencil => create_icon(PencilGeometryKey);
|
||||
public static ImageSource Play => create_icon(PlayGeometryKey);
|
||||
public static ImageSource PNL => Accounting;
|
||||
public static ImageSource Prohibited => create_icon(ProhibitedGeometryKey);
|
||||
public static ImageSource RecurringSchedule => create_icon(RecurringScheduleGeometryKey);
|
||||
public static ImageSource RecurringScheduleGray => create_icon(RecurringScheduleGeometryKey, Brushes.Gray);
|
||||
public static ImageSource RubberStamp => create_icon(RubberStampGeometryKey);
|
||||
public static ImageSource RedoCircular => create_icon(UndoCircularGeometryKey, Brushes.Black, null, new ScaleTransform(-1, 1));
|
||||
public static ImageSource rfq => paper_plane;
|
||||
public static ImageSource Spawn { get { return load_resource_and_freeze("Spawn"); } }
|
||||
public static ImageSource Speaker => create_icon(SpeakerGeometryKey);
|
||||
public static ImageSource Star => create_icon(StarGeometryKey);
|
||||
|
||||
@@ -325,18 +325,6 @@
|
||||
M50.14375,33.389126C50.416863,33.394688,50.653496,33.587773,50.705998,33.864617L50.015995,45.114388C49.810295,46.291462,49.130394,45.097489,49.130394,45.097489L47.65659,42.640538C42.747776,49.635197 34.633152,54.221001 25.433924,54.221001 14.884193,54.221001 5.7437552,48.204125 1.2449617,39.419205 0.80087067,38.552021 0.21358696,37.705738 0.052086769,36.736958 -0.49735315,33.490925 3.4507786,32.901036 4.8049124,34.432404 5.3674143,35.067692 6.034036,36.16407 6.5079177,37.026051 10.106778,43.799416 17.2321,48.413819 25.433924,48.413819 32.656544,48.413819 39.026364,44.826695 42.903977,39.351506L40.229367,38.854115C40.229367,38.854115,38.677464,38.647118,39.742466,37.996033L50.024895,33.398526C50.064972,33.391365,50.104733,33.388333,50.14375,33.389126z M23.030291,9.0310004L27.889918,9.0310004 27.889918,13.028299C30.539786,13.205498,32.324932,13.958096,33.464161,14.528294L33.964176,14.775793 32.417435,20.038878 31.706417,19.68068C30.579987,19.11958 28.839241,18.244583 26.149073,18.244583 24.006916,18.244583 22.723183,19.122181 22.723183,20.590876 22.723183,21.894272 23.943314,22.804369 27.551308,24.187165 32.706444,26.124659 34.911,28.702853 34.911,32.817341 34.911,36.892929 32.090527,40.05172 27.673611,40.989117L27.673611,45.540001 22.767485,45.540001 22.767485,41.330414C20.252919,41.155815,17.695551,40.424118,16.101811,39.404721L15.683999,39.137619 17.221739,33.731438 17.969059,34.180634C19.088988,34.851235 21.402748,35.97873 24.340325,35.97873 26.734886,35.97873 28.276728,34.921635 28.276728,33.291336 28.276728,31.986641 27.547409,30.853846 23.986016,29.57255 20.083815,28.144253 16.095511,26.04406 16.095511,21.239174 16.095511,17.280985 18.737379,14.291395 23.030291,13.329098z M25.268765,0C35.819447,2.7347414E-07 44.961449,6.0155495 49.458798,14.804573 49.902695,15.669173 50.490094,16.516972 50.651287,17.48427 51.198281,20.734265 47.255726,21.318962 45.901341,19.789065 45.336346,19.153567 44.669552,18.051968 44.19566,17.19517 40.5957,10.421881 33.473275,5.8072398 25.268765,5.8072393 18.047545,5.8072398 11.678013,9.3918336 7.8003562,14.867073L10.474627,15.367072C10.474627,15.367072,12.026909,15.574172,10.962921,16.223872L0.67933281,20.826762C0.36037083,20.880062,0.057029126,20.669165,0.00099972012,20.354063L0.69093342,9.1118043C0.89552094,7.9296158,1.5738537,9.124924,1.5738539,9.124924L3.0452772,11.583379C7.9566038,4.584462,16.073666,2.7347414E-07,25.268765,0z
|
||||
</sys:String>
|
||||
|
||||
<!-- Paper Plane (the icon is free to use if we include this information in our credit section)
|
||||
Icon by <a href="https://freeicons.io/profile/2257">www.wishforge.games</a> on <a href="https://freeicons.io">freeicons.io</a>
|
||||
-->
|
||||
<x:Array x:Key="{x:Static mbts:Icons.PaperPlaneGeometryKey}" Type="sys:String">
|
||||
<sys:String>
|
||||
M26.4,2.9L3.8,15c-0.7,0.4-0.7,1.5,0.1,1.8l20.8,8.7c0.6,0.3,1.3-0.2,1.4-0.8l1.7-20.8 C27.9,3,27.1,2.5,26.4,2.9z
|
||||
</sys:String>
|
||||
<sys:String>
|
||||
M26,4L13,20v7.3c0,0.9,1.2,1.4,1.8,0.7L19,23
|
||||
</sys:String>
|
||||
</x:Array>
|
||||
|
||||
<sys:String x:Key="{x:Static mbts:Icons.PauseGeometryKey}">
|
||||
M17.94,0L29.150001,0 29.150001,32 17.94,32z M0,0L11.210002,0 11.210002,32 0,32z
|
||||
</sys:String>
|
||||
@@ -671,7 +659,7 @@ M0,0L63.999001,0 63.999001,48.792999 0,48.792999z">
|
||||
<DrawingGroup.Children>
|
||||
<GeometryDrawing Brush="Black" Geometry="m 127.71875,0.03125 c 1.96953,0.68706766 3.77873,1.728511 5.53125,2.84375 5.68444,-0.1664634 11.35972,0.1351305 17.03125,0.46875 -1.73194,-1.1492389 -3.57847,-2.1023993 -5.53125,-2.8125 -5.6651,-0.45913017 -11.34995,-0.58354857 -17.03125,-0.5 z m -4.25,0.125 c -5.70361,0.2336956 -11.37548,0.81394241 -17.03125,1.5625 1.95847,0.6900238 3.78385,1.7005175 5.53125,2.8125 C 117.61899,3.7613446 123.30363,3.2513106 129,3 127.28567,1.8094865 125.39256,0.94326338 123.46875,0.15625 z M 149,0.90625 c 1.96418,0.6694319 3.78573,1.7017145 5.53125,2.8125 5.71276,0.5944911 11.3908,1.4529283 17.03125,2.53125 C 169.85207,5.0455955 167.95676,4.1939604 166.03125,3.40625 160.39919,2.2891664 154.71106,1.4856327 149,0.90625 z m -46.8125,1.4375 C 96.464888,3.3096165 90.767826,4.4520829 85.15625,5.9375 87.106815,6.6380546 88.941831,7.6391195 90.6875,8.75 96.310308,7.3225043 101.99157,6.1139557 107.71875,5.1875 106.00019,4.0048872 104.11138,3.1307925 102.1875,2.34375 z m 32.46875,1.5 c 2.00275,1.4247295 3.75993,3.1494432 5.53125,4.84375 5.68351,-0.080003 11.36274,0.089238 17.03125,0.5 -1.73044,-1.7529327 -3.58348,-3.3699033 -5.53125,-4.875 -5.66508,-0.4641114 -11.35053,-0.55229 -17.03125,-0.46875 z m -4.28125,0.125 C 124.103,4.2953783 119.00738,4.7504024 113.34375,5.5 c 1.99941,1.4415661 3.79164,3.1353901 5.53125,4.875 5.65135,-0.7706117 11.33386,-1.2798945 17.03125,-1.53125 -1.66132,-1.8295873 -3.58341,-3.3698478 -5.53125,-4.875 z m 39.9375,0.34375 c 1.96346,0.6759081 3.78484,1.7011488 5.53125,2.8125 5.74468,1.2638733 11.4064,2.8505892 17.03125,4.5625 -1.72987,-1.168721 -3.60534,-2.0558794 -5.53125,-2.84375 C 181.73627,7.0795573 176.0521,5.5785891 170.3125,4.3125 z m -14.375,0.375 c 1.9717,1.4743322 3.79243,3.136185 5.53125,4.875 5.71797,0.542825 11.39215,1.453188 17.03125,2.53125 -1.6913,-1.79287 -3.58414,-3.3704114 -5.53125,-4.875 C 167.33901,6.0657565 161.63964,5.35834 155.9375,4.6875 z m -46.84375,1.46875 c -5.72932,0.9221197 -11.402883,2.1554082 -17.03125,3.5625 1.99347,1.451281 3.791265,3.135015 5.53125,4.875 5.62016,-1.451631 11.30209,-2.635724 17.03125,-3.5625 -1.69439,-1.7852366 -3.54058,-3.4272419 -5.53125,-4.875 z M 80.90625,7.0625 c -5.768034,1.593637 -11.417957,3.561289 -17.03125,5.625 1.930762,0.74325 3.819326,1.676529 5.53125,2.84375 5.568779,-2.194858 11.293752,-3.937501 17.03125,-5.625 C 84.697913,8.7506893 82.833288,7.8508336 80.90625,7.0625 z m 96.3125,1.03125 c 2.01998,1.5283684 3.9853,3.332564 5.53125,4.875 5.75001,1.241656 11.41327,2.827536 17.03125,4.5625 -1.70386,-1.770251 -3.54256,-3.428678 -5.53125,-4.875 -5.59469,-1.822363 -11.3081,-3.215876 -17.03125,-4.5625 z M 141.5625,10.1875 c 1.98812,2.171216 3.79154,4.502672 5.53125,6.875 5.68335,-0.07635 11.3631,0.08322 17.03125,0.5 -1.70296,-2.41177 -3.58181,-4.690977 -5.53125,-6.90625 -5.82598,-0.440889 -11.98586,-0.537879 -17.03125,-0.46875 z m -4.25,0.125 c -5.69916,0.210199 -11.37949,0.783222 -17.03125,1.53125 1.96864,2.199545 3.78641,4.526916 5.53125,6.90625 5.65033,-0.779208 11.33395,-1.279899 17.03125,-1.53125 -1.7175,-2.400101 -3.58197,-4.691155 -5.53125,-6.90625 z m -49.5,0.5625 c -5.756209,1.627414 -11.443914,3.488666 -17.03125,5.625 1.986252,1.443163 3.797302,3.109802 5.53125,4.84375 C 81.914775,19.260145 87.586406,17.35867 93.34375,15.75 91.661607,13.944308 89.760517,12.380286 87.8125,10.875 z m 75.03125,0.15625 c 1.99219,2.183637 3.78522,4.525295 5.53125,6.90625 6.28774,0.687745 11.37979,1.450824 17.03125,2.53125 -1.68349,-2.427307 -3.58184,-4.691013 -5.53125,-6.90625 -5.63506,-1.107989 -11.31933,-1.943258 -17.03125,-2.53125 z M 116,12.5 c -5.73799,0.878008 -11.39825,2.174659 -17.03125,3.5625 2.03956,2.148921 3.76403,4.56042 5.5625,6.90625 5.61994,-1.453285 11.29946,-2.648737 17.03125,-3.5625 C 119.8176,17.015603 118.00451,14.67882 116,12.5 z m -56.40625,1.84375 c -5.792814,2.278458 -11.419014,4.940887 -17.03125,7.625 1.967004,0.694041 3.777949,1.728013 5.53125,2.84375 5.58415,-2.744879 11.247417,-5.328478 17.03125,-7.625 -1.725645,-1.141384 -3.572016,-2.162277 -5.53125,-2.84375 z M 184.125,14.4375 c 2.02152,2.155746 3.78605,4.526439 5.53125,6.90625 5.75343,1.228401 11.41327,2.827536 17.03125,4.5625 C 205.01516,23.467587 203.10649,21.216187 201.15625,19 195.55578,17.209943 189.86603,15.703904 184.125,14.4375 z m -89.40625,2.78125 c -5.757378,1.612569 -11.421181,3.531225 -17.03125,5.59375 2.013414,2.164294 3.785804,4.526096 5.53125,6.90625 C 88.826875,27.652066 94.492577,25.733692 100.25,24.125 98.572893,21.691803 96.66853,19.434409 94.71875,17.21875 z m -28.1875,0.9375 c -5.809395,2.239258 -11.434051,4.908712 -17.03125,7.625 1.996367,1.448111 3.791108,3.134858 5.53125,4.875 C 60.587618,27.843081 66.305928,25.370353 72.0625,23 70.325483,21.271546 68.515383,19.599256 66.53125,18.15625 z m 81.9375,0.90625 C 150.4643,21.946692 152.27759,24.946629 154,28 c 5.68473,-0.186058 11.35951,0.135118 17.03125,0.46875 -1.70966,-3.061344 -3.58704,-6.02118 -5.53125,-8.9375 -5.66815,-0.423667 -11.34913,-0.552311 -17.0Line truncated
|
||||
<GeometryDrawing.Pen>
|
||||
<Pen Brush="{mbts:BTSColor UI.icon_foreground}" Thickness="2" />
|
||||
<Pen Brush="White" Thickness="2" />
|
||||
</GeometryDrawing.Pen>
|
||||
</GeometryDrawing>
|
||||
</DrawingGroup.Children>
|
||||
@@ -1282,23 +1270,8 @@ M0,0L63.999001,0 63.999001,48.792999 0,48.792999z">
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
<!-- Credits: https://freeicons.io/icon/download?_token=zMXvmlGgqOxtOIVOq4byxkcsakzIoDKVPValPURT&icon_id=line-chart-icon-6411&type=svg -->
|
||||
<x:Array x:Key="{x:Static mbts:Icons.MarketGeometryKey}" Type="sys:String">
|
||||
<sys:String>M33,362.371v78.9c0,4.8,3.9,8.8,8.8,8.8h61c4.8,0,8.8-3.9,8.8-8.8v-138.8l-44.3,44.3C57.9,356.071,45.9,361.471,33,362.371z</sys:String>
|
||||
<sys:String>M142,301.471v139.8c0,4.8,3.9,8.8,8.8,8.8h61c4.8,0,8.8-3.9,8.8-8.8v-82.3c-13.9-0.3-26.9-5.8-36.7-15.6L142,301.471z</sys:String>
|
||||
<sys:String>M251,350.271v91c0,4.8,3.9,8.8,8.8,8.8h61c4.8,0,8.8-3.9,8.8-8.8v-167.9l-69.9,69.9C257,345.971,254.1,348.271,251,350.271z</sys:String>
|
||||
<sys:String>M432.7,170.171l-72.7,72.7v198.4c0,4.8,3.9,8.8,8.8,8.8h61c4.8,0,8.8-3.9,8.8-8.8v-265.6c-2-1.7-3.5-3.2-4.6-4.2L432.7,170.171z</sys:String>
|
||||
<sys:String>M482.6,41.371c-2.9-3.1-7.3-4.7-12.9-4.7c-0.5,0-1.1,0-1.6,0c-28.4,1.3-56.7,2.7-85.1,4c-3.8,0.2-9,0.4-13.1,4.5c-1.3,1.3-2.3,2.8-3.1,4.6c-4.2,9.1,1.7,15,4.5,17.8l7.1,7.2c4.9,5,9.9,10,14.9,14.9l-171.6,171.7l-77.1-77.1c-4.6-4.6-10.8-7.2-17.4-7.2c-6.6,0-12.7,2.6-17.3,7.2L7.2,286.871c-9.6,9.6-9.6,25.1,0,34.7l4.6,4.6c4.6,4.6,10.8,7.2,17.4,7.2s12.7-2.6,17.3-7.2l80.7-80.7l77.1,77.1c4.6,4.6,10.8,7.2,17.4,7.2c6.6,0,12.7-2.6,17.4-7.2l193.6-193.6l21.9,21.8c2.6,2.6,6.2,6.2,11.7,6.2c2.3,0,4.6-0.6,7-1.9c1.6-0.9,3-1.9,4.2-3.1c4.3-4.3,5.1-9.8,5.3-14.1c0.8-18.4,1.7-36.8,2.6-55.3l1.3-27.7C487,49.071,485.7,44.571,482.6,41.371z</sys:String>
|
||||
</x:Array>
|
||||
<!-- Credits: -->
|
||||
<x:Array x:Key="{x:Static mbts:Icons.RefreshGeometryKey}" Type="sys:String">
|
||||
<sys:String>M45.633,17.348C46.54,19.792,47,22.367,47,25c0,12.131-9.869,22-22,22c-6.595,0-12.795-2.963-16.958-8H15v-2H5v10h2v-6.126C11.53,46.007,18.068,49,25,49c13.234,0,24-10.767,24-24c0-2.872-0.502-5.68-1.492-8.348L45.633,17.348z</sys:String>
|
||||
<sys:String>M35,13h10V3h-2v6.125C38.47,3.992,31.934,1,25,1C11.767,1,1,11.767,1,25c0,2.872,0.502,5.68,1.492,8.348l1.875-0.696C3.46,30.208,3,27.633,3,25C3,12.869,12.869,3,25,3c6.598,0,12.795,2.962,16.958,8H35V13z</sys:String>
|
||||
</x:Array>
|
||||
<!-- Credits: -->
|
||||
<x:Array x:Key="{x:Static mbts:Icons.FavoriteWindowGeometryKey}" Type="sys:String">
|
||||
<sys:String>M4 2h16a1 1 0 0 1 1 1v19.276a.5.5 0 0 1-.704.457L12 19.03l-8.296 3.702A.5.5 0 0 1 3 22.276V3a1 1 0 0 1 1-1zm15 17.965V4H5v15.965l7-3.124 7 3.124zM12 13.5l-2.939 1.545.561-3.272-2.377-2.318 3.286-.478L12 6l1.47 2.977 3.285.478-2.377 2.318.56 3.272L12 13.5z</sys:String>
|
||||
</x:Array>
|
||||
|
||||
|
||||
<!-- Pin
|
||||
<Path Data="F1M3,11L3,7 0,7 0,6 1,6 1,1 1,0 6,0 6,1 6,6 7,6 7,7 4,7 4,11 3,11z M2,1L2,6 4,6 4,1 2,1z" />
|
||||
Unpin
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using mbts.utils;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Reactive;
|
||||
|
||||
using System;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#nullable enable
|
||||
namespace Spark.Model {
|
||||
using bts;
|
||||
using bts.api;
|
||||
using bts.co2;
|
||||
|
||||
using mbts.spark;
|
||||
|
||||
using Spark.Api.Reactive;
|
||||
using Spark.Core;
|
||||
|
||||
using System.Composition;
|
||||
|
||||
class SecurityResolverExporter : VirtualSingleton<SecurityResolverExporter> {
|
||||
readonly LazyOnce<SecurityResolver>? _resolver;
|
||||
|
||||
[ImportingConstructor]
|
||||
public SecurityResolverExporter(IBus bus, MarketDataRelay md_relay) =>
|
||||
_resolver = new(() => new(md_relay, bus.subscribe(SparkTags.SecuritiesTag)));
|
||||
|
||||
[Export]
|
||||
public SecurityResolver resolver =>
|
||||
Log.notnull(_resolver);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace mbts.ui.settings {
|
||||
public interface ISavedWindowFactory {
|
||||
Task<IShellWindow> restore(WindowSettings window);
|
||||
Task<IShellWindow> restore(WindowState window);
|
||||
}
|
||||
|
||||
[Export(typeof(ISavedWindowFactory))]
|
||||
@@ -28,7 +28,7 @@ namespace mbts.ui.settings {
|
||||
[Import]
|
||||
public ObservableCollection<IShellModule> modules { get; set; }
|
||||
|
||||
public Task<IShellWindow> restore(WindowSettings window) {
|
||||
public Task<IShellWindow> restore(WindowState window) {
|
||||
Log.Ui.info("Loading window '{0}'".fmt(window.title));
|
||||
bool changed;
|
||||
int count = 0;
|
||||
@@ -49,7 +49,7 @@ namespace mbts.ui.settings {
|
||||
/// ex: If change the data format twice from A to B to C then we would write 2 IShellWindowMigration instances.
|
||||
/// Starting in state A one of the _compat tests changes to state B. Now we need to re-run
|
||||
/// the migrations because state B will match a different rule and be converted to state C.
|
||||
private bool apply_compatability_migrations(ref WindowSettings window) {
|
||||
private bool apply_compatability_migrations(ref WindowState window) {
|
||||
foreach (var test in _compat) {
|
||||
try {
|
||||
if (test.apply(ref window)) {
|
||||
|
||||
@@ -14,9 +14,9 @@ using System.Windows.Threading;
|
||||
namespace mbts.ui.settings {
|
||||
public interface ISettingsCollector {
|
||||
// Get the save state for every open window
|
||||
Task<List<WindowSettings>> get_window_state();
|
||||
Task<WindowSettings> get_window_state(IShellWindow window);
|
||||
IEnumerable<ModuleSettings> get_module_state();
|
||||
Task<List<WindowState>> get_window_state();
|
||||
Task<WindowState> get_window_state(IShellWindow window);
|
||||
IEnumerable<ModuleState> get_module_state();
|
||||
WindowPosition get_launcher_state();
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace mbts.ui.settings {
|
||||
|
||||
IWindowsInterop _interop => _wm;
|
||||
|
||||
public async Task<List<WindowSettings>> get_window_state() {
|
||||
public async Task<List<WindowState>> get_window_state() {
|
||||
var windows = _wm.list_windows();
|
||||
var rv = new List<WindowSettings>(windows.Count);
|
||||
var rv = new List<WindowState>(windows.Count);
|
||||
foreach (var window in windows) {
|
||||
// Check that the window is still open since we might be iterating asyncronously
|
||||
if (_wm.contains(window)) {
|
||||
@@ -54,12 +54,12 @@ namespace mbts.ui.settings {
|
||||
return rv;
|
||||
}
|
||||
|
||||
public IEnumerable<ModuleSettings> get_module_state() {
|
||||
public IEnumerable<ModuleState> get_module_state() {
|
||||
//Note: I'm assuming that the list of modules is stable and I don't have to protect against it changing here
|
||||
foreach (var module in modules.OfTypeSafe<IPersistShellModule>()) {
|
||||
MemoryStream out_stream = new MemoryStream();
|
||||
module.get_state(out_stream);
|
||||
yield return new ModuleSettings() {
|
||||
yield return new ModuleState() {
|
||||
name = module.key(),
|
||||
app_data = out_stream.ToArray(),
|
||||
};
|
||||
@@ -70,7 +70,7 @@ namespace mbts.ui.settings {
|
||||
return _launcher.get_position();
|
||||
}
|
||||
|
||||
public async Task<WindowSettings> get_window_state(IShellWindow window) {
|
||||
public async Task<WindowState> get_window_state(IShellWindow window) {
|
||||
try {
|
||||
if (window == null || window.Owner == null) return null;
|
||||
Dispatcher dispatcher = null;
|
||||
@@ -89,10 +89,10 @@ namespace mbts.ui.settings {
|
||||
}
|
||||
|
||||
var pos = _interop.GetPosition(window);
|
||||
var state = new WindowSettings() {
|
||||
var state = new WindowState() {
|
||||
owner = window.Owner.key(),
|
||||
app_data = dispatcher is null ?
|
||||
serialize() : (await dispatcher.InvokeAsync(serialize)),
|
||||
(await dispatcher.InvokeAsync(serialize)) : serialize(),
|
||||
position = pos,
|
||||
title = string.IsNullOrEmpty(pos.custom_title) ? window.Title : pos.custom_title
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using bts.shell.pnl;
|
||||
using bts.shell.pnl;
|
||||
using bts.utils;
|
||||
|
||||
using mbts.ui.settings;
|
||||
@@ -21,8 +21,6 @@ namespace bts.settings {
|
||||
interface IPNLSettingsMigrationRule : ISettingsMigrationRule<PNLSettings> { }
|
||||
interface ISyntheticManagementMigrationRule : ISettingsMigrationRule<GridSettings> { }
|
||||
interface IReconcileReportMigrationRule : ISettingsMigrationRule<GridSettings> { }
|
||||
interface IDayFillsGridSettingsMigrationRule : ISettingsMigrationRule<GridSettings> { }
|
||||
interface IOpenOrdersGridSettingsMigrationRule : ISettingsMigrationRule<GridSettings> { }
|
||||
|
||||
static class SettingsMigrationHelper {
|
||||
public static bool apply<T>(T settings, IEnumerable<ISettingsMigrationRule<T>> migration_rules, out T new_settings) {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using mbts.spark;
|
||||
using mbts.utils;
|
||||
|
||||
using Spark.Core.Disposables;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
@@ -89,8 +87,7 @@ namespace mbts.persist {
|
||||
public IWindowSettingsManagerNonShared<T> as_non_shared() =>
|
||||
new NonSharedWrapper(_wsm);
|
||||
|
||||
public void Dispose() =>
|
||||
Disposable.dispose(ref _dispose);
|
||||
public void Dispose() => Disposable.dispose(ref _dispose);
|
||||
}
|
||||
|
||||
public class DisconnectedImpl : IWindowSettingsManager<T> {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#nullable enable
|
||||
namespace mbts.ui.shell {
|
||||
using ProtoBuf;
|
||||
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
[ProtoContract]
|
||||
public class ModuleSettings : IProtobuf<ModuleSettings> {
|
||||
[ProtoMember(1)]
|
||||
public string? name { get; set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public byte[]? app_data { get; set; }
|
||||
|
||||
public bool Equals(ModuleSettings? other) =>
|
||||
other is not null &&
|
||||
name == other.name &&
|
||||
app_data.safe_sequence_equals(other.app_data);
|
||||
|
||||
public override bool Equals(object? obj) =>
|
||||
Equals(obj as ModuleSettings);
|
||||
|
||||
public override int GetHashCode() =>
|
||||
GetType().GetHashCode();
|
||||
|
||||
public ModuleSettings Clone() =>
|
||||
ProtobufSerializationHelper.clone(this);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#nullable enable
|
||||
#nullable enable
|
||||
namespace mbts.spark {
|
||||
using bts.shell;
|
||||
using bts.shell.fills;
|
||||
@@ -34,8 +34,6 @@ namespace mbts.spark {
|
||||
_notification = NotificationSettings.Default,
|
||||
_market_view_grid = MarketViewSettings.DefaultGridSettings,
|
||||
_fills_grid = FillsSettings.DefaultGridSettings,
|
||||
_day_fills_grid = DayFillsSettings.default_grid(),
|
||||
_open_orders_grid = OpenOrdersSettings.default_grid(),
|
||||
_time_and_sales_grid = TimeAndSalesSettings.DefaultGridSettings,
|
||||
_synthetic_management = SyntheticManagementSettings.default_grid_settings,
|
||||
_reconcile_report = ReconcileReportSettings.Default().grid,
|
||||
@@ -66,10 +64,6 @@ namespace mbts.spark {
|
||||
GridSettings? _time_and_sales_grid;
|
||||
[ProtoMember(7)]
|
||||
GridSettings? _fills_grid;
|
||||
[ProtoMember(15)]
|
||||
GridSettings? _day_fills_grid;
|
||||
[ProtoMember(16)]
|
||||
GridSettings? _open_orders_grid;
|
||||
[ProtoMember(8)]
|
||||
GridSettings? _synthetic_management;
|
||||
[ProtoMember(14)]
|
||||
@@ -105,12 +99,6 @@ namespace mbts.spark {
|
||||
public GridSettings fills_grid =>
|
||||
_fills_grid ??= FillsSettings.DefaultGridSettings;
|
||||
|
||||
public GridSettings day_fills_grid =>
|
||||
_day_fills_grid ??= DayFillsSettings.default_grid();
|
||||
|
||||
public GridSettings open_orders_grid =>
|
||||
_open_orders_grid ??= OpenOrdersSettings.default_grid();
|
||||
|
||||
public GridSettings synthetic_management_grid =>
|
||||
_synthetic_management ??=
|
||||
SyntheticManagementSettings.default_grid_settings;
|
||||
@@ -135,8 +123,6 @@ namespace mbts.spark {
|
||||
GridSettings? market_view = null,
|
||||
GridSettings? time_and_sales = null,
|
||||
GridSettings? fills = null,
|
||||
GridSettings? day_fills = null,
|
||||
GridSettings? open_orders = null,
|
||||
GridSettings? synthetic_management = null,
|
||||
GridSettings? reconcile_report = null,
|
||||
PNLSettings? pnl = null,
|
||||
@@ -149,8 +135,6 @@ namespace mbts.spark {
|
||||
_market_view_grid = market_view ?? _market_view_grid,
|
||||
_time_and_sales_grid = time_and_sales ?? _time_and_sales_grid,
|
||||
_fills_grid = fills ?? _fills_grid,
|
||||
_day_fills_grid = day_fills ?? _day_fills_grid,
|
||||
_open_orders_grid = open_orders ?? _open_orders_grid,
|
||||
_synthetic_management = synthetic_management ?? _synthetic_management,
|
||||
_reconcile_report = reconcile_report ?? _reconcile_report,
|
||||
_pnl = pnl ?? _pnl,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using bts;
|
||||
using bts;
|
||||
using bts.settings;
|
||||
using bts.shell.pnl;
|
||||
using bts.utils;
|
||||
@@ -26,8 +26,6 @@ namespace mbts.persist {
|
||||
|
||||
static readonly IImmutableProperty<UserSettings, GridSettings>
|
||||
_fills_propi = ImmutableProperty.create<UserSettings, GridSettings>(us => us.fills_grid, (us, gs) => us.with(fills: gs)),
|
||||
_day_fills_propi = ImmutableProperty.create<UserSettings, GridSettings>(us => us.day_fills_grid, (us, gs) => us.with(day_fills: gs)),
|
||||
_open_orders_propi = ImmutableProperty.create<UserSettings, GridSettings>(us => us.open_orders_grid, (us, gs) => us.with(open_orders: gs)),
|
||||
_mview_propi = ImmutableProperty.create<UserSettings, GridSettings>(us => us.market_view_grid, (us, gs) => us.with(market_view: gs)),
|
||||
_synth_propi = ImmutableProperty.create<UserSettings, GridSettings>(us => us.synthetic_management_grid, (us, gs) => us.with(synthetic_management: gs)),
|
||||
_reconcile_report_propi = ImmutableProperty.create<UserSettings, GridSettings>(us => us.reconcile_report_grid, (us, gs) => us.with(reconcile_report: gs));
|
||||
@@ -38,8 +36,6 @@ namespace mbts.persist {
|
||||
readonly object _default_settings_lock = new object();
|
||||
readonly BehaviorSubject<UserSettings> _default_settings_subject = new BehaviorSubject<UserSettings>(UserSettings.factory_defaults);
|
||||
readonly IEnumerable<IFillsGridSettingsMigrationRule> _fills_migration_rules;
|
||||
readonly IEnumerable<IDayFillsGridSettingsMigrationRule> _day_fills_migration_rules;
|
||||
readonly IEnumerable<IOpenOrdersGridSettingsMigrationRule> _open_orders_migration_rules;
|
||||
readonly IEnumerable<IMarketViewGridSettingsMigrationRule> _mview_migration_rules;
|
||||
readonly IEnumerable<IPNLSettingsMigrationRule> _pnl_migration_rules;
|
||||
readonly IEnumerable<ISyntheticManagementMigrationRule> _synth_migration_rules;
|
||||
@@ -52,8 +48,6 @@ namespace mbts.persist {
|
||||
public UserSettingsHub(
|
||||
IUserPersist persist,
|
||||
[ImportMany] IEnumerable<IFillsGridSettingsMigrationRule> fills_migration_rules,
|
||||
[ImportMany] IEnumerable<IDayFillsGridSettingsMigrationRule> day_fills_migration_rules,
|
||||
[ImportMany] IEnumerable<IOpenOrdersGridSettingsMigrationRule> open_orders_migration_rules,
|
||||
[ImportMany] IEnumerable<IMarketViewGridSettingsMigrationRule> mview_migration_rules,
|
||||
[ImportMany] IEnumerable<IPAndLGridSettingsMigrationRule> pandl_migration_rules,
|
||||
[ImportMany] IEnumerable<IPNLSettingsMigrationRule> pnl_migration_rules,
|
||||
@@ -62,8 +56,6 @@ namespace mbts.persist {
|
||||
//
|
||||
_persist = persist;
|
||||
_fills_migration_rules = fills_migration_rules ?? Enumerable.Empty<IFillsGridSettingsMigrationRule>();
|
||||
_day_fills_migration_rules = day_fills_migration_rules ?? Enumerable.Empty<IDayFillsGridSettingsMigrationRule>();
|
||||
_open_orders_migration_rules = open_orders_migration_rules ?? Enumerable.Empty<IOpenOrdersGridSettingsMigrationRule>();
|
||||
_mview_migration_rules = mview_migration_rules ?? Enumerable.Empty<IMarketViewGridSettingsMigrationRule>();
|
||||
_pnl_migration_rules = pnl_migration_rules ?? Enumerable.Empty<IPNLSettingsMigrationRule>();
|
||||
_synth_migration_rules = synth_migration_rules ?? Enumerable.Empty<ISyntheticManagementMigrationRule>();
|
||||
@@ -76,8 +68,6 @@ namespace mbts.persist {
|
||||
if (s != null) {
|
||||
var wrapped_rules = new[] {
|
||||
_fills_migration_rules.merge().wrap(_fills_propi),
|
||||
_day_fills_migration_rules.merge().wrap(_day_fills_propi),
|
||||
_open_orders_migration_rules.merge().wrap(_open_orders_propi),
|
||||
_mview_migration_rules.merge().wrap(_mview_propi),
|
||||
_pnl_migration_rules.merge().wrap(_pnl_propi),
|
||||
_synth_migration_rules.merge().wrap(_synth_propi),
|
||||
@@ -162,20 +152,6 @@ namespace mbts.persist {
|
||||
_reconcile_report_migration_rules,
|
||||
_reconcile_report_propi);
|
||||
|
||||
public IWindowSettingsManager<GridSettings> create_day_fills_settings_manager(
|
||||
GridSettings instance_settings) =>
|
||||
_create_settings_manager(
|
||||
instance_settings,
|
||||
_day_fills_migration_rules,
|
||||
_day_fills_propi);
|
||||
|
||||
public IWindowSettingsManager<GridSettings> create_open_orders_settings_manager(
|
||||
GridSettings instance_settings) =>
|
||||
_create_settings_manager(
|
||||
instance_settings,
|
||||
_day_fills_migration_rules,
|
||||
_day_fills_propi);
|
||||
|
||||
public async Task save_default(UserSettings value) {
|
||||
// notify observers before persisting so the changes are reflected immediately in the ui
|
||||
lock (_default_settings_lock) {
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#nullable enable
|
||||
namespace mbts.ui.shell {
|
||||
using ProtoBuf;
|
||||
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
[ProtoContract]
|
||||
public class WindowPosition : IProtobuf<WindowPosition> {
|
||||
[ProtoMember(3)]
|
||||
public int width { get; set; }
|
||||
|
||||
[ProtoMember(4)]
|
||||
public int height { get; set; }
|
||||
|
||||
[ProtoMember(5)]
|
||||
public int left { get; set; }
|
||||
|
||||
[ProtoMember(6)]
|
||||
public int top { get; set; }
|
||||
|
||||
[ProtoMember(7)]
|
||||
public bool is_maximized { get; set; }
|
||||
|
||||
[ProtoMember(8)]
|
||||
public string? host_id { get; set; }
|
||||
|
||||
[ProtoMember(9)]
|
||||
public int tab_index { get; set; }
|
||||
|
||||
[ProtoMember(100)]
|
||||
public bool horizontal { get; set; }
|
||||
|
||||
[ProtoMember(101), DefaultValue(true)]
|
||||
public bool show_text { get; set; } = true;
|
||||
|
||||
[ProtoMember(102), DefaultValue(true)]
|
||||
public bool always_on_top { get; set; } = true;
|
||||
|
||||
[ProtoMember(104)]
|
||||
public string? custom_title { get; set; }
|
||||
|
||||
public bool Equals(WindowPosition? other) =>
|
||||
other is not null &&
|
||||
width == other.width &&
|
||||
height == other.height &&
|
||||
left == other.left &&
|
||||
top == other.top &&
|
||||
is_maximized == other.is_maximized &&
|
||||
host_id == other.host_id &&
|
||||
tab_index == other.tab_index &&
|
||||
horizontal == other.horizontal &&
|
||||
show_text == other.show_text &&
|
||||
always_on_top == other.always_on_top &&
|
||||
custom_title == other.custom_title;
|
||||
|
||||
public override bool Equals(object? obj) =>
|
||||
Equals(obj as WindowPosition);
|
||||
|
||||
public override int GetHashCode() =>
|
||||
GetType().GetHashCode();
|
||||
|
||||
public WindowPosition Clone() =>
|
||||
ProtobufSerializationHelper.clone(this);
|
||||
|
||||
object ICloneable.Clone() =>
|
||||
Clone();
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#nullable enable
|
||||
namespace mbts.ui.shell {
|
||||
using bts.utils;
|
||||
|
||||
using ProtoBuf;
|
||||
|
||||
using Spark.Core.Protobuf;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[ProtoContract]
|
||||
public class WindowSettings : IProtobuf<WindowSettings> {
|
||||
[ProtoMember(1)]
|
||||
public string? owner { get; set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public byte[]? app_data { get; set; }
|
||||
|
||||
[ProtoMember(8)]
|
||||
public WindowPosition? position { get; set; }
|
||||
|
||||
[ProtoMember(9)]
|
||||
public string? title { get; set; }
|
||||
|
||||
public bool Equals(WindowSettings? other) =>
|
||||
other is not null &&
|
||||
owner == other.owner &&
|
||||
app_data.safe_sequence_equals(other.app_data) &&
|
||||
position.safe_equals(other.position) &&
|
||||
title == other.title;
|
||||
|
||||
public override bool Equals(object? obj) =>
|
||||
Equals(obj as WindowSettings);
|
||||
|
||||
public override int GetHashCode() =>
|
||||
GetType().GetHashCode();
|
||||
|
||||
public WindowSettings Clone() =>
|
||||
ProtobufSerializationHelper.clone(this);
|
||||
|
||||
object ICloneable.Clone() =>
|
||||
Clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using ProtoBuf;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace mbts.ui.shell {
|
||||
public enum DockState {
|
||||
FLOATING = 1,
|
||||
TOP = 2,
|
||||
BOTTOM = 3,
|
||||
LEFT = 4,
|
||||
RIGHT = 5,
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
public class WindowPosition {
|
||||
[ProtoMember(3)]
|
||||
public int width;
|
||||
[ProtoMember(4)]
|
||||
public int height;
|
||||
[ProtoMember(5)]
|
||||
public int left;
|
||||
[ProtoMember(6)]
|
||||
public int top;
|
||||
[ProtoMember(7)]
|
||||
public bool is_maximized;
|
||||
[ProtoMember(8)]
|
||||
public string host_id;
|
||||
[ProtoMember(9)]
|
||||
public int tab_index;
|
||||
|
||||
[ProtoMember(100), DefaultValue(false)]
|
||||
public bool horizontal = false;
|
||||
[ProtoMember(101), DefaultValue(true)]
|
||||
public bool show_text = true;
|
||||
[ProtoMember(102), DefaultValue(true)]
|
||||
public bool always_on_top = true;
|
||||
//[ProtoMember(103)] //used
|
||||
|
||||
[ProtoMember(104)]
|
||||
public string custom_title;
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
public class WindowState {
|
||||
[ProtoMember(1)]
|
||||
public string owner;
|
||||
[ProtoMember(2)]
|
||||
public byte[] app_data;
|
||||
|
||||
//optional bool is_open = 3 [default = true];
|
||||
//optional bool is_favorite = 4;
|
||||
//optional string title = 5;
|
||||
|
||||
//optional string id = 6;
|
||||
// optional bool is_loaded = 7 [default = false];
|
||||
[ProtoMember(8)]
|
||||
public WindowPosition position;
|
||||
|
||||
[ProtoMember(9)]
|
||||
public string title; // for debugging
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
public class ModuleState {
|
||||
[ProtoMember(1)]
|
||||
public string name;
|
||||
[ProtoMember(2)]
|
||||
public byte[] app_data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
#nullable enable
|
||||
namespace Spark.Trading {
|
||||
using bts;
|
||||
using bts.api;
|
||||
namespace bts.api.position {
|
||||
using bts.api.core;
|
||||
using bts.api.orderman;
|
||||
using bts.api.position;
|
||||
using bts.shell.pnl;
|
||||
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Trading;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
@@ -16,10 +17,10 @@ namespace Spark.Trading {
|
||||
IObservable<TableUpdate<(SecurityImmutable?, PositionUnitImmutable), int>> on_positions { get; }
|
||||
IObservable<TableUpdate<(SecurityImmutable? sec, RetrievedExchangePositionImmutable exch_pos), AccountSecurityKey>> on_exchange_positions { get; }
|
||||
IObservable<TableUpdate<ReconcileReportRowData, AccountSecurityKey>> merged_positions { get; }
|
||||
IObservable<TableUpdate<DayFillsRowData, DayFillsRowKey>> day_fills { get; }
|
||||
|
||||
// pnl
|
||||
IObservable<TableUpdate<PNLRowData, AccountSecurityKey>> pnl { get; }
|
||||
IObservable<TableUpdate<(SecurityImmutable?, PNLUnitImmutable, QuantityConversionData<double>), int>> on_pnl { get; }
|
||||
IObservable<TableUpdate<PNLRowData, AccountSecurityKey>> security_account_pnl { get; }
|
||||
|
||||
IObservable<TableUpdate<(SecurityImmutable?, PositionUnitImmutable), int>> on_security_positions(
|
||||
uint security_key);
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace Spark.Model.Trading {
|
||||
|
||||
using mbts.spark;
|
||||
|
||||
using Spark.Api.Reactive;
|
||||
using Spark.Core.Reactive;
|
||||
|
||||
using System;
|
||||
@@ -26,7 +25,7 @@ namespace Spark.Model.Trading {
|
||||
public OrderDataSource(
|
||||
IBus bus,
|
||||
AdminModel admin_model,
|
||||
SecurityResolver sec_resolver,
|
||||
SecurityStore security_store,
|
||||
OrderService order_service,
|
||||
ISecurityAuxiliaryDataModel security_auxiliary_model,
|
||||
ErrorReporter error_reporter
|
||||
@@ -39,7 +38,7 @@ namespace Spark.Model.Trading {
|
||||
order_service.subscribei_orders()
|
||||
.Naggle(interval, scheduler),
|
||||
o => o.account_id())
|
||||
.join(sec_resolver, o => o.security_key())
|
||||
.join(security_store, o => o.security_key())
|
||||
.Table()
|
||||
.Cache();
|
||||
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
#nullable enable
|
||||
namespace Spark.Trading {
|
||||
using bts;
|
||||
using bts.api;
|
||||
namespace bts.api.position {
|
||||
using bts.api.core;
|
||||
using bts.api.orderman;
|
||||
using bts.api.position;
|
||||
using bts.collections;
|
||||
using bts.shell.pnl;
|
||||
using bts.spark;
|
||||
|
||||
using mbts.analytics;
|
||||
using mbts;
|
||||
using mbts.spark;
|
||||
using mbts.ui;
|
||||
|
||||
using Spark.Api.Reactive;
|
||||
using Spark.Core;
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Reactive;
|
||||
using Spark.Model.Trading;
|
||||
using Spark.Trading;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -33,13 +29,13 @@ namespace Spark.Trading {
|
||||
readonly ErrorReporter _error_reporter;
|
||||
readonly TableUpdateDemuxer<(SecurityImmutable?, PositionUnitImmutable), int, uint> _security_positions_demuxer;
|
||||
|
||||
ThreadSafeDisposable? _dispose;
|
||||
IDisposable _dispose;
|
||||
|
||||
[ImportingConstructor]
|
||||
public PositionModel(
|
||||
IBus bus,
|
||||
AdminModel admin_model,
|
||||
SecurityResolver sec_resolver,
|
||||
SecurityStore security_store,
|
||||
PositionService position_service,
|
||||
OrderService order_service,
|
||||
OrderDataSource order_data,
|
||||
@@ -56,7 +52,7 @@ namespace Spark.Trading {
|
||||
on_exchange_positions = order_service.subscribei_exchange_positions()
|
||||
.Filter(ep => ep.SecurityKey != 0)
|
||||
.SelectKeyValue(ep => ep, ep => new AccountSecurityKey(ep.AccountId, ep.SecurityKey))
|
||||
.join(sec_resolver, ep => ep.SecurityKey)
|
||||
.join(security_store, ep => ep.SecurityKey)
|
||||
.Table()
|
||||
.Cache();
|
||||
|
||||
@@ -64,15 +60,31 @@ namespace Spark.Trading {
|
||||
.permission_filter(
|
||||
_position_service.subscribei_position_data().Naggle(interval, scheduler),
|
||||
p => p.AccountId)
|
||||
.join(sec_resolver, pos => pos.SecurityId)
|
||||
.join(security_store, pos => pos.SecurityId)
|
||||
.Table()
|
||||
.Cache();
|
||||
|
||||
day_fills = DayFillsDataSource.create(bus, sec_resolver);
|
||||
on_pnl = admin_model
|
||||
.permission_filter(
|
||||
_position_service.subscribei_pnl_data().Naggle(interval, scheduler),
|
||||
p => p.Pos.AccountId)
|
||||
.join(security_store, p => p.Pos.SecurityId)
|
||||
.Select(
|
||||
tup => (tup.sec, tup.val, new QuantityConversionData<double>(
|
||||
security_auxiliary_model.get_display_quantity_divisor(tup.sec),
|
||||
QuantityConversionOpType.DivideActual)),
|
||||
tup => tup.val.RecordId)
|
||||
.TableCheckedAutoCorrect(
|
||||
EqualityComparer<(SecurityImmutable?, PNLUnitImmutable, QuantityConversionData<double>)>.Default)
|
||||
.Where(t => t.has_changes())
|
||||
.Cache();
|
||||
|
||||
pnl = bus.subscribe(SparkTags.ReportBlackboardTags.PNL.PNLData)
|
||||
.Select(d => d.position_data.ToDictionary(u => u.id(), PNLRowData.from_pnl_unit))
|
||||
.Table(PNLRowData.key_fn)
|
||||
// security account pnl
|
||||
security_account_pnl = on_pnl
|
||||
#if DEBUG
|
||||
.AssertIncremental(p => new AccountSecurityKey(p.Item2.Pos.AccountId, p.Item2.Pos.SecurityId))
|
||||
#endif
|
||||
.SelectKeyValue(PNLRowDataFactory.create, PNLRowData.key_fn)
|
||||
.FullJoin(
|
||||
order_data.working_account_security_orders,
|
||||
PNLRowData.key_fn,
|
||||
@@ -99,18 +111,18 @@ namespace Spark.Trading {
|
||||
.Where(t => t.has_changes())
|
||||
.Cache();
|
||||
|
||||
merged_positions = ReconcileReportDataSource.create(
|
||||
on_exchange_positions, on_positions.Filter(tup => !(tup.Item1?.HasSpread ?? false)))
|
||||
merged_positions = ReconcileReportDataSource.create(on_exchange_positions, on_positions)
|
||||
.Cache();
|
||||
|
||||
_dispose = new(on_positions.Subscribe(_security_positions_demuxer));
|
||||
_dispose = Disposable.Create(
|
||||
on_positions.Subscribe(_security_positions_demuxer));
|
||||
}
|
||||
|
||||
public IObservable<TableUpdate<(SecurityImmutable? sec, RetrievedExchangePositionImmutable exch_pos), AccountSecurityKey>> on_exchange_positions { get; }
|
||||
public IObservable<TableUpdate<(SecurityImmutable?, PositionUnitImmutable), int>> on_positions { get; }
|
||||
public IObservable<TableUpdate<PNLRowData, AccountSecurityKey>> pnl { get; }
|
||||
public IObservable<TableUpdate<(SecurityImmutable?, PNLUnitImmutable, QuantityConversionData<double>), int>> on_pnl { get; }
|
||||
public IObservable<TableUpdate<ReconcileReportRowData, AccountSecurityKey>> merged_positions { get; }
|
||||
public IObservable<TableUpdate<DayFillsRowData, DayFillsRowKey>> day_fills { get; }
|
||||
public IObservable<TableUpdate<PNLRowData, AccountSecurityKey>> security_account_pnl { get; }
|
||||
|
||||
public IObservable<TableUpdate<(SecurityImmutable?, PositionUnitImmutable), int>> on_security_positions(uint security) =>
|
||||
_security_positions_demuxer.subscribe(security);
|
||||
@@ -143,6 +155,6 @@ namespace Spark.Trading {
|
||||
"reset positions");
|
||||
|
||||
public void Dispose() =>
|
||||
Disposable.dispose(ref _dispose);
|
||||
Disposable.dispose_thread_safe(ref _dispose);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#nullable enable
|
||||
namespace Spark.Trading {
|
||||
namespace bts.api.position {
|
||||
using bts.api.core;
|
||||
|
||||
using Spark.Api.Position;
|
||||
|
||||
File renamed without changes.
@@ -1,11 +1,9 @@
|
||||
namespace mbts.spark {
|
||||
using bts;
|
||||
using bts.api;
|
||||
using bts.api.analytics;
|
||||
using bts.api.core;
|
||||
using bts.collections;
|
||||
using bts.shell;
|
||||
using bts.shell.pnl;
|
||||
using bts.spark;
|
||||
|
||||
using mbts.analytics;
|
||||
@@ -14,10 +12,7 @@ namespace mbts.spark {
|
||||
using mbts.ui.shell;
|
||||
using mbts.ui.utility;
|
||||
|
||||
using Spark.Core.Data;
|
||||
using Spark.Core.Disposables;
|
||||
using Spark.Core.Reactive;
|
||||
using Spark.Trading;
|
||||
using Spark.ViewModel;
|
||||
|
||||
using System;
|
||||
@@ -40,13 +35,7 @@ namespace mbts.spark {
|
||||
|
||||
[ImportingConstructor]
|
||||
public AnalyticsShellModule(
|
||||
IBus bus,
|
||||
WindowManager wm,
|
||||
UserSettingsHub settings_hub,
|
||||
OrdersModel orders_model,
|
||||
IPositionModel position_model,
|
||||
ISecurityMetadataStore sec_meta_store,
|
||||
Lazy<UserTuple> user) {
|
||||
IBus bus, WindowManager wm, UserSettingsHub settings_hub, OrdersModel orders_model) {
|
||||
_wm = wm;
|
||||
_bus = bus;
|
||||
var reports_demuxer = new TableUpdateDemuxer<ReportImmutable?, int>(default, false);
|
||||
@@ -60,21 +49,15 @@ namespace mbts.spark {
|
||||
new AnalyticsExpirationParametersWindowFactory(this, bus),
|
||||
new SlideReportWindowFactory(this, bus, reports_demuxer.subscribe),
|
||||
new ComboReportWindowFactory(this, bus, reports_demuxer.subscribe),
|
||||
new PNLWindowFactory(
|
||||
this, bus, settings_hub, orders_model, position_model, sec_meta_store),
|
||||
new DayFillsWindowFactory(
|
||||
this, bus, settings_hub, position_model, sec_meta_store, user.Value)
|
||||
};
|
||||
var vol_surfaces_src = _bus.subscribe(SparkTags.VolSurfaceListTag).OnDispatcher();
|
||||
var reports_src = _bus.subscribe(SparkTags.ReportBlackboardTags.ListTag).OnDispatcher();
|
||||
_dispose = Disposable.Create(
|
||||
_dispose = new DisposableCombo(
|
||||
vol_surfaces_src.Subscribe(_on_vol_surfaces),
|
||||
reports_src.Subscribe(_on_reports),
|
||||
nullable_reports_src.Subscribe(reports_demuxer),
|
||||
reports_demuxer,
|
||||
vm.launch_exp_params_view_cmd.subscribe_executed(_launch_exp_params_view),
|
||||
vm.launch_pnl_cmd.subscribe_executed(_launch_pnl),
|
||||
vm.launch_day_fills_cmd.subscribe_executed(_launch_day_fills),
|
||||
// vol surface
|
||||
vm.vol_surface_launcher_vm.launch_cmd.subscribe_executed(_launch_vol_surface),
|
||||
vm.vol_surface_launcher_vm.create_cmd.subscribe_executed(_create_vol_surface),
|
||||
@@ -131,12 +114,6 @@ namespace mbts.spark {
|
||||
_bus.post(SparkTags.show_analytics_exp_params, settings);
|
||||
}
|
||||
|
||||
void _launch_pnl() =>
|
||||
_bus.post(SparkTags.ShowPNLTag, null);
|
||||
|
||||
void _launch_day_fills() =>
|
||||
_bus.post(SparkTags.show_day_fills, DayFillsSettings.Default());
|
||||
|
||||
void _launch_vol_surface(int id) {
|
||||
var windows = _wm.list_windows();
|
||||
if (windows.OfType<VolSurfaceWindow>().TryGetFirst(w => w.vs_id == id, out var win)) {
|
||||
|
||||
@@ -13,10 +13,6 @@ namespace mbts.spark {
|
||||
public KeyValueLauncherVM<int, string> slide_report_launcher_vm { get; } = new() { type_name = "Slide Report" };
|
||||
public KeyValueLauncherVM<int, string> combo_report_launcher_vm { get; } = new() { type_name = "Combo Report" };
|
||||
|
||||
// pnl
|
||||
public EventCommand launch_pnl_cmd { get; } = new();
|
||||
public EventCommand launch_day_fills_cmd { get; } = new();
|
||||
|
||||
public string? selected_window_type {
|
||||
get => _selected_window_type;
|
||||
set => Set(ref _selected_window_type, value);
|
||||
|
||||
Loaded 100 of 1411 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user