282 lines
9.4 KiB
C++
282 lines
9.4 KiB
C++
/* @file websock_utest_main.cpp */
|
|
|
|
#include "websock/Webserver.hpp"
|
|
#include "volfit/init_volfit.hpp"
|
|
#include "volfit/Volfit.hpp"
|
|
#include "volfit/VolfitInputCapture.hpp"
|
|
#include "filter/init_filter.hpp"
|
|
#include "filter/KalmanFilterSvc.hpp"
|
|
#include "option/StrikeSetOmd.hpp"
|
|
#include "option/StrikeSetMarketModel.hpp"
|
|
#include "option/UlMarketModel.hpp"
|
|
#include "option/PricingContext.hpp"
|
|
#include "option/OptionStrikeSet.hpp"
|
|
#include "process/init_process.hpp"
|
|
#include "process/RealizationSource.hpp"
|
|
#include "process/RealizationTracer.hpp"
|
|
#include "process/UpxEvent.hpp"
|
|
#include "process/ExpProcess.hpp"
|
|
#include "process/BrownianMotion.hpp"
|
|
#include "simulator/init_simulator.hpp"
|
|
#include "simulator/Simulator.hpp"
|
|
#include "reactor/EventStore.hpp"
|
|
#include "randomgen/random_seed.hpp"
|
|
#include "randomgen/xoshiro256.hpp"
|
|
#include "time/Time.hpp"
|
|
#include "printjson/PrintJson.hpp"
|
|
#include "indentlog/print/tag.hpp"
|
|
#include <signal.h>
|
|
|
|
/* webserver instance */
|
|
static xo::ref::rp<xo::web::Webserver> g_ws;
|
|
|
|
void sigint_handler(int /*sig*/) {
|
|
std::cerr << "main thread interrupt_handler\n";
|
|
|
|
if (g_ws)
|
|
g_ws->interrupt_stop_webserver();
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv) {
|
|
using xo::web::Webserver;
|
|
using xo::web::WebserverConfig;
|
|
using xo::json::PrintJsonSingleton;
|
|
using xo::vf::Volfit;
|
|
using xo::vf::VolfitInputCaptureSvc;
|
|
using xo::kalman::KalmanFilterStateExt;
|
|
using xo::kalman::KalmanFilterSvc;
|
|
using xo::kalman::KalmanFilterSpec;
|
|
using xo::option::FlatVolsfc;
|
|
using xo::option::BboTick;
|
|
using xo::option::StrikeSetOmd;
|
|
using xo::option::StrikeSetMarketModel;
|
|
using xo::option::UlMarketModel;
|
|
using xo::option::PricingContext;
|
|
using xo::option::OptionStrikeSet;
|
|
using xo::option::Secid;
|
|
using xo::option::Pxtick;
|
|
using xo::process::UpxEvent;
|
|
using xo::process::RealizationSource;
|
|
using xo::process::RealizationTracer;
|
|
using xo::process::StochasticProcess;
|
|
using xo::process::ExpProcess;
|
|
using xo::process::BrownianMotion;
|
|
using xo::sim::Simulator;
|
|
using xo::reactor::PtrEventStore;
|
|
using xo::reactor::StructEventStore;
|
|
using xo::reactor::ReactorSource;
|
|
using xo::rng::Seed;
|
|
using xo::rng::xoshiro256ss;
|
|
using xo::ref::rp;
|
|
using xo::time::utc_nanos;
|
|
using xo::time::timeutil;
|
|
using xo::json::PrintJsonSingleton;
|
|
using xo::json::PrintJson;
|
|
using xo::Subsystem;
|
|
using xo::scope;
|
|
using xo::xtag;
|
|
|
|
try {
|
|
#ifdef NOT_USING
|
|
InitSubsys<S_option_tag>::require();
|
|
InitSubsys<S_process_tag>::require();
|
|
InitSubsys<S_reactor_tag>::require();
|
|
#endif
|
|
|
|
XO_SUBSYSTEM_REQUIRE(volfit);
|
|
XO_SUBSYSTEM_REQUIRE(filter);
|
|
XO_SUBSYSTEM_REQUIRE(simulator);
|
|
XO_SUBSYSTEM_REQUIRE(process);
|
|
|
|
Subsystem::initialize_all();
|
|
|
|
signal(SIGINT, sigint_handler);
|
|
|
|
scope log(XO_ENTER0(always));
|
|
|
|
rp<PrintJson> pjson = PrintJsonSingleton::instance();
|
|
|
|
/* RC Sep 2022 - adding c++ translation of kalman/src/pywebsock/ex_websock.py;
|
|
* intending to debug server segfault without complication of running
|
|
* from python interpreter
|
|
*/
|
|
|
|
Secid secid0(0, 0);
|
|
Secid ul0 = Secid::ul(0);
|
|
|
|
utc_nanos t0 = timeutil::ymd_hms_usec(20220926 /*ymd*/,
|
|
93000 /*hms*/,
|
|
0 /*usec*/);
|
|
utc_nanos t1 = t0 + std::chrono::hours(30 * 24);
|
|
|
|
/* sim = pysimulator.Simulator.make() */
|
|
rp<Simulator> sim = Simulator::make(t0);
|
|
|
|
/* ss = pyoption.make_option_strike_set(3, secid0, 10, 1, t1, Pxtick.penny_nickel) */
|
|
rp<OptionStrikeSet> ss
|
|
= OptionStrikeSet::regular(3 /*n*/,
|
|
secid0 /*start_id*/,
|
|
10.0 /*lo_strike*/,
|
|
1.0 /*d_strike*/,
|
|
t1 /*expiry*/,
|
|
Pxtick::penny_nickel);
|
|
|
|
/* cx = pyoption.make_pricing_context(t0, 11.11, .5, .06) */
|
|
rp<PricingContext> cx
|
|
= PricingContext::make(t0, 11.11 /*ref_spot*/,
|
|
FlatVolsfc::make(0.5) /*volatility*/,
|
|
0.06 /*rate*/);
|
|
|
|
/* TODO: replace with constant to get deterministic behavior */
|
|
Seed<xoshiro256ss> seed;
|
|
|
|
/* ebm = pyprocess.make_exponential_brownian_motion(t0, 11.0, 0.5) */
|
|
rp<ExpProcess> ebm
|
|
= ExpProcess::make(11.0,
|
|
BrownianMotion<xoshiro256ss>::make(t0,
|
|
0.5 /*volatility*/,
|
|
seed));
|
|
|
|
/* src = pyprocess.make_realization_source(ebm, dt.timedelta(seconds=1)) */
|
|
rp<ReactorSource> src
|
|
= RealizationSource<UpxEvent, double>::make(RealizationTracer<double>::make(ebm),
|
|
std::chrono::seconds(1));
|
|
src->set_name("src");
|
|
|
|
/* (A)
|
|
* ulm = pyoption.make_ul_market_model(ul0, cx)
|
|
*/
|
|
rp<UlMarketModel> ulm = UlMarketModel::make(ul0, cx);
|
|
ulm->set_name("ulm");
|
|
|
|
/* (B)
|
|
* ssm = pyoption.make_strikeset_market_model(ss, cx)
|
|
*/
|
|
rp<StrikeSetMarketModel> ssm = StrikeSetMarketModel::make(ss, cx);
|
|
ssm->set_name("ssm");
|
|
|
|
/* (C)
|
|
* ssmd = pyoption.make_strikeset_omd(ss)
|
|
*/
|
|
rp<StrikeSetOmd> ssmd = StrikeSetOmd::make(ss);
|
|
ssmd->set_name("ssmd");
|
|
|
|
/* (D)
|
|
* bbos = pyoption.BboTickStore.make()
|
|
*/
|
|
using BboTickStore = StructEventStore<BboTick>;
|
|
rp<BboTickStore> bbos = StructEventStore<BboTick>::make();
|
|
bbos->set_name("bbos");
|
|
|
|
/* (E)
|
|
* vfin = pyvolfit.make_volfit_input_capture(cx)
|
|
*/
|
|
rp<VolfitInputCaptureSvc> vfin = VolfitInputCaptureSvc::make(cx);
|
|
vfin->set_name("vfin");
|
|
|
|
/* (F)
|
|
* kfspec = pyvolfit.make_kf_spec_m1(t0, s0=0.3, p0=1.0, q=5)
|
|
*/
|
|
KalmanFilterSpec kfspec = Volfit::kf_spec_m1(t0, 0.3, 1.0, 5.0);
|
|
/* kf = pyfilter.make_kalman_filter(spec=kfspec) */
|
|
rp<KalmanFilterSvc> kf = KalmanFilterSvc::make(kfspec);
|
|
kf->set_debug_sim_flag(true);
|
|
kf->set_name("kf");
|
|
|
|
using KalmanFilterStateEventStore
|
|
= PtrEventStore<rp<KalmanFilterStateExt>>;
|
|
|
|
/* (G)
|
|
* kfs = pyfilter.KalmanFilterStateEventStore.make()
|
|
*/
|
|
rp<KalmanFilterStateEventStore> kfs
|
|
= KalmanFilterStateEventStore::make();
|
|
|
|
/* sim.add_source(src) */
|
|
sim->add_source(src);
|
|
|
|
/* uls = pyprocess.UpxEventStore.make() */
|
|
using UpxEventStore = StructEventStore<UpxEvent>;
|
|
rp<UpxEventStore> uls = UpxEventStore::make();
|
|
src->attach_sink(uls);
|
|
|
|
/* (A) */
|
|
sim->add_source(ulm);
|
|
src->attach_sink(ulm);
|
|
|
|
/* (B) */
|
|
sim->add_source(ssm);
|
|
src->attach_sink(ssm);
|
|
|
|
/* (C) */
|
|
sim->add_source(ssmd);
|
|
ulm->attach_sink(ssmd);
|
|
ssm->attach_sink(ssmd);
|
|
|
|
/* (D) */
|
|
ulm->attach_sink(bbos);
|
|
ssm->attach_sink(bbos);
|
|
|
|
/* (E) */
|
|
// sim->add_source(vfin) ?
|
|
ssmd->attach_sink(vfin);
|
|
|
|
/* (F) */
|
|
// sim->add_source(kf) ?
|
|
vfin->attach_sink(kf);
|
|
|
|
/* (G) */
|
|
kf->attach_sink(kfs);
|
|
|
|
/* wconfig=pywebsock.WebserverConfig(7682, False, False, False)
|
|
* web=pywebsock.Webserver.make(wconfig)
|
|
*/
|
|
g_ws = Webserver::make(WebserverConfig(7682 /*port*/,
|
|
false /*!tls_flag*/,
|
|
false /*!strict_host_check_flag*/,
|
|
false /*!use_retry_flag*/),
|
|
PrintJsonSingleton::instance());
|
|
|
|
/* web.register_http_endpoint(uls.http_endpoint_descr("/uls")) # /dyn/uls/snap
|
|
* web.register_http_endpoint(kfs.http_endpoint_descr("/kfs")) # /dyn/kfs/snap
|
|
*/
|
|
g_ws->register_http_endpoint(uls->http_endpoint_descr(pjson, "/uls"));
|
|
g_ws->register_http_endpoint(kfs->http_endpoint_descr(pjson, "/kfs"));
|
|
|
|
/* web.register_stream_endpoint(src.stream_endpoint_descr("/ws/uls"))
|
|
* web.register_stream_endpoint(kf.stream_endpoint_descr("/ws/kfs"))
|
|
*/
|
|
g_ws->register_stream_endpoint(src->stream_endpoint_descr("/ws/uls"));
|
|
g_ws->register_stream_endpoint(kf->stream_endpoint_descr("/ws/kfs"));
|
|
|
|
log("starting webserver..");
|
|
|
|
g_ws->start_webserver();
|
|
|
|
log("..webserver started");
|
|
|
|
/* attempt simulation.
|
|
* throttle so that we have time to connect browser, give url
|
|
* http://localhost:7682/ex_websock.html
|
|
* pywebsock/ex_websock.py implements a governed simulation loop
|
|
* in python, so that it's interruptible.
|
|
* here, we can rely on simulator instead
|
|
*/
|
|
sim->run_throttled_until(t0 /*t1 - ignored if <= sim.t0()*/,
|
|
50 /*n_max*/,
|
|
2.5 /*replay_factor*/);
|
|
|
|
|
|
log("joining webserver..");
|
|
|
|
g_ws->join_webserver();
|
|
|
|
log("..joined webserver");
|
|
} catch (std::exception & ex) {
|
|
std::cerr << "caught exception" << xtag("ex", ex.what()) << std::endl;
|
|
}
|
|
|
|
} /*main*/
|
|
|
|
/* end websock_utest_main.cpp */
|