Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5aab80aed6 | ||
|
|
12e7c82698 | ||
|
|
0c4cdd0bc9 | ||
|
|
00d8ea9322 | ||
|
|
a586b75226 | ||
|
|
c6039723da | ||
|
|
6f26164072 | ||
|
|
7b01fdcb23 | ||
|
|
d6df085d8e | ||
|
|
c6f2fe9b13 | ||
|
|
c56b41bf47 | ||
|
|
484c7a98a8 | ||
|
|
559b6f8fd1 | ||
|
|
41fa3046f1 | ||
|
|
fdf21c71bb | ||
|
|
f03453f7c5 | ||
|
|
9ebdb107fa | ||
|
|
057d5df6da | ||
|
|
f539659ab5 | ||
|
|
e4d9b902d8 | ||
|
|
9fb180ff20 | ||
|
|
a6fde760ff | ||
|
|
c705867218 |
No files matched your search
@@ -44,6 +44,7 @@ else ()
|
||||
add_subdirectory(src/server/sparkd)
|
||||
add_subdirectory(src/lib)
|
||||
add_subdirectory(src/web)
|
||||
add_subdirectory(doc/user)
|
||||
add_subdirectory(src/sdk)
|
||||
add_subdirectory(src/data_files)
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(doc)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/tools/safe_dep_glob.cmake)
|
||||
include(${CMAKE_SOURCE_DIR}/tools/Protobuf.cmake)
|
||||
|
||||
# DEPENDENCIES
|
||||
set(DOC_GLOBS
|
||||
*.md
|
||||
*.jpeg
|
||||
*.png
|
||||
*.html
|
||||
*.css
|
||||
*.js
|
||||
*.eot
|
||||
favicon.ico
|
||||
)
|
||||
file (GLOB_RECURSE All_Deps RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${DOC_GLOBS})
|
||||
update_deps_file("${All_Deps}")
|
||||
# END DEPENDENCIES
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/web/docs/index.html
|
||||
COMMAND /bin/bash ${CMAKE_CURRENT_SOURCE_DIR}/build.sh
|
||||
ARGS ${CMAKE_BINARY_DIR}/web/docs/
|
||||
COMMENT "Building Manual UI"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS ${All_Deps})
|
||||
|
||||
add_custom_target(doc_manual_bundle ALL DEPENDS ${CMAKE_BINARY_DIR}/web/docs/index.html)
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), url(../fonts/Source-Sans-Pro-300.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(../fonts/Source-Sans-Pro-400.ttf) format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Sans Pro';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Source Sans Pro SemiBold'), local('SourceSansPro-SemiBold'), url(../fonts/Source-Sans-Pro-600.ttf) format('truetype');
|
||||
}
|
||||
@@ -204,7 +204,7 @@ namespace mbts.spark {
|
||||
new HedgeRatioModel(),
|
||||
new QuoteHiddenModel(),
|
||||
new MarketDataTypeModel(),
|
||||
//new MarketDataCalculationModel(),
|
||||
new MarketDataCalculationModel(),
|
||||
new QuoteThrottleEnabledModel(quote_throttle_inside_ticks, quote_throttle_outside_ticks),
|
||||
quote_throttle_inside_ticks,
|
||||
quote_throttle_outside_ticks,
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace bts.shell {
|
||||
Configuration.get<bts.config.System>().config_port);
|
||||
string temp = uristr;
|
||||
if (uristr.StartsWith("bts://m/")) {
|
||||
temp = uristr.Replace("bts://m/", http_base + "doc/manual/");
|
||||
temp = uristr.Replace("bts://m/", http_base + "docs/");
|
||||
}
|
||||
else {
|
||||
temp = uristr.Replace("bts://", http_base);
|
||||
|
||||
@@ -53,18 +53,22 @@ namespace mbts.ui {
|
||||
ToastNotificationController _toast_controller;
|
||||
SoundNotificationPlayer _sound_player;
|
||||
Dispatcher _dispatcher;
|
||||
bool _toast_notifications_enabled, _sound_notifications_enabled = NotificationSettings.Default.sound_notification.enabled;
|
||||
bool
|
||||
_sound_notifications_enabled = Configuration.get<bts.config.toggles.SoundNotifications>().enabled,
|
||||
_toast_notifications_enabled = Configuration.get<bts.config.toggles.ToastNotifications>().enabled;
|
||||
|
||||
[ImportingConstructor]
|
||||
public Notifier(IBus bus, UserSettingsHub settings_hub) {
|
||||
_disposer = new ThreadSafeDisposable(dispose_core);
|
||||
Thread thread = new Thread(start) {
|
||||
IsBackground = true,
|
||||
Priority = ThreadPriority.BelowNormal,
|
||||
Name = "BTSNotifications"
|
||||
};
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
if (_sound_notifications_enabled || _toast_notifications_enabled) {
|
||||
Thread thread = new Thread(start) {
|
||||
IsBackground = true,
|
||||
Priority = ThreadPriority.BelowNormal,
|
||||
Name = "BTSNotifications"
|
||||
};
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
void start() {
|
||||
try {
|
||||
@@ -102,7 +106,9 @@ namespace mbts.ui {
|
||||
(_dispatcher = Dispatcher.CurrentDispatcher).UnhandledException += _on_dispatcher_UnhandledException;
|
||||
Dispatcher.Run();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
catch (NAudio.MmException) { }
|
||||
catch (Exception ex) {
|
||||
Log.assert(false, $"Exception in {Thread.CurrentThread.Name} thread: {ex}");
|
||||
_disposer.Dispose();
|
||||
}
|
||||
|
||||
@@ -521,12 +521,14 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ItemsControl}">
|
||||
<Border
|
||||
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"
|
||||
>
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Border>
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
|
||||
<Border
|
||||
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"
|
||||
>
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Border>
|
||||
</ScrollViewer>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace bts.spark
|
||||
SparkCommand.create("Manual", Icons.Browser, SparkTags.ShowUri, new Uri("https://www.bluetradingsystems.com/documentation/"));
|
||||
|
||||
public static SparkCommand ShowReleaseNotes =>
|
||||
SparkCommand.create("Release Notes", Icons.Browser, SparkTags.ShowUri, new Uri("bts://files/release_notes.txt"));
|
||||
SparkCommand.create("Release Notes", Icons.Browser, SparkTags.ShowUri, new Uri("bts://docs/release_notes/"));
|
||||
|
||||
public static SparkCommand DoNothing =>
|
||||
SparkCommand.create("Nothing", Icons.Support, SparkTags.NotImplemented);
|
||||
|
||||
+6
-2
@@ -28,7 +28,7 @@ namespace mbts.ui.controls {
|
||||
new AnonymousValueConverter(obj =>
|
||||
obj is SoundNotification.SystemSound s ?
|
||||
EnumHelper.get_attribute<SoundNotification.SystemSound, LicenseAttribute>(s)?.link : null);
|
||||
|
||||
|
||||
public static readonly DependencyProperty BusProperty =
|
||||
WPFHelper.create_dp<IBus, SoundAnimationView>(nameof(Bus));
|
||||
|
||||
@@ -38,7 +38,11 @@ namespace mbts.ui.controls {
|
||||
}
|
||||
|
||||
public static ICommand PreviewSoundCommand =>
|
||||
new DelegateCommand<SoundNotification.SystemSound>(s => NAudioPlayer.create(s).play());
|
||||
new DelegateCommand<SoundNotification.SystemSound>(s => {
|
||||
try {
|
||||
NAudioPlayer.create(s).play();
|
||||
} catch (NAudio.MmException) { }
|
||||
});
|
||||
|
||||
#region SoundTypes
|
||||
public static readonly DependencyProperty SoundTypesProperty =
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFrameworks>netstandard2.0;net471</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageOutputPath>$(OutputPath)\net471</PackageOutputPath>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
|
||||
|
||||
@@ -22,14 +22,14 @@ PublisherNamespace {
|
||||
CMEOptions {
|
||||
value {
|
||||
feed_engine {
|
||||
name: "default"
|
||||
name: "mdp3feed"
|
||||
# udp_socket_buffer_size: 425984
|
||||
# channels_per_thread: 1
|
||||
spin_time: 0
|
||||
}
|
||||
channel {
|
||||
id: "*"
|
||||
feed_engine: "default"
|
||||
feed_engine: "mdp3feed"
|
||||
use_tcp_replay: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
Threads {
|
||||
value {
|
||||
thread_group {name_rx: "mdp3feed" core: 0}
|
||||
thread_group {name_rx: "oman_orders" core: 1}
|
||||
thread_group {name_rx: ".*" exclude:true core:0 core:1}
|
||||
# thread_group {name_rx: "mdp3feed" core: 0}
|
||||
# thread_group {name_rx: "oman_orders" core: 1}
|
||||
# thread_group {name_rx: ".*" exclude:true core:0 core:1}
|
||||
thread_group {name_rx: ".*" }
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,6 @@ message OrdersSoftCleanupCutoff{
|
||||
|
||||
message SODTime{
|
||||
// utc time
|
||||
optional uint32 sod_hh = 20 [default=21];
|
||||
optional uint32 sod_hh = 20 [default=15];
|
||||
optional uint32 sod_mm = 30 [default=30];
|
||||
}
|
||||
@@ -28,6 +28,10 @@ message ToastNotifications {
|
||||
optional bool enabled = 1 [default = false];
|
||||
}
|
||||
|
||||
message SoundNotifications {
|
||||
optional bool enabled = 1 [default = true];
|
||||
}
|
||||
|
||||
message VolumeAtPrice{
|
||||
optional bool enabled = 1 [default = true];
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "lib/orderman/orderman_utils/orderman_common.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader/SpreaderLegData.h" // fix this (not needed, all the headers can be fwd ref's)
|
||||
#include "lib/orderman/orders/spreader_orders/spreader_states/SpreaderState.h"
|
||||
#include "lib/orderman/events/SettlementUpdateEvent.h"
|
||||
|
||||
namespace bts {
|
||||
namespace api {namespace orderman {class OrderDefinition;}}
|
||||
@@ -34,6 +35,8 @@ public:
|
||||
virtual void on_cancel() = 0;
|
||||
// 6. on market data update (support late joiners)
|
||||
virtual void on_book(const Book&,PerfTrace &) = 0;
|
||||
// 15. settlement price update
|
||||
virtual void on_settlement_price(const SettlementUpdateEvent&) = 0;
|
||||
// 7. time event called by the infrastructure
|
||||
virtual void on_time(const TimeStamp&) = 0;
|
||||
// 8. when a quoter order ack from the exchange has an error
|
||||
|
||||
@@ -25,7 +25,11 @@ _order_services(nullptr),
|
||||
_curr_timestamp(),
|
||||
_last_check_termination_timestamp(),
|
||||
_state_worker(nullptr),
|
||||
_start_state_worker(this), _working_state_worker(this), _waiting_for_cancel_all_state_worker(this), _end_state_worker(this){
|
||||
_start_state_worker(this),
|
||||
_waiting_for_initial_data_state_worker(this),
|
||||
_working_state_worker(this),
|
||||
_waiting_for_cancel_all_state_worker(this),
|
||||
_end_state_worker(this){
|
||||
_transform_to_START();
|
||||
}
|
||||
SpreaderOrder::~SpreaderOrder () {}
|
||||
@@ -108,13 +112,8 @@ void SpreaderOrder::_on_settlement_update(const SettlementUpdateEvent&
|
||||
"key:{} sec_key:{} state:{} settlement:{}",
|
||||
key(), settlement_event.key(),
|
||||
static_cast<int>(_state_worker->state()),
|
||||
settlement_event.settlement_price.price());
|
||||
// this is a key->index lookup
|
||||
SpreaderLegData& md_leg =
|
||||
_bookkeeping_data().get_leg_data(settlement_event.key());
|
||||
md_leg.update_settlement_price(settlement_event.settlement_price);
|
||||
bts::PerfTrace trace;
|
||||
_state_worker->on_book (md_leg.book(),trace);
|
||||
settlement_event.settlement_price.price());
|
||||
_state_worker->on_settlement_price(settlement_event);
|
||||
}
|
||||
void SpreaderOrder::_on_child_order_update(const OrderStateUpdateEvent& ord_ev){
|
||||
auto trace = ord_ev.trace;
|
||||
@@ -194,8 +193,12 @@ void SpreaderOrder::_transform_to_START(){
|
||||
bts_assert (_state_worker == nullptr);
|
||||
_switch_state (&_start_state_worker);
|
||||
}
|
||||
void SpreaderOrder::_transform_to_WAITING_FOR_INITIAL_DATA(){
|
||||
bts_assert (_state_worker->state()==SpreaderState::START);
|
||||
_switch_state (&_waiting_for_initial_data_state_worker);
|
||||
}
|
||||
void SpreaderOrder::_transform_to_WORKING(){
|
||||
bts_assert(_state_worker->state() == SpreaderState::START);
|
||||
bts_assert(_state_worker->state() == SpreaderState::WAITING_FOR_INIT_DATA);
|
||||
_switch_state(&_working_state_worker);
|
||||
}
|
||||
void SpreaderOrder::_transform_to_WAITING_FOR_CANCEL_ALL(){
|
||||
@@ -332,7 +335,7 @@ void SpreaderOrder::_compute_hedge_price_quantity(size_t filled_leg_index,
|
||||
SpreaderLegData& filled_leg_data = _bookkeeping_data().get_leg_data(filled_leg_index);
|
||||
SpreaderLegData& hedged_leg_data = _bookkeeping_data().get_leg_data(hedge_leg_index);
|
||||
if (_bookkeeping_data().n_legs() == 2)
|
||||
SpreaderUtils::compute_hedge_price_size_2_legs (_bookkeeping_data().price(),
|
||||
SpreaderUtils::compute_hedge_price_size_2_legs (_bookkeeping_data().effective_price(),
|
||||
filled_leg_data.leg_property_data(),
|
||||
fill_price,
|
||||
fill_quantity,
|
||||
@@ -357,15 +360,15 @@ void SpreaderOrder::_compute_hedge_price_quantity(size_t filled_leg_index,
|
||||
Quantity(hedge_quantity));
|
||||
}
|
||||
void SpreaderOrder::_report_state (){
|
||||
if (_activated()){
|
||||
SpreaderBookkeepingData& bookkeeping_data = _bookkeeping_data();
|
||||
if (_activated()){
|
||||
SpreaderBookkeepingData& bookkeeping_data = _bookkeeping_data();
|
||||
auto& reported_state = bookkeeping_data.reported_state();
|
||||
api::orderman::OrderStatus status = _get_order_status ();
|
||||
if(bookkeeping_data.inited_new()){
|
||||
if(bookkeeping_data.inited_new()){
|
||||
Quantity filled_qty; Price avg_filled_price;
|
||||
bookkeeping_data.total_fills(filled_qty, avg_filled_price);
|
||||
reported_state.set_status(status);
|
||||
reported_state.set_price(bookkeeping_data.price().value());
|
||||
reported_state.set_price(bookkeeping_data.input_price().value());
|
||||
reported_state.set_quantity(bookkeeping_data.quantity().value());
|
||||
reported_state.set_filled_quantity(filled_qty.value());
|
||||
reported_state.set_avg_price(avg_filled_price.value());
|
||||
@@ -394,6 +397,7 @@ bts::api::orderman::OrderStatus SpreaderOrder::_get_order_status () const{
|
||||
bts::api::orderman::OrderStatus::ORDER_STATUS_CANCELED :
|
||||
bts::api::orderman::OrderStatus::ORDER_STATUS_COMPLETED;
|
||||
case SpreaderState::START:
|
||||
case SpreaderState::WAITING_FOR_INIT_DATA:
|
||||
return bts::api::orderman::OrderStatus::ORDER_STATUS_INACTIVE;
|
||||
default:
|
||||
bts_assert(false);
|
||||
@@ -407,4 +411,31 @@ void SpreaderOrder::_send_check_termination(bool force){
|
||||
_state_worker->on_check_termination();
|
||||
}
|
||||
}
|
||||
bool SpreaderOrder::_contains_net_change_leg(){
|
||||
for (size_t l_idx = 0; l_idx < _bookkeeping_data().n_legs(); l_idx++){
|
||||
const LegPropertyData& leg_data =
|
||||
_bookkeeping_data().get_leg_data(l_idx).leg_property_data();
|
||||
if(leg_data.leg_md_calc()==bts::spark::LegSpreaderParams::NET_CHANGE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Price SpreaderOrder::_compute_effective_price (Price input_price){
|
||||
double rv = 0;
|
||||
if(_contains_net_change_leg()){
|
||||
for (size_t l_idx = 0; l_idx < _bookkeeping_data().n_legs(); l_idx++){
|
||||
const SpreaderLegData& leg_data = _bookkeeping_data().get_leg_data(l_idx);
|
||||
if(leg_data.leg_property_data().leg_md_calc()==bts::spark::LegSpreaderParams::NET_CHANGE){
|
||||
if (!leg_data.settlement_populated())
|
||||
return Price(os::nan());
|
||||
else
|
||||
rv += leg_data.leg_property_data().price_multiplier() *
|
||||
leg_data.settlement_price().value();
|
||||
}
|
||||
}
|
||||
return Price(input_price.value()+rv);
|
||||
}
|
||||
else
|
||||
return input_price;
|
||||
}
|
||||
}}
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "lib/orderman/orders/spreader_orders/spreader/SpreaderBookkeepingData.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader/ISpreaderManager.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader_states/SpreaderStartStateWorker.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader_states/SpreaderWaitingForInitialDataStateWorker.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader_states/SpreaderWorkingStateWorker.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader_states/SpreaderWaitingForCancelAllStateWorker.h"
|
||||
#include "lib/orderman/orders/spreader_orders/spreader_states/SpreaderEndStateWorker.h"
|
||||
@@ -29,6 +30,7 @@ class SettlementUpdateEvent;
|
||||
class SpreaderOrder : public Order, public ISpreaderManager
|
||||
{
|
||||
friend class SpreaderStartStateWorker;
|
||||
friend class SpreaderWaitingForInitialDataStateWorker;
|
||||
friend class SpreaderWorkingStateWorker;
|
||||
friend class SpreaderWaitingForCancelAllStateWorker;
|
||||
friend class SpreaderEndStateWorker;
|
||||
@@ -68,6 +70,7 @@ private:
|
||||
// current state
|
||||
ISpreaderStateWorker* _state_worker;
|
||||
SpreaderStartStateWorker _start_state_worker;
|
||||
SpreaderWaitingForInitialDataStateWorker _waiting_for_initial_data_state_worker;
|
||||
SpreaderWorkingStateWorker _working_state_worker;
|
||||
SpreaderWaitingForCancelAllStateWorker _waiting_for_cancel_all_state_worker;
|
||||
SpreaderEndStateWorker _end_state_worker;
|
||||
@@ -131,6 +134,7 @@ private:
|
||||
// State Transformations ////////////////////
|
||||
/////////////////////////////////////////////
|
||||
void _transform_to_START();
|
||||
void _transform_to_WAITING_FOR_INITIAL_DATA();
|
||||
void _transform_to_WORKING();
|
||||
void _transform_to_WAITING_FOR_CANCEL_ALL();
|
||||
// optionally parameter to state the end reason
|
||||
@@ -193,8 +197,12 @@ private:
|
||||
return *_bookkeeping_data_ptr;
|
||||
}
|
||||
// just sets the price and qty in the bookkeeping data
|
||||
void _set_price_quantity (Price price, Quantity quantity) {
|
||||
_bookkeeping_data().update_order (price, quantity);
|
||||
void _set_price_quantity (Price input_price,
|
||||
Quantity quantity) {
|
||||
Price effective_price = _compute_effective_price(input_price);
|
||||
_bookkeeping_data().update_order (input_price,
|
||||
effective_price,
|
||||
quantity);
|
||||
}
|
||||
// returns the equivelant order status of the spreader order
|
||||
bts::api::orderman::OrderStatus _get_order_status () const;
|
||||
@@ -223,6 +231,15 @@ private:
|
||||
// when there's an order update, as well as on
|
||||
// a periodic bases
|
||||
void _send_check_termination(bool force);
|
||||
// if any leg is priced on net_change
|
||||
// this teturns true
|
||||
bool _contains_net_change_leg();
|
||||
// computes the effective price of the spreader order
|
||||
// if any of of the legs are in terms of net_change
|
||||
// this function offsets the effective price by that
|
||||
// (if settlements are not available returns nan)
|
||||
// Otherwise effectiv_price==order_price.
|
||||
Price _compute_effective_price (Price order_price);
|
||||
// testing only //////////////////
|
||||
// this provides direct way to inject
|
||||
// data into the spreader, as well as
|
||||
@@ -247,7 +264,11 @@ public:
|
||||
_on_child_order_update (ord_ev);
|
||||
}
|
||||
void test_only_on_init_new(const bts::api::orderman::OrderDefinition& order_def, const SpreaderPreActivationOrderServices& pao_services) {_on_init_new(order_def, pao_services);}
|
||||
void test_only_on_activate(Price price, Quantity quantity, SpreaderOrderServices& order_services) {_on_activate(price, quantity, order_services);}
|
||||
void test_only_on_activate(Price price,
|
||||
Quantity quantity,
|
||||
SpreaderOrderServices& order_services) {
|
||||
_on_activate(price, quantity, order_services);
|
||||
}
|
||||
void test_only_on_time (TimeStamp){}
|
||||
};
|
||||
}}
|
||||
@@ -71,7 +71,11 @@ void SpreaderBookkeepingData::total_fills (Quantity& out_quantity,
|
||||
leg_data.total_fills(leg_fill_qty, leg_fill_price);
|
||||
double normalized_qty = std::abs(static_cast<double>(leg_fill_qty.value()) / leg_data.leg_property_data().size_multiplier());
|
||||
fills = normalized_qty < fills ? normalized_qty : fills;
|
||||
avg_price += leg_fill_price.value() * leg_data.leg_property_data().price_multiplier();
|
||||
if(leg_data.leg_property_data().leg_md_calc()==bts::spark::LegSpreaderParams::NET_CHANGE)
|
||||
avg_price += (leg_fill_price.value()-leg_data.settlement_price().value()) *
|
||||
leg_data.leg_property_data().price_multiplier();
|
||||
else
|
||||
avg_price += leg_fill_price.value() * leg_data.leg_property_data().price_multiplier();
|
||||
}
|
||||
out_quantity = Quantity(fills);
|
||||
out_price = Price(avg_price);
|
||||
|
||||
@@ -39,7 +39,8 @@ private:
|
||||
// state thats sent out in report (its kept here amd modified
|
||||
// vs creating a new one everytime)
|
||||
bts::api::orderman::OrderState _reported_state;
|
||||
Price _price;
|
||||
Price _input_price;
|
||||
Price _effective_price;
|
||||
Quantity _quantity;
|
||||
public:
|
||||
SpreaderBookkeepingData (ISpreaderManager& spreader_manager,
|
||||
@@ -62,7 +63,8 @@ public:
|
||||
size_t n_legs() const { return _n_legs; }
|
||||
bool all_legs_resolved() const {return n_legs() > 0;}
|
||||
const api::orderman::OrderDefinition& order_def() const {return _order_def;}
|
||||
Price price () const {return _price;}
|
||||
Price input_price () const {return _input_price;}
|
||||
Price effective_price () const {return _effective_price;}
|
||||
Quantity quantity () const {return _quantity;}
|
||||
// gets leg data from leg's sec key
|
||||
SpreaderLegData& get_leg_data (SecurityKey security_key){
|
||||
@@ -111,9 +113,16 @@ public:
|
||||
// the size and price ratio, across all legs)
|
||||
void total_fills (Quantity& out_quantity, Price& out_price) const;
|
||||
// updates the price, qty of the spreader order
|
||||
void update_order (Price price, Quantity quantity){
|
||||
_price = price;
|
||||
_quantity = quantity;
|
||||
void update_order (Price input_price,
|
||||
Quantity quantity){
|
||||
update_order(input_price, input_price, quantity);
|
||||
}
|
||||
void update_order(Price input_price,
|
||||
Price effective_price,
|
||||
Quantity quantity){
|
||||
_input_price=input_price;
|
||||
_effective_price=effective_price;
|
||||
_quantity=quantity;
|
||||
}
|
||||
bts::api::orderman::OrderState& reported_state(){
|
||||
return _reported_state;
|
||||
@@ -121,5 +130,8 @@ public:
|
||||
bool inited_new () const{
|
||||
return _inited_new;
|
||||
}
|
||||
bool has_effective_price() const{
|
||||
return !os::is_nan(_effective_price.value());
|
||||
}
|
||||
};
|
||||
}}
|
||||
@@ -59,7 +59,8 @@ public:
|
||||
SingleLegQuoter& quoter() {return _quoter;}
|
||||
const SingleLegQuoter& quoter() const {return _quoter;}
|
||||
const bts::orderman::Book& book () const {return _book;}
|
||||
//md::Price settlement_price() const {return _settlement_price;}
|
||||
Price settlement_price() const {return Price(_settlement_price.price());}
|
||||
bool settlement_populated() const {return !os::is_nan(_settlement_price.price());}
|
||||
SpreaderChildOrderState& order_update_message () {return _quoter_child_order_state;}
|
||||
bts::orderman::OrderKey key() {return _quoter_child_order_state.order_key();}
|
||||
bts::orderman::OrderKey order_key() {return _quoter_child_order_state.order_key();}
|
||||
@@ -107,7 +108,7 @@ public:
|
||||
SpreaderUtils::copy_book(book,
|
||||
_settlement_price,
|
||||
_leg_property_data.md_type(),
|
||||
_leg_property_data.leg_md_calc(),
|
||||
bts::spark::LegSpreaderParams::BOOK,
|
||||
_book);
|
||||
}
|
||||
void update_settlement_price(md::IntPrice price){
|
||||
@@ -115,7 +116,7 @@ public:
|
||||
SpreaderUtils::copy_book(_book,
|
||||
_settlement_price,
|
||||
_leg_property_data.md_type(),
|
||||
_leg_property_data.leg_md_calc(),
|
||||
bts::spark::LegSpreaderParams::BOOK,
|
||||
_book);
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,14 @@ void SpreaderEndStateWorker::on_init_recovered(const bts::api::orderman::OrderRe
|
||||
const SpreaderPreActivationOrderServices&){
|
||||
bts_assert_msg (false, "SpreaderEndStateWorker::on_init_new is an illegal operation");
|
||||
}
|
||||
void SpreaderEndStateWorker::on_activate(Price price, Quantity quantity,
|
||||
void SpreaderEndStateWorker::on_activate(Price price,
|
||||
Quantity quantity,
|
||||
SpreaderOrderServices&){
|
||||
// this can only happen if the security could not be resolved
|
||||
// resulting in START->END. however on_active could still
|
||||
// be called
|
||||
bts_assert (!_spreader->_bookkeeping_data().all_legs_resolved());
|
||||
_spreader->_bookkeeping_data().update_order(price, quantity);
|
||||
_spreader->_set_price_quantity(price, quantity);
|
||||
}
|
||||
void SpreaderEndStateWorker::on_update(Price, Quantity){
|
||||
}
|
||||
@@ -35,6 +36,8 @@ void SpreaderEndStateWorker::on_cancel(){
|
||||
}
|
||||
void SpreaderEndStateWorker::on_book(const Book&,PerfTrace&){
|
||||
}
|
||||
void SpreaderEndStateWorker::on_settlement_price(const SettlementUpdateEvent&){
|
||||
}
|
||||
void SpreaderEndStateWorker::on_time(const TimeStamp&){
|
||||
}
|
||||
void SpreaderEndStateWorker::on_quoter_order_error(SpreaderLegData&){
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
void on_update(Price, Quantity) override;
|
||||
void on_cancel() override;
|
||||
void on_book(const Book&,PerfTrace&) override;
|
||||
void on_settlement_price(const SettlementUpdateEvent&) override;
|
||||
void on_time(const TimeStamp&) override;
|
||||
void on_quoter_order_error(SpreaderLegData& leg_data) override;
|
||||
void on_quoter_order_fill(SpreaderLegData& leg_data,
|
||||
|
||||
+10
-14
@@ -66,9 +66,11 @@ void SpreaderStartStateWorker::on_init_recovered(const bts::api::orderman::Order
|
||||
std::string msg = "Recovered spreader orders (from last session) are cancelled";
|
||||
_spreader->_transform_to_END (&msg);
|
||||
}
|
||||
void SpreaderStartStateWorker::on_activate(Price price, Quantity quantity, SpreaderOrderServices& order_services){
|
||||
void SpreaderStartStateWorker::on_activate(Price price,
|
||||
Quantity quantity,
|
||||
SpreaderOrderServices& order_services){
|
||||
// 1. update price, qty
|
||||
_spreader->_bookkeeping_data().update_order (price, quantity);
|
||||
_spreader->_set_price_quantity (price, quantity);
|
||||
// 2. activate order builders
|
||||
for (size_t l_idx = 0; l_idx < _spreader->_bookkeeping_data().n_legs(); l_idx++)
|
||||
{
|
||||
@@ -103,18 +105,8 @@ void SpreaderStartStateWorker::on_activate(Price price, Quantity quantity, Sprea
|
||||
// 6. sub to time
|
||||
order_services.order_services().time_change.sub([this](const bts::mercury::TimerEvent& t_event){_spreader->_on_time(t_event);});
|
||||
}
|
||||
// 7. init all quoters (this is when the quoters get assigned a price, qty for
|
||||
// the first time) (this could have been done on the on_transition of WORKING state.
|
||||
// that way, in the START state there would be no active quoters, which technically
|
||||
// is happening right before transfer is being controlled to WORKING state)
|
||||
for (size_t l_idx = 0; l_idx < _spreader->_bookkeeping_data_ptr->n_legs(); l_idx++)
|
||||
{
|
||||
SpreaderLegData& leg_data = _spreader->_bookkeeping_data().get_leg_data(l_idx);
|
||||
if (leg_data.leg_property_data().is_active_quoting())
|
||||
leg_data.quoter().one_time_activate(price, quantity);
|
||||
}
|
||||
// 8. transofrm state
|
||||
_spreader->_transform_to_WORKING ();
|
||||
// quoters are init'ed in the next state
|
||||
_spreader->_transform_to_WAITING_FOR_INITIAL_DATA();
|
||||
}
|
||||
void SpreaderStartStateWorker::on_update(Price, Quantity){
|
||||
bts_assert_msg (false, "SpreaderStartStateWorker::on_update is an illegal operation");
|
||||
@@ -128,6 +120,10 @@ void SpreaderStartStateWorker::on_cancel(){
|
||||
void SpreaderStartStateWorker::on_book(const bts::orderman::Book&,PerfTrace &){
|
||||
bts_assert_msg (false, "SpreaderStartStateWorker::on_book is an illegal operation");
|
||||
}
|
||||
void SpreaderStartStateWorker::on_settlement_price(const SettlementUpdateEvent&){
|
||||
bts_assert_msg (false, "SpreaderStartStateWorker::on_settlement_price "
|
||||
"is an illegal operation");
|
||||
}
|
||||
void SpreaderStartStateWorker::on_time(const TimeStamp&){
|
||||
bts_assert_msg (false, "SpreaderStartStateWorker::on_time is an illegal operation");
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ public:
|
||||
void on_update(Price, Quantity) override;
|
||||
void on_cancel() override;
|
||||
void on_book(const Book&,PerfTrace &) override;
|
||||
void on_time(const TimeStamp&) override;
|
||||
void on_time(const TimeStamp&) override;
|
||||
void on_settlement_price(const SettlementUpdateEvent&) override;
|
||||
void on_quoter_order_error(SpreaderLegData& leg_data) override;
|
||||
void on_quoter_order_fill(SpreaderLegData& leg_data,
|
||||
PerfTrace &) override;
|
||||
|
||||
@@ -6,6 +6,8 @@ enum class SpreaderState
|
||||
{
|
||||
// pre init state
|
||||
START,
|
||||
// waiting for initial data such as settlements (in some case)
|
||||
WAITING_FOR_INIT_DATA,
|
||||
// after the first connection, the general waiting state
|
||||
WORKING,
|
||||
// waiting for all quoters and hedgers to be done
|
||||
|
||||
+2
@@ -42,6 +42,8 @@ void SpreaderWaitingForCancelAllStateWorker::on_time(const TimeStamp& ts){
|
||||
_spreader->_transform_to_END ();
|
||||
}
|
||||
}
|
||||
void SpreaderWaitingForCancelAllStateWorker::on_settlement_price(const SettlementUpdateEvent&){
|
||||
}
|
||||
void SpreaderWaitingForCancelAllStateWorker::on_quoter_order_error(SpreaderLegData& leg_data){
|
||||
leg_data.quoter().update_order_status (leg_data.order_update_message());
|
||||
}
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ public:
|
||||
void on_update(Price, Quantity) override;
|
||||
void on_cancel() override;
|
||||
void on_book(const Book&,PerfTrace &) override;
|
||||
void on_settlement_price(const SettlementUpdateEvent&) override;
|
||||
void on_time(const TimeStamp&) override;
|
||||
void on_quoter_order_error(SpreaderLegData& leg_data) override;
|
||||
void on_quoter_order_fill(SpreaderLegData& leg_data,
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#include "SpreaderWaitingForInitialDataStateWorker.h"
|
||||
#include "lib/orderman/orders/spreader_orders/SpreaderOrder.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman {
|
||||
|
||||
SpreaderWaitingForInitialDataStateWorker::SpreaderWaitingForInitialDataStateWorker (SpreaderOrder* spreader)
|
||||
:
|
||||
_spreader(spreader){
|
||||
}
|
||||
SpreaderState SpreaderWaitingForInitialDataStateWorker::state() const {
|
||||
return SpreaderState::WAITING_FOR_INIT_DATA;
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_transition (){
|
||||
if(!_spreader->_contains_net_change_leg()){
|
||||
_go_to_working();
|
||||
}
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_init_new(api::orderman::OrderDefinition const&,
|
||||
const SpreaderPreActivationOrderServices&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_init_new is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_init_recovered(
|
||||
const bts::api::orderman::OrderRecord&,
|
||||
const SpreaderPreActivationOrderServices&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::on_init_new "
|
||||
"is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_activate(Price,
|
||||
Quantity,
|
||||
SpreaderOrderServices&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_activate is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_update(Price,
|
||||
Quantity){
|
||||
// spreader can not accept modification
|
||||
// right now (for netchange spreaders this will be such
|
||||
// a such a short time period that it should not matter)
|
||||
LOG(OrderMan, Warn, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_update key:{}, order change rejected",
|
||||
_spreader->key());
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_cancel(){
|
||||
_spreader->_transform_to_END();
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_book(const Book& book,
|
||||
PerfTrace&){
|
||||
SpreaderBookkeepingData& bookkeeping_data = _spreader->_bookkeeping_data();
|
||||
SpreaderLegData& md_leg = bookkeeping_data.get_leg_data(book.security_key());
|
||||
md_leg.update_book(book);
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_settlement_price(
|
||||
const SettlementUpdateEvent& settlement_event){
|
||||
// if it did not contrain a net change leg
|
||||
// on transition would have moved to working
|
||||
bts_assert(_spreader->_contains_net_change_leg());
|
||||
SpreaderBookkeepingData& bookkeeping_data = _spreader->_bookkeeping_data();
|
||||
SpreaderLegData& md_leg = bookkeeping_data.get_leg_data(settlement_event.security_key);
|
||||
md_leg.update_settlement_price(settlement_event.settlement_price);
|
||||
_spreader->_set_price_quantity(bookkeeping_data.input_price(),
|
||||
bookkeeping_data.quantity());
|
||||
if(bookkeeping_data.has_effective_price())
|
||||
_go_to_working ();
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_time(const TimeStamp&){
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_quoter_order_error(SpreaderLegData&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_quoter_order_error is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_quoter_order_fill(SpreaderLegData&,
|
||||
PerfTrace&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_quoter_order_fill is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_quoter_order_status_update(SpreaderLegData&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_quoter_order_status_update is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_hedger_order_error(SingleFillHedger&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_hedger_order_error is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_hedger_order_update(SingleFillHedger&){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_hedger_order_update is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_check_termination(){
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::on_quoter_irrecoverable_error (){
|
||||
bts_assert_msg (false, "SpreaderWaitingForInitialDataStateWorker::"
|
||||
"on_quoter_irrecoverable_error is an illegal operation");
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::_init_quoters(){
|
||||
Price effective_price = _spreader->_bookkeeping_data().effective_price();
|
||||
Quantity quantity = _spreader->_bookkeeping_data().quantity();
|
||||
for (size_t l_idx = 0; l_idx < _spreader->_bookkeeping_data().n_legs(); l_idx++){
|
||||
SpreaderLegData& leg_data = _spreader->_bookkeeping_data().get_leg_data(l_idx);
|
||||
if (leg_data.leg_property_data().is_active_quoting())
|
||||
leg_data.quoter().one_time_activate(effective_price, quantity);
|
||||
}
|
||||
}
|
||||
void SpreaderWaitingForInitialDataStateWorker::_go_to_working(){
|
||||
_init_quoters();
|
||||
_spreader->_transform_to_WORKING();
|
||||
}
|
||||
}}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "lib/orderman/orders/spreader_orders/ISpreaderStateWorker.h"
|
||||
|
||||
namespace bts {
|
||||
namespace orderman {
|
||||
|
||||
class SpreaderOrder;
|
||||
|
||||
// START state leads to this. Here, the spreader waits for data
|
||||
// that is needed to start the machinery, ex settlement prices
|
||||
// if the legs are in net change mode
|
||||
class SpreaderWaitingForInitialDataStateWorker : public ISpreaderStateWorker
|
||||
{
|
||||
private:
|
||||
SpreaderOrder* const _spreader;
|
||||
public:
|
||||
SpreaderWaitingForInitialDataStateWorker (SpreaderOrder*);
|
||||
void on_transition() override;
|
||||
SpreaderState state() const override;
|
||||
void on_init_new(api::orderman::OrderDefinition const&,
|
||||
const SpreaderPreActivationOrderServices&) override;
|
||||
void on_init_recovered(const bts::api::orderman::OrderRecord&,
|
||||
const SpreaderPreActivationOrderServices&) override;
|
||||
void on_activate(Price, Quantity,
|
||||
SpreaderOrderServices&) override;
|
||||
void on_update(Price, Quantity) override;
|
||||
void on_cancel() override;
|
||||
void on_book(const Book&,PerfTrace &) override;
|
||||
void on_settlement_price(const SettlementUpdateEvent&) override;
|
||||
void on_time(const TimeStamp&) override;
|
||||
void on_quoter_order_error(SpreaderLegData& leg_data) override;
|
||||
void on_quoter_order_fill(SpreaderLegData& leg_data,
|
||||
PerfTrace &) override;
|
||||
void on_quoter_order_status_update(SpreaderLegData& leg_data) override;
|
||||
void on_hedger_order_error(SingleFillHedger&) override;
|
||||
void on_hedger_order_update(SingleFillHedger&) override;
|
||||
void on_check_termination () override;
|
||||
void on_quoter_irrecoverable_error () override;
|
||||
private:
|
||||
void _init_quoters();
|
||||
void _go_to_working();
|
||||
};
|
||||
}}
|
||||
+6
-2
@@ -29,11 +29,12 @@ void SpreaderWorkingStateWorker::on_activate(Price, Quantity,
|
||||
void SpreaderWorkingStateWorker::on_update(Price price, Quantity quantity){
|
||||
if (_spreader->_quoters_can_accept_modification()){
|
||||
_spreader->_set_price_quantity (price, quantity);
|
||||
Price effective_price = _spreader->_bookkeeping_data().effective_price();
|
||||
// updating all active quoters, nothing to do with the hedgers
|
||||
for (size_t q_idx = 0; q_idx < _spreader->_bookkeeping_data().n_legs(); q_idx++){
|
||||
SpreaderLegData& leg_data = _spreader->_bookkeeping_data().get_leg_data(q_idx);
|
||||
if (leg_data.leg_property_data().is_active_quoting())
|
||||
leg_data.quoter().update_order_price_quantity (price, quantity);
|
||||
leg_data.quoter().update_order_price_quantity (effective_price, quantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +46,8 @@ void SpreaderWorkingStateWorker::on_book(const Book& book,PerfTrace &trace){
|
||||
SpreaderBookkeepingData& bookkeeping_data = _spreader->_bookkeeping_data();
|
||||
// this is a key->index lookup
|
||||
SpreaderLegData& md_leg = bookkeeping_data.get_leg_data(book.security_key());
|
||||
// updating md state (this is the only place where its done)
|
||||
// updating md state (this and SpreaderWaitingForInitialDataStateWorker
|
||||
// are the only place where its done)
|
||||
md_leg.update_book(book);
|
||||
// sending md to all quoters
|
||||
for (size_t q_idx = 0; q_idx < bookkeeping_data.n_legs(); q_idx++){
|
||||
@@ -57,6 +59,8 @@ void SpreaderWorkingStateWorker::on_book(const Book& book,PerfTrace &trace){
|
||||
for (size_t h_idx = 0; h_idx < md_leg.n_hedgers(); h_idx++)
|
||||
md_leg.get_hedger(h_idx).on_book(book,trace);
|
||||
}
|
||||
void SpreaderWorkingStateWorker::on_settlement_price(const SettlementUpdateEvent&){
|
||||
}
|
||||
void SpreaderWorkingStateWorker::on_time(const TimeStamp& ts){
|
||||
SpreaderBookkeepingData& bookkeeping_data = _spreader->_bookkeeping_data();
|
||||
for (size_t q_idx = 0; q_idx < bookkeeping_data.n_legs(); q_idx++){
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
void on_update(Price, Quantity) override;
|
||||
void on_cancel() override;
|
||||
void on_book(const Book&,PerfTrace &) override;
|
||||
void on_settlement_price(const SettlementUpdateEvent&) override;
|
||||
void on_time(const TimeStamp&) override;
|
||||
void on_quoter_order_error(SpreaderLegData& leg_data) override;
|
||||
void on_quoter_order_fill(SpreaderLegData& leg_data,
|
||||
|
||||
@@ -464,7 +464,7 @@ void verify_basic_spreader_state (SpreaderOrder& spreader, SpreaderState state,
|
||||
{
|
||||
REQUIRE(spreader.test_only_func_spreader_state() == state);
|
||||
SpreaderBookkeepingData& spreader_data = spreader.test_only_func_spreader_full_data ();
|
||||
REQUIRE (spreader_data.price() == price);
|
||||
REQUIRE (spreader_data.effective_price() == price);
|
||||
REQUIRE (spreader_data.quantity() == quantity);
|
||||
}
|
||||
void validate_leg_property_data (const LegPropertyData& leg_property_data, size_t leg_index, const bts::api::ContractLeg& contract_leg, const bts::spark::LegSpreaderParams&, api::Side trading_side)
|
||||
|
||||
@@ -250,6 +250,7 @@ namespace http {
|
||||
std::string config = "/config";
|
||||
std::string files = "/files";
|
||||
std::string perf_trace = "/perf_trace";
|
||||
std::string docs = "/docs";
|
||||
|
||||
if (resource.compare(0, config.size(), config) == 0) {
|
||||
return _conf + resource.substr(config.size());
|
||||
@@ -260,6 +261,9 @@ namespace http {
|
||||
else if (resource.compare(0, perf_trace.size(), perf_trace) == 0) {
|
||||
return os::sparkd_wd() + "/data_files" + resource;
|
||||
}
|
||||
else if (resource.compare(0, docs.size(), docs) == 0) {
|
||||
return os::sparkd_wd() + "/web" + resource;
|
||||
}
|
||||
return web_ui_path(os::get_install_path()) / resource;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ const onixs::FeedEngineSettings feed_engine_settings_from_config(const CMEOption
|
||||
|
||||
result.socketBufferSize(settings.udp_socket_buffer_size());
|
||||
|
||||
auto affinity = threading::get_affinity("mdp3feed");
|
||||
auto affinity = threading::get_affinity(settings.name());
|
||||
for (auto& core : affinity) {
|
||||
result.threadAffinity().cpus().insert(core);
|
||||
}
|
||||
@@ -101,14 +101,6 @@ map<string,onixs::FeedEngineSettings> create_feed_engine_settings(const std::vec
|
||||
}
|
||||
}
|
||||
|
||||
// If a channel asks for defaults ensure it exists.
|
||||
if (settings.count("default") == 0) {
|
||||
size_t channels_using_default = count_engine_uses(channels, "default");
|
||||
if (channels_using_default > 0) {
|
||||
settings["default"] = feed_engine_settings_from_config(CMEOptions::FeedEngineSettings(), channels_using_default);
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ docker run \
|
||||
-u $UID \
|
||||
-v /home:/home \
|
||||
-e DISPLAY=$DISPLAY \
|
||||
--name bts \
|
||||
-d \
|
||||
-t bluetradingsystems/linux_docker \
|
||||
/bin/bash -c "(sudo /usr/sbin/sshd) & (cd ~ && $DIR/../externals/linux/bin/unison -socket 8080) & /bin/bash --login"
|
||||
|
||||
|
||||
Reference in new issue
Block a user