Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
518bd5771e | ||
|
|
16522056ba | ||
|
|
51178d85d3 | ||
|
|
86b50e58f4 | ||
|
|
8431c05dfe | ||
|
|
18c05e2c8c | ||
|
|
06535c0938 | ||
|
|
0d8f01c8bb | ||
|
|
36f85b1e62 | ||
|
|
502a22a2d9 | ||
|
|
daa49a5568 | ||
|
|
0ef371cc40 | ||
|
|
b23f0fc21b | ||
|
|
d0dc1b8e51 | ||
|
|
0bbc4f737b | ||
|
|
29fb1b427b | ||
|
|
9de6d3ffe6 | ||
|
|
a168d4da99 | ||
|
|
d65d4b3258 | ||
|
|
b4771abad0 |
No files matched your search
@@ -1,122 +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
|
||||
|
||||
# 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"
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"dockerFile": "Dockerfile",
|
||||
// Creates local dir to mount to HOME in docker
|
||||
"initializeCommand": "mkdir -p ${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId}",
|
||||
"hostRequirements": {
|
||||
"memory": "4gb",
|
||||
"storage": "6gb"
|
||||
},
|
||||
"postCreateCommand": "/home/bts/spark/docker/sparkd/dev/devcontainer_post_create.sh",
|
||||
"containerUser": "bts",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/bts/spark,type=bind",
|
||||
"workspaceFolder": "/home/bts/spark",
|
||||
"updateRemoteUserUID": true,
|
||||
"shutdownAction": "none",
|
||||
// Note: If running multiple containers on the same host, each must use a
|
||||
// unique set of ports. Usually we just add 1000 to each port as needed. For
|
||||
// example, if 8000-8003 is taken, go with 9000-9003, then 10000-10003, etc.
|
||||
"runArgs": [
|
||||
"--shm-size",
|
||||
"2gb",
|
||||
"-p",
|
||||
"8000:8000",
|
||||
"-p",
|
||||
"8001:8001",
|
||||
"-p",
|
||||
"8002:8002",
|
||||
"-p",
|
||||
"8003:8003"
|
||||
],
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}/.bts/devcontainer-mounts/${devcontainerId},target=/home/bts,type=bind"
|
||||
],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"clangd.arguments": [
|
||||
"--compile-commands-dir=${workspaceFolder}/build/clang/debug"
|
||||
]
|
||||
},
|
||||
"extensions": [
|
||||
"eamodio.gitlens",
|
||||
"llvm-vs-code-extensions.vscode-clangd",
|
||||
"ms-vscode.cmake-tools",
|
||||
"ms-vscode.cpptools"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
this_dir="$(realpath "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")"
|
||||
sudo dpkg -i "$this_dir/emumba-deribit-connector-3.3.1-Linux.LICENSE_DISABLED.deb"
|
||||
+1
-1
@@ -54,6 +54,6 @@ trace_data/
|
||||
/src/Spark.Admin.WebApp/src/bin/
|
||||
**/CMakeDeps.cmake
|
||||
**/CMakeDeps_win.cmake
|
||||
.devcontainer/
|
||||
**/.devcontainer
|
||||
*.Generated.cs
|
||||
*.lst
|
||||
+1
-1
@@ -143,7 +143,7 @@
|
||||
"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",
|
||||
"CMAKE_CXX_FLAGS_RELEASE": "-fPIC -Wall -pedantic -Wextra -Werror -Wno-missing-braces -Wno-ignored-qualifiers --std=c++20 -fdiagnostics-color -Wno-stringop-overread -Wno-maybe-uninitialized -fno-omit-frame-pointer -DNDEBUG -O3",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/gcc/release/sparkd"
|
||||
}
|
||||
},
|
||||
|
||||
Submodule
+1
Submodule docker/linux added at 56c61231f3.
Submodule
+1
Submodule docker/windows added at de7d40c09d.
@@ -0,0 +1,45 @@
|
||||
/* global use, db */
|
||||
// MongoDB Playground
|
||||
// To disable this template go to Settings | MongoDB | Use Default Template For Playground.
|
||||
// Make sure you are connected to enable completions and to be able to run a playground.
|
||||
// Use Ctrl+Space inside a snippet or a string literal to trigger completions.
|
||||
// The result of the last command run in a playground is shown on the results panel.
|
||||
// By default the first 20 documents will be returned with a cursor.
|
||||
// Use 'console.log()' to print to the debug output.
|
||||
// For more documentation on playgrounds please refer to
|
||||
// https://www.mongodb.com/docs/mongodb-vscode/playgrounds/
|
||||
|
||||
// Select the database to use.
|
||||
use('mongodbVSCodePlaygroundDB');
|
||||
|
||||
// Insert a few documents into the sales collection.
|
||||
db.getCollection('sales').insertMany([
|
||||
{ 'item': 'abc', 'price': 10, 'quantity': 2, 'date': new Date('2014-03-01T08:00:00Z') },
|
||||
{ 'item': 'jkl', 'price': 20, 'quantity': 1, 'date': new Date('2014-03-01T09:00:00Z') },
|
||||
{ 'item': 'xyz', 'price': 5, 'quantity': 10, 'date': new Date('2014-03-15T09:00:00Z') },
|
||||
{ 'item': 'xyz', 'price': 5, 'quantity': 20, 'date': new Date('2014-04-04T11:21:39.736Z') },
|
||||
{ 'item': 'abc', 'price': 10, 'quantity': 10, 'date': new Date('2014-04-04T21:23:13.331Z') },
|
||||
{ 'item': 'def', 'price': 7.5, 'quantity': 5, 'date': new Date('2015-06-04T05:08:13Z') },
|
||||
{ 'item': 'def', 'price': 7.5, 'quantity': 10, 'date': new Date('2015-09-10T08:43:00Z') },
|
||||
{ 'item': 'abc', 'price': 10, 'quantity': 5, 'date': new Date('2016-02-06T20:20:13Z') },
|
||||
]);
|
||||
|
||||
// Run a find command to view items sold on April 4th, 2014.
|
||||
const salesOnApril4th = db.getCollection('sales').find({
|
||||
date: { $gte: new Date('2014-04-04'), $lt: new Date('2014-04-05') }
|
||||
}).count();
|
||||
|
||||
// Print a message to the output window.
|
||||
console.log(`${salesOnApril4th} sales occurred in 2014.`);
|
||||
|
||||
// Here we run an aggregation and open a cursor to the results.
|
||||
// Use '.toArray()' to exhaust the cursor to return the whole result set.
|
||||
// You can use '.hasNext()/.next()' to iterate through the cursor page by page.
|
||||
db.getCollection('sales').aggregate([
|
||||
// Find all of the sales that occurred in 2014.
|
||||
{ $match: { date: { $gte: new Date('2014-01-01'), $lt: new Date('2015-01-01') } } },
|
||||
// Group the total sales for each product.
|
||||
{ $group: { _id: '$item', totalSaleAmount: { $sum: { $multiply: ['$price', '$quantity'] } } } }
|
||||
]);
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ type Tab =
|
||||
| PositionManagementTab
|
||||
| MarginTab
|
||||
|
||||
let venues = [| Venue.BINANCE; Venue.BinanceUs; Venue.BinanceUsdsFutures; Venue.COINBASE; Venue.DERIBIT; Venue.GLBX; Venue.ICE; Venue.SIM; |]
|
||||
let venues = [| Venue.DERIBIT; Venue.GLBX; Venue.ICE; Venue.SIM; |]
|
||||
|
||||
let securityTypes = [| SecurityType.SPOT; SecurityType.FUTURE; SecurityType.OPTION; SecurityType.SPREAD; |]
|
||||
let securityTypes = [| SecurityType.FUTURE; SecurityType.OPTION; SecurityType.SPREAD; |]
|
||||
|
||||
let emptyAccount = Access.Accounts.empty
|
||||
|
||||
@@ -35,26 +35,6 @@ type CMEExchangeField =
|
||||
| ClearingAccount of string
|
||||
| MiscTagMapping of JSMap<string>
|
||||
|
||||
type BINANCEExchangeField =
|
||||
| CTI of CTICode
|
||||
| Origin of CustomerOrFirm
|
||||
| ClearingAccount of string
|
||||
|
||||
type BinanceUsExchangeField =
|
||||
| CTI of CTICode
|
||||
| Origin of CustomerOrFirm
|
||||
| ClearingAccount of string
|
||||
|
||||
type BinanceUsdsFUTURESExchangeField =
|
||||
| CTI of CTICode
|
||||
| Origin of CustomerOrFirm
|
||||
| ClearingAccount of string
|
||||
|
||||
type COINBASEExchangeField =
|
||||
| CTI of CTICode
|
||||
| Origin of CustomerOrFirm
|
||||
| ClearingAccount of string
|
||||
|
||||
type DERIBITExchangeField =
|
||||
| CTI of CTICode
|
||||
| Origin of CustomerOrFirm
|
||||
|
||||
@@ -797,7 +797,6 @@ let venueToString (venue:bts.api.Venue) =
|
||||
| bts.api.Venue.BINANCE -> "BINANCE"
|
||||
| bts.api.Venue.BinanceUs -> "BinanceUs"
|
||||
| bts.api.Venue.BinanceUsdsFutures -> "BinanceUsdsFutures"
|
||||
| bts.api.Venue.COINBASE -> "COINBASE"
|
||||
| bts.api.Venue.FTX -> "FTX"
|
||||
| bts.api.Venue.OKX -> "OKX"
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#nullable enable
|
||||
namespace Spark.Api.Orders {
|
||||
using bts;
|
||||
using bts.api;
|
||||
|
||||
using bts.api.core;
|
||||
using bts.api.orderman;
|
||||
using bts.api.position;
|
||||
@@ -16,8 +14,6 @@ namespace Spark.Api.Orders {
|
||||
using Spark.Core.Reactive;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System.Reactive.Concurrency;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@@ -59,7 +55,7 @@ namespace Spark.Api.Orders {
|
||||
o => o.order.ParentKey,
|
||||
(o, r) => new OrderRecordTupleWithRoot(o, r),
|
||||
o => new OrderRecordTupleWithRoot(o),
|
||||
o => o.key)
|
||||
o => o.root.order.Key)
|
||||
.Cache()
|
||||
.ToObservable());
|
||||
|
||||
@@ -131,29 +127,11 @@ namespace Spark.Api.Orders {
|
||||
});
|
||||
return r.value;
|
||||
} catch {
|
||||
var r = new Response {
|
||||
ErrorCode = OrderError.Undefined
|
||||
};
|
||||
var r = new Response();
|
||||
r.ErrorCode = OrderError.Undefined;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
public async Task<Response> TrySetPrecomputedTheosAsync(
|
||||
List<PrecomputedTheoPoint> ptp_list
|
||||
) {
|
||||
bts.api.orderman.PrecomputedTheos server_theos = new();
|
||||
server_theos.Theos.AddRange(ptp_list);
|
||||
var r = await _order_service.set_precomputed_theos_async(server_theos);
|
||||
var r2 = new Response {
|
||||
ErrorCode = OrderError.Ok,
|
||||
Msg = r.ToString()
|
||||
};
|
||||
return r2;
|
||||
}
|
||||
|
||||
public async Task<RegisteredDynamicOrderTypes> GetRegisteredDynamicOrderTypesAsync(){
|
||||
Result<RegisteredDynamicOrderTypes> r = await _order_service.get_registered_dynamic_order_types_async(new bts.api.VoidMessage());
|
||||
return r.value;
|
||||
}
|
||||
public async Task<Response> TryUpdateOrderAsync(
|
||||
CustomOrderDefinition custom,
|
||||
double price, double quantity, uint order_id
|
||||
@@ -168,9 +146,8 @@ namespace Spark.Api.Orders {
|
||||
});
|
||||
return r.value;
|
||||
} catch {
|
||||
var r = new Response {
|
||||
ErrorCode = OrderError.Undefined
|
||||
};
|
||||
var r = new Response();
|
||||
r.ErrorCode = OrderError.Undefined;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -182,9 +159,8 @@ namespace Spark.Api.Orders {
|
||||
});
|
||||
return r.value;
|
||||
} catch {
|
||||
var r = new Response {
|
||||
ErrorCode = OrderError.Undefined
|
||||
};
|
||||
var r = new Response();
|
||||
r.ErrorCode = OrderError.Undefined;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
var gwy = new bts.websocket_core.WebsocketConnectionGateway();
|
||||
var prms = new WebsocketServerConfig {
|
||||
DefaultEndPoint = "/",
|
||||
Host = "titan",
|
||||
Host = "0.0.0.0",
|
||||
Scheme = "http",
|
||||
Port = "8080",
|
||||
Port = "3000",
|
||||
KeepAliveIntervalSecs = 0.1,
|
||||
};
|
||||
gwy.init(sync);
|
||||
await sync.initAsync(gwy);
|
||||
sync.init(gwy);
|
||||
var errors = Errors.None;
|
||||
Log.Api.info("Starting websocket server...");
|
||||
// try {
|
||||
|
||||
@@ -424,6 +424,7 @@ namespace bts.websocket_core {
|
||||
/// </summary>
|
||||
/// <param name="server_params">The parameters for the websocket server includind the URL and endpoint,</param>
|
||||
public Task start_listening(WebsocketServerConfig server_params) {
|
||||
LoggerContext logger = new(Log.Gen, $"WebsocketGateway.start_listening ", "");
|
||||
// start listening, assert that init has been called already
|
||||
bts.Log.notnull(_sync);
|
||||
bts.Log.isnull(_server_params);
|
||||
@@ -433,6 +434,7 @@ namespace bts.websocket_core {
|
||||
_server_params = server_params;
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.WebHost.UseUrls(_server_params.Uri());
|
||||
logger.warn(_server_params.Uri());
|
||||
// var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
|
||||
builder.Services.AddLogging(builder => {
|
||||
builder.AddFilter("Microsoft", Microsoft.Extensions.Logging.LogLevel.Warning)
|
||||
|
||||
@@ -151,15 +151,6 @@ namespace bts.websocket_core {
|
||||
_orders_client = value;
|
||||
}
|
||||
}
|
||||
|
||||
IReadOnlyDictionary<string, DynamicOrderDescriptor>? _dynamic_descriptors;
|
||||
IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors{
|
||||
get => Log.notnull<IReadOnlyDictionary<string, DynamicOrderDescriptor>>(_dynamic_descriptors);
|
||||
set {
|
||||
Log.isnull<IReadOnlyDictionary<string, DynamicOrderDescriptor>>(_dynamic_descriptors);
|
||||
_dynamic_descriptors=value.ToDictionary(k=>k.Key.ToLower(),v => v.Value);
|
||||
}
|
||||
}
|
||||
WebsocketConnectionGateway? gateway;
|
||||
WebsocketConnectionGateway Gateway {
|
||||
get => Log.notnull<WebsocketConnectionGateway>(gateway);
|
||||
@@ -187,7 +178,7 @@ namespace bts.websocket_core {
|
||||
/// Should be called in the start, stores pointer for gtwy and creates dictionary for clients, starts broadcast thread
|
||||
/// </summary>
|
||||
/// <param name="gtwy"></param>
|
||||
public async Task initAsync(WebsocketConnectionGateway gtwy) {
|
||||
public void init(WebsocketConnectionGateway gtwy) {
|
||||
Gateway = gtwy;
|
||||
clients = new ClientsStore();
|
||||
TimeSpan md_throttle = TimeSpan.FromSeconds(0.1);
|
||||
@@ -206,10 +197,6 @@ namespace bts.websocket_core {
|
||||
var sec_table_src = MD_Source.subscribe_securities()
|
||||
.Table(s => s.security.Id)
|
||||
.Select(s => s.security, s => s.Id);
|
||||
var r = await Orders_Client.GetRegisteredDynamicOrderTypesAsync();
|
||||
Dynamic_Descriptors = r
|
||||
.DynamicOrderDesc
|
||||
.ToDictionary(d => d.DynamicOrderType);
|
||||
Synth_Sec_Client = new(synth_sec_service, sec_table_src);
|
||||
|
||||
|
||||
@@ -283,10 +270,6 @@ namespace bts.websocket_core {
|
||||
handle_update_order(req);
|
||||
break;
|
||||
}
|
||||
case WebsocketRequest.REQUEST_TYPES.SET_PRECOMPUTED_THEOS: {
|
||||
handle_set_theos(req);
|
||||
break;
|
||||
}
|
||||
case WebsocketRequest.REQUEST_TYPES.UNKOWN: {
|
||||
///send error
|
||||
break;
|
||||
@@ -301,21 +284,30 @@ namespace bts.websocket_core {
|
||||
System.Console.WriteLine("error for req", client_id, ex.ToString());
|
||||
}
|
||||
}
|
||||
public async Task HandleRestRequest(WebsocketRequest req, Func<WebsocketRequest, OrdersClient, Task<(bool success, uint? id, string status)>> handlerAsync) {
|
||||
(bool success, uint? id, string status) = await handlerAsync(req, Orders_Client);
|
||||
if (!success){
|
||||
public async void handle_delete_order(WebsocketRequest req) {
|
||||
(bool suc, string status) = await WebsocketRestHandler.DeleteOrderAsync(req, Orders_Client);
|
||||
if (!suc) {
|
||||
handle_incorrect_request(req, status);
|
||||
return;
|
||||
}
|
||||
handle_correct_request(req.id, status, id != null ? new { order_key = id } : null, req.client_id);
|
||||
handle_correct_request(req.id, status, null, req.client_id);
|
||||
}
|
||||
public async void handle_enter_order(WebsocketRequest req) {
|
||||
(bool suc, uint? id, string status) = await WebsocketRestHandler.EnterOrderAsync(req, Orders_Client, _securities);
|
||||
if (!suc) {
|
||||
handle_incorrect_request(req, status);
|
||||
return;
|
||||
}
|
||||
handle_correct_request(req.id, status, new { order_key = id }, req.client_id);
|
||||
}
|
||||
public async void handle_update_order(WebsocketRequest req) {
|
||||
(bool suc, string status) = await WebsocketRestHandler.UpdateOrderAsync(req, Orders_Client);
|
||||
if (!suc) {
|
||||
handle_incorrect_request(req, status);
|
||||
return;
|
||||
}
|
||||
handle_correct_request(req.id, status, null, req.client_id);
|
||||
}
|
||||
public async void handle_delete_order(WebsocketRequest req) { await HandleRestRequest(req,WebsocketRestHandler.DeleteOrderAsync);}
|
||||
public async void handle_set_theos(WebsocketRequest req) { await HandleRestRequest(req,(req, Orders_Client) => WebsocketRestHandler.SetTheosAsync(req, Orders_Client, _securities));}
|
||||
public async void handle_enter_order(WebsocketRequest req) { await HandleRestRequest(req,(req, Orders_Client) => WebsocketRestHandler.EnterOrderAsync(
|
||||
req, Orders_Client, _securities,Dynamic_Descriptors
|
||||
));}
|
||||
public async void handle_update_order(WebsocketRequest req) { await HandleRestRequest(req,(req, Orders_Client) => WebsocketRestHandler.UpdateOrderAsync(req,Orders_Client,Dynamic_Descriptors));}
|
||||
|
||||
public void handle_subscription(WebsocketRequest req) {
|
||||
WebsocketSubscriptionHandler? hdlr;
|
||||
string status;
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
namespace bts.websocket_core {
|
||||
using bts.api;
|
||||
using bts.api.core;
|
||||
using bts.api.orderman;
|
||||
|
||||
using bts.md;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -31,67 +27,9 @@ namespace bts.websocket_core {
|
||||
public static Object to_json<T>(IList<T> list)
|
||||
where T : IJsonFormatter<T> =>
|
||||
to_json(list, T.ToJsonObj);
|
||||
public struct PrecomputedTheoPointWrapper {
|
||||
UInt32 SecId{get;init;}
|
||||
public double driver{get;init;}
|
||||
UInt32 DriverSecId{get;init;}
|
||||
public double theo{get;init;}
|
||||
public double delta{get;init;}
|
||||
public double gamma{get;init;}
|
||||
public double vega{get;init;}
|
||||
public double theta{get;init;}
|
||||
public double rho{get;init;}
|
||||
public double vol{get;init;}
|
||||
public Venue venue{get;init;}
|
||||
public String exchange_security_name{get;init;}
|
||||
public String driver_exchange_security_name{get;init;}
|
||||
public static bool GetTheoPoint(PrecomputedTheoPointWrapper inp, [NotNullWhen(true)] out PrecomputedTheoPoint? p, IReadOnlyDictionary<uint, mbts.SecurityMD> _securites){
|
||||
p = null;
|
||||
if (!_securites.Values.TryGetFirst(sc_md =>
|
||||
(
|
||||
sc_md.security.Exchange == inp.venue &&
|
||||
sc_md.security.ToString() == inp.exchange_security_name),
|
||||
out mbts.SecurityMD sec
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
if (!_securites.Values.TryGetFirst(sc_md =>
|
||||
(
|
||||
sc_md.security.Exchange == inp.venue &&
|
||||
sc_md.security.ToString() == inp.driver_exchange_security_name),
|
||||
out mbts.SecurityMD driver_sec
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
p = new(){
|
||||
SecId = sec.id,
|
||||
Driver=inp.driver,
|
||||
DriverSecId=driver_sec.id,
|
||||
Theo=inp.theo,
|
||||
Delta=inp.delta,
|
||||
Gamma=inp.gamma,
|
||||
Vega=inp.vega,
|
||||
Theta=inp.theta,
|
||||
Rho=inp.rho,
|
||||
Vol=inp.vol,
|
||||
};
|
||||
return true;
|
||||
|
||||
}
|
||||
public static bool TryParse(string input, [NotNullWhen(true)] out PrecomputedTheoPointWrapper? P) {
|
||||
P = null;
|
||||
try {
|
||||
var temp = JsonConvert.DeserializeObject<PrecomputedTheoPointWrapper>(input);
|
||||
P = temp;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
public struct StringListWrapper : IEnumerable<string> {
|
||||
public struct ListWrapper : IEnumerable<string> {
|
||||
public List<string> Lis { get; set; }
|
||||
public StringListWrapper(List<string> l) {
|
||||
public ListWrapper(List<string> l) {
|
||||
Lis = l;
|
||||
}
|
||||
|
||||
@@ -111,24 +49,14 @@ namespace bts.websocket_core {
|
||||
public string[] getlwrarr() {
|
||||
return Lis.Select(v => v.ToLower()).ToArray();
|
||||
}
|
||||
public static bool TryParse(string input, [NotNullWhen(true)] out StringListWrapper? l) {
|
||||
public static bool TryParse(string input, [NotNullWhen(true)] out ListWrapper? l) {
|
||||
l = null;
|
||||
try {
|
||||
var temp = JsonConvert.DeserializeObject<List<Object>>(input);
|
||||
var temp = JsonConvert.DeserializeObject<List<string>>(input);
|
||||
if (temp == null) {
|
||||
return false;
|
||||
}
|
||||
List<string> stringList = new List<string>();
|
||||
|
||||
foreach (object obj in temp)
|
||||
{
|
||||
string? val = obj.ToString();
|
||||
if(val==null){
|
||||
return false;
|
||||
}
|
||||
stringList.Add(val);
|
||||
}
|
||||
l = new StringListWrapper(stringList);
|
||||
l = new ListWrapper(temp);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
@@ -143,33 +71,26 @@ namespace bts.websocket_core {
|
||||
|
||||
}
|
||||
public static bool TryParse<T>(JObject filter, string key, out T[]? list, out string error) where T : struct {
|
||||
T[] values = new T[] { };
|
||||
list = null;
|
||||
if (TryParse<StringListWrapper>(filter, key, out StringListWrapper? wrap, out error)) {
|
||||
ListWrapper? wrap;
|
||||
if (TryParse<ListWrapper>(filter, key, out wrap, out error)) {
|
||||
if (wrap != null) {
|
||||
var values = new List<T>();
|
||||
foreach (var item in wrap) {
|
||||
if (TryParse<T>(item, key, out T? obj, out error) && obj != null) {
|
||||
values.Add(obj.Value);
|
||||
T? obj;
|
||||
if (TryParse<T>(item, key, out obj, out error) && obj != null) {
|
||||
values = values.ToList().Append<T>((T)obj).ToArray();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
list = values.ToArray();
|
||||
list = values;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool TryParse<T>(JObject filter, string key, out T? obj, [NotNullWhen(false)] out string error) where T : struct {
|
||||
obj = null;
|
||||
var value = filter.GetValueOrDefault(key)?.ToString();
|
||||
if (value == null) {
|
||||
error = $"{key} not present";
|
||||
return true;
|
||||
}
|
||||
return TryParse<T>(value, key, out obj, out error);
|
||||
|
||||
}
|
||||
public static bool TryParse<T>(string value, string key, [NotNullWhen(true)] out T? obj, [NotNull] out string error) where T : struct {
|
||||
error = "";
|
||||
if (typeof(T).IsEnum && Enum.TryParse<T>(value, true, out var result)) {
|
||||
@@ -179,10 +100,7 @@ namespace bts.websocket_core {
|
||||
if (typeof(T) == typeof(double) && double.TryParse(value, out var d)) {
|
||||
obj = (T)(object)d;
|
||||
return true;
|
||||
}
|
||||
if (typeof(T) == typeof(bool) && bool.TryParse(value, out var b)) {
|
||||
obj = (T)(object)b;
|
||||
return true;
|
||||
|
||||
}
|
||||
if (typeof(T) == typeof(uint) && uint.TryParse(value, out var uin)) {
|
||||
obj = (T)(object)uin;
|
||||
@@ -200,14 +118,10 @@ namespace bts.websocket_core {
|
||||
obj = (T)(object)new StringWrapper(value);
|
||||
return true;
|
||||
}
|
||||
if (typeof(T) == typeof(StringListWrapper) && StringListWrapper.TryParse(value, out var l)) {
|
||||
if (typeof(T) == typeof(ListWrapper) && ListWrapper.TryParse(value, out var l)) {
|
||||
obj = (T)(object)l;
|
||||
return true;
|
||||
}
|
||||
if (typeof(T)==typeof(PrecomputedTheoPointWrapper) && PrecomputedTheoPointWrapper.TryParse(value, out var p)){
|
||||
obj=(T)(object)p;
|
||||
return true;
|
||||
}
|
||||
if (typeof(T) == typeof(DateTime) && DateTime.TryParseExact(value, "yyyy/MM/dd", CultureInfo.InvariantCulture,
|
||||
DateTimeStyles.None, out var dt)) {
|
||||
obj = (T)(object)dt;
|
||||
@@ -218,7 +132,16 @@ namespace bts.websocket_core {
|
||||
obj = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryParse<T>(JObject filter, string key, out T? obj, [NotNullWhen(false)] out string error) where T : struct {
|
||||
obj = null;
|
||||
var value = filter.GetValueOrDefault(key)?.ToString();
|
||||
if (value == null) {
|
||||
error = $"{key} not present";
|
||||
return true;
|
||||
}
|
||||
return TryParse<T>(value, key, out obj, out error);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ namespace bts.websocket_core {
|
||||
UNSUBSCRIBE,
|
||||
ENTER_ORDER,
|
||||
DELETE_ORDER,
|
||||
|
||||
UPDATE_ORDER,
|
||||
SET_PRECOMPUTED_THEOS,
|
||||
DELETE,
|
||||
PATCH,
|
||||
UNKOWN = 0
|
||||
|
||||
@@ -6,352 +6,109 @@ namespace bts.websocket_core {
|
||||
|
||||
using mbts;
|
||||
|
||||
using Microsoft.VisualBasic;
|
||||
|
||||
using mbts.spark;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using Spark.Api.Orders;
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using bts.spark;
|
||||
using bts.utils;
|
||||
|
||||
public class WebsocketRestHandler {
|
||||
public static (bool,DynamicOrderParam?,string) TryGetDynamicParam(JObject custom,string key, DynamicOrderParamDescriptor descriptor, IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors) {
|
||||
var rv = new DynamicOrderParam();
|
||||
string error = "";
|
||||
switch (descriptor.ParamType.DescriptorCase) {
|
||||
case DynamicOrderTypeDescriptor.DescriptorOneofCase.Array:
|
||||
if (custom[key] is not JArray arr_obj) {
|
||||
return (false, null, key + " not correct");
|
||||
}
|
||||
rv.AsArray = new DynamicOrderArray();
|
||||
foreach (var p in arr_obj.ToList()){
|
||||
var child_key = key+"_child";
|
||||
DynamicOrderParamDescriptor child_descriptor=new() {
|
||||
ParamName = child_key,
|
||||
ParamType = descriptor.ParamType.Array.ElementType
|
||||
};
|
||||
|
||||
JObject child = new() {
|
||||
[child_key] = p
|
||||
};
|
||||
|
||||
(bool suc, DynamicOrderParam? param, error) = TryGetDynamicParam(child,child_key,child_descriptor,Dynamic_Descriptors);
|
||||
if(!suc){
|
||||
return (suc,null,error);
|
||||
}
|
||||
rv.AsArray.Element.Add(param);
|
||||
}
|
||||
return (true,rv,error);
|
||||
case DynamicOrderTypeDescriptor.DescriptorOneofCase.Enumerated:
|
||||
return (false,null,key+"Enumerated DynamicOrderTypeDescriptors not enabled on api");
|
||||
case DynamicOrderTypeDescriptor.DescriptorOneofCase.Primitive:
|
||||
switch (descriptor.ParamType.Primitive) {
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveBool:
|
||||
if (!WebsocketJsonParsers.TryParse<bool>(custom, key, out bool? b, out error) || b == null) {
|
||||
return (false, null, error);
|
||||
}
|
||||
rv.AsBool = (bool)b;
|
||||
return (true,rv,error);
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveDouble:
|
||||
if (!WebsocketJsonParsers.TryParse<double>(custom, key, out double? d, out error) || d == null) {
|
||||
return (false, null, error);
|
||||
}
|
||||
rv.AsDouble = (double)d;
|
||||
return (true,rv,error);
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveInt:
|
||||
if (!WebsocketJsonParsers.TryParse<int>(custom, key, out int? i, out error) || i == null) {
|
||||
return (false, null, error);
|
||||
}
|
||||
rv.AsInt32 = (int)i;
|
||||
return (true,rv,error);
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveOrderDef:
|
||||
if (custom[key] is not JObject child_custom) {
|
||||
return (false, null, key + " not correct");
|
||||
}
|
||||
(bool suc,var child_custom_def,error) = TryGetCustomDef(child_custom,Dynamic_Descriptors);
|
||||
if(!suc || child_custom_def==null){
|
||||
return (false,null,error);
|
||||
}
|
||||
rv.AsOrderDef = child_custom_def;
|
||||
return(true,rv,error);
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveString:
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(custom,key,out WebsocketJsonParsers.StringWrapper? s,out error)|| s == null) {
|
||||
return (false, null, error);
|
||||
}
|
||||
rv.AsString = s.Value.Val;
|
||||
return (true,rv,error);
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveSecurityKey:
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveUint:
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(custom, key, out uint? u, out error) || u == null) {
|
||||
return (false, null, error);
|
||||
}
|
||||
rv.AsUint32 = (uint)u;
|
||||
return (true,rv,error);
|
||||
case DynamicOrderPrimitiveDescriptor.DynamicOrderPrimitiveQuantity:
|
||||
if (WebsocketJsonParsers.TryParse<uint>(custom, key, out uint? q, out error) && q != null) {
|
||||
rv.AsQuantity = new QuantityMeasure() {
|
||||
Absolute = (uint)q
|
||||
};
|
||||
return (true, rv, error);
|
||||
} else if (WebsocketJsonParsers.TryParse<double>(custom, key, out double? qd, out error) && qd != null){
|
||||
rv.AsQuantity = new QuantityMeasure() {
|
||||
Ratio = (double)qd
|
||||
};
|
||||
return (true, rv, error);
|
||||
}
|
||||
else{
|
||||
return (false,null,key+" not correct");
|
||||
}
|
||||
}
|
||||
return (false,null,key+" not correct");
|
||||
case DynamicOrderTypeDescriptor.DescriptorOneofCase.Structure:
|
||||
if (custom[key] is not JObject obj) {
|
||||
return (false, null, key + " not correct");
|
||||
}
|
||||
rv.AsStruct = new DynamicOrderStruct();
|
||||
|
||||
foreach (var prop in obj.Properties()) {
|
||||
var child_key = prop.Name;
|
||||
var check = descriptor.ParamType.Structure.Field.TryGetFirst(v => v?.ParamName == child_key,out DynamicOrderParamDescriptor? p);
|
||||
if(!check || p == null){
|
||||
return (false,null,key+" "+child_key+" not correct");
|
||||
}
|
||||
var child_descriptor = new DynamicOrderParamDescriptor {
|
||||
ParamName = child_key,
|
||||
ParamType = p.ParamType
|
||||
};
|
||||
|
||||
(bool success, DynamicOrderParam? param, error) = TryGetDynamicParam(obj, child_key, child_descriptor, Dynamic_Descriptors);
|
||||
if (!success) {
|
||||
return (success, null, error);
|
||||
}
|
||||
rv.AsStruct.Field[child_key] = param;
|
||||
}
|
||||
return (true,rv,error);
|
||||
}
|
||||
return (false,null,key+" not correct");
|
||||
}
|
||||
readonly static Lazy<AdminService> _admin = new Lazy<AdminService>(() => Locator.locate<AdminService>(), true);
|
||||
|
||||
private static (bool, CustomOrderDefinition?, string) TryGetCustomDef(WebsocketRequest req, IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors){
|
||||
if (req.parameters["options"] is not JObject custom) {
|
||||
return (false, null, "options not correct");
|
||||
}
|
||||
return TryGetCustomDef(custom,Dynamic_Descriptors);
|
||||
}
|
||||
private static (bool, CustomOrderDefinition?, string) TryGetCustomDef(JObject custom, IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors) {
|
||||
private static (bool, CustomOrderDefinition?, string) TryGetCustomDef(WebsocketRequest req) {
|
||||
string status = "";
|
||||
CustomOrderDefinition customdef;
|
||||
|
||||
if (!WebsocketJsonParsers.TryParse<CustomOrderDefinition.CustomOneofCase>(custom, "order_type", out CustomOrderDefinition.CustomOneofCase? order_type, out string status) || order_type == null) {
|
||||
JObject? custom = req.parameters["custom"] as JObject;
|
||||
if (!WebsocketJsonParsers.TryParse<CustomOrderDefinition.CustomOneofCase>(
|
||||
req.parameters,
|
||||
"order_type",
|
||||
out CustomOrderDefinition.CustomOneofCase? order_type,
|
||||
out status)
|
||||
|| order_type == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
switch (order_type) {
|
||||
case CustomOrderDefinition.CustomOneofCase.Stop:{
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Stop = new StopOrderDefinition()
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.StopLimit:{
|
||||
if (!WebsocketJsonParsers.TryParse<double>(custom, "stop_price", out double? sp, out status) || sp == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
customdef = new CustomOrderDefinition() {
|
||||
StopLimit = new StopLimitOrderDefinition(){
|
||||
StopPrice=(double)sp
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Iceberg: {
|
||||
if (!WebsocketJsonParsers.TryParse<double>(custom, "show_quantity", out double? sq, out status) || sq == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (custom["child"] is not JObject child) {
|
||||
return (false, null, "Iceberg child not correct");
|
||||
}
|
||||
(var check, var childdef, status) = TryGetCustomDef(child,Dynamic_Descriptors);
|
||||
if(!check){
|
||||
return (false, null, status);
|
||||
}
|
||||
// mbts.spark.utilities.OrderDataHelper
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Iceberg = new IcebergOrderDefinition() {
|
||||
ShowQuantity = (double)sq,
|
||||
Child = childdef
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.TimeBox:{
|
||||
return (false,null,"timebox not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Spreader: {
|
||||
// if (custom == null) {
|
||||
// message = "custom not present";
|
||||
// return false;
|
||||
// }
|
||||
return (false,null,"spreaders not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Tick:{
|
||||
return (false,null,"Ticks not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Lean:{
|
||||
return (false,null,"Lean not enabled on api");
|
||||
// if (!WebsocketJsonParsers.TryParse<double>(custom, "", out double? sq, out status) || sq == null) {
|
||||
// return (false, null, status);
|
||||
// }
|
||||
// if (custom["child"] is not JObject child) {
|
||||
// return (false, null, "Lean child not correct");
|
||||
// }
|
||||
// (var check, var childdef, status) = TryGetCustomDef(child,Dynamic_Descriptors);
|
||||
// if(!check){
|
||||
// return (false, null, status);
|
||||
// }
|
||||
|
||||
// customdef = new CustomOrderDefinition() {
|
||||
// Lean = new LeanOrderDefinition(){
|
||||
// DetachOnToward = false,
|
||||
// CrossThreshold = 0,
|
||||
// MaxChaseTicks = 0,
|
||||
// Child = childdef
|
||||
|
||||
// }
|
||||
// };
|
||||
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Join:{
|
||||
return (false,null,"join not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Top:{
|
||||
return (false,null,"top not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Trigger:{
|
||||
return (false,null,"trigger not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Cover: {
|
||||
if (
|
||||
!WebsocketJsonParsers.TryParse<uint>( custom, "hedge_ticks", out uint? ht, out status) || ht == null ||
|
||||
!WebsocketJsonParsers.TryParse<bool>(custom, "cancel_on_external_hedge_cancel", out bool? coehc, out status) || coehc == null ||
|
||||
!WebsocketJsonParsers.TryParse<bool>(custom, "cancel_hedges_on_cancel", out bool? choc, out status) || choc == null ||
|
||||
!WebsocketJsonParsers.TryParse<bool>(custom, "detach_hedges", out bool? dh, out status) || dh == null
|
||||
) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (custom["child"] is not JObject child) {
|
||||
return (false, null, "Cover child not correct");
|
||||
}
|
||||
(var check, var childdef, status) = TryGetCustomDef(child,Dynamic_Descriptors);
|
||||
if(!check){
|
||||
return (false, null, status);
|
||||
}
|
||||
if (custom["hedge"] is not JObject hedge) {
|
||||
return (false, null, "Cover hedge not correct");
|
||||
}
|
||||
(check, var hedgedef, status) = TryGetCustomDef(hedge,Dynamic_Descriptors);
|
||||
if(!check){
|
||||
return (false, null, status);
|
||||
}
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Cover = new CoverOrderDefinition() {
|
||||
HedgeTicks = (uint)ht,
|
||||
CancelOnExternalHedgeCancel = (bool)coehc,
|
||||
CancelHedgesOnCancel = (bool)choc,
|
||||
DetachHedges = (bool)dh,
|
||||
Hedge = hedgedef,
|
||||
Child = childdef
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Offset:{
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(custom, "tick_offset", out uint? to, out status) || to == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (custom["child"] is not JObject child) {
|
||||
return (false, null, "offset child not correct");
|
||||
}
|
||||
(var check, var childdef, status) = TryGetCustomDef(child,Dynamic_Descriptors);
|
||||
if(!check){
|
||||
return (false, null, status);
|
||||
}
|
||||
// mbts.spark.utilities.OrderDataHelper
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Offset = new OffsetOrderDefinition() {
|
||||
TickOffsetOnDeploy = (uint)to,
|
||||
Child = childdef
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Oco:{
|
||||
return (false,null,"Oco not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Pricer:{
|
||||
return (false,null,"pricer not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Composite:{
|
||||
return (false,null,"Composite not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.GlbxIceberg:{
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(custom, "max_show_quantity", out uint? msq, out status) || msq == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
// mbts.spark.utilities.OrderDataHelper
|
||||
customdef = new CustomOrderDefinition() {
|
||||
GlbxIceberg = new GLBXIcebergOrderDefinition() {
|
||||
MaxShowQuantity = (uint)msq,
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Splitter:{
|
||||
return (false,null,"splitter not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.QueueHolder:{
|
||||
return (false,null,"QueueHolder not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Scratch:{
|
||||
return (false,null,"Scratch not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Prorata:{
|
||||
return (false,null,"Prorata not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.DeleteAndCover:{
|
||||
return (false,null,"DeleteAndCover not enabled on api");
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Limit: {
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Limit = new LimitOrderDefinition()
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Dynamic: {
|
||||
}
|
||||
|
||||
// case CustomOrderDefinition.CustomOneofCase.Spreader: {
|
||||
// // if (custom == null) {
|
||||
// // message = "custom not present";
|
||||
// // return false;
|
||||
// // }
|
||||
// //ENTER SPREADER CODE HERE
|
||||
// break;
|
||||
// }
|
||||
case CustomOrderDefinition.CustomOneofCase.Iceberg: {
|
||||
if (custom == null) {
|
||||
return (false, null, "custom not present");
|
||||
}
|
||||
if(!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(custom, "dynamic_order_type", out WebsocketJsonParsers.StringWrapper? dynamic_order_type, out status) || dynamic_order_type == null ||
|
||||
!Dynamic_Descriptors.TryGetValue(dynamic_order_type.Value.Val, out var desc)){
|
||||
double? sq;
|
||||
if (!WebsocketJsonParsers.TryParse<double>(custom, "show_quantity", out sq, out status) || sq == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
var def = new DynamicOrderDefinition() {
|
||||
DynamicOrderType = desc.DynamicOrderType
|
||||
};
|
||||
|
||||
foreach (var p in desc.ParamDesc) {
|
||||
(bool suc, var d, var error)=TryGetDynamicParam(custom,p.ParamName,p,Dynamic_Descriptors);
|
||||
if(!suc){
|
||||
return (suc,null,error);
|
||||
}
|
||||
def.OrderParams[p.ParamName] = d;
|
||||
}
|
||||
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Dynamic = def
|
||||
Iceberg = new IcebergOrderDefinition() {
|
||||
ShowQuantity = (double)sq,
|
||||
Child = new CustomOrderDefinition() {
|
||||
Limit = new LimitOrderDefinition()
|
||||
}
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case CustomOrderDefinition.CustomOneofCase.Cover: {
|
||||
if (custom == null) {
|
||||
return (false, null, "custom not present");
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(
|
||||
custom,
|
||||
"hedge_ticks",
|
||||
out uint? ht,
|
||||
out status)
|
||||
|| ht == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<bool>(
|
||||
custom,
|
||||
"cancel_on_external_hedge_cancel",
|
||||
out bool? coehc,
|
||||
out status)
|
||||
|| coehc == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<bool>(
|
||||
custom,
|
||||
"cancel_hedges_on_cancel",
|
||||
out bool? choc,
|
||||
out status)
|
||||
|| choc == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<bool>(
|
||||
custom,
|
||||
"detach_hedges",
|
||||
out bool? dh,
|
||||
out status)
|
||||
|| dh == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
customdef = new CustomOrderDefinition() {
|
||||
Cover = new CoverOrderDefinition() {
|
||||
Hedge = new CustomOrderDefinition() {
|
||||
Limit = new LimitOrderDefinition()
|
||||
},
|
||||
HedgeTicks = (uint)ht,
|
||||
CancelOnExternalHedgeCancel = (bool)coehc,
|
||||
CancelHedgesOnCancel = (bool)choc,
|
||||
DetachHedges = (bool)dh,
|
||||
Child = new CustomOrderDefinition() {
|
||||
Limit = new LimitOrderDefinition()
|
||||
}
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
@@ -367,20 +124,26 @@ namespace bts.websocket_core {
|
||||
};
|
||||
return (true, customdef, status);
|
||||
}
|
||||
private async static Task<(bool, OrderDefinition?, string)> TryGetOrderDefAsync(WebsocketRequest req, IReadOnlyDictionary<uint, SecurityMD> securities, IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors) {
|
||||
private async static Task<(bool, OrderDefinition?, string)> TryGetOrderDefAsync(WebsocketRequest req, IReadOnlyDictionary<uint, SecurityMD> securities) {
|
||||
if (req.parameters == null) {
|
||||
return (false, null, "parameters not present");
|
||||
}
|
||||
if (
|
||||
!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(req.parameters,"user",out WebsocketJsonParsers.StringWrapper? usr,out string status) || usr == null ||
|
||||
!WebsocketJsonParsers.TryParse<Venue>(req.parameters, "venue", out Venue? exchange, out status) || exchange == null ||
|
||||
!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(req.parameters, "account", out WebsocketJsonParsers.StringWrapper? act, out status) || act == null ||
|
||||
!WebsocketJsonParsers.TryParse<Side>(req.parameters, "side", out Side? side, out status) || side == null ||
|
||||
!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(req.parameters, "exchange_security_name", out WebsocketJsonParsers.StringWrapper? exchange_securty_name, out status) || exchange_securty_name == null
|
||||
) {
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(
|
||||
req.parameters,
|
||||
"user",
|
||||
out WebsocketJsonParsers.StringWrapper? usr,
|
||||
out string status)
|
||||
|| usr == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(
|
||||
req.parameters,
|
||||
"account",
|
||||
out WebsocketJsonParsers.StringWrapper? act,
|
||||
out status)
|
||||
|| act == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
|
||||
Result<AdminData> adminResult = await _admin.Value.get_admin_data_async(new VoidMessage());
|
||||
uint user_id;
|
||||
uint account_id;
|
||||
@@ -400,8 +163,20 @@ namespace bts.websocket_core {
|
||||
return (false, null, "account not correct");
|
||||
}
|
||||
account_id = (uint)account.Id;
|
||||
|
||||
|
||||
if (!WebsocketJsonParsers.TryParse<Side>(
|
||||
req.parameters,
|
||||
"side",
|
||||
out Side? side,
|
||||
out status)
|
||||
|| side == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(req.parameters, "exchange_securty_name", out WebsocketJsonParsers.StringWrapper? exchange_securty_name, out status) || exchange_securty_name == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<Venue>(req.parameters, "venue", out Venue? exchange, out status) || exchange == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
var _securites = securities;
|
||||
if (!_securites.Values.TryGetFirst(sc_md =>
|
||||
(
|
||||
@@ -412,100 +187,73 @@ namespace bts.websocket_core {
|
||||
return (false, null, "security not found");
|
||||
}
|
||||
|
||||
(var check, var customdef, status) = TryGetCustomDef(req, Dynamic_Descriptors);
|
||||
(var check, var customdef, status) = TryGetCustomDef(req);
|
||||
if (check == false) {
|
||||
return (false, null, status);
|
||||
}
|
||||
|
||||
|
||||
return (true, new OrderDefinition {
|
||||
TimeInForce = TimeInForce.Day,
|
||||
TimeInForce = TimeInForce.Gtc,
|
||||
SecurityKey = sc_md.id,
|
||||
Side = (Side)side,
|
||||
UserId = user_id,
|
||||
AccountId = account_id,
|
||||
CustomDef = customdef,
|
||||
Account = account.Name,
|
||||
User = user.Name
|
||||
CustomDef = customdef
|
||||
}, status);
|
||||
}
|
||||
static bool TryGetPoints(WebsocketRequest req, [NotNullWhen(true)] out List<PrecomputedTheoPoint>? theos, out string message, IReadOnlyDictionary<uint, SecurityMD> securities) {
|
||||
theos = null;
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.PrecomputedTheoPointWrapper>(req.parameters, "points", out WebsocketJsonParsers.PrecomputedTheoPointWrapper[]? wrapper_theos, out message) || wrapper_theos == null) {
|
||||
return false;
|
||||
}
|
||||
theos = wrapper_theos.Select(wrapper => {
|
||||
if (WebsocketJsonParsers.PrecomputedTheoPointWrapper.GetTheoPoint(wrapper, out PrecomputedTheoPoint? point, securities)) {
|
||||
return point;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.Where(p => p != null)
|
||||
.Cast<PrecomputedTheoPoint>()
|
||||
.ToList();
|
||||
return true;
|
||||
|
||||
}
|
||||
public static async Task<(bool success, uint? id, string status)> SetTheosAsync(WebsocketRequest req, OrdersClient oc, IReadOnlyDictionary<uint, SecurityMD> securities) {
|
||||
public static async Task<(bool success, string status)> DeleteOrderAsync(WebsocketRequest req, OrdersClient oc) {
|
||||
if (req.parameters == null) {
|
||||
return (false, null, "parameters not present");
|
||||
return (false, "parameters not present");
|
||||
}
|
||||
var log_txt = $"SetTheosAsync req {req.ToString()}";
|
||||
bts.Log.Gen.warn(log_txt);
|
||||
|
||||
var _securites = securities;
|
||||
if (!TryGetPoints(req, out List<PrecomputedTheoPoint>? theos, out string message, _securites)) {
|
||||
return (false, null, message);
|
||||
}
|
||||
Response res = await oc.TrySetPrecomputedTheosAsync(theos);
|
||||
return (res.ErrorCode != OrderError.Ok, null, res.Msg);
|
||||
}
|
||||
public static async Task<(bool success, uint? id, string status)> DeleteOrderAsync(WebsocketRequest req, OrdersClient oc) {
|
||||
if (req.parameters == null) {
|
||||
return (false, null, "parameters not present");
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(req.parameters, "order_key", out uint? key, out string status) || key == null) {
|
||||
return (false, null, status);
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(req.parameters, "order_id", out uint? key, out string status) || key == null) {
|
||||
return (false, status);
|
||||
}
|
||||
Response res = await oc.TryDeleteOrderAsync((uint)key);
|
||||
status = res.ErrorCode.ToString();
|
||||
return (res.ErrorCode != OrderError.Ok, null, status);
|
||||
return (res.ErrorCode != OrderError.Ok, status);
|
||||
}
|
||||
public static async Task<(bool success, uint? id, string status)> UpdateOrderAsync(WebsocketRequest request, OrdersClient oc, IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors) {
|
||||
public static async Task<(bool success, string status)> UpdateOrderAsync(WebsocketRequest request, OrdersClient oc) {
|
||||
if (request.parameters == null) {
|
||||
return (false, null, "parameters not present");
|
||||
return (false, "parameters not present");
|
||||
}
|
||||
if (
|
||||
!WebsocketJsonParsers.TryParse<uint>(request.parameters, "order_key", out uint? key, out string status) || key == null ||
|
||||
!WebsocketJsonParsers.TryParse(request.parameters, "quantity", out double? quantity, out status) || quantity == null ||
|
||||
!WebsocketJsonParsers.TryParse(request.parameters, "price", out double? price, out status) || price == null
|
||||
) {
|
||||
return (false, null, status);
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(request.parameters, "order_id", out uint? key, out string status) || key == null) {
|
||||
return (false, status);
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse(request.parameters, "quantity", out double? quantity, out status) || quantity == null) {
|
||||
return (false, status);
|
||||
}
|
||||
|
||||
(var check, var customdef, status) = TryGetCustomDef(request, Dynamic_Descriptors);
|
||||
if (!WebsocketJsonParsers.TryParse(request.parameters, "price", out double? price, out status) || price == null) {
|
||||
return (false, status);
|
||||
}
|
||||
(var check, var customdef, status) = TryGetCustomDef(request);
|
||||
if (check == false || customdef == null) {
|
||||
return (false, null, status);
|
||||
return (false, status);
|
||||
}
|
||||
Response res = await oc.TryUpdateOrderAsync(customdef, (double)price, (double)quantity, (uint)key);
|
||||
status = res.ErrorCode.ToString();
|
||||
return (res.ErrorCode != OrderError.Ok, null, status);
|
||||
return (res.ErrorCode != OrderError.Ok, status);
|
||||
}
|
||||
public static async Task<(bool success, uint? orderId, string status)> EnterOrderAsync(
|
||||
WebsocketRequest request, OrdersClient ordersClient, IReadOnlyDictionary<uint, SecurityMD> securities, IReadOnlyDictionary<string, DynamicOrderDescriptor> Dynamic_Descriptors) {
|
||||
WebsocketRequest request, OrdersClient ordersClient, IReadOnlyDictionary<uint, SecurityMD> securities) {
|
||||
double? quantity = null;
|
||||
double? price = null;
|
||||
OrderDefinition? orderDefinition = null;
|
||||
uint? orderId = null;
|
||||
string status = string.Empty;
|
||||
|
||||
(bool success, orderDefinition, status) = await TryGetOrderDefAsync(request, securities, Dynamic_Descriptors);
|
||||
|
||||
if (
|
||||
!success || orderDefinition == null ||
|
||||
!WebsocketJsonParsers.TryParse(request.parameters, "quantity", out double? quantity, out status) || quantity == null ||
|
||||
!WebsocketJsonParsers.TryParse(request.parameters, "price", out double? price, out status) || price == null ) {
|
||||
if (!WebsocketJsonParsers.TryParse(request.parameters, "quantity", out quantity, out status) || quantity == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
|
||||
if (!WebsocketJsonParsers.TryParse(request.parameters, "price", out price, out status) || price == null) {
|
||||
return (false, null, status);
|
||||
}
|
||||
|
||||
(bool success, orderDefinition, status) = await TryGetOrderDefAsync(request, securities);
|
||||
if (!success || orderDefinition == null) {
|
||||
return (success, null, status);
|
||||
}
|
||||
|
||||
var result = await ordersClient.TryEnterOrderAsync(orderDefinition, (uint)price, (double)quantity);
|
||||
|
||||
if (result.ErrorCode != OrderError.Ok) {
|
||||
|
||||
@@ -100,28 +100,36 @@ namespace bts.websocket_core {
|
||||
}
|
||||
|
||||
static bool TryGetTradesFilter(WebsocketRequest req, [NotNullWhen(true)] out TradesSubscriptionFilter? trades_filter, out string message) {
|
||||
SecurityCriteria? cri;
|
||||
trades_filter = null;
|
||||
JObject? filter = req.parameters?["filter"] as JObject;
|
||||
if (filter == null) {
|
||||
message = "filter not present";
|
||||
return false;
|
||||
}
|
||||
if (!TryGetFilter(req, out SecurityCriteria? cri, out message)) {
|
||||
if (!TryGetFilter(req, out cri, out message)) {
|
||||
return false;
|
||||
}
|
||||
trades_filter = new TradesSubscriptionFilter(cri);
|
||||
return true;
|
||||
}
|
||||
static bool TryGetFillsFilter(WebsocketRequest req, [NotNullWhen(true)] out FillsSubscriptionFilter? order_filter, out string message) {
|
||||
SecurityCriteria? cri;
|
||||
order_filter = null;
|
||||
if (req.parameters?["filter"] is not JObject filter) {
|
||||
JObject? filter = req.parameters?["filter"] as JObject;
|
||||
if (filter == null) {
|
||||
message = "filter not present";
|
||||
return false;
|
||||
}
|
||||
if (!TryGetFilter(req, out SecurityCriteria? cri, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<uint>(filter, "accounts", out uint[]? accounts, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<OrderStatus>(filter, "statuses", out OrderStatus[]? statuses, out message)
|
||||
) {
|
||||
if (!TryGetFilter(req, out cri, out message)) {
|
||||
return false;
|
||||
}
|
||||
uint[]? accounts;
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(filter, "accounts", out accounts, out message)) {
|
||||
return false;
|
||||
}
|
||||
OrderStatus[]? statuses;
|
||||
if (!WebsocketJsonParsers.TryParse<OrderStatus>(filter, "statuses", out statuses, out message)) {
|
||||
return false;
|
||||
}
|
||||
order_filter = new FillsSubscriptionFilter(
|
||||
@@ -130,16 +138,22 @@ namespace bts.websocket_core {
|
||||
return true;
|
||||
}
|
||||
static bool TryGetOrdersFilter(WebsocketRequest req, [NotNullWhen(true)] out OrdersSubscriptionFilter? order_filter, out string message) {
|
||||
SecurityCriteria? cri;
|
||||
order_filter = null;
|
||||
if (req.parameters?["filter"] is not JObject filter) {
|
||||
JObject? filter = req.parameters?["filter"] as JObject;
|
||||
if (filter == null) {
|
||||
message = "filter not present";
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
!TryGetFilter(req, out SecurityCriteria? cri, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<uint>(filter, "accounts", out uint[]? accounts, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<OrderStatus>(filter, "statuses", out OrderStatus[]? statuses, out message)
|
||||
) {
|
||||
if (!TryGetFilter(req, out cri, out message)) {
|
||||
return false;
|
||||
}
|
||||
uint[]? accounts;
|
||||
if (!WebsocketJsonParsers.TryParse<uint>(filter, "accounts", out accounts, out message)) {
|
||||
return false;
|
||||
}
|
||||
OrderStatus[]? statuses;
|
||||
if (!WebsocketJsonParsers.TryParse<OrderStatus>(filter, "statuses", out statuses, out message)) {
|
||||
return false;
|
||||
}
|
||||
order_filter = new OrdersSubscriptionFilter(
|
||||
@@ -151,19 +165,39 @@ namespace bts.websocket_core {
|
||||
|
||||
static bool TryGetFilter(WebsocketRequest req, [NotNullWhen(true)] out SecurityCriteria? cri, out string message) {
|
||||
cri = null;
|
||||
if (req.parameters?["filter"] is not JObject filter) {
|
||||
JObject? filter = req.parameters?["filter"] as JObject;
|
||||
if (filter == null) {
|
||||
message = "filter not present";
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
!WebsocketJsonParsers.TryParse<Venue>(filter, "venue", out Venue[]? exchanges, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<SecurityType>(filter, "kind", out SecurityType[]? types, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<PutOrCall>(filter, "call_or_put", out PutOrCall[]? callputs, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<DateTime>(filter, "expiration", out DateTime[]? expiration, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringListWrapper>(filter, "symbol", out WebsocketJsonParsers.StringListWrapper? symbols, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringListWrapper>(filter, "name", out WebsocketJsonParsers.StringListWrapper? names, out message) ||
|
||||
!WebsocketJsonParsers.TryParse<double>(filter, "strikes", out double[]? strikes, out message)
|
||||
) {
|
||||
Venue[]? exchanges;
|
||||
if (!WebsocketJsonParsers.TryParse<Venue>(filter, "venue", out exchanges, out message)) {
|
||||
return false;
|
||||
}
|
||||
SecurityType[]? types;
|
||||
if (!WebsocketJsonParsers.TryParse<SecurityType>(filter, "kind", out types, out message)) {
|
||||
return false;
|
||||
}
|
||||
PutOrCall[]? callputs;
|
||||
if (!WebsocketJsonParsers.TryParse<PutOrCall>(filter, "call_or_put", out callputs, out message)) {
|
||||
return false;
|
||||
}
|
||||
DateTime[]? expiration;
|
||||
if (!WebsocketJsonParsers.TryParse<DateTime>(filter, "expiration", out expiration, out message)) {
|
||||
return false;
|
||||
}
|
||||
// string[]? symbols = (string[]?)(filter.GetValueOrDefault("symbol")?.ToString()?.Split(",").Select(s => s.ToUpper()));
|
||||
WebsocketJsonParsers.ListWrapper? symbols;
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.ListWrapper>(filter, "symbol", out symbols, out message)) {
|
||||
return false;
|
||||
}
|
||||
WebsocketJsonParsers.ListWrapper? names;
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.ListWrapper>(filter, "name", out names, out message)) {
|
||||
return false;
|
||||
}
|
||||
// filter.GetValueOrDefault("symbol")?.ToString()?.Split(",");
|
||||
double[]? strikes;
|
||||
if (!WebsocketJsonParsers.TryParse<double>(filter, "strikes", out strikes, out message)) {
|
||||
return false;
|
||||
}
|
||||
var clause = new SecurityCriteriaClause(
|
||||
@@ -189,12 +223,13 @@ namespace bts.websocket_core {
|
||||
out string status) {
|
||||
hdlr = null;
|
||||
|
||||
if (
|
||||
!WebsocketJsonParsers.TryParse<SUBSCRIPTION_TYPE>(req.parameters, "type", out SUBSCRIPTION_TYPE? type, out status) || status != "" ||
|
||||
!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(req.parameters, "subscription_id", out WebsocketJsonParsers.StringWrapper? id, out status) || id == null) {
|
||||
SUBSCRIPTION_TYPE? type;
|
||||
if (!WebsocketJsonParsers.TryParse<SUBSCRIPTION_TYPE>(req.parameters, "type", out type, out status) || status != "") {
|
||||
return false;
|
||||
}
|
||||
if (!WebsocketJsonParsers.TryParse<WebsocketJsonParsers.StringWrapper>(req.parameters, "subscription_id", out WebsocketJsonParsers.StringWrapper? id, out status) || id == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Action<WebsocketSubscriptionHandler> sub;
|
||||
switch (type) {
|
||||
case SUBSCRIPTION_TYPE.BOOKS: {
|
||||
|
||||
@@ -93,6 +93,10 @@ function(get_cpp_sources dest)
|
||||
md/MDConsumerInterop.cpp
|
||||
md/MDProducer.cpp
|
||||
md/MDProducerHandle.cpp
|
||||
md/MarketDataError.cpp
|
||||
md/MarketDataGateway.cpp
|
||||
md/MarketDataRegistrationFactory.cpp
|
||||
md/MarketDataSubscription.cpp
|
||||
md/MemorySegmentUtils.cpp
|
||||
md/PriceSize.cpp
|
||||
md/Product.cpp
|
||||
@@ -109,6 +113,8 @@ function(get_cpp_sources dest)
|
||||
md/cme/MDP3Utils.cpp
|
||||
md/common.cpp
|
||||
md/ice/ICEUtils.cpp
|
||||
md/recording/MDRecorder.cpp
|
||||
md/recording/MDReplayer.cpp
|
||||
md/relay/QueryServer.cpp
|
||||
md/relay/RelayClient.cpp
|
||||
md/relay/RelayRecorder.cpp
|
||||
|
||||
@@ -87,6 +87,10 @@ function(get_cpp_sources dest)
|
||||
md/MDConsumerInterop.cpp
|
||||
md/MDProducer.cpp
|
||||
md/MDProducerHandle.cpp
|
||||
md/MarketDataError.cpp
|
||||
md/MarketDataGateway.cpp
|
||||
md/MarketDataRegistrationFactory.cpp
|
||||
md/MarketDataSubscription.cpp
|
||||
md/MemorySegmentUtils.cpp
|
||||
md/PriceSize.cpp
|
||||
md/Product.cpp
|
||||
|
||||
@@ -17,9 +17,7 @@ JetFIXSimConnection {
|
||||
raw_data: "1JE9X"
|
||||
use_cme_secure_logon: false
|
||||
seconds_to_pause : 1
|
||||
max_order_msgs_per_window: 300
|
||||
window_duration_msecs: 1000
|
||||
max_connection_attempts: 9999999
|
||||
max_connection_attempts: 9999999
|
||||
}
|
||||
sim_ice {
|
||||
name: "sim_ice"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#define ENUM_BASIC_MEMBERS(type) \
|
||||
Value value; \
|
||||
\
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
#include "lib/utils/ValueWrapper.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace bts {
|
||||
|
||||
using SecurityKey = utils::ValueWrapper<struct SecurityKeyTag, std::uint32_t>;
|
||||
|
||||
} // namespace bts
|
||||
|
||||
FMT_IMPL(bts::SecurityKey, k, "{}", k.value());
|
||||
using SecurityKey = utils::ValueWrapper<struct SecurityKeyTag, uint32_t>;
|
||||
}
|
||||
@@ -69,6 +69,8 @@ inline void from_json(const nlohmann::json &j, JsonRpcRequestT<ParamsT> &req) {
|
||||
j.at("method").get_to(req.method);
|
||||
j.at("params").get_to(req.params);
|
||||
std::vector<std::string> vec;
|
||||
*vec.begin();
|
||||
vec.begin()->size();
|
||||
auto id_j = j.find("id");
|
||||
if (id_j == j.end()) {
|
||||
req.id = std::nullopt;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace bts::io::websocket {
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#include "logging.h"
|
||||
|
||||
#include "LoggerHub.h"
|
||||
#include "lib/core/LockGuard.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <ccapi_cpp/ccapi_logger.h>
|
||||
#include <ccapi_cpp/service/ccapi_market_data_service_deribit.h>
|
||||
#include <fmt/format.h>
|
||||
#include <google/protobuf/io/gzip_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace ccapi {
|
||||
|
||||
class CcapiLogger final : public Logger {
|
||||
public:
|
||||
void logMessage(
|
||||
const std::string &severity,
|
||||
const std::string & /*thread_id*/,
|
||||
const std::string & /*time_iso*/,
|
||||
const std::string &file_name,
|
||||
const std::string &line_num,
|
||||
const std::string &msg) override {
|
||||
auto level = to_bts_level_(severity);
|
||||
if (!bts::log::_thread_logger.logger->is_loggable(bts::log::md, level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add file name to cache to preserve it in memory until the log is
|
||||
// [asynchronously] committed
|
||||
const auto &cached_file_name = store_file_name_(file_name);
|
||||
bts::log::_thread_logger.logger->enqueue(
|
||||
bts::log::log_ts(), bts::log::md, level, cached_file_name.c_str(),
|
||||
stoi(line_num), "{}", msg);
|
||||
}
|
||||
|
||||
static bts::log::Level to_bts_level_(const std::string &ccapi_severity) {
|
||||
bts_assert(!ccapi_severity.empty());
|
||||
// TRACE and DEBUG translate to Diag; all other levels have identical
|
||||
// names in ccapi and spark
|
||||
if (ccapi_severity[0] == 'T' || ccapi_severity[0] == 'D') {
|
||||
return bts::Diag;
|
||||
}
|
||||
if (ccapi_severity[0] == 'I') {
|
||||
return bts::Info;
|
||||
}
|
||||
if (ccapi_severity[0] == 'W') {
|
||||
return bts::Warn;
|
||||
}
|
||||
if (ccapi_severity[0] == 'E') {
|
||||
return bts::Error;
|
||||
}
|
||||
if (ccapi_severity[0] == 'F') {
|
||||
return bts::Fatal;
|
||||
}
|
||||
bts_assert(false);
|
||||
return bts::Fatal;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex instance_mx_;
|
||||
std::unordered_set<std::string> file_name_store_;
|
||||
// This buffer is intended to keep file name strings in memory until the log
|
||||
// is [asynchronously] committed. There is no mechanism for determining when
|
||||
// the log is actually committed; we just hope that the log system won't be
|
||||
// flooded to the point that file names are pushed out of the buffer before
|
||||
// their corresponding logs are committed.
|
||||
//
|
||||
// Note: Another implementation, which would guarentee file names are
|
||||
// preserved, is to maintain a set of unique file names. Naturally, it's
|
||||
// size would be limited, but not without cost in additional overhead for
|
||||
// lookups.
|
||||
const std::string &store_file_name_(const std::string &file_name) {
|
||||
LOCK_GUARD(instance_mx_);
|
||||
return *file_name_store_.insert(file_name).first;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ccapi
|
||||
@@ -1,16 +1,17 @@
|
||||
#include "logging.h"
|
||||
|
||||
#include "LoggerHub.h"
|
||||
#include "lib/config/config.h"
|
||||
#include "lib/config/protos/deployment_type.pb.h"
|
||||
#include "lib/config/protos/logging.pb.h"
|
||||
#include "lib/config/protos/system_config.pb.h"
|
||||
#include "lib/core/LockGuard.h"
|
||||
#include "lib/os/os.h"
|
||||
#include "lib/utils/Dispatcher.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/bts_chrono.h"
|
||||
#include "lib/utils/file_utils.h"
|
||||
#include "lib/utils/thread_manager.h"
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/logging/ccapi_logger.h"
|
||||
#endif
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
@@ -18,12 +19,16 @@
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include <ccapi_cpp/ccapi_logger.h>
|
||||
#include <ccapi_cpp/service/ccapi_market_data_service_deribit.h>
|
||||
#endif
|
||||
#include <fstream>
|
||||
#include <google/protobuf/io/gzip_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace bts {
|
||||
namespace log {
|
||||
@@ -218,9 +223,72 @@ extern "C" BTS_EXPORT void Logger_log(
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
namespace ccapi {
|
||||
class SparkLoggerAdaptor final : public Logger {
|
||||
public:
|
||||
void logMessage(
|
||||
const std::string &severity,
|
||||
const std::string & /*thread_id*/,
|
||||
const std::string & /*time_iso*/,
|
||||
const std::string &file_name,
|
||||
const std::string &line_num,
|
||||
const std::string &msg) override {
|
||||
auto level = to_bts_level_(severity);
|
||||
if (!bts::log::_thread_logger.logger->is_loggable(bts::log::md, level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CcapiLogger ccapi_logger;
|
||||
Logger *Logger::logger = &ccapi_logger;
|
||||
// Add file name to cache to preserve it in memory until the log is
|
||||
// [asynchronously] committed
|
||||
const auto &cached_file_name = store_file_name_(file_name);
|
||||
bts::log::_thread_logger.logger->enqueue(
|
||||
bts::log::log_ts(), bts::log::md, level, cached_file_name.c_str(),
|
||||
stoi(line_num), "{}", msg);
|
||||
}
|
||||
|
||||
static bts::log::Level to_bts_level_(const std::string &ccapi_severity) {
|
||||
bts_assert(!ccapi_severity.empty());
|
||||
// TRACE and DEBUG translate to Diag; all other levels have identical
|
||||
// names in ccapi and spark
|
||||
if (ccapi_severity[0] == 'T' || ccapi_severity[0] == 'D') {
|
||||
return bts::Diag;
|
||||
}
|
||||
if (ccapi_severity[0] == 'I') {
|
||||
return bts::Info;
|
||||
}
|
||||
if (ccapi_severity[0] == 'W') {
|
||||
return bts::Warn;
|
||||
}
|
||||
if (ccapi_severity[0] == 'E') {
|
||||
return bts::Error;
|
||||
}
|
||||
if (ccapi_severity[0] == 'F') {
|
||||
return bts::Fatal;
|
||||
}
|
||||
bts_assert(false);
|
||||
return bts::Fatal;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex instance_mx_;
|
||||
std::unordered_set<std::string> file_name_store_;
|
||||
// This buffer is intended to keep file name strings in memory until the log
|
||||
// is [asynchronously] committed. There is no mechanism for determining when
|
||||
// the log is actually committed; we just hope that the log system won't be
|
||||
// flooded to the point that file names are pushed out of the buffer before
|
||||
// their corresponding logs are committed.
|
||||
//
|
||||
// Note: Another implementation, which would guarentee file names are
|
||||
// preserved, is to maintain a set of unique file names. Naturally, it's
|
||||
// size would be limited, but not without cost in additional overhead for
|
||||
// lookups.
|
||||
const std::string &store_file_name_(const std::string &file_name) {
|
||||
LOCK_GUARD(instance_mx_);
|
||||
return *file_name_store_.insert(file_name).first;
|
||||
}
|
||||
};
|
||||
|
||||
SparkLoggerAdaptor spark_logger_adaptor;
|
||||
Logger *Logger::logger = &spark_logger_adaptor;
|
||||
|
||||
} // namespace ccapi
|
||||
#endif
|
||||
+2
@@ -1,3 +1,4 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiCompositeMessageHandler.h"
|
||||
#include "lib/collections/Remove.h"
|
||||
|
||||
@@ -36,3 +37,4 @@ void CCApiCompositeMessageHandler::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
+3
-3
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -39,3 +38,4 @@ T &CCApiCompositeMessageHandler::emplace(Args... args) {
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
#include "lib/core/StringFinder.h"
|
||||
#include "lib/core/StringJoiner.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
@@ -270,3 +269,4 @@ struct std::hash<bts::md::CCApiCorrelationID> {
|
||||
};
|
||||
|
||||
FMT_IMPL(bts::md::CCApiCorrelationID, cid, "{}", cid.to_string());
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiDepthWalker.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace bts::md {
|
||||
@@ -37,3 +37,4 @@ bool CCApiDepthWalker::parse_field(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/domain/BookSide.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace bts::md {
|
||||
@@ -19,3 +18,4 @@ class CCApiDepthWalker {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiEventDemuxer.h"
|
||||
#include "lib/collections/DiscreteValuesFilter.h"
|
||||
#include "lib/collections/Find.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
|
||||
#include "lib/utils/helper_macros.h"
|
||||
#include <ccapi_cpp/ccapi_event_handler.h>
|
||||
@@ -165,3 +166,4 @@ bool CCApiEventDemuxer::remove_handler(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include <ccapi_cpp/ccapi_event_handler.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -80,3 +79,4 @@ class CCApiEventDemuxer : public ccapi::EventHandler,
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/logging/logging.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_event_handler.h>
|
||||
|
||||
namespace bts::md {
|
||||
@@ -16,3 +15,4 @@ class CCApiRequestor_Handler : public ccapi::EventHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "CCApiHttpParams.h"
|
||||
#include "lib/algorithm/StringCaseConverter.h"
|
||||
|
||||
@@ -45,3 +47,4 @@ map<string, string> CCApiHttpParams::to_map() const {
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "lib/io/QueryParams.h"
|
||||
#include "lib/io/http/HttpMethod.h"
|
||||
@@ -24,3 +25,4 @@ class CCApiHttpParams {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "lib/io/websocket/JsonRpcRequest.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_subscription.h>
|
||||
|
||||
@@ -54,3 +55,4 @@ inline const io::websocket::JsonRpcId &CCApiJsonRpcRequest::id() const {
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
+4
-1
@@ -1,8 +1,10 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "CCApiJsonRpcRouter.h"
|
||||
#include "lib/algorithm/TryCatch.h"
|
||||
#include "lib/io/websocket/JsonRpcHandler.h"
|
||||
#include "lib/md/CCApiReader.h"
|
||||
#include "lib/utils/bts_fatal.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiReader.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
@@ -43,3 +45,4 @@ void CCApiJsonRpcRouter::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "lib/io/websocket/JsonRpcHandler.h"
|
||||
#include "lib/io/websocket/JsonRpcRouter.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
|
||||
#include <memory>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -73,3 +74,4 @@ CCApiJsonRpcRouter::notification_handler(const std::string &method) {
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
+5
-3
@@ -1,9 +1,10 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiMarketDepthAdaptor.h"
|
||||
#include "lib/domain/BUY_SELL.h"
|
||||
#include "lib/domain/Book.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiDepthWalker.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
#include "lib/md/CCApiDepthWalker.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_macro.h>
|
||||
@@ -73,3 +74,4 @@ void CCApiMarketDepthAdaptor::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
+3
-3
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/domain/Book.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ccapi {
|
||||
@@ -42,3 +41,4 @@ class CCApiMarketDepthAdaptor : public ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include "lib/utils/Delegate.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
#include <ccapi_cpp/ccapi_session.h>
|
||||
@@ -44,3 +43,4 @@ class CCApiMessageHandler : public ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiMessageLogger.h"
|
||||
#include "lib/core/StringJoiner.h"
|
||||
#include "lib/core/TimeStamp.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <range/v3/view.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
@@ -30,3 +30,4 @@ void CCApiMessageLogger::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/domain/Book.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ccapi {
|
||||
@@ -30,3 +31,4 @@ class CCApiMessageLogger : public ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiReader.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_macro.h>
|
||||
@@ -110,3 +111,4 @@ vector<json> CCApiReader::read_http_jsons(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/utils/bts_assert.h"
|
||||
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sstream>
|
||||
@@ -193,3 +192,4 @@ inline bool CCApiReader::parse_(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiSession.h"
|
||||
#include "lib/logging/logging.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiEventDemuxer.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
#include "lib/md/CCApiEventDemuxer.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_event_dispatcher.h>
|
||||
@@ -146,3 +147,4 @@ void CCApiSession::subscribe(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include "lib/utils/Delegate.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -99,3 +98,4 @@ class CCApiSession {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiTradeAdaptor.h"
|
||||
#include "lib/core/TimeStamp.h"
|
||||
#include "lib/domain/SecurityID.h"
|
||||
#include "lib/domain/TradeRecord.h"
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
#include "lib/md/CCApiTradeRecord.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include "lib/utils/bts_fatal.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiTradeRecord.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
@@ -66,3 +67,4 @@ void CCApiTradeAdaptor::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/domain/SecurityID.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiTradeRecord.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/CCApiTradeRecord.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ccapi {
|
||||
@@ -37,3 +36,4 @@ class CCApiTradeAdaptor : public ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "CCApiTradeRecord.h"
|
||||
#include "lib/domain/AggressorSide.h"
|
||||
#include "lib/domain/Price.h"
|
||||
@@ -5,10 +6,9 @@
|
||||
#include "lib/domain/TradeRecord.h"
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "lib/md/CCApiReader.h"
|
||||
#include "lib/utils/bts_chrono.h"
|
||||
#include "lib/utils/datetime.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiReader.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_element.h>
|
||||
#include <ccapi_cpp/ccapi_macro.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
@@ -109,3 +109,4 @@ std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/NaN.h"
|
||||
|
||||
#include "lib/core/TimeStamp.h"
|
||||
#include <cstdint>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <vector>
|
||||
@@ -47,3 +47,4 @@ void to_json(nlohmann::json &j, const CCApiTradeRecord &r);
|
||||
std::ostream &operator<<(std::ostream &out, const CCApiTradeRecord &r) noexcept;
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,15 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/utils/ValueWrapper.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace bts::md {
|
||||
|
||||
namespace bts {
|
||||
namespace md {
|
||||
using ExchangeOrderKey =
|
||||
utils::ValueWrapper<struct ExchangeOrderKeyTag, std::uint64_t>;
|
||||
|
||||
using SparkOrderKey =
|
||||
utils::ValueWrapper<struct SparkOrderKeyTag, std::uint64_t>;
|
||||
|
||||
} // namespace bts::md
|
||||
utils::ValueWrapper<struct ExchangeOrderKeyTag, uint64_t>;
|
||||
using SparkOrderKey = utils::ValueWrapper<struct SparkOrderKeyTag, uint64_t>;
|
||||
} // namespace md
|
||||
} // namespace bts
|
||||
@@ -1,12 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/utils/ValueWrapper.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace bts {
|
||||
|
||||
using ExchangeSecurityKey =
|
||||
utils::ValueWrapper<struct ExchangeSecurityKeyTag, std::uint64_t>;
|
||||
|
||||
} // namespace bts
|
||||
utils::ValueWrapper<struct ExchangeSecurityKeyTag, uint64_t>;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
//#ifdef SPARK_ENABLE_CCAPI
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "GeneralMarketDataListener.h"
|
||||
#include "lib/api/domain/Currency.pb.h"
|
||||
#include "lib/api/domain/SecurityType.pb.h"
|
||||
@@ -464,4 +464,4 @@ void GeneralMarketDataListener::_possibly_match_with_sim_orders(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
//#endif
|
||||
#endif
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "ICCApiMessageHandler.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
|
||||
namespace bts::md {
|
||||
|
||||
ICCApiMessageHandler::~ICCApiMessageHandler() = default;
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "server/sparkd/md/ccapi/CCApiCorrelationID.h"
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/md/CCApiCorrelationID.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
#include <vector>
|
||||
@@ -29,3 +29,4 @@ class ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -537,7 +537,7 @@ class SyntheticConsumerInst {
|
||||
IncompleteStrategy to_strategy(const shared_ptr<api::Security> &security) {
|
||||
IncompleteStrategy res;
|
||||
res.security = security;
|
||||
auto meta = _ss->get_metadata(bts::SecurityKey(security->id()));
|
||||
auto meta = _ss->get_metadata(SecurityKey(security->id()));
|
||||
// If metadata is set copy it otherwise we use the default proto
|
||||
if (meta) {
|
||||
res.strategy.CopyFrom(meta->strategy());
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,38 +1,48 @@
|
||||
#include "lib/api/md/GlbxMarketDataConfig.pb.h"
|
||||
#if !defined(_WIN32) && defined(SPARK_ENABLE_CCAPI)
|
||||
#include "MarketDataGateway.h"
|
||||
#include "lib/api/md/EmumbaDeribitMarketDataConfig.pb.h"
|
||||
#include "lib/api/md/GlbxMarketDataConfig.pb.h"
|
||||
#include "lib/api/md/MarketDataConfig.pb.h"
|
||||
#include "lib/api/md/MarketDataConfigUtils.h"
|
||||
#include "lib/api/md/MarketDataReplayConfig.pb.h"
|
||||
#include "lib/collections/Contains.h"
|
||||
#include "lib/config/protos/system_config.pb.h"
|
||||
#include "lib/core/FMT.h"
|
||||
#include "lib/domain/FutureSecurity.h"
|
||||
#include "lib/domain/OptionSecurity.h"
|
||||
#include "lib/domain/Security.h"
|
||||
#include "lib/domain/SecurityID.h"
|
||||
#include "lib/domain/SpotSecurity.h"
|
||||
#include "lib/domain_model/Security.pb.h"
|
||||
#include "lib/io/ProtoPrinter.h"
|
||||
#include "lib/logging/logging.h"
|
||||
#include "lib/md/GeneralMarketDataListener.h"
|
||||
#include "lib/md/GeneralSecurityIndex.h"
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
#include "lib/md/MDProducer.h"
|
||||
#include "lib/md/MarketDataListenerID.h"
|
||||
#include "lib/md/MarketDataRegistration.h"
|
||||
#include "lib/md/MarketDataRegistrationError.h"
|
||||
#include "lib/md/MarketDataRegistrationFactory.h"
|
||||
#include "lib/md/MarketDataSubscription.h"
|
||||
#include "lib/md/binance/BinanceSubscription.h"
|
||||
#include "lib/md/binance_us/BinanceUsSubscription.h"
|
||||
#include "lib/md/binance_usds_futures/BinanceUsdsFuturesSubscription.h"
|
||||
#include "lib/md/coinbase/CoinbaseSubscription.h"
|
||||
#include "lib/md/deribit/DeribitSubscription.h"
|
||||
#include "lib/md/ftx/FTXSubscription.h"
|
||||
#include "lib/md/okx/OkxSubscription.h"
|
||||
#include "lib/md/recording/MDReplayer.h"
|
||||
#include "lib/md/vendor/emumba/EmumbaDeribitData.h"
|
||||
#include "lib/persistence/IDGenerator.h"
|
||||
#include "lib/utils/PBUtils.h"
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/bts_fatal.h"
|
||||
#include "lib/utils/thread_manager.h"
|
||||
#include "server/sparkd/md/MarketDataListenerID.h"
|
||||
#include "server/sparkd/md/MarketDataRegistration.h"
|
||||
#include "server/sparkd/md/MarketDataRegistrationError.h"
|
||||
#include "server/sparkd/md/MarketDataRegistrationFactory.h"
|
||||
#include "server/sparkd/md/MarketDataSubscription.h"
|
||||
#include "server/sparkd/md/binance/BinanceSubscription.h"
|
||||
#include "server/sparkd/md/binance_us/BinanceUsSubscription.h"
|
||||
#include "server/sparkd/md/binance_usds_futures/BinanceUsdsFuturesSubscription.h"
|
||||
#include "server/sparkd/md/coinbase/CoinbaseSubscription.h"
|
||||
#include "server/sparkd/md/deribit/DeribitSubscription.h"
|
||||
#include "server/sparkd/md/emumba/EmumbaDeribitData.h"
|
||||
#include "server/sparkd/md/ftx/FTXSubscription.h"
|
||||
#include "server/sparkd/md/okx/OkxSubscription.h"
|
||||
#include "server/sparkd/md/platforms/emumba/EmumbaMain.h"
|
||||
#include "server/sparkd/md/platforms/mdp3_onixs/MDP3Main.h"
|
||||
#include "server/sparkd/md/recording/MDReplayer.h"
|
||||
#include "server/sparkd/md/cme/CMEActivSession.h"
|
||||
#include "lib/md/cme/CMEActivSession.h"
|
||||
|
||||
#include <bits/stdint-uintn.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -40,6 +50,7 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace bts::md {
|
||||
@@ -387,3 +398,4 @@ void MarketDataGateway::_start_replays(
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(_WIN32) && defined(SPARK_ENABLE_CCAPI)
|
||||
#include "lib/api/md/GlbxMarketDataConfig.pb.h"
|
||||
#include "server/sparkd/md/MarketDataListenerID.h"
|
||||
|
||||
#include "MarketDataListenerID.h"
|
||||
#include <memory>
|
||||
|
||||
namespace bts::api::md {
|
||||
@@ -43,3 +43,4 @@ class MarketDataGateway {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
#ifndef _WIN32
|
||||
#include "IMarketDataListener.h"
|
||||
#include "lib/domain/Book.h"
|
||||
#include "lib/domain/Security.h"
|
||||
#include "lib/domain/SecurityMarketDataStatistics.h"
|
||||
#include "lib/domain/SecurityState.h"
|
||||
#include "lib/domain/TradeRecord.h"
|
||||
#include "server/sparkd/md/MarketDataError.h"
|
||||
#include "lib/md/MarketDataError.h"
|
||||
|
||||
namespace bts::md {
|
||||
|
||||
@@ -29,23 +29,24 @@ class MarketDataListener : public IMarketDataListener {
|
||||
// Definition
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
inline void MarketDataListener::on_securities(
|
||||
void MarketDataListener::on_securities(
|
||||
const std::vector<const domain::Security *> & /*complete_security_list*/) {}
|
||||
|
||||
inline void MarketDataListener::on_security_state(
|
||||
void MarketDataListener::on_security_state(
|
||||
const domain::SecurityState & /*security_state*/) {}
|
||||
|
||||
inline void MarketDataListener::on_security_statistics(
|
||||
void MarketDataListener::on_security_statistics(
|
||||
const domain::SecurityMarketDataStatistics & /*security_stats*/) {}
|
||||
|
||||
inline void MarketDataListener::on_book(const domain::Book & /*book*/) {}
|
||||
void MarketDataListener::on_book(const domain::Book & /*book*/) {}
|
||||
|
||||
inline void MarketDataListener::on_trades(
|
||||
void MarketDataListener::on_trades(
|
||||
const std::vector<const domain::TradeRecord *> & /*trades*/) {}
|
||||
|
||||
inline void MarketDataListener::on_rfqs(
|
||||
void MarketDataListener::on_rfqs(
|
||||
const std::vector<const domain::RFQ *> & /*rfqs*/) {}
|
||||
|
||||
inline void MarketDataListener::on_error(const MarketDataError & /*error*/) {}
|
||||
void MarketDataListener::on_error(const MarketDataError & /*error*/) {}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+11
-8
@@ -1,12 +1,14 @@
|
||||
#if !defined(_WIN32) && defined(SPARK_ENABLE_CCAPI)
|
||||
#include "MarketDataSubscription.h"
|
||||
#include "server/sparkd/md/binance/BinanceSubscription.h"
|
||||
#include "server/sparkd/md/binance_us/BinanceUsSubscription.h"
|
||||
#include "server/sparkd/md/binance_usds_futures/BinanceUsdsFuturesSubscription.h"
|
||||
#include "server/sparkd/md/coinbase/CoinbaseSubscription.h"
|
||||
#include "server/sparkd/md/deribit/DeribitSubscription.h"
|
||||
#include "server/sparkd/md/ftx/FTXSubscription.h"
|
||||
#include "server/sparkd/md/okx/OkxSubscription.h"
|
||||
|
||||
#include "lib/api/md/MarketDataConfig.pb.h"
|
||||
#include "lib/md/binance/BinanceSubscription.h"
|
||||
#include "lib/md/binance_us/BinanceUsSubscription.h"
|
||||
#include "lib/md/binance_usds_futures/BinanceUsdsFuturesSubscription.h"
|
||||
#include "lib/md/coinbase/CoinbaseSubscription.h"
|
||||
#include "lib/md/deribit/DeribitSubscription.h"
|
||||
#include "lib/md/ftx/FTXSubscription.h"
|
||||
#include "lib/md/okx/OkxSubscription.h"
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace bts::md {
|
||||
@@ -58,3 +60,4 @@ void MarketDataSubscription::add(okx::OkxSubscription sub) {
|
||||
}
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(_WIN32) && defined(SPARK_ENABLE_CCAPI)
|
||||
#include <memory>
|
||||
|
||||
namespace bts::md::binance {
|
||||
@@ -57,3 +57,4 @@ class MarketDataSubscription {
|
||||
};
|
||||
|
||||
} // namespace bts::md
|
||||
#endif
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "../common.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
#include "lib/core/TimeStamp.h"
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "lib/utils/ValueWrapper.h"
|
||||
@@ -10,8 +9,8 @@
|
||||
#include "lib/utils/bts_assert.h"
|
||||
#include "lib/utils/bts_export.h"
|
||||
#include "lib/utils/bts_no_copy.h"
|
||||
#include "lib/core/TimeStamp.h"
|
||||
#include "lib/utils/warn_ctrl.h"
|
||||
#include "lib/domain_model/SecurityKey.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sstream>
|
||||
@@ -20,13 +19,10 @@
|
||||
namespace bts {
|
||||
namespace md {
|
||||
|
||||
using SecurityKey = bts::SecurityKey;
|
||||
using SecurityKey = utils::ValueWrapper<struct SecurityKeyTag, uint32_t>;
|
||||
using ExchangeKey = utils::ValueWrapper<struct ExchangeKeyTag, uint64_t>;
|
||||
|
||||
GCC_DIAG_OFF("-Weffc++") // No Virtual Destructors by design
|
||||
#ifndef __clang__
|
||||
GCC_DIAG_OFF("-Wstringop-truncation")
|
||||
#endif
|
||||
|
||||
#define STRING_PROPERTY(NAME) \
|
||||
const char *NAME() const { return _##NAME; } \
|
||||
@@ -133,7 +129,7 @@ struct BTS_EXPORT FixedSpreadLeg {
|
||||
double leg_delta;
|
||||
};
|
||||
|
||||
template <int LEGCOUNT = 64>
|
||||
template <int LEGCOUNT = 16>
|
||||
class FixedSpreadSecurity : public FixedSecurity {
|
||||
char _summary[128];
|
||||
|
||||
@@ -220,6 +216,7 @@ SecurityType securitytype_of(const Security &);
|
||||
size_t num_legs(const Security &);
|
||||
uint64_t exchange_id(const Security &security);
|
||||
|
||||
|
||||
void to_json(nlohmann::json &j, const FixedSpreadLeg &f);
|
||||
|
||||
void to_json(nlohmann::json &j, const FixedSecurity &f);
|
||||
@@ -389,3 +386,5 @@ void with_security_like(const api::Security &security, C cb) {
|
||||
|
||||
} // namespace md
|
||||
} // namespace bts
|
||||
|
||||
FMT_IMPL(bts::md::SecurityKey, k, "{}", *k);
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/EnumMacros.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace bts::md::binance {
|
||||
|
||||
@@ -23,3 +23,5 @@ ENUM_CLASS_DEF(BinanceContractType, FOR_ALL_VALUES)
|
||||
} // namespace bts::md::binance
|
||||
|
||||
FMT_IMPL(bts::md::binance::BinanceContractType, t, "{}", t.name());
|
||||
|
||||
#endif
|
||||
+15
-14
@@ -1,20 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
#include "server/sparkd/md/binance/BinanceIcebergPartsFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceLotSizeFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceMarketLotSizeFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceMaxNumAlgoOrdersFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceMaxNumOrdersFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceMaxPositionFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceMinNotionalFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceNotionalFilter.h"
|
||||
#include "server/sparkd/md/binance/BinancePercentPriceBySideFilter.h"
|
||||
#include "server/sparkd/md/binance/BinancePercentPriceFilter.h"
|
||||
#include "server/sparkd/md/binance/BinancePriceFilter.h"
|
||||
#include "server/sparkd/md/binance/BinanceTrailingDeltaFilter.h"
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include "lib/md/binance/BinanceIcebergPartsFilter.h"
|
||||
#include "lib/md/binance/BinanceLotSizeFilter.h"
|
||||
#include "lib/md/binance/BinanceMarketLotSizeFilter.h"
|
||||
#include "lib/md/binance/BinanceMaxNumAlgoOrdersFilter.h"
|
||||
#include "lib/md/binance/BinanceMaxNumOrdersFilter.h"
|
||||
#include "lib/md/binance/BinanceMaxPositionFilter.h"
|
||||
#include "lib/md/binance/BinanceMinNotionalFilter.h"
|
||||
#include "lib/md/binance/BinanceNotionalFilter.h"
|
||||
#include "lib/md/binance/BinancePercentPriceBySideFilter.h"
|
||||
#include "lib/md/binance/BinancePercentPriceFilter.h"
|
||||
#include "lib/md/binance/BinancePriceFilter.h"
|
||||
#include "lib/md/binance/BinanceTrailingDeltaFilter.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
@@ -125,3 +125,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/EnumMacros.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace bts::md::binance {
|
||||
|
||||
@@ -40,3 +40,5 @@ ENUM_CLASS_DEF(BinanceFilterType, FOR_ALL_VALUES)
|
||||
} // namespace bts::md::binance
|
||||
|
||||
FMT_IMPL(bts::md::binance::BinanceFilterType, t, "{}", t.name());
|
||||
|
||||
#endif
|
||||
+3
-1
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "lib/io/JsonMacros.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -33,3 +34,4 @@ OSTREAM_JSON_IMPL(BinanceIcebergPartsFilter);
|
||||
#undef FOR_EACH
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/EnumMacros.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace bts::md::binance {
|
||||
|
||||
@@ -25,3 +25,5 @@ ENUM_CLASS_DEF(BinanceInstrumentStatus, FOR_ALL_VALUES)
|
||||
} // namespace bts::md::binance
|
||||
|
||||
FMT_IMPL(bts::md::binance::BinanceInstrumentStatus, s, "{}", s.name());
|
||||
|
||||
#endif
|
||||
+3
-3
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -53,3 +52,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace bts::md::binance {
|
||||
@@ -57,5 +56,5 @@ inline std::ostream &operator<<(
|
||||
out << f.min_qty << " <==> " << f.max_qty << "by " << f.step_size;
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-3
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -62,3 +61,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-3
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -56,3 +55,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-3
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace bts::md::binance {
|
||||
@@ -54,3 +53,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/EnumMacros.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace bts::md::binance {
|
||||
|
||||
@@ -33,3 +33,5 @@ ENUM_CLASS_DEF(BinanceMessageType, FOR_ALL_VALUES)
|
||||
} // namespace bts::md::binance
|
||||
|
||||
FMT_IMPL(bts::md::binance::BinanceMessageType, t, "{}", t.name());
|
||||
|
||||
#endif
|
||||
+3
-1
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "lib/io/JsonMacros.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -50,3 +51,4 @@ OSTREAM_JSON_IMPL(BinanceMinNotionalFilter);
|
||||
#undef FOR_EACH
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+6
-1
@@ -1,7 +1,11 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "BinanceMiniTickerAdaptor.h"
|
||||
#include "lib/domain/Security.h"
|
||||
#include "lib/domain/SecurityMarketDataStatistics.h"
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
#include "server/sparkd/md/binance/BinanceMiniTickerUpdate.h"
|
||||
#include "lib/md/binance/BinanceMiniTickerUpdate.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
|
||||
@@ -44,3 +48,4 @@ void BinanceMiniTickerAdaptor::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-2
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/domain/SecurityID.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
|
||||
namespace bts::md {
|
||||
class IMarketDataListener;
|
||||
@@ -28,3 +28,4 @@ class BinanceMiniTickerAdaptor : public ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
File renamed without changes.
+1
-1
@@ -6,7 +6,7 @@
|
||||
#include "lib/domain/SecurityMarketDataStatistics.h"
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiReader.h"
|
||||
#include "lib/md/CCApiReader.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
#include <type_traits>
|
||||
+4
-2
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/TimeStamp.h"
|
||||
#include "lib/domain/SecurityMarketDataStatistics.h"
|
||||
#include "server/sparkd/md/binance/BinanceMiniTickerEventType.h"
|
||||
#include "lib/md/binance/BinanceMiniTickerEventType.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -44,3 +45,4 @@ std::ostream &operator<<(
|
||||
std::ostream &out, const BinanceMiniTickerUpdate &upd) noexcept;
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+4
-1
@@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
|
||||
#include "lib/io/JsonMacros.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include <nlohmann/detail/macro_scope.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -49,3 +51,4 @@ OSTREAM_JSON_IMPL(BinanceNotionalFilter);
|
||||
#undef FOR_EACH
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/EnumMacros.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace bts::md::binance {
|
||||
|
||||
@@ -29,3 +29,5 @@ ENUM_CLASS_DEF(BinanceOrderType, FOR_ALL_VALUES)
|
||||
} // namespace bts::md::binance
|
||||
|
||||
FMT_IMPL(bts::md::binance::BinanceOrderType, t, "{}", t.name());
|
||||
|
||||
#endif
|
||||
+3
-3
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -73,3 +72,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-3
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -63,3 +62,4 @@ inline std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+4
-2
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/EnumMacros.h"
|
||||
#include "lib/core/FMT_IMPL.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace bts::md::binance {
|
||||
|
||||
@@ -29,3 +29,5 @@ ENUM_CLASS_DEF(BinancePermission, FOR_ALL_VALUES)
|
||||
} // namespace bts::md::binance
|
||||
|
||||
FMT_IMPL(bts::md::binance::BinancePermission, p, "{}", p.name());
|
||||
|
||||
#endif
|
||||
+3
-3
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/binance/BinanceFilterType.h"
|
||||
|
||||
#include "lib/md/binance/BinanceFilterType.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
@@ -62,3 +61,4 @@ inline std::ostream &operator<<(
|
||||
return out;
|
||||
}
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-1
@@ -1,3 +1,4 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "BinancePriceStatistics.h"
|
||||
#include "lib/core/TimeStamp.h"
|
||||
#include "lib/domain/Price.h"
|
||||
@@ -5,7 +6,7 @@
|
||||
#include "lib/domain/SecurityMarketDataStatistics.h"
|
||||
#include "lib/io/JsonDumper.h"
|
||||
#include "lib/io/JsonReader.h"
|
||||
#include "server/sparkd/md/ccapi/CCApiReader.h"
|
||||
#include "lib/md/CCApiReader.h"
|
||||
|
||||
#include <ccapi_cpp/ccapi_macro.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
@@ -120,3 +121,4 @@ std::ostream &operator<<(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/core/TimeStamp.h"
|
||||
|
||||
#include <cstdint>
|
||||
@@ -61,3 +61,4 @@ std::ostream &operator<<(
|
||||
std::ostream &out, const BinancePriceStatistics &p) noexcept;
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+5
-1
@@ -1,10 +1,13 @@
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "BinancePriceStatisticsAdaptor.h"
|
||||
#include "lib/domain/Security.h"
|
||||
#include "lib/domain/SecurityID.h"
|
||||
#include "lib/domain/SecurityMarketDataStatistics.h"
|
||||
#include "lib/md/IMarketDataListener.h"
|
||||
#include "lib/md/binance/BinancePriceStatistics.h"
|
||||
#include "lib/utils/bts_fatal.h"
|
||||
#include "server/sparkd/md/binance/BinancePriceStatistics.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ccapi_cpp/ccapi_event.h>
|
||||
#include <ccapi_cpp/ccapi_message.h>
|
||||
|
||||
@@ -69,3 +72,4 @@ void BinancePriceStatisticsAdaptor::on_messages(
|
||||
}
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
+3
-3
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SPARK_ENABLE_CCAPI
|
||||
#include "lib/domain/SecurityID.h"
|
||||
#include "server/sparkd/md/ccapi/ICCApiMessageHandler.h"
|
||||
|
||||
#include "lib/md/ICCApiMessageHandler.h"
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -37,3 +36,4 @@ class BinancePriceStatisticsAdaptor : public ICCApiMessageHandler {
|
||||
};
|
||||
|
||||
} // namespace bts::md::binance
|
||||
#endif
|
||||
Loaded 100 of 280 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user