├── .clang-format ├── .clang-tidy ├── .github ├── docker │ ├── Build_Marketsim.Dockerfile │ ├── Deploy_Marketsim.Dockerfile │ ├── Postgres_Marketsim.Dockerfile │ ├── init.sql │ └── liquibase_custom.Dockerfile └── workflows │ ├── build-builder-image.yml │ ├── build-deploy-documentation.yml │ ├── build-liquibase-image.yml │ ├── build-postgres-image.yml │ └── marketsim-ci.yml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── LICENSE ├── README.md ├── THIRD-PARTY-LICENSES.md ├── cfg ├── client_qasimulator.xml ├── configSim.txt └── default │ ├── FIX50SP2_marketsimulator.xml │ └── FIXT11_marketsimulator.xml ├── cmake ├── CheckDependencyExist.cmake ├── Conan.cmake ├── TargetInit.cmake ├── TargetTest.cmake ├── build │ ├── Archive.cmake │ ├── CompilerWarnings.cmake │ ├── PreventInSourceBuilds.cmake │ ├── StandardProjectSettings.cmake │ └── Version.cmake └── utils │ ├── Git.cmake │ ├── Sanitizers.cmake │ ├── StaticAnalyzers.cmake │ └── TimeTrace.cmake ├── db ├── external-price-seed │ ├── root-changelog.yml │ └── schema │ │ ├── changelog.yml │ │ └── tables │ │ └── price_seed.yml ├── market-simulator │ ├── root-changelog.yml │ ├── sample-data │ │ ├── changelog.yml │ │ ├── common │ │ │ ├── changelog.yml │ │ │ └── setting.yml │ │ └── demo │ │ │ ├── changelog.yml │ │ │ └── xetra │ │ │ ├── changelog.yml │ │ │ ├── listings │ │ │ ├── 1-AMZ.yml │ │ │ ├── 2-MSF.yml │ │ │ ├── 3-NFC.yml │ │ │ ├── 4-VODI.yml │ │ │ └── 5-VOW.yml │ │ │ ├── price_seeds │ │ │ ├── 1-AMZ.yml │ │ │ ├── 2-MSF.yml │ │ │ ├── 3-NFC.yml │ │ │ ├── 4-VODI.yml │ │ │ └── 5-VOW.yml │ │ │ ├── setting │ │ │ └── setting.yml │ │ │ └── venue.yml │ └── schema │ │ ├── changelog.yml │ │ ├── constraints │ │ ├── data_source.yml │ │ ├── listing.yml │ │ ├── market_phase.yml │ │ └── venue.yml │ │ ├── keys │ │ ├── column_mapping.yml │ │ ├── data_source.yml │ │ ├── listing.yml │ │ ├── market_phase.yml │ │ ├── price_seed.yml │ │ ├── setting.yml │ │ └── venue.yml │ │ ├── sequences │ │ ├── data_source.yml │ │ ├── listing.yml │ │ └── price_seed.yml │ │ └── tables │ │ ├── column_mapping.yml │ │ ├── data_source.yml │ │ ├── listing.yml │ │ ├── market_phase.yml │ │ ├── price_seed.yml │ │ ├── setting.yml │ │ └── venue.yml └── root-changelog.yml ├── docs ├── FIXRulesOfEngagement │ ├── AdminMessages │ │ └── AdminMessages.adoc │ ├── CommonComponents │ │ └── CommonComponents.adoc │ ├── FIXRulesOfEngagement.adoc │ ├── Introduction │ │ ├── Cover.odt │ │ ├── Cover.pdf │ │ └── Introduction.adoc │ ├── MessageFlows │ │ └── MessageFlows.adoc │ ├── PhaseReportingMessages │ │ └── PhaseReportingMessages.adoc │ ├── PreTradeMessages │ │ └── PreTradeMessages.adoc │ ├── TradeMessages │ │ └── TradeMessages.adoc │ ├── build.bat │ ├── build.sh │ └── images │ │ ├── 01MktDataIncrementalMsg.png │ │ ├── 02MktDataStreamingMsg.png │ │ ├── 03MktDataSnapReqRsp.png │ │ ├── 04MktDataReqRct.png │ │ ├── 05MktDataNewOrderSgl.png │ │ ├── 06MktDataNewOrderRct.png │ │ ├── 07MktDataExeRpt.png │ │ ├── 08MktDataCancel.png │ │ ├── 09MktDataPartialCancel.png │ │ ├── 10MktDataOrderReplace.png │ │ ├── 11MktDataCancelReject.png │ │ ├── 12MktDataCancelSuccess.png │ │ ├── 13MktDataCancelReplaceReject.png │ │ ├── 14MktDataStsReport.png │ │ ├── 15MktDataStsSnapSht.png │ │ └── 16MktDataStsReject.png ├── Overview │ ├── Overview.adoc │ ├── build.bat │ └── build.sh ├── RESTAPI │ ├── AdministrativeCommands │ │ └── AdministrativeCommands.adoc │ ├── AdministrativeSettings │ │ └── AdministrativeSettings.adoc │ ├── General │ │ └── General.adoc │ ├── Introduction │ │ ├── Cover.odt │ │ ├── Cover.pdf │ │ └── Introduction.adoc │ ├── RESTAPI.adoc │ ├── build.bat │ ├── build.sh │ └── images │ │ └── 17pricebook.png ├── common │ ├── adoc │ │ ├── docinfo-footer.html │ │ ├── docinfo.html │ │ ├── header.adoc │ │ └── titleblock.adoc │ ├── favicon.ico │ └── pdf │ │ ├── Logo.png │ │ └── PDFTheme.yml └── index.html ├── images ├── image01_dark.png ├── image01_light.png ├── image02_dark.png └── image02_light.png ├── project ├── CMakeLists.txt ├── app │ ├── CMakeLists.txt │ ├── ih │ │ ├── application.hpp │ │ ├── command_options.hpp │ │ ├── components │ │ │ ├── fix_acceptor.hpp │ │ │ ├── generator.hpp │ │ │ ├── http_server.hpp │ │ │ └── trading_engine.hpp │ │ ├── dispatchers │ │ │ └── venue_trading_reply_dispatcher.hpp │ │ ├── loading.hpp │ │ ├── loop.hpp │ │ └── platforms │ │ │ ├── platform.hpp │ │ │ └── venue_simulation_platform.hpp │ ├── src │ │ ├── application.cpp │ │ ├── command_options.cpp │ │ ├── loading.cpp │ │ ├── loop.cpp │ │ ├── main.cpp │ │ └── platforms │ │ │ └── venue_simulation_platform.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── test_main.cpp │ │ └── unit_tests │ │ └── command_options_tests.cpp ├── cfg │ ├── CMakeLists.txt │ ├── include │ │ └── cfg │ │ │ └── api │ │ │ └── cfg.hpp │ └── src │ │ ├── cfg_impl.cpp │ │ └── cfg_impl.hpp ├── core │ ├── CMakeLists.txt │ ├── include │ │ └── core │ │ │ ├── common │ │ │ ├── attribute.hpp │ │ │ ├── enum_converter.hpp │ │ │ ├── json │ │ │ │ ├── field.hpp │ │ │ │ ├── type.hpp │ │ │ │ ├── type_container.hpp │ │ │ │ ├── type_enum.hpp │ │ │ │ └── type_struct.hpp │ │ │ ├── meta.hpp │ │ │ ├── name.hpp │ │ │ ├── return_code.hpp │ │ │ ├── std_formatter.hpp │ │ │ └── unreachable.hpp │ │ │ ├── domain │ │ │ ├── attributes.hpp │ │ │ ├── enumerators.hpp │ │ │ ├── instrument_descriptor.hpp │ │ │ ├── json │ │ │ │ ├── instrument_descriptor.hpp │ │ │ │ ├── market_phase.hpp │ │ │ │ └── party.hpp │ │ │ ├── market_data_entry.hpp │ │ │ ├── market_phase.hpp │ │ │ └── party.hpp │ │ │ ├── tools │ │ │ ├── format.hpp │ │ │ ├── numeric.hpp │ │ │ ├── overload.hpp │ │ │ ├── string_checkers.hpp │ │ │ └── time.hpp │ │ │ └── version.hpp │ ├── src │ │ ├── common │ │ │ ├── json │ │ │ │ └── type.cpp │ │ │ └── return_code.cpp │ │ ├── domain │ │ │ ├── attributes.cpp │ │ │ ├── composites.cpp │ │ │ ├── enumerators.cpp │ │ │ ├── market_phase.cpp │ │ │ └── party.cpp │ │ ├── tools │ │ │ ├── string_checkers.cpp │ │ │ └── time.cpp │ │ └── version.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── fixtures │ │ └── given_expected_fixture.hpp │ │ ├── test_definitions │ │ └── test_attributes.hpp │ │ ├── test_main.cpp │ │ ├── test_utils │ │ └── matchers.hpp │ │ └── unit_tests │ │ ├── common │ │ ├── attributes_tests.cpp │ │ ├── enum_converter_tests.cpp │ │ ├── json │ │ │ ├── attribute_tests.cpp │ │ │ ├── attributes_tests.cpp │ │ │ ├── type_container_tests.cpp │ │ │ ├── type_enum_tests.cpp │ │ │ ├── type_struct_tests.cpp │ │ │ └── type_tests.cpp │ │ └── return_code_tests.cpp │ │ ├── domain │ │ ├── enumerators_tests.cpp │ │ ├── instrument_descriptor_tests.cpp │ │ ├── market_phase_tests.cpp │ │ └── party_tests.cpp │ │ └── tools │ │ ├── numeric_tests.cpp │ │ ├── string_checkers_tests.cpp │ │ └── time_tests.cpp ├── data_layer │ ├── CMakeLists.txt │ ├── ih │ │ ├── common │ │ │ ├── command │ │ │ │ ├── commands.hpp │ │ │ │ └── handlers.hpp │ │ │ ├── database │ │ │ │ ├── context_resolver.hpp │ │ │ │ ├── driver.hpp │ │ │ │ └── ping_agent.hpp │ │ │ ├── exceptions.hpp │ │ │ └── queries │ │ │ │ └── data_extractor.hpp │ │ ├── formatters │ │ │ └── pqxx │ │ │ │ └── context.hpp │ │ └── pqxx │ │ │ ├── common │ │ │ ├── column_resolver.hpp │ │ │ ├── enumeration_resolver.hpp │ │ │ └── names │ │ │ │ ├── database_entries.hpp │ │ │ │ └── enumerations.hpp │ │ │ ├── context.hpp │ │ │ ├── dao │ │ │ ├── datasource_dao.hpp │ │ │ ├── listing_dao.hpp │ │ │ ├── price_seed_dao.hpp │ │ │ ├── setting_dao.hpp │ │ │ └── venue_dao.hpp │ │ │ ├── database │ │ │ ├── connector.hpp │ │ │ ├── transaction.hpp │ │ │ └── value_sanitizer.hpp │ │ │ ├── queries │ │ │ ├── datasource_queries.hpp │ │ │ ├── detail │ │ │ │ ├── delete_query_builder.hpp │ │ │ │ ├── insert_query_builder.hpp │ │ │ │ ├── predicate_formatter.hpp │ │ │ │ ├── select_query_builder.hpp │ │ │ │ └── update_query_builder.hpp │ │ │ ├── listing_queries.hpp │ │ │ ├── price_seed_queries.hpp │ │ │ ├── setting_queries.hpp │ │ │ └── venue_queries.hpp │ │ │ └── result │ │ │ ├── datasource_parser.hpp │ │ │ ├── detail │ │ │ └── basic_row_parser.hpp │ │ │ ├── listing_parser.hpp │ │ │ ├── price_seed_parser.hpp │ │ │ ├── setting_parser.hpp │ │ │ └── venue_parser.hpp │ ├── include │ │ └── data_layer │ │ │ └── api │ │ │ ├── converters │ │ │ └── column_mapping.hpp │ │ │ ├── data_access_layer.hpp │ │ │ ├── database │ │ │ └── context.hpp │ │ │ ├── exceptions │ │ │ └── exceptions.hpp │ │ │ ├── inspectors │ │ │ ├── column_mapping.hpp │ │ │ ├── datasource.hpp │ │ │ ├── listing.hpp │ │ │ ├── market_phase.hpp │ │ │ ├── price_seed.hpp │ │ │ ├── setting.hpp │ │ │ └── venue.hpp │ │ │ ├── models │ │ │ ├── column_mapping.hpp │ │ │ ├── datasource.hpp │ │ │ ├── listing.hpp │ │ │ ├── market_phase.hpp │ │ │ ├── price_seed.hpp │ │ │ ├── setting.hpp │ │ │ └── venue.hpp │ │ │ ├── predicate │ │ │ ├── definitions.hpp │ │ │ ├── expression.hpp │ │ │ ├── lexeme.hpp │ │ │ ├── predicate.hpp │ │ │ └── traits.hpp │ │ │ └── validations │ │ │ ├── column_mapping.hpp │ │ │ └── datasource.hpp │ ├── src │ │ ├── api │ │ │ ├── converters │ │ │ │ └── column_mapping.cpp │ │ │ ├── data_access_layer.cpp │ │ │ ├── database │ │ │ │ └── context.cpp │ │ │ ├── exceptions │ │ │ │ └── exceptions.cpp │ │ │ ├── models │ │ │ │ ├── column_mapping.cpp │ │ │ │ ├── datasource.cpp │ │ │ │ ├── listing.cpp │ │ │ │ ├── market_phase.cpp │ │ │ │ ├── price_seed.cpp │ │ │ │ ├── setting.cpp │ │ │ │ └── venue.cpp │ │ │ └── validations │ │ │ │ ├── column_mapping.cpp │ │ │ │ └── datasource.cpp │ │ ├── common │ │ │ ├── database │ │ │ │ └── ping_agent.cpp │ │ │ └── exceptions.cpp │ │ └── pqxx │ │ │ ├── common │ │ │ ├── column_resolver.cpp │ │ │ └── enumeration_resolver.cpp │ │ │ ├── context.cpp │ │ │ ├── dao │ │ │ ├── datasource_dao.cpp │ │ │ ├── listing_dao.cpp │ │ │ ├── price_seed_dao.cpp │ │ │ ├── setting_dao.cpp │ │ │ └── venue_dao.cpp │ │ │ └── database │ │ │ └── connector.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── common │ │ ├── marshaller.hpp │ │ └── model.hpp │ │ ├── test_main.cpp │ │ ├── test_utils │ │ ├── matchers.hpp │ │ └── sanitizer_stub.hpp │ │ └── unit_tests │ │ ├── common │ │ ├── command │ │ │ └── commands_tests.cpp │ │ ├── database │ │ │ └── ping_agent_tests.cpp │ │ └── queries │ │ │ └── data_extractor_tests.cpp │ │ ├── converters │ │ └── column_mapping_tests.cpp │ │ ├── inspectors │ │ ├── column_mapping_inspectors_tests.cpp │ │ ├── datasource_inspectors_tests.cpp │ │ ├── listing_inspectors_tests.cpp │ │ ├── market_phase_inspectors_tests.cpp │ │ ├── price_seed_inspectors_tests.cpp │ │ ├── setting_inspectors_tests.cpp │ │ └── venue_inspectors_tests.cpp │ │ ├── models │ │ ├── column_mapping_tests.cpp │ │ ├── datasource_tests.cpp │ │ ├── listing_tests.cpp │ │ ├── market_phase_tests.cpp │ │ ├── price_seed_tests.cpp │ │ ├── setting_tests.cpp │ │ └── venue_tests.cpp │ │ ├── pqxx │ │ ├── common │ │ │ ├── column_resolver_tests.cpp │ │ │ └── enumeration_resolver_tests.cpp │ │ ├── context_tests.cpp │ │ ├── database │ │ │ ├── connector_tests.cpp │ │ │ └── transaction_tests.cpp │ │ └── queries │ │ │ ├── datasource_queries_tests.cpp │ │ │ ├── detail │ │ │ ├── delete_query_builder_tests.cpp │ │ │ ├── insert_query_builder_tests.cpp │ │ │ ├── predicate_formatter_tests.cpp │ │ │ ├── select_query_builder_tests.cpp │ │ │ └── update_query_builder_tests.cpp │ │ │ ├── listing_queries_tests.cpp │ │ │ ├── price_seed_queries_tests.cpp │ │ │ ├── setting_queries_tests.cpp │ │ │ └── venue_queries_tests.cpp │ │ ├── predicate │ │ ├── expression_tests.cpp │ │ └── lexemes_tests.cpp │ │ └── validations │ │ ├── column_mapping_tests.cpp │ │ └── datasource_tests.cpp ├── fix │ ├── CMakeLists.txt │ ├── acceptor │ │ ├── CMakeLists.txt │ │ ├── ih │ │ │ ├── acceptor.hpp │ │ │ ├── communicators │ │ │ │ ├── application.hpp │ │ │ │ ├── fix_reply_sender.hpp │ │ │ │ └── reply_sender.hpp │ │ │ ├── mapping │ │ │ │ ├── from_fix_mapper.hpp │ │ │ │ └── to_fix_mapper.hpp │ │ │ └── processors │ │ │ │ ├── app_event_processor.hpp │ │ │ │ ├── app_reply_processor.hpp │ │ │ │ ├── app_request_processor.hpp │ │ │ │ ├── event_processor.hpp │ │ │ │ └── request_processor.hpp │ │ ├── include │ │ │ └── acceptor │ │ │ │ ├── acceptor.hpp │ │ │ │ ├── lifetime.hpp │ │ │ │ └── transport.hpp │ │ ├── src │ │ │ ├── acceptor.cpp │ │ │ ├── communicators │ │ │ │ ├── application.cpp │ │ │ │ └── fix_reply_sender.cpp │ │ │ └── mapping │ │ │ │ ├── from_fix_mapper.cpp │ │ │ │ └── to_fix_mapper.cpp │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── mocks │ │ │ ├── event_processor_mock.hpp │ │ │ ├── from_fix_mapper_stub.hpp │ │ │ ├── reply_sender_mock.hpp │ │ │ ├── request_processor_mock.hpp │ │ │ ├── to_fix_mapper_stub.hpp │ │ │ └── trading_request_receiver_mock.hpp │ │ │ ├── test_main.cpp │ │ │ └── unit_tests │ │ │ ├── communicators │ │ │ └── application_tests.cpp │ │ │ ├── mapping │ │ │ ├── from_fix_mapper_tests.cpp │ │ │ └── to_fix_mapper_tests.cpp │ │ │ └── processors │ │ │ ├── app_reply_processor_tests.cpp │ │ │ └── app_request_processor_tests.cpp │ └── common │ │ ├── CMakeLists.txt │ │ ├── include │ │ └── common │ │ │ ├── custom_fields.hpp │ │ │ ├── custom_values.hpp │ │ │ ├── fix_logger.hpp │ │ │ ├── mapping │ │ │ ├── checks.hpp │ │ │ ├── detail │ │ │ │ ├── definitions.hpp │ │ │ │ ├── error_reporting.hpp │ │ │ │ ├── from_fix_conversion.hpp │ │ │ │ └── to_fix_conversion.hpp │ │ │ ├── from_fix_mapping.hpp │ │ │ ├── setting │ │ │ │ ├── mapping_settings.hpp │ │ │ │ └── timestamp_precision.hpp │ │ │ └── to_fix_mapping.hpp │ │ │ ├── message_store.hpp │ │ │ ├── meta.hpp │ │ │ ├── session_conversion.hpp │ │ │ └── session_settings.hpp │ │ ├── src │ │ ├── fix_logger.cpp │ │ ├── mapping │ │ │ ├── detail │ │ │ │ ├── from_fix_conversion.cpp │ │ │ │ └── to_fix_conversion.cpp │ │ │ └── setting │ │ │ │ └── mapping_settings.cpp │ │ ├── message_store.cpp │ │ ├── session_conversion.cpp │ │ └── session_settings.cpp │ │ └── tests │ │ ├── CMakeLists.txt │ │ ├── test_main.cpp │ │ └── unit_tests │ │ ├── mapping │ │ ├── checks_tests.cpp │ │ ├── from_fix_conversion_tests.cpp │ │ ├── from_fix_mapping_tests.cpp │ │ ├── setting │ │ │ └── mapping_settings_tests.cpp │ │ └── to_fix_conversion_tests.cpp │ │ ├── session_conversion_tests.cpp │ │ └── settings_tests.cpp ├── generator │ ├── CMakeLists.txt │ ├── ih │ │ ├── adaptation │ │ │ ├── generated_message.hpp │ │ │ └── protocol_conversion.hpp │ │ ├── constants.hpp │ │ ├── context │ │ │ ├── component_context.hpp │ │ │ ├── generation_manager.hpp │ │ │ ├── instrument_context.hpp │ │ │ ├── order_generation_context.hpp │ │ │ ├── order_generation_context_impl.hpp │ │ │ └── order_market_data_provider.hpp │ │ ├── factory │ │ │ ├── executable_factory.hpp │ │ │ └── executable_factory_impl.hpp │ │ ├── generator.hpp │ │ ├── generator_impl.hpp │ │ ├── historical │ │ │ ├── adapters │ │ │ │ ├── csv_reader.hpp │ │ │ │ ├── data_access_adapter.hpp │ │ │ │ └── postgresql_connector.hpp │ │ │ ├── data │ │ │ │ ├── provider.hpp │ │ │ │ ├── record.hpp │ │ │ │ └── time.hpp │ │ │ ├── mapping │ │ │ │ ├── column_mapping_filter.hpp │ │ │ │ ├── configurator.hpp │ │ │ │ ├── datasource_params.hpp │ │ │ │ ├── depth_config.hpp │ │ │ │ ├── params.hpp │ │ │ │ └── specification.hpp │ │ │ ├── parsing │ │ │ │ ├── params.hpp │ │ │ │ ├── parsing.hpp │ │ │ │ └── row.hpp │ │ │ ├── processor.hpp │ │ │ ├── record_applier.hpp │ │ │ ├── replier.hpp │ │ │ └── scheduler.hpp │ │ ├── random │ │ │ ├── algorithm │ │ │ │ ├── generation_algorithm.hpp │ │ │ │ ├── order_generation_algorithm.hpp │ │ │ │ └── utils │ │ │ │ │ ├── attributes_setter.hpp │ │ │ │ │ ├── max_mktdepth_selector.hpp │ │ │ │ │ ├── price_params_selector.hpp │ │ │ │ │ └── quantity_params_selector.hpp │ │ │ ├── generators │ │ │ │ ├── counterparty_generator.hpp │ │ │ │ ├── event_generator.hpp │ │ │ │ ├── price_generator.hpp │ │ │ │ ├── quantity_generator.hpp │ │ │ │ ├── resting_order_action_generator.hpp │ │ │ │ ├── value_generator.hpp │ │ │ │ └── value_generator_impl.hpp │ │ │ ├── instrument_generator.hpp │ │ │ ├── utils.hpp │ │ │ └── values │ │ │ │ ├── event.hpp │ │ │ │ ├── price_generation_params.hpp │ │ │ │ ├── quantity_generation_params.hpp │ │ │ │ └── resting_order_action.hpp │ │ ├── registry │ │ │ ├── generated_order_data.hpp │ │ │ ├── generated_orders_registry.hpp │ │ │ ├── generated_orders_registry_impl.hpp │ │ │ └── registry_updater.hpp │ │ ├── tracing │ │ │ ├── json_tracer.hpp │ │ │ ├── null_tracer.hpp │ │ │ ├── trace_logger.hpp │ │ │ ├── trace_value.hpp │ │ │ └── tracing.hpp │ │ └── utils │ │ │ ├── executable.hpp │ │ │ ├── executor.hpp │ │ │ ├── parsers.hpp │ │ │ ├── request_builder.hpp │ │ │ └── validator.hpp │ ├── include │ │ └── generator │ │ │ └── generator.hpp │ ├── src │ │ ├── adaptation │ │ │ ├── generated_message.cpp │ │ │ └── protocol_conversion.cpp │ │ ├── context │ │ │ ├── generation_manager.cpp │ │ │ ├── order_generation_context_impl.cpp │ │ │ └── order_market_data_provider.cpp │ │ ├── factory │ │ │ └── executable_factory_impl.cpp │ │ ├── generator.cpp │ │ ├── generator_impl.cpp │ │ ├── historical │ │ │ ├── adapters │ │ │ │ ├── csv_reader.cpp │ │ │ │ ├── data_access_adapter.cpp │ │ │ │ └── postgresql_connector.cpp │ │ │ ├── data │ │ │ │ ├── provider.cpp │ │ │ │ └── record.cpp │ │ │ ├── mapping │ │ │ │ ├── column_mapping_filter.cpp │ │ │ │ ├── configurator.cpp │ │ │ │ ├── datasource_params.cpp │ │ │ │ ├── params.cpp │ │ │ │ └── specification.cpp │ │ │ ├── parsing │ │ │ │ ├── params.cpp │ │ │ │ └── parsing.cpp │ │ │ ├── processor.cpp │ │ │ ├── record_applier.cpp │ │ │ ├── replier.cpp │ │ │ └── scheduler.cpp │ │ ├── random │ │ │ ├── algorithm │ │ │ │ ├── order_generation_algorithm.cpp │ │ │ │ └── utils │ │ │ │ │ └── quantity_params_selector.cpp │ │ │ ├── generators │ │ │ │ ├── counterparty_generator.cpp │ │ │ │ ├── event_generator.cpp │ │ │ │ ├── price_generator.cpp │ │ │ │ ├── quantity_generator.cpp │ │ │ │ ├── resting_order_action_generator.cpp │ │ │ │ └── value_generator_impl.cpp │ │ │ ├── instrument_generator.cpp │ │ │ └── values │ │ │ │ ├── event.cpp │ │ │ │ ├── price_generation_params.cpp │ │ │ │ ├── quantity_generation_params.cpp │ │ │ │ └── resting_order_action.cpp │ │ ├── registry │ │ │ ├── generated_orders_registry_impl.cpp │ │ │ └── registry_updater.cpp │ │ └── utils │ │ │ ├── executor.cpp │ │ │ ├── parsers.cpp │ │ │ ├── request_builder.cpp │ │ │ └── validator.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── mocks │ │ ├── context │ │ │ └── order_context.hpp │ │ ├── historical │ │ │ ├── data_access_adapter.hpp │ │ │ └── provider.hpp │ │ ├── random │ │ │ ├── counterparty_generator.hpp │ │ │ ├── price_generator.hpp │ │ │ ├── quantity_generator.hpp │ │ │ ├── random_event_generator.hpp │ │ │ ├── resting_order_action_generator.hpp │ │ │ └── value_generator.hpp │ │ ├── registry │ │ │ └── generated_orders_registry.hpp │ │ └── trading_request_channel.hpp │ │ ├── test_main.cpp │ │ ├── test_utils │ │ ├── generated_message_utils.hpp │ │ ├── historical_data_utils.hpp │ │ └── historical_mapping_utils.hpp │ │ └── unit_tests │ │ ├── adaptation │ │ ├── instrument_descriptor_conversion_tests.cpp │ │ └── to_protocol_message_conversion_tests.cpp │ │ ├── context │ │ └── generation_manager_tests.cpp │ │ ├── historical │ │ ├── adapters │ │ │ ├── csv_reader_tests.cpp │ │ │ └── data_access_adapter_tests.cpp │ │ ├── data │ │ │ ├── action_tests.cpp │ │ │ ├── level_tests.cpp │ │ │ ├── provider_tests.cpp │ │ │ └── record_tests.cpp │ │ ├── mapping │ │ │ ├── column_mapping_filter_tests.cpp │ │ │ ├── configurator_default_association_tests.cpp │ │ │ ├── configurator_no_source_columns_tests.cpp │ │ │ ├── configurator_tests.cpp │ │ │ ├── depth_config_tests.cpp │ │ │ ├── source_column_tests.cpp │ │ │ └── specification_tests.cpp │ │ ├── parsing │ │ │ ├── csv_parsing_params_tests.cpp │ │ │ ├── database_parsing_params_tests.cpp │ │ │ ├── general_datasource_params_tests.cpp │ │ │ ├── params_tests.cpp │ │ │ ├── parsing_tests.cpp │ │ │ ├── parsing_value_tests.cpp │ │ │ └── row_tests.cpp │ │ ├── record_applier_tests.cpp │ │ └── record_checker_tests.cpp │ │ ├── random │ │ ├── algorithm │ │ │ ├── order_generation_algorithm_tests.cpp │ │ │ └── utils │ │ │ │ ├── attributes_setter_tests.cpp │ │ │ │ ├── max_mktdepth_selector_tests.cpp │ │ │ │ ├── price_params_selector_tests.cpp │ │ │ │ └── quantity_params_selector_tests.cpp │ │ ├── generators │ │ │ ├── counterparty_generator_tests.cpp │ │ │ ├── event_generator_tests.cpp │ │ │ ├── price_generator_tests.cpp │ │ │ ├── quantity_generator_tests.cpp │ │ │ ├── resting_order_action_generator_tests.cpp │ │ │ └── value_generator_impl_tests.cpp │ │ └── values │ │ │ ├── event_tests.cpp │ │ │ ├── price_generation_params_tests.cpp │ │ │ ├── quantity_generation_params_tests.cpp │ │ │ └── resting_order_action_tests.cpp │ │ ├── registry │ │ ├── generated_order_data_tests.cpp │ │ ├── generated_orders_registry_tests.cpp │ │ └── registry_updater_tests.cpp │ │ ├── tracing │ │ ├── json_tracer_tests.cpp │ │ └── trace_value_tests.cpp │ │ └── utils │ │ └── validator_tests.cpp ├── http │ ├── CMakeLists.txt │ ├── ih │ │ ├── constants.hpp │ │ ├── controllers │ │ │ ├── datasource_controller.hpp │ │ │ ├── listing_controller.hpp │ │ │ ├── price_seed_controller.hpp │ │ │ ├── setting_controller.hpp │ │ │ ├── trading_controller.hpp │ │ │ └── venue_controller.hpp │ │ ├── data_bridge │ │ │ ├── datasource_accessor.hpp │ │ │ ├── listing_accessor.hpp │ │ │ ├── operation_failure.hpp │ │ │ ├── price_seed_accessor.hpp │ │ │ ├── setting_accessor.hpp │ │ │ └── venue_accessor.hpp │ │ ├── endpoint.hpp │ │ ├── formatters │ │ │ ├── redirect.hpp │ │ │ └── request_formatter.hpp │ │ ├── headers │ │ │ └── x_api_version.hpp │ │ ├── marshalling │ │ │ └── json │ │ │ │ ├── datasource.hpp │ │ │ │ ├── detail │ │ │ │ ├── enumeration_resolver.hpp │ │ │ │ ├── key_resolver.hpp │ │ │ │ ├── keys.hpp │ │ │ │ ├── marshaller.hpp │ │ │ │ ├── traits.hpp │ │ │ │ ├── unmarshaller.hpp │ │ │ │ └── utils.hpp │ │ │ │ ├── halt.hpp │ │ │ │ ├── listing.hpp │ │ │ │ ├── price_seed.hpp │ │ │ │ ├── setting.hpp │ │ │ │ └── venue.hpp │ │ ├── processors │ │ │ ├── delete_processor.hpp │ │ │ ├── get_processor.hpp │ │ │ ├── post_processor.hpp │ │ │ └── put_processor.hpp │ │ ├── redirect │ │ │ ├── destination.hpp │ │ │ ├── destination_resolver.hpp │ │ │ ├── redirection_processor.hpp │ │ │ ├── redirector.hpp │ │ │ ├── request.hpp │ │ │ ├── request_redirector.hpp │ │ │ ├── resolver.hpp │ │ │ └── result.hpp │ │ ├── router.hpp │ │ ├── server.hpp │ │ └── utils │ │ │ └── response_formatters.hpp │ ├── include │ │ └── http │ │ │ └── http.hpp │ ├── src │ │ ├── controllers │ │ │ ├── datasource_controller.cpp │ │ │ ├── listing_controller.cpp │ │ │ ├── price_seed_controller.cpp │ │ │ ├── setting_controller.cpp │ │ │ ├── trading_controller.cpp │ │ │ └── venue_controller.cpp │ │ ├── data_bridge │ │ │ ├── datasource_accessor.cpp │ │ │ ├── listing_accessor.cpp │ │ │ ├── price_seed_accessor.cpp │ │ │ ├── setting_accessor.cpp │ │ │ └── venue_accessor.cpp │ │ ├── http.cpp │ │ ├── marshalling │ │ │ └── json │ │ │ │ ├── datasource.cpp │ │ │ │ ├── detail │ │ │ │ ├── enumeration_resolver.cpp │ │ │ │ └── key_resolver.cpp │ │ │ │ ├── halt.cpp │ │ │ │ ├── listing.cpp │ │ │ │ ├── price_seed.cpp │ │ │ │ ├── setting.cpp │ │ │ │ └── venue.cpp │ │ ├── processors │ │ │ ├── delete_processor.cpp │ │ │ ├── get_processor.cpp │ │ │ ├── post_processor.cpp │ │ │ └── put_processor.cpp │ │ ├── redirect │ │ │ ├── destination_resolver.cpp │ │ │ ├── redirection_processor.cpp │ │ │ └── request_redirector.cpp │ │ └── router.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── mocks │ │ ├── redirector.hpp │ │ ├── resolver.hpp │ │ ├── trading_admin_request_receiver.hpp │ │ └── venue_accessor.hpp │ │ ├── test_main.cpp │ │ ├── test_utils │ │ ├── matchers.hpp │ │ └── test_server.hpp │ │ └── unit_tests │ │ ├── controllers │ │ └── trading_controller_tests.cpp │ │ ├── headers │ │ └── x_api_version_tests.cpp │ │ ├── marshalling │ │ └── json │ │ │ ├── datasource_marshalling_tests.cpp │ │ │ ├── detail │ │ │ ├── enumeration_resolver_tests.cpp │ │ │ ├── key_resolver_tests.cpp │ │ │ ├── marshaller_tests.cpp │ │ │ └── unmarshaller_tests.cpp │ │ │ ├── halt_unmarshalling_tests.cpp │ │ │ ├── listing_marshalling_tests.cpp │ │ │ ├── price_seed_marshalling_tests.cpp │ │ │ ├── setting_marshalling_tests.cpp │ │ │ └── venue_marshalling_tests.cpp │ │ └── redirect │ │ ├── destination_resolver_tests.cpp │ │ ├── redirection_processor_tests.cpp │ │ ├── request_redirector_tests.cpp │ │ └── result_tests.cpp ├── log │ ├── CMakeLists.txt │ ├── ih │ │ ├── custom_spd_flags.hpp │ │ ├── factories │ │ │ ├── logger_factory.hpp │ │ │ └── sink_factory.hpp │ │ └── util.hpp │ ├── include │ │ └── log │ │ │ ├── logger.hpp │ │ │ └── logging.hpp │ ├── src │ │ ├── custom_spd_flags.cpp │ │ ├── factories │ │ │ └── logger_factory.cpp │ │ ├── logger.cpp │ │ └── util.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── test_main.cpp │ │ ├── test_utils │ │ ├── matchers.hpp │ │ └── rapidjson_utils.hpp │ │ └── unit_tests │ │ ├── custom_spd_flags_tests.cpp │ │ ├── factories │ │ ├── logger_factory_tests.cpp │ │ └── sink_factory_tests.cpp │ │ ├── logger_tests.cpp │ │ ├── logging_tests.cpp │ │ └── util_tests.cpp ├── middleware │ ├── CMakeLists.txt │ ├── ih │ │ └── channels.hpp │ ├── include │ │ └── middleware │ │ │ ├── channels │ │ │ ├── detail │ │ │ │ └── receiver.hpp │ │ │ ├── generator_admin_channel.hpp │ │ │ ├── trading_admin_channel.hpp │ │ │ ├── trading_reply_channel.hpp │ │ │ ├── trading_request_channel.hpp │ │ │ └── trading_session_event_channel.hpp │ │ │ └── routing │ │ │ ├── errors.hpp │ │ │ ├── generator_admin_channel.hpp │ │ │ ├── trading_admin_channel.hpp │ │ │ ├── trading_reply_channel.hpp │ │ │ ├── trading_request_channel.hpp │ │ │ └── trading_session_event_channel.hpp │ ├── src │ │ └── middleware.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── mocks │ │ ├── generator_admin_receiver_mock.hpp │ │ ├── trading_admin_receiver_mock.hpp │ │ ├── trading_reply_receiver_mock.hpp │ │ ├── trading_request_receiver_mock.hpp │ │ └── trading_session_event_listener_mock.hpp │ │ ├── test_main.cpp │ │ ├── test_utils │ │ └── protocol_utils.hpp │ │ └── unit_tests │ │ ├── generator_admin_channel_tests.cpp │ │ ├── trading_admin_channel_tests.cpp │ │ ├── trading_reply_channel_tests.cpp │ │ ├── trading_request_channel_tests.cpp │ │ └── trading_session_event_channel_tests.cpp ├── protocol │ ├── CMakeLists.txt │ ├── include │ │ └── protocol │ │ │ ├── admin │ │ │ ├── generator.hpp │ │ │ ├── market_state.hpp │ │ │ └── trading_phase.hpp │ │ │ ├── app │ │ │ ├── business_message_reject.hpp │ │ │ ├── execution_report.hpp │ │ │ ├── instrument_state_request.hpp │ │ │ ├── market_data_reject.hpp │ │ │ ├── market_data_request.hpp │ │ │ ├── market_data_snapshot.hpp │ │ │ ├── market_data_update.hpp │ │ │ ├── order_cancellation_confirmation.hpp │ │ │ ├── order_cancellation_reject.hpp │ │ │ ├── order_cancellation_request.hpp │ │ │ ├── order_modification_confirmation.hpp │ │ │ ├── order_modification_reject.hpp │ │ │ ├── order_modification_request.hpp │ │ │ ├── order_placement_confirmation.hpp │ │ │ ├── order_placement_reject.hpp │ │ │ ├── order_placement_request.hpp │ │ │ ├── security_status.hpp │ │ │ ├── security_status_request.hpp │ │ │ └── session_terminated_event.hpp │ │ │ └── types │ │ │ ├── json │ │ │ └── session.hpp │ │ │ └── session.hpp │ ├── src │ │ ├── admin.cpp │ │ ├── app.cpp │ │ └── types.cpp │ └── tests │ │ ├── CMakeLists.txt │ │ ├── test_main.cpp │ │ └── unit_tests │ │ └── types │ │ └── session_tests.cpp └── trading_system │ ├── CMakeLists.txt │ ├── components │ ├── common │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── common │ │ │ │ ├── attributes.hpp │ │ │ │ ├── events.hpp │ │ │ │ ├── instrument.hpp │ │ │ │ ├── json │ │ │ │ ├── instrument.hpp │ │ │ │ └── trade.hpp │ │ │ │ ├── market_state │ │ │ │ ├── json │ │ │ │ │ ├── instrument_info.hpp │ │ │ │ │ ├── instrument_state.hpp │ │ │ │ │ ├── limit_order.hpp │ │ │ │ │ ├── order_book.hpp │ │ │ │ │ ├── session.hpp │ │ │ │ │ └── snapshot.hpp │ │ │ │ └── snapshot.hpp │ │ │ │ ├── phase.hpp │ │ │ │ ├── trade.hpp │ │ │ │ └── trading_engine.hpp │ │ ├── src │ │ │ ├── attributes.cpp │ │ │ ├── instrument.cpp │ │ │ ├── phase.cpp │ │ │ ├── snapshot.cpp │ │ │ └── trade.cpp │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── test_main.cpp │ │ │ ├── test_utils │ │ │ └── matchers.hpp │ │ │ └── unit_tests │ │ │ ├── events_tests.cpp │ │ │ ├── instrument_test.cpp │ │ │ ├── market_state │ │ │ ├── instrument_info_tests.cpp │ │ │ ├── instrument_state_tests.cpp │ │ │ ├── limit_order_tests.cpp │ │ │ ├── order_book_tests.cpp │ │ │ ├── session_tests.cpp │ │ │ ├── session_type_tests.cpp │ │ │ └── snapshot_tests.cpp │ │ │ ├── phase_test.cpp │ │ │ └── trade_tests.cpp │ ├── idgen │ │ ├── CMakeLists.txt │ │ ├── benchmarks │ │ │ ├── CMakeLists.txt │ │ │ └── idgen_benchmarks.cpp │ │ ├── ih │ │ │ ├── contexts │ │ │ │ ├── execution_id_context.hpp │ │ │ │ ├── instrument_id_context.hpp │ │ │ │ ├── market_entry_id_context.hpp │ │ │ │ └── order_id_context.hpp │ │ │ ├── generation.hpp │ │ │ └── sequences │ │ │ │ ├── chrono_sequence.hpp │ │ │ │ ├── common.hpp │ │ │ │ └── numeric_sequence.hpp │ │ ├── include │ │ │ └── idgen │ │ │ │ ├── errors.hpp │ │ │ │ ├── execution_id.hpp │ │ │ │ ├── instrument_id.hpp │ │ │ │ ├── market_entry_id.hpp │ │ │ │ └── order_id.hpp │ │ ├── src │ │ │ ├── contexts │ │ │ │ ├── execution_id_context.cpp │ │ │ │ ├── instrument_id_context.cpp │ │ │ │ ├── market_entry_id_context.cpp │ │ │ │ └── order_id_context.cpp │ │ │ ├── generation.cpp │ │ │ └── idgen.cpp │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── api_tests │ │ │ └── api_test.cpp │ │ │ ├── test_main.cpp │ │ │ └── unit_tests │ │ │ ├── generation │ │ │ ├── execution_id_generation_tests.cpp │ │ │ ├── instrument_id_generation_tests.cpp │ │ │ ├── market_entry_id_generation_tests.cpp │ │ │ └── order_id_generation_tests.cpp │ │ │ └── sequences │ │ │ ├── chrono_sequence_tests.cpp │ │ │ └── numeric_sequence_tests.cpp │ ├── ies │ │ ├── CMakeLists.txt │ │ ├── ih │ │ │ ├── controller_impl.hpp │ │ │ ├── phases │ │ │ │ ├── phase_scheduler.hpp │ │ │ │ └── states.hpp │ │ │ ├── system_tick_controller.hpp │ │ │ ├── tick_event_factory.hpp │ │ │ └── trading_phase_controller.hpp │ │ ├── include │ │ │ └── ies │ │ │ │ ├── controller.hpp │ │ │ │ ├── phase_record.hpp │ │ │ │ └── phase_schedule.hpp │ │ ├── src │ │ │ ├── controller.cpp │ │ │ ├── phase_schedule.cpp │ │ │ ├── phases │ │ │ │ └── states.cpp │ │ │ └── trading_phase_controller.cpp │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── test_main.cpp │ │ │ └── unit_tests │ │ │ ├── phase_schedule_test.cpp │ │ │ ├── phases │ │ │ ├── phase_scheduler_test.cpp │ │ │ └── states_test.cpp │ │ │ ├── tick_event_factory_test.cpp │ │ │ └── trading_phase_controller_test.cpp │ ├── instruments │ │ ├── CMakeLists.txt │ │ ├── ih │ │ │ ├── instruments_cache.hpp │ │ │ ├── instruments_container.hpp │ │ │ ├── instruments_matcher.hpp │ │ │ └── lookup │ │ │ │ ├── currency_category.hpp │ │ │ │ ├── lookup.hpp │ │ │ │ ├── match_rate.hpp │ │ │ │ ├── matchers.hpp │ │ │ │ └── strategies.hpp │ │ ├── include │ │ │ └── instruments │ │ │ │ ├── cache.hpp │ │ │ │ ├── lookup_error.hpp │ │ │ │ ├── matcher.hpp │ │ │ │ ├── sources.hpp │ │ │ │ └── view.hpp │ │ ├── src │ │ │ ├── instruments.cpp │ │ │ ├── instruments_cache.cpp │ │ │ ├── instruments_matcher.cpp │ │ │ ├── lookup │ │ │ │ ├── lookup.cpp │ │ │ │ ├── matchers.cpp │ │ │ │ └── strategies.cpp │ │ │ └── sources.cpp │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── api_tests │ │ │ ├── cache_tests.cpp │ │ │ └── matcher_tests.cpp │ │ │ ├── test_main.cpp │ │ │ ├── test_utils │ │ │ └── utils.hpp │ │ │ └── unit_tests │ │ │ ├── currency_category_tests.cpp │ │ │ ├── instruments_cache_test.cpp │ │ │ ├── instruments_container_test.cpp │ │ │ ├── instruments_matcher_tests.cpp │ │ │ ├── lookup_tests.cpp │ │ │ ├── match_rate_tests.cpp │ │ │ ├── matchers_tests.cpp │ │ │ ├── sources_test.cpp │ │ │ └── strategies_tests.cpp │ ├── matching_engine │ │ ├── CMakeLists.txt │ │ ├── ih │ │ │ ├── commands │ │ │ │ ├── client_notification_cache.hpp │ │ │ │ └── commands.hpp │ │ │ ├── common │ │ │ │ ├── abstractions │ │ │ │ │ ├── event_listener.hpp │ │ │ │ │ ├── market_data_publisher.hpp │ │ │ │ │ ├── market_data_request_processor.hpp │ │ │ │ │ ├── order_event_handler.hpp │ │ │ │ │ └── order_request_processor.hpp │ │ │ │ ├── data │ │ │ │ │ └── market_data_updates.hpp │ │ │ │ ├── events │ │ │ │ │ ├── client_notification.hpp │ │ │ │ │ ├── event.hpp │ │ │ │ │ ├── event_reporter.hpp │ │ │ │ │ └── order_book_notification.hpp │ │ │ │ └── validation │ │ │ │ │ ├── checker_utils.hpp │ │ │ │ │ ├── conclusion.hpp │ │ │ │ │ └── validation.hpp │ │ │ ├── dispatching │ │ │ │ └── event_dispatcher.hpp │ │ │ ├── implementation.hpp │ │ │ ├── market_data │ │ │ │ ├── actions │ │ │ │ │ └── market_data_recover.hpp │ │ │ │ ├── cache │ │ │ │ │ ├── cache_manager.hpp │ │ │ │ │ ├── depth_cache.hpp │ │ │ │ │ ├── instrument_info_cache.hpp │ │ │ │ │ ├── market_data_provider.hpp │ │ │ │ │ └── trade_cache.hpp │ │ │ │ ├── depth │ │ │ │ │ ├── depth_level.hpp │ │ │ │ │ ├── depth_node.hpp │ │ │ │ │ ├── depth_node_comparator.hpp │ │ │ │ │ ├── depth_quantity_list.hpp │ │ │ │ │ ├── depth_record.hpp │ │ │ │ │ ├── depth_sheet.hpp │ │ │ │ │ ├── depth_stats_reader.hpp │ │ │ │ │ ├── full_depth_update.hpp │ │ │ │ │ └── incremental_depth_update.hpp │ │ │ │ ├── market_data_facade.hpp │ │ │ │ ├── streaming_settings.hpp │ │ │ │ ├── subscriptions │ │ │ │ │ ├── subscription.hpp │ │ │ │ │ └── subscription_manager.hpp │ │ │ │ ├── tools │ │ │ │ │ ├── algorithms.hpp │ │ │ │ │ ├── instrument_px.hpp │ │ │ │ │ ├── market_entry_id_generator.hpp │ │ │ │ │ └── notification_creators.hpp │ │ │ │ └── validation │ │ │ │ │ ├── checkers.hpp │ │ │ │ │ ├── errors.hpp │ │ │ │ │ ├── market_data_validator.hpp │ │ │ │ │ └── validator.hpp │ │ │ └── orders │ │ │ │ ├── actions │ │ │ │ ├── cancellation.hpp │ │ │ │ ├── elimination.hpp │ │ │ │ ├── limit_order_recover.hpp │ │ │ │ ├── order_action_handler.hpp │ │ │ │ ├── regular_amendment.hpp │ │ │ │ ├── regular_order_action_processor.hpp │ │ │ │ └── regular_placement.hpp │ │ │ │ ├── book │ │ │ │ ├── limit_order.hpp │ │ │ │ ├── market_order.hpp │ │ │ │ ├── order_algorithms.hpp │ │ │ │ ├── order_book.hpp │ │ │ │ ├── order_metadata.hpp │ │ │ │ └── order_updates.hpp │ │ │ │ ├── matchers │ │ │ │ ├── order_matcher.hpp │ │ │ │ └── regular_order_matcher.hpp │ │ │ │ ├── order_system_facade.hpp │ │ │ │ ├── phase_handler.hpp │ │ │ │ ├── replies │ │ │ │ ├── cancellation_reply_builders.hpp │ │ │ │ ├── client_reject_reporter.hpp │ │ │ │ ├── execution_reply_builders.hpp │ │ │ │ ├── modification_reply_builders.hpp │ │ │ │ ├── placement_reply_builders.hpp │ │ │ │ └── reject_notifier.hpp │ │ │ │ ├── requests │ │ │ │ └── interpretation.hpp │ │ │ │ ├── tools │ │ │ │ ├── exec_id_generator.hpp │ │ │ │ ├── id_conversion.hpp │ │ │ │ ├── notification_creators.hpp │ │ │ │ ├── order_book_state_converter.hpp │ │ │ │ ├── order_id_generator.hpp │ │ │ │ └── order_lookup.hpp │ │ │ │ └── validation │ │ │ │ ├── checkers.hpp │ │ │ │ ├── client_request_validator.hpp │ │ │ │ ├── errors.hpp │ │ │ │ ├── order_book_side.hpp │ │ │ │ └── validator.hpp │ │ ├── include │ │ │ └── matching_engine │ │ │ │ ├── configuration.hpp │ │ │ │ └── matching_engine.hpp │ │ ├── src │ │ │ ├── commands │ │ │ │ ├── client_notification_cache.cpp │ │ │ │ └── commands.cpp │ │ │ ├── dispatching │ │ │ │ └── event_dispatcher.cpp │ │ │ ├── implementation.cpp │ │ │ ├── market_data │ │ │ │ ├── actions │ │ │ │ │ └── market_data_recover.cpp │ │ │ │ ├── cache │ │ │ │ │ ├── cache_manager.cpp │ │ │ │ │ ├── depth_cache.cpp │ │ │ │ │ ├── instrument_info_cache.cpp │ │ │ │ │ └── trade_cache.cpp │ │ │ │ ├── depth │ │ │ │ │ ├── depth_node.cpp │ │ │ │ │ ├── depth_quantity_list.cpp │ │ │ │ │ ├── depth_sheet.cpp │ │ │ │ │ ├── full_depth_update.cpp │ │ │ │ │ └── incremental_depth_update.cpp │ │ │ │ ├── market_data_facade.cpp │ │ │ │ ├── subscriptions │ │ │ │ │ ├── subscription.cpp │ │ │ │ │ └── subscription_manager.cpp │ │ │ │ ├── tools │ │ │ │ │ └── market_entry_id_generator.cpp │ │ │ │ └── validation │ │ │ │ │ ├── checkers.cpp │ │ │ │ │ └── market_data_validator.cpp │ │ │ ├── matching_engine.cpp │ │ │ └── orders │ │ │ │ ├── actions │ │ │ │ ├── cancellation.cpp │ │ │ │ ├── elimination.cpp │ │ │ │ ├── limit_order_recover.cpp │ │ │ │ ├── regular_amendment.cpp │ │ │ │ ├── regular_order_action_processor.cpp │ │ │ │ └── regular_placement.cpp │ │ │ │ ├── book │ │ │ │ ├── order_book.cpp │ │ │ │ └── orders.cpp │ │ │ │ ├── matchers │ │ │ │ └── regular_order_matcher.cpp │ │ │ │ ├── order_system_facade.cpp │ │ │ │ ├── phase_handler.cpp │ │ │ │ ├── replies │ │ │ │ ├── client_reject_reporter.cpp │ │ │ │ └── reply_builders.cpp │ │ │ │ ├── requests │ │ │ │ └── interpretation.cpp │ │ │ │ ├── tools │ │ │ │ ├── exec_id_generator.cpp │ │ │ │ ├── id_conversion.cpp │ │ │ │ ├── notification_creators.cpp │ │ │ │ ├── order_book_state_converter.cpp │ │ │ │ ├── order_id_generator.cpp │ │ │ │ └── order_lookup.cpp │ │ │ │ └── validation │ │ │ │ ├── checkers.cpp │ │ │ │ └── client_request_validator.cpp │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── actions │ │ │ └── save_copy_constructible.hpp │ │ │ ├── mocks │ │ │ ├── event_listener_mock.hpp │ │ │ ├── market_data_publisher_mock.hpp │ │ │ ├── mock_client_notification_listener.hpp │ │ │ ├── mock_execution_reports_listener.hpp │ │ │ ├── mock_market_entry_id_generator.hpp │ │ │ ├── mock_order_id_generator.hpp │ │ │ ├── mocks.cpp │ │ │ ├── order_event_handler_mock.hpp │ │ │ └── trading_reply_receiver_mock.hpp │ │ │ ├── test_main.cpp │ │ │ ├── tools │ │ │ ├── fake_depth_node.hpp │ │ │ ├── matchers.hpp │ │ │ ├── order_book_notification_builder.hpp │ │ │ ├── order_test_tools.hpp │ │ │ ├── protocol_test_tools.hpp │ │ │ └── tools.cpp │ │ │ └── unit_tests │ │ │ ├── commands │ │ │ ├── phase_transition_command_tests.cpp │ │ │ └── tick_command_tests.cpp │ │ │ ├── common │ │ │ ├── data │ │ │ │ └── market_data_updates_tests.cpp │ │ │ └── validation │ │ │ │ ├── checker_utils_tests.cpp │ │ │ │ ├── conclusion_tests.cpp │ │ │ │ └── validation_tests.cpp │ │ │ ├── dispatching │ │ │ └── event_dispatcher_tests.cpp │ │ │ ├── market_data │ │ │ ├── actions │ │ │ │ └── market_data_recover_tests.cpp │ │ │ ├── depth_cache_tests.cpp │ │ │ ├── depth_node_comparator_tests.cpp │ │ │ ├── depth_node_tests.cpp │ │ │ ├── depth_quantity_list_tests.cpp │ │ │ ├── depth_sheet_tests.cpp │ │ │ ├── depth_stats_reader_tests.cpp │ │ │ ├── full_depth_update_tests.cpp │ │ │ ├── incremental_depth_update.cpp │ │ │ ├── instrument_info_cache_tests.cpp │ │ │ ├── instrument_px_tests.cpp │ │ │ ├── streaming_settings_tests.cpp │ │ │ ├── trade_cache_tests.cpp │ │ │ └── validation │ │ │ │ ├── checkers_tests.cpp │ │ │ │ ├── errors_tests.cpp │ │ │ │ └── market_data_validator_tests.cpp │ │ │ └── orders │ │ │ ├── actions │ │ │ ├── all_orders_elimination_tests.cpp │ │ │ ├── limit_order_recover_tests.cpp │ │ │ └── system_elimination_tests.cpp │ │ │ ├── book │ │ │ ├── better_order_comparator_tests.cpp │ │ │ ├── limit_order_tests.cpp │ │ │ ├── market_order_tests.cpp │ │ │ ├── order_algorithms_tests.cpp │ │ │ └── order_book_tests.cpp │ │ │ ├── matchers │ │ │ └── regular_order_matcher_tests.cpp │ │ │ ├── replies │ │ │ ├── cancellation_reply_builders_tests.cpp │ │ │ ├── client_reject_reporter_tests.cpp │ │ │ ├── execution_reply_builders_tests.cpp │ │ │ ├── modification_reply_builders_tests.cpp │ │ │ └── placement_reply_builders_tests.cpp │ │ │ ├── requests │ │ │ └── interpretation_tests.cpp │ │ │ ├── tools │ │ │ ├── notification_creators_tests.cpp │ │ │ └── order_book_state_converter_tests.cpp │ │ │ └── validation │ │ │ ├── checkers_tests.cpp │ │ │ ├── client_request_validator_tests.cpp │ │ │ └── errors_tests.cpp │ └── runtime │ │ ├── CMakeLists.txt │ │ ├── ih │ │ ├── chained_mux.hpp │ │ ├── loop_impl.hpp │ │ ├── mux_impl.hpp │ │ ├── one_second_rate_loop.hpp │ │ ├── simple_thread_pool.hpp │ │ └── thread_pool_impl.hpp │ │ ├── include │ │ └── runtime │ │ │ ├── loop.hpp │ │ │ ├── mux.hpp │ │ │ ├── service.hpp │ │ │ └── thread_pool.hpp │ │ ├── src │ │ ├── chained_mux.cpp │ │ ├── one_second_rate_loop.cpp │ │ ├── runtime.cpp │ │ └── simple_thread_pool.cpp │ │ └── tests │ │ ├── CMakeLists.txt │ │ ├── test_main.cpp │ │ └── unit_tests │ │ ├── chained_mux_test.cpp │ │ ├── one_second_rate_loop_test.cpp │ │ └── simple_thread_pool_test.cpp │ ├── ih │ ├── config │ │ ├── config.hpp │ │ ├── phase_entry_reader.hpp │ │ └── venue_entry_reader.hpp │ ├── execution │ │ ├── execution_system.hpp │ │ └── reject_notifier.hpp │ ├── repository │ │ ├── repository_accessor.hpp │ │ └── trading_engines_repository.hpp │ ├── state_persistence │ │ ├── market_state_persistence_controller.hpp │ │ └── serializer.hpp │ ├── tools │ │ ├── instrument_resolver.hpp │ │ ├── loaders.hpp │ │ └── trading_engine_factory.hpp │ ├── trading_system.hpp │ └── trading_system_facade.hpp │ ├── include │ └── trading_system │ │ └── trading_system.hpp │ ├── src │ ├── config.cpp │ ├── execution │ │ ├── execution_system.cpp │ │ └── reject_notifier.cpp │ ├── repository │ │ ├── repository_accessor.cpp │ │ └── trading_engines_repository.cpp │ ├── state_persistence │ │ ├── market_state_persistence_controller.cpp │ │ └── serializer.cpp │ ├── tools │ │ ├── instrument_resolver.cpp │ │ ├── loaders.cpp │ │ └── trading_engine_factory.cpp │ ├── trading_system.cpp │ └── trading_system_facade.cpp │ └── tests │ ├── CMakeLists.txt │ ├── mocks │ ├── executor_mock.hpp │ ├── instrument_resolver_mock.hpp │ ├── repository_accessor_mock.hpp │ ├── serializer_mock.hpp │ ├── trading_engine_mock.hpp │ └── trading_reply_receiver_mock.hpp │ ├── test_main.cpp │ └── unit_tests │ ├── config │ ├── phase_entry_reader_tests.cpp │ └── venue_entry_reader_tests.cpp │ ├── execution │ ├── execution_system_tests.cpp │ └── reject_notifier_tests.cpp │ ├── repository │ └── trading_engines_repository_tests.cpp │ ├── state_persistence │ ├── market_state_persistence_controller_tests.cpp │ └── serializer_tests.cpp │ └── tools │ └── instrument_resolver_tests.cpp ├── script └── entrypoint_os.sh └── template └── cfg ├── configSim.txt ├── default ├── FIX50SP2_marketsimulator.xml └── FIXT11_marketsimulator.xml └── market_simulator.xml /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | Standard: c++20 3 | BasedOnStyle: Google 4 | ColumnLimit: 80 5 | BinPackArguments: false 6 | BinPackParameters: false 7 | DerivePointerAlignment: false 8 | PointerAlignment: Left 9 | ReferenceAlignment: Left 10 | BreakAfterAttributes: Leave 11 | QualifierAlignment: Left -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: > 3 | -*, 4 | bugprone-*, 5 | cert-*, 6 | clang-analyzer-*, 7 | concurrency-*, 8 | cppcoreguidelines-*, 9 | google-*, 10 | modernize-*, 11 | performance-*, 12 | portability-*, 13 | readability-*, 14 | -modernize-use-nodiscard 15 | WarningsAsErrors: '*' 16 | FormatStyle: none 17 | -------------------------------------------------------------------------------- /.github/docker/Build_Marketsim.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rockylinux:8 2 | 3 | RUN dnf --refresh makecache 4 | 5 | RUN dnf install -y \ 6 | gcc-toolset-12 \ 7 | git \ 8 | make \ 9 | openssl-devel \ 10 | perl \ 11 | python3-pip 12 | 13 | RUN pip3 install --upgrade pip 14 | 15 | RUN pip3 install cmake==3.21 conan==1.59 gcovr 16 | 17 | # Hardcoding env variables to allow a container to use gcc 12, 18 | # located in /opt/rh/gcc-toolset-12, without additional scripting 19 | ENV PATH="/opt/rh/gcc-toolset-12/root/usr/bin:${PATH}" 20 | ENV LD_LIBRARY_PATH="/opt/rh/gcc-toolset-12/root/usr/lib64:/opt/rh/gcc-toolset-12/root/usr/lib:${LD_LIBRARY_PATH}" -------------------------------------------------------------------------------- /.github/docker/Deploy_Marketsim.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rockylinux:8 2 | 3 | RUN dnf --refresh makecache 4 | RUN dnf install -y gcc-toolset-12 5 | 6 | RUN groupadd -g 1000 quantreplay-user && \ 7 | useradd -m -u 1000 -g quantreplay-user quantreplay-user 8 | 9 | # Set environment variables 10 | ENV LOG_DIR=/market-simulator/quod/data/log 11 | ENV LD_LIBRARY_PATH="/opt/rh/gcc-toolset-12/root/usr/lib64:/opt/rh/gcc-toolset-12/root/usr/lib:${LD_LIBRARY_PATH}" 12 | 13 | RUN mkdir -p /market-simulator/quod/data/cfg 14 | RUN mkdir /template 15 | COPY template/ /template/ 16 | 17 | COPY package/quod /market-simulator/quod 18 | 19 | RUN chmod +x /market-simulator/quod/bin/marketsimulator 20 | 21 | # Remove specific files from the cfg folder 22 | RUN rm -f /market-simulator/quod/cfg/market_simulator.xml \ 23 | && rm -f /market-simulator/quod/cfg/configSim.txt 24 | 25 | COPY script/entrypoint_os.sh /entrypoint_os.sh 26 | RUN chmod +x /entrypoint_os.sh 27 | 28 | RUN chown -R quantreplay-user:quantreplay-user /market-simulator /entrypoint_os.sh 29 | 30 | USER quantreplay-user 31 | 32 | WORKDIR /market-simulator/quod 33 | 34 | ENTRYPOINT ["/entrypoint_os.sh"] 35 | -------------------------------------------------------------------------------- /.github/docker/Postgres_Marketsim.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:13.4 2 | 3 | COPY init.sql /docker-entrypoint-initdb.d/init.sql -------------------------------------------------------------------------------- /.github/docker/init.sql: -------------------------------------------------------------------------------- 1 | CREATE USER sim WITH PASSWORD 'sim' NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN; 2 | CREATE SCHEMA AUTHORIZATION sim; 3 | REVOKE USAGE ON SCHEMA public FROM sim; -------------------------------------------------------------------------------- /.github/docker/liquibase_custom.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM liquibase/liquibase 2 | 3 | COPY db /liquibase/project/ 4 | 5 | ENV SIMULATOR_DATABASE_HOST="market-simulator-database" 6 | ENV SIMULATOR_DATABASE_PORT="5432" 7 | ENV SIMULATOR_DATABASE_DBNAME="simdb" 8 | ENV SIMULATOR_DATABASE_APP_USER="sim" 9 | ENV SIMULATOR_DATABASE_APP_PASSWORD="sim" 10 | ENV SIMULATOR_LIQUIBASE_CONTEXT="market-simulator,schema,demo" 11 | ENV CHANGELOG_FILE="root-changelog.yml" 12 | 13 | ENTRYPOINT sh -c "liquibase \ 14 | --url=jdbc:postgresql://${SIMULATOR_DATABASE_HOST}:${SIMULATOR_DATABASE_PORT}/${SIMULATOR_DATABASE_DBNAME} \ 15 | --username=${SIMULATOR_DATABASE_APP_USER} \ 16 | --password=${SIMULATOR_DATABASE_APP_PASSWORD} \ 17 | --classpath=/liquibase/project \ 18 | --changelog-file=${CHANGELOG_FILE} \ 19 | --contexts=${SIMULATOR_LIQUIBASE_CONTEXT} \ 20 | update" 21 | 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all directories, and all sub-directories, and it's contents: 2 | 3 | */* 4 | # Now ignore all files in the current directory. This fails to ignore files without a ".". 5 | # For example 'file.txt' works, but 'file' doesn't. 6 | 7 | *.* 8 | 9 | # But don't ignore these specific directories and subdirectories: 10 | 11 | !/conan 12 | !/hooks 13 | !/script 14 | !/test 15 | 16 | # But don't ignore these specific files: 17 | 18 | !CMakeLists.txt 19 | !CMakePresets.json 20 | !README.md 21 | 22 | !**.adoc 23 | !**.bat 24 | !**.cmake 25 | !**.cpp 26 | !**.Dockerfile 27 | !**.err 28 | !**.hpp 29 | !**.html 30 | !**.ico 31 | !**.json 32 | !**.odt 33 | !**.pdf 34 | !**.png 35 | !**.properties 36 | !**.py 37 | !**.sh 38 | !**.sky 39 | !**.txt 40 | !**.xml 41 | !**.yml 42 | !**.yml.example 43 | 44 | # ...even if they are in subdirectories 45 | !*/ 46 | 47 | # But make git ignore all cmake dev build directories, 48 | cmake-build-*/ 49 | 50 | # cmake dev install directories, 51 | cmake-install-*/ 52 | 53 | # and local development environment 54 | devenv/* 55 | 56 | # Ignore PySys output files 57 | **/Output/** 58 | .idea/* 59 | 60 | # Ignore Python virtual environment 61 | env/* 62 | -------------------------------------------------------------------------------- /cfg/configSim.txt: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | ConnectionType=acceptor 3 | SocketAcceptPort=9001 4 | SocketReuseAddress=Y 5 | SocketNodelay=Y 6 | AppDataDictionary=FIX50SP2_marketsimulator.xml 7 | TransportDataDictionary=FIXT11_marketsimulator.xml 8 | StartTime=00:00:00 9 | EndTime=00:00:00 10 | TimestampPrecision=6 11 | HeartBtInt=30 12 | 13 | [SESSION] 14 | BeginString=FIXT.1.1 15 | SenderCompID=MktSimulator 16 | TargetCompID=MyGateway 17 | DefaultApplVerID=9 18 | PersistMessages=Y 19 | FileStorePath=quickfix_MktSimulator_MyGateway 20 | ResetOnLogon=N 21 | RefreshOnLogon=Y 22 | 23 | [SESSION] 24 | BeginString=FIXT.1.1 25 | SenderCompID=MktSimulator 26 | TargetCompID=MyFeedhandler 27 | DefaultApplVerID=9 28 | PersistMessages=N 29 | FileStorePath=quickfix_MktSimulator_MyFeedhandler 30 | ResetOnLogon=Y 31 | RefreshOnLogon=N 32 | -------------------------------------------------------------------------------- /cmake/CheckDependencyExist.cmake: -------------------------------------------------------------------------------- 1 | function(ensure_dependency_target_exist TARGET_NAME DEPENDENT_NAME) 2 | if(NOT TARGET ${TARGET_NAME}) 3 | string(CONCAT ERROR_MESSAGE 4 | "Failed to configure ${DEPENDENT_NAME}, " 5 | "required dependency target ${TARGET_NAME} does not exits") 6 | message(FATAL_ERROR ${ERROR_MESSAGE}) 7 | else() 8 | message(DEBUG "Found ${DEPENDENT_NAME} dependency - ${TARGET_NAME}") 9 | endif() 10 | endfunction() 11 | 12 | macro(ensure_project_dependency_exist TARGET_NAME) 13 | ensure_dependency_target_exist(${TARGET_NAME} ${PROJECT_NAME}) 14 | endmacro() -------------------------------------------------------------------------------- /cmake/build/PreventInSourceBuilds.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # This function will prevent in-source builds 3 | function(AssureOutOfSourceBuilds) 4 | # make sure the user doesn't play dirty with symlinks 5 | get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) 6 | get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) 7 | 8 | # disallow in-source builds 9 | if("${srcdir}" STREQUAL "${bindir}") 10 | message("######################################################") 11 | message("Warning: in-source builds are disabled") 12 | message("Please create a separate build directory and run cmake from there") 13 | message("######################################################") 14 | message(FATAL_ERROR "Quitting configuration") 15 | endif() 16 | endfunction() 17 | 18 | assureoutofsourcebuilds() 19 | -------------------------------------------------------------------------------- /cmake/utils/Git.cmake: -------------------------------------------------------------------------------- 1 | find_package(Git QUIET) 2 | 3 | 4 | macro(call_git) 5 | set(single_value_args OUT) 6 | set(multi_value_args ARGS) 7 | cmake_parse_arguments(git "" "${single_value_args}" "${multi_value_args}" ${ARGN}) 8 | 9 | if (NOT Git_FOUND) 10 | message(FATAL_ERROR "Can not call git: git executable was not found") 11 | endif () 12 | 13 | execute_process( 14 | COMMAND ${GIT_EXECUTABLE} ${git_ARGS} 15 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 16 | RESULT_VARIABLE GIT_CALL_CODE 17 | OUTPUT_VARIABLE GIT_CALL_OUTPUT 18 | OUTPUT_STRIP_TRAILING_WHITESPACE 19 | ) 20 | 21 | string(REPLACE ";" " " GIT_ARGS "${git_ARGS}") 22 | if (${GIT_CALL_CODE} EQUAL "0") 23 | set(${git_OUT} ${GIT_CALL_OUTPUT}) 24 | message(DEBUG "\"${GIT_EXECUTABLE} ${GIT_ARGS}\" exited with code ${GIT_CALL_CODE}") 25 | else () 26 | message(FATAL_ERROR 27 | "\"${GIT_EXECUTABLE} ${GIT_ARGS}\" exited with code ${GIT_CALL_CODE}") 28 | endif () 29 | endmacro() 30 | -------------------------------------------------------------------------------- /cmake/utils/TimeTrace.cmake: -------------------------------------------------------------------------------- 1 | if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 2 | option(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF) 3 | endif() 4 | 5 | function(enable_time_trace project_name) 6 | 7 | if(ENABLE_BUILD_WITH_TIME_TRACE) 8 | add_compile_definitions(${project_name} INTERFACE -ftime-trace) 9 | endif() 10 | 11 | endfunction() 12 | -------------------------------------------------------------------------------- /db/external-price-seed/root-changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - context: external-price-seed 3 | - include: 4 | file: schema/changelog.yml 5 | relativeToChangelogFile: true -------------------------------------------------------------------------------- /db/external-price-seed/schema/changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | file: tables/price_seed.yml 4 | relativeToChangelogFile: true -------------------------------------------------------------------------------- /db/market-simulator/root-changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - context: market-simulator 3 | - include: 4 | file: schema/changelog.yml 5 | relativeToChangelogFile: true 6 | - include: 7 | file: sample-data/changelog.yml 8 | relativeToChangelogFile: true -------------------------------------------------------------------------------- /db/market-simulator/sample-data/changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | context: "schema" 4 | file: common/changelog.yml 5 | relativeToChangelogFile: true 6 | - include: 7 | context: "schema AND demo" 8 | file: demo/changelog.yml 9 | relativeToChangelogFile: true 10 | -------------------------------------------------------------------------------- /db/market-simulator/sample-data/common/changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | file: setting.yml 4 | relativeToChangelogFile: true -------------------------------------------------------------------------------- /db/market-simulator/sample-data/demo/xetra/changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | file: venue.yml 4 | relativeToChangelogFile: true 5 | - includeAll: 6 | path: listings/ 7 | relativeToChangelogFile: true 8 | - includeAll: 9 | path: price_seeds/ 10 | relativeToChangelogFile: true 11 | - includeAll: 12 | path: setting/ 13 | relativeToChangelogFile: true -------------------------------------------------------------------------------- /db/market-simulator/schema/constraints/market_phase.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_constraint_market_phase_1 5 | labels: schema,v4 6 | comment: Add NOT NULL constraint market_phase_phase_idx on market_phase.phase 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: market_phase 11 | - columnExists: 12 | tableName: market_phase 13 | columnName: phase 14 | changes: 15 | - addNotNullConstraint: 16 | constraintName: market_phase_phase_idx 17 | tableName: market_phase 18 | columnName: phase 19 | validate: true -------------------------------------------------------------------------------- /db/market-simulator/schema/keys/price_seed.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_key_price_seed_1 5 | labels: schema,v4 6 | comment: Add price_seed_pkey (price_seed_id) for price_seed table 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: price_seed 11 | - columnExists: 12 | tableName: price_seed 13 | columnName: price_seed_id 14 | - not: 15 | - primaryKeyExists: 16 | tableName: price_seed 17 | primaryKeyName: price_seed_pkey 18 | changes: 19 | - addPrimaryKey: 20 | constraintName: price_seed_pkey 21 | tableName: price_seed 22 | columnNames: price_seed_id 23 | validate: true -------------------------------------------------------------------------------- /db/market-simulator/schema/keys/setting.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_key_setting_1 5 | labels: schema,v4 6 | comment: Add setting_pkey (key) for setting table 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: setting 11 | - columnExists: 12 | tableName: setting 13 | columnName: key 14 | - not: 15 | - primaryKeyExists: 16 | tableName: setting 17 | primaryKeyName: setting_pkey 18 | changes: 19 | - addPrimaryKey: 20 | constraintName: setting_pkey 21 | tableName: setting 22 | columnNames: key 23 | validate: true -------------------------------------------------------------------------------- /db/market-simulator/schema/keys/venue.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_key_venue_1 5 | labels: schema,v4 6 | comment: Add venue_pkey (venue_id) for venue table 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: venue 11 | - columnExists: 12 | tableName: venue 13 | columnName: venue_id 14 | - not: 15 | - primaryKeyExists: 16 | tableName: venue 17 | primaryKeyName: venue_pkey 18 | changes: 19 | - addPrimaryKey: 20 | tableName: venue 21 | columnNames: venue_id 22 | constraintName: venue_pkey 23 | validate: true -------------------------------------------------------------------------------- /db/market-simulator/schema/sequences/data_source.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_sequence_data_source_1 5 | labels: schema,v4 6 | comment: Add auto-increment sequence for data_source.data_source_id column 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: data_source 11 | - columnExists: 12 | tableName: data_source 13 | columnName: data_source_id 14 | changes: 15 | - addAutoIncrement: 16 | tableName: data_source 17 | columnName: data_source_id 18 | columnDataType: int 19 | startWith: 1 20 | incrementBy: 1 21 | generationType: BY DEFAULT -------------------------------------------------------------------------------- /db/market-simulator/schema/sequences/listing.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_sequence_listing_1 5 | labels: schema,v4 6 | comment: Add auto-increment sequence for listing.listing_id column 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: listing 11 | - columnExists: 12 | tableName: listing 13 | columnName: listing_id 14 | changes: 15 | - addAutoIncrement: 16 | tableName: listing 17 | columnName: listing_id 18 | columnDataType: int 19 | startWith: 1 20 | incrementBy: 1 21 | generationType: BY DEFAULT -------------------------------------------------------------------------------- /db/market-simulator/schema/sequences/price_seed.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_sequence_price_seed_1 5 | labels: schema,v4 6 | comment: Add auto-increment sequence for price_seed.price_seed_id column 7 | preConditions: 8 | - onFail: MARK_RAN 9 | - tableExists: 10 | tableName: price_seed 11 | - columnExists: 12 | tableName: price_seed 13 | columnName: price_seed_id 14 | changes: 15 | - addAutoIncrement: 16 | tableName: price_seed 17 | columnName: price_seed_id 18 | columnDataType: int 19 | startWith: 1 20 | incrementBy: 1 21 | generationType: BY DEFAULT -------------------------------------------------------------------------------- /db/market-simulator/schema/tables/setting.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | author: avovchen 4 | id: market_simulator_schema_table_listing_1 5 | labels: schema,v4 6 | comment: Create listing table 7 | preConditions: 8 | - not: 9 | - tableExists: 10 | tableName: setting 11 | changes: 12 | - createTable: 13 | tableName: setting 14 | columns: 15 | - column: 16 | name: key 17 | type: text 18 | - column: 19 | name: value 20 | type: text -------------------------------------------------------------------------------- /db/root-changelog.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | file: market-simulator/root-changelog.yml 4 | relativeToChangelogFile: true 5 | - include: 6 | file: external-price-seed/root-changelog.yml 7 | relativeToChangelogFile: true 8 | -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/FIXRulesOfEngagement.adoc: -------------------------------------------------------------------------------- 1 | :maintitle: FIX Rules of Engagement 2 | include::../common/adoc/titleblock.adoc[] 3 | :docinfo: shared 4 | :docinfodir: ../common/adoc 5 | :toc: left 6 | :toclevels: 4 7 | :table-stripes: even 8 | :front-cover-image: Introduction/Cover.pdf 9 | 10 | ifndef::imagesDir[] 11 | :imagesDir: images 12 | endif::[] 13 | 14 | include::../common/adoc/header.adoc[] 15 | 16 | <<< 17 | 18 | include::Introduction/Introduction.adoc[] 19 | 20 | <<< 21 | 22 | include::CommonComponents/CommonComponents.adoc[] 23 | 24 | <<< 25 | 26 | include::AdminMessages/AdminMessages.adoc[] 27 | 28 | 29 | <<< 30 | 31 | include::PreTradeMessages/PreTradeMessages.adoc[] 32 | 33 | <<< 34 | 35 | include::TradeMessages/TradeMessages.adoc[] 36 | 37 | <<< 38 | 39 | include::PhaseReportingMessages/PhaseReportingMessages.adoc[] 40 | 41 | <<< 42 | 43 | include::MessageFlows/MessageFlows.adoc[] 44 | 45 | <<< 46 | 47 | -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/Introduction/Cover.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/Introduction/Cover.odt -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/Introduction/Cover.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/Introduction/Cover.pdf -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/build.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | echo Generate Documentation... 4 | if not exist "output" mkdir "output" 5 | del "output\*.html" >nul 2>&1 6 | 7 | call asciidoctor "FIXRulesOfEngagement.adoc" -a imagesDir="../images" -D "output" 8 | echo HTML Done 9 | 10 | call asciidoctor-pdf -a allow-uri-read -a pdf-theme="../common/pdf/PDFTheme.yml" "FIXRulesOfEngagement.adoc" -D "output" 11 | echo PDF Done 12 | 13 | IF %0 == "%~0" pause 14 | -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo Generate Documentation... 4 | if [ ! -d "output" ]; then 5 | mkdir "output" 6 | fi 7 | rm -f output/*.html 8 | 9 | asciidoctor "FIXRulesOfEngagement.adoc" -a imagesDir="../images" -D "output" 10 | echo HTML Done 11 | 12 | asciidoctor-pdf -a allow-uri-read -a pdf-theme="../common/pdf/PDFTheme.yml" "FIXRulesOfEngagement.adoc" -D "output" 13 | echo PDF Done 14 | -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/01MktDataIncrementalMsg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/01MktDataIncrementalMsg.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/02MktDataStreamingMsg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/02MktDataStreamingMsg.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/03MktDataSnapReqRsp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/03MktDataSnapReqRsp.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/04MktDataReqRct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/04MktDataReqRct.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/05MktDataNewOrderSgl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/05MktDataNewOrderSgl.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/06MktDataNewOrderRct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/06MktDataNewOrderRct.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/07MktDataExeRpt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/07MktDataExeRpt.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/08MktDataCancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/08MktDataCancel.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/09MktDataPartialCancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/09MktDataPartialCancel.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/10MktDataOrderReplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/10MktDataOrderReplace.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/11MktDataCancelReject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/11MktDataCancelReject.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/12MktDataCancelSuccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/12MktDataCancelSuccess.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/13MktDataCancelReplaceReject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/13MktDataCancelReplaceReject.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/14MktDataStsReport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/14MktDataStsReport.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/15MktDataStsSnapSht.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/15MktDataStsSnapSht.png -------------------------------------------------------------------------------- /docs/FIXRulesOfEngagement/images/16MktDataStsReject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/FIXRulesOfEngagement/images/16MktDataStsReject.png -------------------------------------------------------------------------------- /docs/Overview/Overview.adoc: -------------------------------------------------------------------------------- 1 | :maintitle: Documentation Overview 2 | include::../common/adoc/titleblock.adoc[] 3 | :docinfo: shared 4 | :nofooter: 5 | 6 | See below for user documentation for the {orgname} Market Simulator project at https://github.com/Quod-Financial/quantreplay 7 | 8 | == User Guides 9 | 10 | |=== 11 | 12 | | <<../FIXRulesOfEngagement/FIXRulesOfEngagement.adoc#, FIX Rules of Engagement>> | Rules of Engagement for the FIX trading API. 13 | | <<../RESTAPI/RESTAPI.adoc#, REST API User Guide>> | User guide for the REST administrative API. 14 | 15 | |=== 16 | -------------------------------------------------------------------------------- /docs/Overview/build.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | echo Generate Documentation... 4 | if not exist "output" mkdir "output" 5 | del "output\*.html" >nul 2>&1 6 | 7 | call asciidoctor "Overview.adoc" -D "output" 8 | echo HTML Done 9 | 10 | call asciidoctor-pdf -a allow-uri-read -a pdf-theme="../common/pdf/PDFTheme.yml" "Overview.adoc" -D "output" 11 | echo PDF Done 12 | 13 | IF %0 == "%~0" pause 14 | -------------------------------------------------------------------------------- /docs/Overview/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo Generate Documentation... 4 | if [ ! -d "output" ]; then 5 | mkdir "output" 6 | fi 7 | rm -f output/*.html 8 | 9 | asciidoctor "Overview.adoc" -D "output" 10 | echo HTML Done 11 | 12 | asciidoctor-pdf -a allow-uri-read -a pdf-theme="../common/pdf/PDFTheme.yml" "Overview.adoc" -D "output" 13 | echo PDF Done 14 | -------------------------------------------------------------------------------- /docs/RESTAPI/Introduction/Cover.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/RESTAPI/Introduction/Cover.odt -------------------------------------------------------------------------------- /docs/RESTAPI/Introduction/Cover.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/RESTAPI/Introduction/Cover.pdf -------------------------------------------------------------------------------- /docs/RESTAPI/Introduction/Introduction.adoc: -------------------------------------------------------------------------------- 1 | ifndef::imagesDir[] 2 | :imagesDir: images 3 | endif::[] 4 | 5 | [[introduction]] 6 | == Introduction 7 | This reference document provides details of the {orgname} Market Simulator Representational State Transfer (REST) API. 8 | 9 | [[introduction-scope]] 10 | === Scope 11 | 12 | This document provides technical-level details of using the administrative functions through the REST API of the {orgname} Market Simulator, 13 | for modifying administrative settings and sending administrative requests to market simulator instances. -------------------------------------------------------------------------------- /docs/RESTAPI/RESTAPI.adoc: -------------------------------------------------------------------------------- 1 | :maintitle: REST API 2 | include::../common/adoc/titleblock.adoc[] 3 | :docinfo: shared 4 | :docinfodir: ../common/adoc 5 | :toc: left 6 | :toclevels: 4 7 | :table-stripes: even 8 | :front-cover-image: Introduction/Cover.pdf 9 | 10 | ifndef::imagesDir[] 11 | :imagesDir: images 12 | endif::[] 13 | 14 | include::../common/adoc/header.adoc[] 15 | 16 | <<< 17 | 18 | include::Introduction/Introduction.adoc[] 19 | 20 | <<< 21 | 22 | include::General/General.adoc[] 23 | 24 | <<< 25 | 26 | include::AdministrativeSettings/AdministrativeSettings.adoc[] 27 | 28 | 29 | <<< 30 | 31 | include::AdministrativeCommands/AdministrativeCommands.adoc[] 32 | 33 | <<< 34 | 35 | 36 | -------------------------------------------------------------------------------- /docs/RESTAPI/build.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | echo Generate Documentation... 4 | if not exist "output" mkdir "output" 5 | del "output\*.html" >nul 2>&1 6 | 7 | call asciidoctor "RESTAPI.adoc" -a imagesDir="../images" -D "output" 8 | echo HTML Done 9 | 10 | call asciidoctor-pdf -a allow-uri-read -a pdf-theme="../common/pdf/PDFTheme.yml" "RESTAPI.adoc" -D "output" 11 | echo PDF Done 12 | 13 | IF %0 == "%~0" pause 14 | -------------------------------------------------------------------------------- /docs/RESTAPI/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo Generate Documentation... 4 | if [ ! -d "output" ]; then 5 | mkdir "output" 6 | fi 7 | rm -f output/*.html 8 | 9 | asciidoctor "RESTAPI.adoc" -a imagesDir="../images" -D "output" 10 | echo HTML Done 11 | 12 | asciidoctor-pdf -a allow-uri-read -a pdf-theme="../common/pdf/PDFTheme.yml" "RESTAPI.adoc" -D "output" 13 | echo PDF Done 14 | -------------------------------------------------------------------------------- /docs/RESTAPI/images/17pricebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/RESTAPI/images/17pricebook.png -------------------------------------------------------------------------------- /docs/common/adoc/docinfo-footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/common/adoc/docinfo.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/common/adoc/header.adoc: -------------------------------------------------------------------------------- 1 | ifdef::backend-html5[] 2 | [frame=none,grid=none,cols="<,>"] 3 | |=== 4 | 5 | a| ifndef::hide-overview[link:../Overview/Overview.html[[gray]#All Documents /#]] | 6 | 7 | ifndef::hide-pdf[] 8 | link:{docname}.pdf[[gray]#Download#] 9 | image:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAABbklEQVRIib3WPUscURTG8d8aBMFAKm1cQQOxthTEXgjEVoRYaZsiTap0qUzwA1hpJ66SxqwfwMJKQVIpFlskiCFb7IZYiMtazCzI7Muduys+cBgYnnP+59y5c2doVxEl1NEMRAUrHWoEVUQ1ByAbn2JBpTTxEBMB70IG9iUG1FquYg7viPbJNvOCWgmx/sfx9blATXx+LlAT758SdNwDVHlKUFajeJunTsiwg1+YDgAHBt3iB9ZiQUOBhKxOJS9qPTIv3ElGq2hgPLZO7ES/UcDryLxwJxl9kzyjn3gVU6fQwdDpPgzjCu8wj2V8xCxeoozLHHU6d/JI6zjBB3zHfeptSDbJn5x1ehqmcI3/2MKSZEPMYRfn2BgENIZt3EmWJrTb+gad4QJ/JVPlVfT2vsELLAockrEa9FDtWic70b/0mudT3k2T6bXWy3SQdlLuEzaJo7TGfi/jjP5+t7JRxZtQV0XsSUaPBdTSSdogD7GVvK6jtRJgAAAAAElFTkSuQmCC[link="{docname}.pdf"] 10 | endif::[] 11 | 12 | |=== 13 | endif::[] -------------------------------------------------------------------------------- /docs/common/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/common/favicon.ico -------------------------------------------------------------------------------- /docs/common/pdf/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/docs/common/pdf/Logo.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/image01_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/images/image01_dark.png -------------------------------------------------------------------------------- /images/image01_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/images/image01_light.png -------------------------------------------------------------------------------- /images/image02_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/images/image02_dark.png -------------------------------------------------------------------------------- /images/image02_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quod-Financial/quantreplay/0c82e58e76c5ec803bea397396f18bdf9cae9b6d/images/image02_light.png -------------------------------------------------------------------------------- /project/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(core) 2 | add_subdirectory(protocol) 3 | add_subdirectory(cfg) 4 | add_subdirectory(log) 5 | add_subdirectory(data_layer) 6 | add_subdirectory(middleware) 7 | add_subdirectory(trading_system) 8 | add_subdirectory(fix) 9 | add_subdirectory(generator) 10 | add_subdirectory(http) 11 | add_subdirectory(app) 12 | -------------------------------------------------------------------------------- /project/app/ih/application.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_APP_IH_APPLICATION_HPP_ 2 | #define SIMULATOR_APP_IH_APPLICATION_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/platforms/platform.hpp" 7 | 8 | namespace simulator { 9 | 10 | class Application { 11 | public: 12 | Application(const Application&) = delete; 13 | 14 | Application(Application&&) noexcept = default; 15 | ~Application() noexcept; 16 | 17 | auto operator=(const Application&) -> Application& = delete; 18 | auto operator=(Application&&) noexcept -> Application& = default; 19 | 20 | static auto start() -> Application; 21 | 22 | private: 23 | Application(); 24 | 25 | auto launch() -> void; 26 | 27 | auto terminate() noexcept -> void; 28 | 29 | static auto create_venue_simulation_platform() -> std::unique_ptr; 30 | 31 | std::unique_ptr platform_; 32 | }; 33 | 34 | } // namespace simulator 35 | 36 | #endif // SIMULATOR_APP_IH_APPLICATION_HPP_ -------------------------------------------------------------------------------- /project/app/ih/components/http_server.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_APP_IH_COMPONENTS_HTTP_SERVER_HPP_ 2 | #define SIMULATOR_APP_IH_COMPONENTS_HTTP_SERVER_HPP_ 3 | 4 | #include "data_layer/api/database/context.hpp" 5 | #include "http/http.hpp" 6 | 7 | namespace simulator { 8 | 9 | class HttpServer { 10 | public: 11 | explicit HttpServer(data_layer::database::Context database) 12 | : http_server_(http::create_http_server(std::move(database))) {} 13 | 14 | auto launch() -> void { http::launch_http_server(http_server_); } 15 | 16 | auto terminate() -> void { http::terminate_http_server(http_server_); } 17 | 18 | private: 19 | http::Server http_server_; 20 | }; 21 | 22 | } // namespace simulator 23 | 24 | #endif // SIMULATOR_APP_IH_COMPONENTS_HTTP_SERVER_HPP_ -------------------------------------------------------------------------------- /project/app/ih/loading.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_APP_IH_LOADING_HPP_ 2 | #define SIMULATOR_APP_IH_LOADING_HPP_ 3 | 4 | #include "cfg/api/cfg.hpp" 5 | #include "ih/command_options.hpp" 6 | 7 | namespace simulator { 8 | 9 | auto load_configuration(const simulator::CommandOptions& options) -> void; 10 | 11 | auto load_logger(const simulator::CommandOptions& options, 12 | const simulator::cfg::LogConfiguration& config) -> void; 13 | 14 | } // namespace simulator 15 | 16 | #endif // SIMULATOR_APP_IH_LOADING_HPP_ 17 | -------------------------------------------------------------------------------- /project/app/ih/loop.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_APP_LOOP_HPP_ 2 | #define SIMULATOR_APP_LOOP_HPP_ 3 | 4 | namespace simulator { 5 | 6 | struct Loop { 7 | static auto suspend_main_thread() -> void; 8 | 9 | static auto release_main_thread() -> void; 10 | }; 11 | 12 | } // namespace simulator 13 | 14 | #endif // SIMULATOR_APP_LOOP_HPP_ -------------------------------------------------------------------------------- /project/app/ih/platforms/platform.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_APP_IH_PLATFORMS_PLATFORM_HPP_ 2 | #define SIMULATOR_APP_IH_PLATFORMS_PLATFORM_HPP_ 3 | 4 | namespace simulator { 5 | 6 | struct Platform { 7 | Platform() = default; 8 | Platform(const Platform&) = default; 9 | Platform(Platform&&) noexcept = default; 10 | virtual ~Platform() = default; 11 | 12 | auto operator=(const Platform&) -> Platform& = default; 13 | auto operator=(Platform&&) noexcept -> Platform& = default; 14 | 15 | virtual auto launch() -> void = 0; 16 | 17 | virtual auto terminate() -> void = 0; 18 | }; 19 | 20 | } // namespace simulator 21 | 22 | #endif // SIMULATOR_APP_IH_PLATFORMS_PLATFORM_HPP_ -------------------------------------------------------------------------------- /project/app/ih/platforms/venue_simulation_platform.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_APP_IH_PLATFORMS_VENUE_SIMULATION_PLATFORM_HPP_ 2 | #define SIMULATOR_APP_IH_PLATFORMS_VENUE_SIMULATION_PLATFORM_HPP_ 3 | 4 | #include 5 | 6 | #include "data_layer/api/database/context.hpp" 7 | #include "ih/components/fix_acceptor.hpp" 8 | #include "ih/components/generator.hpp" 9 | #include "ih/components/http_server.hpp" 10 | #include "ih/components/trading_engine.hpp" 11 | #include "ih/platforms/platform.hpp" 12 | 13 | namespace simulator { 14 | 15 | class VenueSimulationPlatform final : public Platform { 16 | public: 17 | explicit VenueSimulationPlatform( 18 | const data_layer::database::Context& database); 19 | 20 | auto launch() -> void override; 21 | 22 | auto terminate() -> void override; 23 | 24 | private: 25 | std::shared_ptr trading_engine_; 26 | std::shared_ptr fix_acceptor_; 27 | std::shared_ptr generator_; 28 | std::shared_ptr http_server_; 29 | }; 30 | 31 | } // namespace simulator 32 | 33 | #endif // SIMULATOR_APP_IH_PLATFORMS_VENUE_SIMULATION_PLATFORM_HPP_ -------------------------------------------------------------------------------- /project/app/src/loop.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/loop.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include "log/logging.hpp" 7 | 8 | namespace simulator { 9 | 10 | static std::mutex loop_mutex; // NOLINT - global application mutex 11 | static std::condition_variable loop_cv; // NOLINT - global main stop condition 12 | 13 | auto Loop::suspend_main_thread() -> void { 14 | log::info("blocking main thread"); 15 | std::unique_lock app_main_lock{loop_mutex}; 16 | loop_cv.wait(app_main_lock); 17 | } 18 | 19 | auto Loop::release_main_thread() -> void { 20 | loop_cv.notify_one(); 21 | log::info("main thread was requested to be released"); 22 | } 23 | 24 | } // namespace simulator -------------------------------------------------------------------------------- /project/app/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${PROJECT_NAME} 3 | UNIT_TESTS 4 | unit_tests/command_options_tests.cpp) -------------------------------------------------------------------------------- /project/app/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | auto main(int argc, char **argv) -> int { 6 | testing::InitGoogleTest(&argc, argv); 7 | 8 | simulator::cfg::init(); 9 | 10 | return RUN_ALL_TESTS(); 11 | } -------------------------------------------------------------------------------- /project/cfg/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(cfg 2 | LANGUAGES CXX 3 | DESCRIPTION 4 | "Global configuration component") 5 | 6 | #------------------------------------------------------------------------------# 7 | 8 | ensure_project_dependency_exist(date::date) 9 | ensure_project_dependency_exist(tinyxml2::tinyxml2) 10 | 11 | #------------------------------------------------------------------------------# 12 | 13 | add_static_library( 14 | NAME ${PROJECT_NAME} 15 | ALIAS simulator::cfg 16 | HEADERS 17 | include/cfg/api/cfg.hpp 18 | src/cfg_impl.hpp 19 | SOURCES 20 | src/cfg_impl.cpp 21 | PUBLIC_INCLUDE_DIRECTORIES 22 | ${PROJECT_SOURCE_DIR}/include 23 | PRIVATE_INCLUDE_DIRECTORIES 24 | ${PROJECT_SOURCE_DIR}/include/cfg 25 | ${PROJECT_SOURCE_DIR} 26 | PUBLIC_DEPENDENCIES 27 | simulator::core 28 | PRIVATE_DEPENDENCIES 29 | date::date 30 | tinyxml2::tinyxml2 31 | fmt::fmt) -------------------------------------------------------------------------------- /project/core/include/core/common/json/field.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_COMMON_JSON_FIELD_HPP_ 2 | #define SIMULATOR_CORE_COMMON_JSON_FIELD_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::core::json { 7 | 8 | template 9 | struct Field { 10 | using value_type = T; 11 | 12 | constexpr Field(T S::* field_pointer, std::string_view field_name) 13 | : ptr{field_pointer}, name{field_name} {} 14 | 15 | T S::* ptr; 16 | std::string_view name; 17 | }; 18 | 19 | template 20 | struct Struct {}; 21 | 22 | } // namespace simulator::core::json 23 | 24 | #endif // SIMULATOR_CORE_COMMON_JSON_FIELD_HPP_ 25 | -------------------------------------------------------------------------------- /project/core/include/core/common/json/type_enum.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_COMMON_JSON_TYPE_ENUM_HPP_ 2 | #define SIMULATOR_CORE_COMMON_JSON_TYPE_ENUM_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "core/common/enum_converter.hpp" 8 | #include "core/common/json/type.hpp" 9 | #include "core/common/meta.hpp" 10 | 11 | namespace simulator::core::json { 12 | 13 | template 14 | struct Type { 15 | [[nodiscard]] 16 | static auto read_json_value(const rapidjson::Value& json_value) -> E { 17 | return EnumConverter::value( 18 | Type::read_json_value(json_value)); 19 | } 20 | 21 | static auto write_json_value(rapidjson::Value& json_value, 22 | rapidjson::Document::AllocatorType& allocator, 23 | const E& value) -> void { 24 | Type::write_json_value( 25 | json_value, allocator, EnumConverter::str(value)); 26 | } 27 | }; 28 | 29 | } // namespace simulator::core::json 30 | 31 | #endif // SIMULATOR_CORE_COMMON_JSON_TYPE_ENUM_HPP_ 32 | -------------------------------------------------------------------------------- /project/core/include/core/common/std_formatter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_COMMON_STD_FORMATTER_HPP_ 2 | #define SIMULATOR_CORE_COMMON_STD_FORMATTER_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | template 10 | requires fmt::is_formattable::value 11 | struct fmt::formatter> { 12 | private: 13 | static constexpr std::string_view none{"none"}; 14 | 15 | public: 16 | constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }; 17 | 18 | auto format(const std::optional& value, format_context& context) const 19 | -> decltype(context.out()) { 20 | return value.has_value() ? format_to(context.out(), "{}", *value) 21 | : format_to(context.out(), none); 22 | } 23 | }; 24 | 25 | #endif // SIMULATOR_CORE_COMMON_STD_FORMATTER_HPP_ 26 | -------------------------------------------------------------------------------- /project/core/include/core/domain/json/market_phase.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_DOMAIN_JSON_MARKET_PHASE_HPP_ 2 | #define SIMULATOR_CORE_DOMAIN_JSON_MARKET_PHASE_HPP_ 3 | 4 | #include "core/common/json/type.hpp" 5 | #include "core/domain/market_phase.hpp" 6 | 7 | namespace simulator::core::json { 8 | 9 | template <> 10 | struct Type { 11 | [[nodiscard]] 12 | static auto read_json_value(const rapidjson::Value& json_value) 13 | -> simulator::MarketPhase; 14 | 15 | static auto write_json_value(rapidjson::Value& json_value, 16 | rapidjson::Document::AllocatorType& allocator, 17 | const simulator::MarketPhase& value) -> void; 18 | }; 19 | 20 | } // namespace simulator::core::json 21 | 22 | #endif // SIMULATOR_CORE_DOMAIN_JSON_MARKET_PHASE_HPP_ 23 | -------------------------------------------------------------------------------- /project/core/include/core/tools/format.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_TOOLS_FORMAT_HPP_ 2 | #define SIMULATOR_CORE_TOOLS_FORMAT_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace simulator::core { 10 | 11 | template 12 | auto format_collection(const std::vector& vector) -> std::string { 13 | return vector.empty() ? "[]" : fmt::format("[ {} ]", fmt::join(vector, ", ")); 14 | } 15 | 16 | } // namespace simulator::core 17 | 18 | #endif // SIMULATOR_CORE_TOOLS_FORMAT_HPP_ 19 | -------------------------------------------------------------------------------- /project/core/include/core/tools/overload.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_TOOLS_OVERLOAD_HPP_ 2 | #define SIMULATOR_CORE_TOOLS_OVERLOAD_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::core { 7 | 8 | template 9 | [[nodiscard]] 10 | constexpr auto overload(Overloads&&... overloads) { 11 | struct Overload : Overloads... { 12 | using Overloads::operator()...; 13 | }; 14 | return Overload{std::forward(overloads)...}; 15 | } 16 | 17 | } // namespace simulator::core 18 | 19 | #endif // SIMULATOR_CORE_TOOLS_OVERLOAD_HPP_ 20 | -------------------------------------------------------------------------------- /project/core/include/core/tools/string_checkers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_TOOLS_STRING_CHECKERS_HPP_ 2 | #define SIMULATOR_CORE_TOOLS_STRING_CHECKERS_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::core { 7 | 8 | [[nodiscard]] auto represents_base10_unsigned_int( 9 | std::string_view string) noexcept -> bool; 10 | 11 | } // namespace simulator::core 12 | 13 | #endif // SIMULATOR_CORE_TOOLS_STRING_CHECKERS_HPP_ 14 | -------------------------------------------------------------------------------- /project/core/include/core/version.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_VERSION_HPP_ 2 | #define SIMULATOR_CORE_VERSION_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::core { 7 | 8 | [[nodiscard]] 9 | auto version() noexcept -> std::string_view; 10 | 11 | [[nodiscard]] 12 | auto major_version() noexcept -> std::string_view; 13 | 14 | } // namespace simulator::core 15 | 16 | #endif // SIMULATOR_CORE_VERSION_HPP_ -------------------------------------------------------------------------------- /project/core/src/domain/market_phase.cpp: -------------------------------------------------------------------------------- 1 | #include "core/domain/json/market_phase.hpp" 2 | 3 | #include "core/domain/market_phase.hpp" 4 | 5 | namespace simulator::core::json { 6 | 7 | auto Type::read_json_value( 8 | const rapidjson::Value& json_value) -> simulator::MarketPhase { 9 | auto phase = json::read_json_value(json_value, "trading_phase"); 10 | auto status = 11 | json::read_json_value(json_value, "trading_status"); 12 | return simulator::MarketPhase{std::move(phase), std::move(status)}; 13 | } 14 | 15 | auto Type::write_json_value( 16 | rapidjson::Value& json_value, 17 | rapidjson::Document::AllocatorType& allocator, 18 | const simulator::MarketPhase& value) -> void { 19 | json_value = rapidjson::Value(rapidjson::Type::kObjectType); 20 | json_value.MemberReserve(2, allocator); 21 | json::write_json_value( 22 | json_value, allocator, value.trading_phase(), "trading_phase"); 23 | json::write_json_value( 24 | json_value, allocator, value.trading_status(), "trading_status"); 25 | } 26 | 27 | } // namespace simulator::core::json 28 | -------------------------------------------------------------------------------- /project/core/src/tools/string_checkers.cpp: -------------------------------------------------------------------------------- 1 | #include "core/tools/string_checkers.hpp" 2 | 3 | #include 4 | #include 5 | 6 | namespace simulator::core { 7 | namespace { 8 | 9 | [[nodiscard]] auto is_base10_digit(unsigned char character) noexcept -> bool { 10 | return std::isdigit(character) != 0; 11 | } 12 | 13 | } // namespace 14 | 15 | auto represents_base10_unsigned_int(std::string_view string) noexcept -> bool { 16 | return !string.empty() && 17 | std::all_of(std::begin(string), std::end(string), is_base10_digit); 18 | } 19 | 20 | } // namespace simulator::core -------------------------------------------------------------------------------- /project/core/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${PROJECT_NAME} 3 | HEADERS 4 | test_definitions/test_attributes.hpp 5 | test_utils/matchers.hpp 6 | fixtures/given_expected_fixture.hpp 7 | UNIT_TESTS 8 | unit_tests/common/json/attribute_tests.cpp 9 | unit_tests/common/json/attributes_tests.cpp 10 | unit_tests/common/json/type_container_tests.cpp 11 | unit_tests/common/json/type_enum_tests.cpp 12 | unit_tests/common/json/type_struct_tests.cpp 13 | unit_tests/common/json/type_tests.cpp 14 | unit_tests/common/attributes_tests.cpp 15 | unit_tests/common/enum_converter_tests.cpp 16 | unit_tests/common/return_code_tests.cpp 17 | unit_tests/domain/enumerators_tests.cpp 18 | unit_tests/domain/instrument_descriptor_tests.cpp 19 | unit_tests/domain/market_phase_tests.cpp 20 | unit_tests/domain/party_tests.cpp 21 | unit_tests/tools/numeric_tests.cpp 22 | unit_tests/tools/string_checkers_tests.cpp 23 | unit_tests/tools/time_tests.cpp) -------------------------------------------------------------------------------- /project/core/tests/fixtures/given_expected_fixture.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CORE_TESTS_FIXTURES_GIVEN_EXPECTED_FIXTURE_HPP_ 2 | #define SIMULATOR_CORE_TESTS_FIXTURES_GIVEN_EXPECTED_FIXTURE_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace simulator::core::test { 9 | 10 | template 11 | struct GivenExpectedFixture 12 | : public testing::TestWithParam> { 13 | auto given() const -> GivenType { return this->GetParam().first; } 14 | 15 | auto expected() const -> ExpectedType { return this->GetParam().second; } 16 | }; 17 | 18 | } // namespace simulator::core::test 19 | 20 | #endif // SIMULATOR_CORE_TESTS_FIXTURES_GIVEN_EXPECTED_FIXTURE_HPP_ 21 | -------------------------------------------------------------------------------- /project/core/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char** argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/core/tests/unit_tests/tools/string_checkers_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "core/tools/string_checkers.hpp" 4 | 5 | namespace simulator::core::test { 6 | namespace { 7 | 8 | using namespace testing; // NOLINT 9 | 10 | TEST(CoreRepresentsBase10UnsignedIntCheck, DetectsEmptyString) { 11 | ASSERT_THAT(represents_base10_unsigned_int(""), IsFalse()); 12 | } 13 | 14 | TEST(CoreRepresentsBase10UnsignedIntCheck, DetectsMinusSign) { 15 | ASSERT_THAT(represents_base10_unsigned_int("-123456789"), IsFalse()); 16 | } 17 | 18 | TEST(CoreRepresentsBase10UnsignedIntCheck, DetectsStringWithSpecialSymbol) { 19 | ASSERT_THAT(represents_base10_unsigned_int("12345@6789"), IsFalse()); 20 | } 21 | 22 | TEST(CoreRepresentsBase10UnsignedIntCheck, DetectsStringWithLetter) { 23 | ASSERT_THAT(represents_base10_unsigned_int("1A23456789"), IsFalse()); 24 | } 25 | 26 | TEST(CoreRepresentsBase10UnsignedIntCheck, DetectsUnsignedInteger) { 27 | ASSERT_THAT(represents_base10_unsigned_int("123456789"), IsTrue()); 28 | } 29 | 30 | } // namespace 31 | } // namespace simulator::core::test -------------------------------------------------------------------------------- /project/data_layer/ih/common/database/context_resolver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_PROJECT_DATA_LAYER_IH_COMMON_CONTEXT_RESOLVER_HPP_ 2 | #define SIMULATOR_PROJECT_DATA_LAYER_IH_COMMON_CONTEXT_RESOLVER_HPP_ 3 | 4 | #include "api/database/context.hpp" 5 | #include "ih/pqxx/context.hpp" 6 | 7 | namespace simulator::data_layer::database { 8 | 9 | class ContextResolver { 10 | friend class database::Context::Implementation; 11 | 12 | public: 13 | ContextResolver() = default; 14 | 15 | ContextResolver(const ContextResolver&) = default; 16 | auto operator=(const ContextResolver&) -> ContextResolver& = default; 17 | 18 | ContextResolver(ContextResolver&&) = default; 19 | auto operator=(ContextResolver&&) -> ContextResolver& = default; 20 | 21 | virtual ~ContextResolver() = default; 22 | 23 | protected: 24 | auto resolve(const database::Context& dbms_context) -> void { 25 | dbms_context.accept(*this); 26 | } 27 | 28 | private: 29 | virtual void execute_with(const internal_pqxx::Context& pqxx_context) = 0; 30 | }; 31 | 32 | } // namespace simulator::data_layer::database 33 | 34 | #endif // SIMULATOR_PROJECT_DATA_LAYER_IH_COMMON_CONTEXT_RESOLVER_HPP_ 35 | -------------------------------------------------------------------------------- /project/data_layer/ih/common/database/driver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_IH_COMMON_DRIVER_HPP_ 2 | #define SIMULATOR_DATA_LAYER_IH_COMMON_DRIVER_HPP_ 3 | 4 | #include "api/database/context.hpp" 5 | #include "cfg/api/cfg.hpp" 6 | #include "ih/common/database/context_resolver.hpp" 7 | #include "ih/pqxx/context.hpp" 8 | 9 | namespace simulator::data_layer::database { 10 | 11 | class Driver final { 12 | public: 13 | [[nodiscard]] 14 | static auto configure(const cfg::DbConfiguration& cfg) 15 | -> database::Context; 16 | 17 | [[nodiscard]] 18 | static auto make_database_context(internal_pqxx::Context pqxx) 19 | -> database::Context; 20 | 21 | private: 22 | Driver() = default; 23 | 24 | [[nodiscard]] 25 | static auto setup_pqxx_backend(const cfg::DbConfiguration& cfg) 26 | -> database::Context; 27 | }; 28 | 29 | } // namespace simulator::data_layer::database 30 | 31 | #endif // SIMULATOR_DATA_LAYER_IH_COMMON_DRIVER_HPP_ 32 | -------------------------------------------------------------------------------- /project/data_layer/ih/common/database/ping_agent.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_IH_COMMON_DATABASE_PING_AGENT_HPP_ 2 | #define SIMULATOR_DATA_LAYER_IH_COMMON_DATABASE_PING_AGENT_HPP_ 3 | 4 | #include 5 | 6 | #include "api/database/context.hpp" 7 | #include "ih/common/database/context_resolver.hpp" 8 | #include "ih/pqxx/database/connector.hpp" 9 | 10 | namespace simulator::data_layer::database { 11 | 12 | class PingAgent final : public ContextResolver { 13 | public: 14 | using PqxxAgentStrategy = std::function; 15 | 16 | static auto ping(const database::Context& context) noexcept -> bool; 17 | 18 | PingAgent() = delete; 19 | 20 | explicit PingAgent(PqxxAgentStrategy pqxx_agent) noexcept; 21 | 22 | auto ping_with_context(const database::Context& context) noexcept -> bool; 23 | 24 | private: 25 | auto execute_with(const internal_pqxx::Context& pqxx_context) 26 | -> void override; 27 | 28 | PqxxAgentStrategy pqxx_agent_; 29 | }; 30 | 31 | } // namespace simulator::data_layer::database 32 | 33 | #endif // SIMULATOR_DATA_LAYER_IH_COMMON_DATABASE_PING_AGENT_HPP_ 34 | -------------------------------------------------------------------------------- /project/data_layer/ih/pqxx/database/value_sanitizer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_IH_PQXX_DATABASE_VALUE_SANITIZER_HPP_ 2 | #define SIMULATOR_DATA_LAYER_IH_PQXX_DATABASE_VALUE_SANITIZER_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace simulator::data_layer::internal_pqxx { 8 | 9 | class ValueSanitizer { 10 | public: 11 | explicit ValueSanitizer(const pqxx::connection& connection) noexcept 12 | : connection_(connection) {} 13 | 14 | template 15 | auto operator()(const T& value) -> std::string { 16 | return connection_.get().quote(value); 17 | } 18 | 19 | private: 20 | std::reference_wrapper connection_; 21 | }; 22 | 23 | } // namespace simulator::data_layer::internal_pqxx 24 | 25 | #endif // SIMULATOR_DATA_LAYER_IH_PQXX_DATABASE_VALUE_SANITIZER_HPP_ 26 | -------------------------------------------------------------------------------- /project/data_layer/include/data_layer/api/database/context.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_DATABASE_CONTEXT_HPP_ 2 | #define SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_DATABASE_CONTEXT_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::data_layer::database { 7 | 8 | class ContextResolver; 9 | 10 | class Context final { 11 | friend class Driver; 12 | friend class ContextResolver; 13 | class Implementation; 14 | 15 | public: 16 | Context(const Context&) = default; 17 | auto operator=(const Context&) -> Context& = default; 18 | 19 | Context(Context&&) = default; 20 | auto operator=(Context&&) -> Context& = default; 21 | 22 | ~Context() = default; 23 | 24 | private: 25 | Context() = default; 26 | 27 | auto accept(ContextResolver& resolver) const -> void; 28 | 29 | std::shared_ptr implementation_; 30 | }; 31 | 32 | } // namespace simulator::data_layer::database 33 | 34 | #endif // SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_DATABASE_CONTEXT_HPP_ 35 | -------------------------------------------------------------------------------- /project/data_layer/include/data_layer/api/predicate/definitions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_PREDICATE_DEFINITIONS_HPP_ 2 | #define SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_PREDICATE_DEFINITIONS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace simulator::data_layer::predicate { 10 | 11 | enum class BasicOperation { Eq, Neq, Less, Greater, LessEq, GreaterEq }; 12 | 13 | enum class CompositeOperation { And, Or }; 14 | 15 | // A tuple of standard types, that can be stored by any predicate expression. 16 | using StandardTypes = 17 | std::tuple; 18 | 19 | // A pre-declaration of a generic predicate expression. 20 | template 21 | class Expression; 22 | 23 | } // namespace simulator::data_layer::predicate 24 | 25 | #endif // SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_PREDICATE_DEFINITIONS_HPP_ 26 | -------------------------------------------------------------------------------- /project/data_layer/include/data_layer/api/validations/column_mapping.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_VALIDATIONS_COLUMN_MAPPING_HPP_ 2 | #define SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_VALIDATIONS_COLUMN_MAPPING_HPP_ 3 | 4 | #include "data_layer/api/models/column_mapping.hpp" 5 | 6 | namespace simulator::data_layer::validation { 7 | 8 | auto valid_variable_depth(const ColumnMapping& column_mapping) -> bool; 9 | auto valid_variable_depth(const ColumnMapping::Patch& column_mapping) -> bool; 10 | 11 | } // namespace simulator::data_layer::validation 12 | 13 | #endif // SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_VALIDATIONS_COLUMN_MAPPING_HPP_ 14 | -------------------------------------------------------------------------------- /project/data_layer/include/data_layer/api/validations/datasource.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_VALIDATIONS_DATASOURCE_HPP_ 2 | #define SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_VALIDATIONS_DATASOURCE_HPP_ 3 | 4 | #include 5 | 6 | #include "data_layer/api/models/datasource.hpp" 7 | 8 | namespace simulator::data_layer::validation { 9 | 10 | [[nodiscard]] 11 | auto valid(const Datasource& datasource) -> tl::expected; 12 | 13 | [[nodiscard]] 14 | auto valid(const Datasource::Patch& datasource) 15 | -> tl::expected; 16 | 17 | } // namespace simulator::data_layer::validation 18 | 19 | #endif // SIMULATOR_DATA_LAYER_INCLUDE_DATA_LAYER_API_VALIDATIONS_DATASOURCE_HPP_ 20 | -------------------------------------------------------------------------------- /project/data_layer/src/api/validations/column_mapping.cpp: -------------------------------------------------------------------------------- 1 | #include "api/validations/column_mapping.hpp" 2 | 3 | #include "api/converters/column_mapping.hpp" 4 | 5 | namespace simulator::data_layer::validation { 6 | 7 | namespace { 8 | 9 | template 10 | auto variable_depth_validation(const T& column_mapping) -> bool { 11 | const auto column_from = converter::extract_column_name_from_variable_depth( 12 | column_mapping.column_from()); 13 | const auto column_to = converter::extract_column_name_from_variable_depth( 14 | column_mapping.column_to()); 15 | return column_from.has_value() && column_to.has_value(); 16 | } 17 | 18 | } // namespace 19 | 20 | auto valid_variable_depth(const ColumnMapping& column_mapping) -> bool { 21 | return variable_depth_validation(column_mapping); 22 | } 23 | 24 | auto valid_variable_depth(const ColumnMapping::Patch& column_mapping) -> bool { 25 | return variable_depth_validation(column_mapping); 26 | } 27 | 28 | } // namespace simulator::data_layer::validation 29 | -------------------------------------------------------------------------------- /project/data_layer/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | int main(int argc, char** argv) { 6 | simulator::cfg::init(); 7 | testing::InitGoogleTest(&argc, argv); 8 | return RUN_ALL_TESTS(); 9 | } 10 | -------------------------------------------------------------------------------- /project/data_layer/tests/test_utils/matchers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_TESTS_TEST_UTILS_MATCHERS_HPP_ 2 | #define SIMULATOR_DATA_LAYER_TESTS_TEST_UTILS_MATCHERS_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::data_layer { 7 | 8 | using namespace ::testing; 9 | 10 | MATCHER_P(IsUnexpected, error_message, "") { 11 | return ExplainMatchResult(IsFalse(), arg.has_value(), result_listener) && 12 | ExplainMatchResult(StrEq(error_message), arg.error(), result_listener); 13 | } 14 | 15 | } // namespace simulator::data_layer 16 | 17 | #endif // SIMULATOR_DATA_LAYER_TESTS_TEST_UTILS_MATCHERS_HPP_ 18 | -------------------------------------------------------------------------------- /project/data_layer/tests/test_utils/sanitizer_stub.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_DATA_LAYER_TESTS_TEST_UTILS_SANITIZER_STUB_HPP_ 2 | #define SIMULATOR_DATA_LAYER_TESTS_TEST_UTILS_SANITIZER_STUB_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace simulator::data_layer { 9 | 10 | struct SanitizerStub { 11 | template 12 | auto operator()(T&& value) -> std::string { 13 | return fmt::format("`{}`", std::forward(value)); 14 | } 15 | }; 16 | 17 | } // namespace simulator::data_layer 18 | 19 | #endif // SIMULATOR_DATA_LAYER_TESTS_TEST_UTILS_SANITIZER_STUB_HPP_ 20 | -------------------------------------------------------------------------------- /project/fix/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(fix 2 | LANGUAGES CXX 3 | DESCRIPTION 4 | "Market Simulator FIX protocol module") 5 | 6 | #------------------------------------------------------------------------------# 7 | # Internal components # 8 | #------------------------------------------------------------------------------# 9 | 10 | add_subdirectory(common) 11 | add_subdirectory(acceptor) -------------------------------------------------------------------------------- /project/fix/acceptor/ih/communicators/fix_reply_sender.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_IH_COMMUNICATORS_FIX_REPLY_SENDER_HPP_ 2 | #define SIMULATOR_ACCEPTOR_IH_COMMUNICATORS_FIX_REPLY_SENDER_HPP_ 3 | 4 | #include "ih/communicators/reply_sender.hpp" 5 | 6 | namespace simulator::fix::acceptor { 7 | 8 | class FixReplySender : public ReplySender { 9 | public: 10 | auto send_reply_message(FIX::Message& fix_message, 11 | const FIX::SessionID& fix_session) const noexcept 12 | -> void override; 13 | }; 14 | 15 | } // namespace simulator::fix::acceptor 16 | 17 | #endif // SIMULATOR_ACCEPTOR_IH_COMMUNICATORS_FIX_REPLY_SENDER_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/ih/communicators/reply_sender.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_IH_COMMUNICATORS_REPLY_SENDER_HPP_ 2 | #define SIMULATOR_ACCEPTOR_IH_COMMUNICATORS_REPLY_SENDER_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace simulator::fix::acceptor { 8 | 9 | class ReplySender { 10 | public: 11 | ReplySender() = default; 12 | ReplySender(const ReplySender&) = default; 13 | ReplySender(ReplySender&&) noexcept = default; 14 | virtual ~ReplySender() = default; 15 | 16 | auto operator=(const ReplySender&) -> ReplySender& = default; 17 | auto operator=(ReplySender&&) noexcept -> ReplySender& = default; 18 | 19 | virtual auto send_reply_message( 20 | FIX::Message& fix_message, 21 | const FIX::SessionID& fix_session) const noexcept -> void = 0; 22 | }; 23 | 24 | } // namespace simulator::fix::acceptor 25 | 26 | #endif // SIMULATOR_ACCEPTOR_IH_COMMUNICATORS_REPLY_SENDER_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/ih/processors/app_event_processor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_IH_PROCESSORS_APP_EVENT_PROCESSOR_HPP_ 2 | #define SIMULATOR_ACCEPTOR_IH_PROCESSORS_APP_EVENT_PROCESSOR_HPP_ 3 | 4 | #include 5 | 6 | #include "common/session_conversion.hpp" 7 | #include "ih/processors/event_processor.hpp" 8 | #include "middleware/routing/trading_session_event_channel.hpp" 9 | 10 | namespace simulator::fix::acceptor { 11 | 12 | class AppEventProcessor : public EventProcessor { 13 | public: 14 | auto process_session_disconnection(const FIX::SessionID& fix_session) const 15 | -> void override { 16 | middleware::emit_trading_session_event( 17 | protocol::SessionTerminatedEvent{decode_session(fix_session)}); 18 | } 19 | }; 20 | 21 | } // namespace simulator::fix::acceptor 22 | 23 | #endif // SIMULATOR_ACCEPTOR_IH_PROCESSORS_APP_EVENT_PROCESSOR_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/ih/processors/event_processor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_IH_PROCESSORS_EVENT_PROCESSOR_HPP_ 2 | #define SIMULATOR_ACCEPTOR_IH_PROCESSORS_EVENT_PROCESSOR_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::fix::acceptor { 7 | 8 | class EventProcessor { 9 | public: 10 | EventProcessor() = default; 11 | EventProcessor(const EventProcessor&) = default; 12 | EventProcessor(EventProcessor&&) noexcept = default; 13 | virtual ~EventProcessor() = default; 14 | 15 | auto operator=(const EventProcessor&) -> EventProcessor& = default; 16 | auto operator=(EventProcessor&&) noexcept -> EventProcessor& = default; 17 | 18 | virtual auto process_session_disconnection( 19 | const FIX::SessionID& fix_session) const -> void = 0; 20 | }; 21 | 22 | } // namespace simulator::fix::acceptor 23 | 24 | #endif // SIMULATOR_ACCEPTOR_IH_PROCESSORS_EVENT_PROCESSOR_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/ih/processors/request_processor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_IH_PROCESSORS_REQUEST_PROCESSOR_HPP_ 2 | #define SIMULATOR_ACCEPTOR_IH_PROCESSORS_REQUEST_PROCESSOR_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace simulator::fix::acceptor { 8 | 9 | class RequestProcessor { 10 | public: 11 | RequestProcessor() = default; 12 | RequestProcessor(const RequestProcessor&) = default; 13 | RequestProcessor(RequestProcessor&&) noexcept = default; 14 | virtual ~RequestProcessor() = default; 15 | 16 | auto operator=(const RequestProcessor&) -> RequestProcessor& = default; 17 | auto operator=(RequestProcessor&&) noexcept -> RequestProcessor& = default; 18 | 19 | virtual auto process_fix_request(const FIX::Message& fix_message, 20 | const FIX::SessionID& fix_session) const 21 | -> void = 0; 22 | }; 23 | 24 | } // namespace simulator::fix::acceptor 25 | 26 | #endif // SIMULATOR_ACCEPTOR_IH_PROCESSORS_REQUEST_PROCESSOR_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/include/acceptor/acceptor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_ACCEPTOR_ACCEPTOR_HPP_ 2 | #define SIMULATOR_FIX_ACCEPTOR_ACCEPTOR_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::fix { 7 | 8 | struct Acceptor { 9 | struct Implementation; 10 | 11 | explicit Acceptor(std::unique_ptr impl) noexcept; 12 | Acceptor(const Acceptor&) = delete; 13 | Acceptor(Acceptor&&) noexcept; 14 | ~Acceptor() noexcept; 15 | 16 | auto operator=(const Acceptor&) -> Acceptor& = delete; 17 | auto operator=(Acceptor&&) noexcept -> Acceptor&; 18 | 19 | auto implementation() noexcept -> Implementation&; 20 | 21 | private: 22 | std::unique_ptr impl_; 23 | }; 24 | 25 | } // namespace simulator::fix 26 | 27 | #endif // SIMULATOR_FIX_ACCEPTOR_ACCEPTOR_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/include/acceptor/lifetime.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_ACCEPTOR_LIFETIME_HPP_ 2 | #define SIMULATOR_FIX_ACCEPTOR_LIFETIME_HPP_ 3 | 4 | #include 5 | 6 | #include "acceptor/acceptor.hpp" 7 | 8 | namespace simulator::fix { 9 | 10 | [[nodiscard]] auto create_fix_acceptor(const std::filesystem::path& config_path) 11 | -> Acceptor; 12 | 13 | auto start_fix_acceptor(Acceptor& acceptor) -> void; 14 | 15 | auto stop_fix_acceptor(Acceptor& acceptor) noexcept -> void; 16 | 17 | } // namespace simulator::fix 18 | 19 | #endif // SIMULATOR_FIX_ACCEPTOR_LIFETIME_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/src/communicators/fix_reply_sender.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/communicators/fix_reply_sender.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "log/logging.hpp" 9 | 10 | namespace simulator::fix::acceptor { 11 | 12 | auto FixReplySender::send_reply_message( 13 | FIX::Message& fix_message, const FIX::SessionID& fix_session) const noexcept 14 | -> void try { 15 | log::debug("sending fix reply message"); 16 | FIX::Session::sendToTarget(fix_message, fix_session); 17 | } catch (const FIX::SessionNotFound& exception) { 18 | log::err("failed to send reply message: session not found: {}", 19 | exception.detail); 20 | } catch (const std::exception& exception) { 21 | log::err("failed to send reply message: an error occurred: {}", 22 | exception.what()); 23 | } catch (...) { 24 | log::err("failed to send reply message: unknown error occurred"); 25 | } 26 | 27 | } // namespace simulator::fix::acceptor -------------------------------------------------------------------------------- /project/fix/acceptor/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${COMPONENT_NAME} 3 | HEADERS 4 | mocks/event_processor_mock.hpp 5 | mocks/from_fix_mapper_stub.hpp 6 | mocks/reply_sender_mock.hpp 7 | mocks/request_processor_mock.hpp 8 | mocks/to_fix_mapper_stub.hpp 9 | mocks/trading_request_receiver_mock.hpp 10 | UNIT_TESTS 11 | unit_tests/communicators/application_tests.cpp 12 | unit_tests/mapping/from_fix_mapper_tests.cpp 13 | unit_tests/mapping/to_fix_mapper_tests.cpp 14 | unit_tests/processors/app_reply_processor_tests.cpp 15 | unit_tests/processors/app_request_processor_tests.cpp) -------------------------------------------------------------------------------- /project/fix/acceptor/tests/mocks/event_processor_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_TESTS_MOCKS_EVENT_PROCESSOR_MOCK_HPP_ 2 | #define SIMULATOR_ACCEPTOR_TESTS_MOCKS_EVENT_PROCESSOR_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/processors/event_processor.hpp" 7 | 8 | namespace simulator::fix::acceptor::test { 9 | 10 | struct EventProcessorMock : public EventProcessor { 11 | MOCK_METHOD(void, 12 | process_session_disconnection, 13 | (const FIX::SessionID&), 14 | (const, override)); 15 | }; 16 | 17 | } // namespace simulator::fix::acceptor::test 18 | 19 | #endif // SIMULATOR_ACCEPTOR_TESTS_MOCKS_EVENT_PROCESSOR_MOCK_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/tests/mocks/reply_sender_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_TESTS_MOCKS_REPLY_SENDER_MOCK_HPP_ 2 | #define SIMULATOR_ACCEPTOR_TESTS_MOCKS_REPLY_SENDER_MOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ih/communicators/reply_sender.hpp" 9 | 10 | namespace simulator::fix::acceptor::test { 11 | 12 | struct ReplySenderMock : public ReplySender { 13 | MOCK_METHOD(void, 14 | send_reply_message, 15 | (FIX::Message&, const FIX::SessionID&), 16 | (const, noexcept, override)); 17 | }; 18 | 19 | } // namespace simulator::fix::acceptor::test 20 | 21 | #endif // SIMULATOR_ACCEPTOR_TESTS_MOCKS_REPLY_SENDER_MOCK_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/tests/mocks/request_processor_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_TESTS_MOCKS_REQUEST_PROCESSOR_MOCK_HPP_ 2 | #define SIMULATOR_ACCEPTOR_TESTS_MOCKS_REQUEST_PROCESSOR_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/processors/request_processor.hpp" 7 | 8 | namespace simulator::fix::acceptor::test { 9 | 10 | struct RequestProcessorMock : public RequestProcessor { 11 | MOCK_METHOD(void, 12 | process_fix_request, 13 | (const FIX::Message&, const FIX::SessionID&), 14 | (const, override)); 15 | }; 16 | 17 | } // namespace simulator::fix::acceptor::test 18 | 19 | #endif // SIMULATOR_ACCEPTOR_TESTS_MOCKS_REQUEST_PROCESSOR_MOCK_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/tests/mocks/trading_request_receiver_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_ACCEPTOR_TESTS_MOCKS_TRADING_REQUEST_RECEIVER_MOCK_HPP_ 2 | #define SIMULATOR_ACCEPTOR_TESTS_MOCKS_TRADING_REQUEST_RECEIVER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "middleware/channels/trading_request_channel.hpp" 7 | 8 | namespace simulator::fix::acceptor::test { 9 | 10 | struct TradingRequestReceiverMock : public middleware::TradingRequestReceiver { 11 | // clang-format off 12 | MOCK_METHOD(void, process, (protocol::OrderPlacementRequest)); 13 | MOCK_METHOD(void, process, (protocol::OrderModificationRequest)); 14 | MOCK_METHOD(void, process, (protocol::OrderCancellationRequest)); 15 | MOCK_METHOD(void, process, (protocol::MarketDataRequest)); 16 | MOCK_METHOD(void, process, (protocol::SecurityStatusRequest)); 17 | MOCK_METHOD(void, process, (const protocol::InstrumentStateRequest&, protocol::InstrumentState&)); 18 | // clang-format on 19 | }; 20 | 21 | } // namespace simulator::fix::acceptor::test 22 | 23 | #endif // SIMULATOR_ACCEPTOR_TESTS_MOCKS_TRADING_REQUEST_RECEIVER_MOCK_HPP_ -------------------------------------------------------------------------------- /project/fix/acceptor/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char** argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/fix/common/include/common/custom_fields.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_FIX_CUSTOM_FIELDS_HPP_ 2 | #define SIMULATOR_FIX_COMMON_FIX_CUSTOM_FIELDS_HPP_ 3 | 4 | #include 5 | 6 | namespace FIX { 7 | 8 | USER_DEFINE_INT(ShortSaleExemptionReason, 1688); 9 | USER_DEFINE_CHAR(AggressorSide, 2446); 10 | 11 | } // namespace FIX 12 | 13 | #endif // SIMULATOR_FIX_COMMON_FIX_CUSTOM_FIELDS_HPP_ 14 | -------------------------------------------------------------------------------- /project/fix/common/include/common/fix_logger.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_FIX_LOGGER_HPP_ 2 | #define SIMULATOR_FIX_COMMON_FIX_LOGGER_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace simulator::fix { 9 | 10 | [[nodiscard]] auto create_log_factory() -> std::unique_ptr; 11 | 12 | } // namespace simulator::fix 13 | 14 | #endif // SIMULATOR_FIX_COMMON_INCLUDE_FIX_COMMON_FIX_LOGGER_HPP_ 15 | -------------------------------------------------------------------------------- /project/fix/common/include/common/mapping/checks.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_MAPPING_CHECKS_HPP_ 2 | #define SIMULATOR_FIX_COMMON_MAPPING_CHECKS_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::fix { 7 | 8 | template 9 | auto contains(const FIX::FieldMap& fix_source) -> bool { 10 | static_assert(sizeof...(FixFieldTags) > 0, 11 | "No FIX field tags are provided to check their presence"); 12 | return (fix_source.isSetField(FixFieldTags) && ...); 13 | } 14 | 15 | } // namespace simulator::fix 16 | 17 | #endif // SIMULATOR_FIX_COMMON_MAPPING_CHECKS_HPP_ -------------------------------------------------------------------------------- /project/fix/common/include/common/mapping/detail/definitions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_MAPPING_DETAIL_DEFINITIONS_HPP_ 2 | #define SIMULATOR_FIX_COMMON_MAPPING_DETAIL_DEFINITIONS_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "core/common/attribute.hpp" 9 | #include "core/common/meta.hpp" 10 | 11 | namespace simulator::fix::detail { 12 | 13 | // Each FIX field is represented by a type derived from FIX::FieldBase. 14 | template 15 | concept FixFieldConcept = std::derived_from; 16 | 17 | // Each internal field is represented by an internal attribute-based type. 18 | template 19 | concept InternalFieldConcept = core::attribute::RepresentsAttribute; 20 | 21 | template 22 | concept NonBooleanArithmetic = core::Arithmetic && !std::same_as; 23 | 24 | } // namespace simulator::fix::detail 25 | 26 | #endif // SIMULATOR_FIX_COMMON_MAPPING_DETAIL_DEFINITIONS_HPP_ -------------------------------------------------------------------------------- /project/fix/common/include/common/mapping/setting/mapping_settings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_MAPPING_SETTING_MAPPING_SETTINGS_HPP_ 2 | #define SIMULATOR_FIX_COMMON_MAPPING_SETTING_MAPPING_SETTINGS_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "common/mapping/setting/timestamp_precision.hpp" 10 | 11 | namespace simulator::fix { 12 | 13 | class MappingSettings { 14 | public: 15 | explicit MappingSettings(const std::vector& sessions); 16 | 17 | struct Setting { 18 | TimestampPrecision timestamp_precision{TimestampPrecision::Milliseconds}; 19 | }; 20 | 21 | auto get_setting(const FIX::SessionID& session_id) const -> Setting; 22 | 23 | private: 24 | std::map settings_; 25 | }; 26 | 27 | } // namespace simulator::fix 28 | 29 | #endif // SIMULATOR_FIX_COMMON_MAPPING_SETTING_MAPPING_SETTINGS_HPP_ 30 | -------------------------------------------------------------------------------- /project/fix/common/include/common/message_store.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_MESSAGE_STORE_HPP_ 2 | #define SIMULATOR_FIX_COMMON_MESSAGE_STORE_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace simulator::fix { 11 | 12 | struct MessageStoreInitializationError : public std::exception {}; 13 | 14 | [[nodiscard]] auto create_message_store_factory( 15 | const FIX::SessionSettings& settings) 16 | -> std::unique_ptr; 17 | 18 | } // namespace simulator::fix 19 | 20 | #endif // SIMULATOR_FIX_COMMON_MESSAGE_STORE_HPP_ -------------------------------------------------------------------------------- /project/fix/common/include/common/meta.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_META_HPP_ 2 | #define SIMULATOR_FIX_COMMON_META_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::fix { 7 | 8 | template 9 | concept RequestMessageMapper = requires( 10 | const Mapper& mapper, const SourceMessage& source, TargetMessage& target) { 11 | { mapper.map(source, target) } -> std::same_as; 12 | }; 13 | 14 | template 18 | concept ReplyMessageMapper = requires(const Mapper& mapper, 19 | const SourceMessage& source, 20 | TargetMessage& target, 21 | const Setting& settings) { 22 | { mapper.map(source, target, settings) } -> std::same_as; 23 | }; 24 | 25 | } // namespace simulator::fix 26 | 27 | #endif // SIMULATOR_FIX_COMMON_COMMON_META_HPP_ -------------------------------------------------------------------------------- /project/fix/common/include/common/session_conversion.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_SESSION_CONVERSION_HPP_ 2 | #define SIMULATOR_FIX_COMMON_SESSION_CONVERSION_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "protocol/types/session.hpp" 10 | 11 | namespace simulator::fix { 12 | 13 | struct InvalidSessionCategoryError : std::invalid_argument { 14 | explicit InvalidSessionCategoryError(const std::string& message); 15 | }; 16 | 17 | [[nodiscard]] 18 | auto decode_session(const FIX::SessionID& session_id) -> protocol::Session; 19 | 20 | [[nodiscard]] 21 | auto encode_session(const protocol::fix::Session& session) -> FIX::SessionID; 22 | 23 | [[nodiscard]] 24 | auto encode_session(const protocol::Session& session) -> FIX::SessionID; 25 | 26 | auto map_sender_sub_id(const FIX::Message& source, 27 | protocol::Session& destination) -> void; 28 | 29 | auto map_target_sub_id(const protocol::Session& source, 30 | FIX::Message& destination) -> void; 31 | 32 | } // namespace simulator::fix 33 | 34 | #endif // SIMULATOR_FIX_COMMON_SESSION_CONVERSION_HPP_ -------------------------------------------------------------------------------- /project/fix/common/include/common/session_settings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_FIX_COMMON_SESSION_SETTINGS_HPP_ 2 | #define SIMULATOR_FIX_COMMON_SESSION_SETTINGS_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace simulator::fix { 9 | 10 | [[nodiscard]] auto read_settings_from_file( 11 | const std::filesystem::path& file_path) -> FIX::SessionSettings; 12 | 13 | } // namespace simulator::fix 14 | 15 | #endif // SIMULATOR_FIX_COMMON_SESSION_SETTINGS_HPP_ -------------------------------------------------------------------------------- /project/fix/common/src/mapping/setting/mapping_settings.cpp: -------------------------------------------------------------------------------- 1 | #include "common/mapping/setting/mapping_settings.hpp" 2 | 3 | #include "log/logging.hpp" 4 | 5 | namespace simulator::fix { 6 | 7 | MappingSettings::MappingSettings(const std::vector& sessions) { 8 | for (const auto& session : sessions) { 9 | if (session != nullptr) { 10 | auto& setting = settings_[session->getSessionID()]; 11 | setting.timestamp_precision = 12 | TimestampPrecision{session->getTimestampPrecision()}; 13 | } 14 | } 15 | } 16 | 17 | auto MappingSettings::get_setting(const FIX::SessionID& session_id) const 18 | -> Setting { 19 | if (const auto iter = settings_.find(session_id); iter != settings_.end()) { 20 | return iter->second; 21 | } 22 | return {}; 23 | } 24 | 25 | } // namespace simulator::fix -------------------------------------------------------------------------------- /project/fix/common/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | auto main(int argc, char **argv) -> int { 6 | testing::InitGoogleTest(&argc, argv); 7 | 8 | simulator::cfg::init(); 9 | 10 | return RUN_ALL_TESTS(); 11 | } -------------------------------------------------------------------------------- /project/generator/ih/context/component_context.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_CONTEXT_COMPONENT_CONTEXT_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_CONTEXT_COMPONENT_CONTEXT_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "data_layer/api/models/venue.hpp" 8 | 9 | namespace simulator::generator { 10 | 11 | class ComponentContext { 12 | public: 13 | using OnStartupCallback = std::function; 14 | 15 | virtual ~ComponentContext() = default; 16 | 17 | [[nodiscard]] 18 | virtual auto is_component_running() const noexcept -> bool = 0; 19 | 20 | [[nodiscard]] 21 | virtual auto get_venue() const noexcept -> const data_layer::Venue& = 0; 22 | 23 | virtual auto generate_identifier() noexcept -> std::string = 0; 24 | 25 | virtual auto next_generated_order_message_number() noexcept 26 | -> std::size_t = 0; 27 | 28 | virtual auto call_on_launch(const OnStartupCallback& callback) -> void = 0; 29 | }; 30 | 31 | } // namespace simulator::generator 32 | 33 | #endif // SIMULATOR_GENERATOR_IH_CONTEXT_COMPONENT_CONTEXT_HPP_ 34 | -------------------------------------------------------------------------------- /project/generator/ih/context/order_generation_context.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_CONTEXT_ORDER_GENERATION_CONTEXT_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_CONTEXT_ORDER_GENERATION_CONTEXT_HPP_ 3 | 4 | #include "data_layer/api/models/price_seed.hpp" 5 | #include "ih/context/instrument_context.hpp" 6 | #include "ih/context/order_market_data_provider.hpp" 7 | 8 | namespace simulator::generator { 9 | 10 | class OrderGenerationContext : public OrderInstrumentContext { 11 | public: 12 | [[nodiscard]] 13 | virtual auto get_price_seed() const noexcept 14 | -> const data_layer::PriceSeed& = 0; 15 | 16 | [[nodiscard]] 17 | virtual auto get_current_market_state() const -> MarketState = 0; 18 | }; 19 | 20 | } // namespace simulator::generator 21 | 22 | #endif // SIMULATOR_GENERATOR_IH_CONTEXT_ORDER_GENERATION_CONTEXT_HPP_ 23 | -------------------------------------------------------------------------------- /project/generator/ih/context/order_market_data_provider.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_CONTEXT_ORDER_MARKET_DATA_PROVIDER_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_CONTEXT_ORDER_MARKET_DATA_PROVIDER_HPP_ 3 | 4 | #include "core/domain/instrument_descriptor.hpp" 5 | 6 | namespace simulator::generator { 7 | 8 | struct MarketState { 9 | std::optional best_bid_price; 10 | std::optional best_offer_price; 11 | std::optional bid_depth_levels; 12 | std::optional offer_depth_levels; 13 | }; 14 | 15 | class OrderMarketDataProvider { 16 | public: 17 | explicit OrderMarketDataProvider(InstrumentDescriptor order_instrument); 18 | 19 | [[nodiscard]] auto get_market_state() const -> MarketState; 20 | 21 | private: 22 | InstrumentDescriptor instrument_descriptor_; 23 | }; 24 | 25 | } // namespace simulator::generator 26 | 27 | #endif // SIMULATOR_GENERATOR_IH_CONTEXT_ORDER_MARKET_DATA_PROVIDER_HPP_ 28 | -------------------------------------------------------------------------------- /project/generator/ih/historical/mapping/column_mapping_filter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_HISTORICAL_MAPPING_COLUMN_MAPPING_FILTER_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_HISTORICAL_MAPPING_COLUMN_MAPPING_FILTER_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "data_layer/api/converters/column_mapping.hpp" 8 | #include "data_layer/api/models/column_mapping.hpp" 9 | 10 | namespace simulator::generator::historical::mapping { 11 | 12 | auto filter(const std::vector& mapping_configs, 13 | std::uint32_t depth_to_parse) 14 | -> std::vector; 15 | 16 | } // namespace simulator::generator::historical::mapping 17 | 18 | #endif // SIMULATOR_GENERATOR_IH_HISTORICAL_MAPPING_COLUMN_MAPPING_FILTER_HPP_ 19 | -------------------------------------------------------------------------------- /project/generator/ih/historical/mapping/datasource_params.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_HISTORICAL_MAPPING_DATASOURCE_PARAMS_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_HISTORICAL_MAPPING_DATASOURCE_PARAMS_HPP_ 3 | 4 | #include 5 | 6 | #include "data_layer/api/models/datasource.hpp" 7 | 8 | namespace simulator::generator::historical { 9 | 10 | class DatasourceParams { 11 | public: 12 | static const DatasourceParams Postgres; 13 | static const DatasourceParams CsvNoHeader; 14 | static const DatasourceParams CsvHasHeader; 15 | 16 | [[nodiscard]] 17 | auto operator==(const DatasourceParams& other) const noexcept 18 | -> bool = default; 19 | 20 | private: 21 | constexpr DatasourceParams(data_layer::Datasource::Format format, 22 | std::optional has_header_row) noexcept 23 | : format_(format), has_header_row_(has_header_row) {} 24 | 25 | data_layer::Datasource::Format format_; 26 | std::optional has_header_row_; 27 | }; 28 | 29 | } // namespace simulator::generator::historical 30 | 31 | #endif // SIMULATOR_GENERATOR_IH_HISTORICAL_MAPPING_DATASOURCE_PARAMS_HPP_ 32 | -------------------------------------------------------------------------------- /project/generator/ih/random/algorithm/generation_algorithm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_RANDOM_ALGORITHM_GENERATION_ALGORITHM_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_RANDOM_ALGORITHM_GENERATION_ALGORITHM_HPP_ 3 | 4 | #include "ih/adaptation/generated_message.hpp" 5 | 6 | namespace simulator::generator::random { 7 | 8 | class GenerationAlgorithm { 9 | public: 10 | virtual ~GenerationAlgorithm() = default; 11 | 12 | // Fills the message with a generated data. 13 | // - `target_message` is considered as finished and valid when `generate` 14 | // returns `true` 15 | // - `target_message` content has to be ignored in case `false` 16 | // is returned 17 | virtual auto generate(GeneratedMessage& target_message) -> bool = 0; 18 | }; 19 | 20 | } // namespace simulator::generator::random 21 | 22 | #endif // SIMULATOR_GENERATOR_IH_RANDOM_ALGORITHM_GENERATION_ALGORITHM_HPP_ 23 | -------------------------------------------------------------------------------- /project/generator/ih/random/generators/value_generator_impl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_RANDOM_GENERATORS_VALUE_GENERATOR_IMPL_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_RANDOM_GENERATORS_VALUE_GENERATOR_IMPL_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "ih/random/generators/value_generator.hpp" 8 | 9 | namespace simulator::generator::random { 10 | 11 | class ValueGeneratorImpl final : public random::ValueGenerator { 12 | public: 13 | ValueGeneratorImpl(); 14 | 15 | static auto create() -> std::shared_ptr; 16 | 17 | private: 18 | auto generate_uniform(RandomInt min, RandomInt max) -> RandomInt override; 19 | 20 | auto generate_uniform(RandomUnsignedInt min, RandomUnsignedInt max) 21 | -> RandomUnsignedInt override; 22 | 23 | auto generate_uniform(RandomFloat min, RandomFloat max) 24 | -> RandomFloat override; 25 | 26 | std::mt19937 engine_; 27 | }; 28 | 29 | } // namespace simulator::generator::random 30 | 31 | #endif // SIMULATOR_GENERATOR_IH_RANDOM_GENERATORS_VALUE_GENERATOR_IMPL_HPP_ 32 | -------------------------------------------------------------------------------- /project/generator/ih/random/utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_RANDOM_UTILS_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_RANDOM_UTILS_HPP_ 3 | 4 | #include "core/domain/attributes.hpp" 5 | #include "ih/context/order_market_data_provider.hpp" 6 | 7 | namespace simulator::generator::random::Utils { 8 | 9 | inline auto opposite(Side side) -> Side { 10 | return side == Side::Option::Buy ? Side::Option::Sell : Side::Option::Buy; 11 | } 12 | 13 | inline auto select_price(const MarketState& mkt_state, Side side) 14 | -> std::optional { 15 | return side == Side::Option::Buy ? mkt_state.best_bid_price 16 | : mkt_state.best_offer_price; 17 | } 18 | 19 | } // namespace simulator::generator::random::Utils 20 | 21 | #endif // SIMULATOR_GENERATOR_IH_RANDOM_UTILS_HPP_ 22 | -------------------------------------------------------------------------------- /project/generator/ih/tracing/null_tracer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_TRACING_NULL_TRACER_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_TRACING_NULL_TRACER_HPP_ 3 | 4 | namespace simulator::generator::trace { 5 | 6 | class NullTracer { 7 | public: 8 | class Step {}; 9 | 10 | template 11 | static auto make_step(Ts&&... /*args*/) noexcept -> NullTracer::Step { 12 | return NullTracer::Step{}; 13 | } 14 | }; 15 | 16 | } // namespace simulator::generator::trace 17 | 18 | #endif // SIMULATOR_GENERATOR_IH_TRACING_NULL_TRACER_HPP_ 19 | -------------------------------------------------------------------------------- /project/generator/ih/utils/executable.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_UTILS_EXECUTABLE_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_UTILS_EXECUTABLE_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::generator { 7 | 8 | class Executable { 9 | public: 10 | virtual ~Executable() = default; 11 | 12 | virtual void prepare() noexcept = 0; 13 | 14 | virtual void execute() = 0; 15 | 16 | [[nodiscard]] 17 | virtual auto finished() const noexcept -> bool = 0; 18 | 19 | [[nodiscard]] 20 | virtual auto next_exec_timeout() const -> std::chrono::microseconds = 0; 21 | }; 22 | 23 | } // namespace simulator::generator 24 | 25 | #endif // SIMULATOR_GENERATOR_IH_UTILS_EXECUTABLE_HPP_ 26 | -------------------------------------------------------------------------------- /project/generator/ih/utils/parsers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_UTILS_PARSERS_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_UTILS_PARSERS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace simulator::generator::parsing { 9 | 10 | // YYYY-mm-dd HH:MM:SS.MS 11 | constexpr std::string_view DefaultTimestampFormat{"%F %T"}; 12 | 13 | auto parse(std::stringstream& buffer, 14 | std::chrono::system_clock::time_point& dest, 15 | std::string_view format = DefaultTimestampFormat) -> bool; 16 | 17 | auto parse(std::string_view timestamp, 18 | std::chrono::system_clock::time_point& dest, 19 | std::stringstream& buffer, 20 | std::string_view format = DefaultTimestampFormat) -> bool; 21 | 22 | auto parse(std::string_view timestamp, 23 | std::chrono::system_clock::time_point& dest, 24 | std::string_view format = DefaultTimestampFormat) -> bool; 25 | 26 | } // namespace simulator::generator::parsing 27 | 28 | #endif // SIMULATOR_GENERATOR_IH_UTILS_PARSERS_HPP_ 29 | -------------------------------------------------------------------------------- /project/generator/ih/utils/validator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_IH_UTILS_VALIDATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_IH_UTILS_VALIDATOR_HPP_ 3 | 4 | #include "data_layer/api/models/listing.hpp" 5 | #include "data_layer/api/models/price_seed.hpp" 6 | 7 | namespace simulator::generator { 8 | 9 | class Validator { 10 | public: 11 | static auto is_acceptable(const data_layer::Listing& listing) -> bool; 12 | 13 | static auto is_acceptable_for_random_generation( 14 | const data_layer::Listing& listing) -> bool; 15 | 16 | static auto is_acceptable(const data_layer::PriceSeed& price_seed) -> bool; 17 | }; 18 | 19 | } // namespace simulator::generator 20 | 21 | #endif // SIMULATOR_GENERATOR_IH_UTILS_VALIDATOR_HPP_ 22 | -------------------------------------------------------------------------------- /project/generator/src/historical/mapping/datasource_params.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/historical/mapping/datasource_params.hpp" 2 | 3 | namespace simulator::generator::historical { 4 | 5 | const DatasourceParams DatasourceParams::Postgres{ 6 | data_layer::Datasource::Format::Postgres, std::nullopt}; 7 | const DatasourceParams DatasourceParams::CsvNoHeader{ 8 | data_layer::Datasource::Format::Csv, false}; 9 | const DatasourceParams DatasourceParams::CsvHasHeader{ 10 | data_layer::Datasource::Format::Csv, true}; 11 | 12 | } // namespace simulator::generator::historical 13 | -------------------------------------------------------------------------------- /project/generator/src/random/generators/event_generator.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/random/generators/event_generator.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include "ih/random/generators/value_generator.hpp" 7 | #include "ih/random/values/event.hpp" 8 | 9 | namespace simulator::generator::random { 10 | 11 | EventGeneratorImpl::EventGeneratorImpl( 12 | std::shared_ptr random_int_generator) noexcept 13 | : random_int_generator_{std::move(random_int_generator)} { 14 | assert(random_int_generator_); 15 | } 16 | 17 | auto EventGeneratorImpl::create( 18 | std::shared_ptr random_int_generator) 19 | -> std::unique_ptr { 20 | return std::make_unique(std::move(random_int_generator)); 21 | } 22 | 23 | auto EventGeneratorImpl::generate_choice_integer() -> Event::RandomInteger { 24 | constexpr auto min = Event::min_random_integer(); 25 | constexpr auto max = Event::max_random_integer(); 26 | static_assert(min <= max); 27 | 28 | return random_int_generator_->generate_uniform_value(min, max); 29 | } 30 | 31 | } // namespace simulator::generator::random 32 | -------------------------------------------------------------------------------- /project/generator/src/utils/parsers.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/utils/parsers.hpp" 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace simulator::generator::parsing { 8 | 9 | auto parse(std::stringstream& buffer, 10 | std::chrono::system_clock::time_point& dest, 11 | std::string_view format) -> bool { 12 | buffer >> date::parse(std::string{format}, dest); 13 | return !buffer.fail() && !buffer.bad(); 14 | } 15 | 16 | auto parse(std::string_view timestamp, 17 | std::chrono::system_clock::time_point& dest, 18 | std::stringstream& buffer, 19 | std::string_view format) -> bool { 20 | buffer.clear(); 21 | buffer << timestamp; 22 | 23 | const bool parsed = parse(buffer, dest, format); 24 | 25 | buffer.clear(); 26 | return parsed; 27 | } 28 | 29 | auto parse(std::string_view timestamp, 30 | std::chrono::system_clock::time_point& dest, 31 | std::string_view format) -> bool { 32 | std::stringstream buffer{}; 33 | return parse(timestamp, dest, buffer, format); 34 | } 35 | 36 | } // namespace simulator::generator::parsing 37 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/historical/provider.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_HISTORICAL_PROVIDER_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_HISTORICAL_PROVIDER_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/historical/data/provider.hpp" 7 | #include "ih/historical/data/record.hpp" 8 | #include "ih/historical/data/time.hpp" 9 | 10 | namespace simulator::generator::mock { 11 | 12 | class DataProvider : public historical::DataProvider { 13 | public: 14 | MOCK_METHOD(bool, is_empty, (), (const, noexcept, override)); 15 | 16 | MOCK_METHOD(void, initialize_time_offset, (), (noexcept, override)); 17 | 18 | MOCK_METHOD(void, add, (historical::Record), (override)); 19 | 20 | MOCK_METHOD(void, pull_into, (historical::Action::Builder&), (override)); 21 | 22 | auto assign_time_offset(historical::Duration offset) -> void { 23 | set_time_offset(offset); 24 | } 25 | }; 26 | 27 | } // namespace simulator::generator::mock 28 | 29 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_HISTORICAL_PROVIDER_HPP_ 30 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/random/counterparty_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_COUNTERPARTY_GENERATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_COUNTERPARTY_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "ih/random/generators/counterparty_generator.hpp" 9 | 10 | namespace simulator::generator::mock { 11 | 12 | class CounterpartyGenerator : public generator::random::CounterpartyGenerator { 13 | public: 14 | MOCK_METHOD(unsigned int, generate_counterparty_number, (), (override)); 15 | }; 16 | 17 | } // namespace simulator::generator::mock 18 | 19 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_COUNTERPARTY_GENERATOR_HPP_ 20 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/random/price_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_PRICE_GENERATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_PRICE_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "data_layer/api/models/price_seed.hpp" 9 | #include "ih/random/generators/price_generator.hpp" 10 | #include "ih/random/values/event.hpp" 11 | 12 | namespace simulator::generator::mock { 13 | 14 | class PriceGenerator : public generator::random::PriceGenerator { 15 | public: 16 | using GenerationOutput = std::pair; 17 | 18 | static auto make_output(double price) -> GenerationOutput { 19 | return std::make_pair(price, GenerationDetails{}); 20 | } 21 | 22 | MOCK_METHOD(GenerationOutput, 23 | generate_px, 24 | (const random::PriceGenerationParams&, 25 | const MarketState&, 26 | const simulator::data_layer::PriceSeed&, 27 | random::Event), 28 | (override)); 29 | }; 30 | 31 | } // namespace simulator::generator::mock 32 | 33 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_PRICE_GENERATOR_HPP_ 34 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/random/quantity_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_QUANTITY_GENERATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_QUANTITY_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/random/generators/quantity_generator.hpp" 7 | 8 | namespace simulator::generator::mock { 9 | 10 | class QuantityGenerator : public generator::random::QuantityGenerator { 11 | public: 12 | static auto make_output(double qty) -> GenerationOutput { 13 | return GenerationOutput{qty, 0}; 14 | } 15 | 16 | MOCK_METHOD(GenerationOutput, 17 | generate_random_qty, 18 | (const random::QuantityGenerationParams&), 19 | (override)); 20 | }; 21 | 22 | } // namespace simulator::generator::mock 23 | 24 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_QUANTITY_GENERATOR_HPP_ 25 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/random/random_event_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_RANDOM_EVENT_GENERATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_RANDOM_EVENT_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/random/generators/event_generator.hpp" 7 | #include "ih/random/values/event.hpp" 8 | 9 | namespace simulator::generator::mock { 10 | 11 | class EventGenerator : public generator::random::EventGenerator { 12 | public: 13 | MOCK_METHOD(random::Event::RandomInteger, 14 | generate_choice_integer, 15 | (), 16 | (override)); 17 | }; 18 | 19 | } // namespace simulator::generator::mock 20 | 21 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_RANDOM_EVENT_GENERATOR_HPP_ 22 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/random/resting_order_action_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_RESTING_ORDER_ACTION_GENERATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_RESTING_ORDER_ACTION_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/random/generators/resting_order_action_generator.hpp" 7 | #include "ih/random/values/resting_order_action.hpp" 8 | 9 | namespace simulator::generator::mock { 10 | 11 | class RestingOrderActionGenerator 12 | : public generator::random::RestingOrderActionGenerator { 13 | public: 14 | MOCK_METHOD(random::RestingOrderAction::RandomInteger, 15 | generate_integer, 16 | (), 17 | (override)); 18 | }; 19 | 20 | } // namespace simulator::generator::mock 21 | 22 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_RESTING_ORDER_ACTION_GENERATOR_HPP_ 23 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/random/value_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_VALUE_GENERATOR_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_VALUE_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/random/generators/value_generator.hpp" 7 | 8 | namespace simulator::generator::mock { 9 | 10 | class ValueGenerator : public generator::random::ValueGenerator { 11 | public: 12 | MOCK_METHOD(RandomInt, generate_uniform, (RandomInt, RandomInt), (override)); 13 | 14 | MOCK_METHOD(RandomUnsignedInt, 15 | generate_uniform, 16 | (RandomUnsignedInt, RandomUnsignedInt), 17 | (override)); 18 | 19 | MOCK_METHOD(RandomFloat, 20 | generate_uniform, 21 | (RandomFloat, RandomFloat), 22 | (override)); 23 | }; 24 | 25 | } // namespace simulator::generator::mock 26 | 27 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_RANDOM_VALUE_GENERATOR_HPP_ 28 | -------------------------------------------------------------------------------- /project/generator/tests/mocks/trading_request_channel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_MOCKS_TRADING_REQUEST_CHANNEL_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_MOCKS_TRADING_REQUEST_CHANNEL_HPP_ 3 | 4 | #include 5 | 6 | #include "middleware/channels/trading_request_channel.hpp" 7 | 8 | namespace simulator::generator::mock { 9 | 10 | struct TradingRequestReceiver 11 | : public simulator::middleware::TradingRequestReceiver { 12 | // clang-format off 13 | MOCK_METHOD(void, process, (simulator::protocol::OrderPlacementRequest)); 14 | MOCK_METHOD(void, process, (simulator::protocol::OrderModificationRequest)); 15 | MOCK_METHOD(void, process, (simulator::protocol::OrderCancellationRequest)); 16 | MOCK_METHOD(void, process, (simulator::protocol::MarketDataRequest)); 17 | MOCK_METHOD(void, process, (simulator::protocol::SecurityStatusRequest)); 18 | MOCK_METHOD(void, process, (const simulator::protocol::InstrumentStateRequest&, simulator::protocol::InstrumentState&)); 19 | // clang-format on 20 | }; 21 | 22 | // clang-format on 23 | 24 | } // namespace simulator::generator::mock 25 | 26 | #endif // SIMULATOR_GENERATOR_TESTS_MOCKS_TRADING_REQUEST_CHANNEL_HPP_ 27 | -------------------------------------------------------------------------------- /project/generator/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | int main(int argc, char** argv) { 6 | simulator::cfg::init(); 7 | testing::InitGoogleTest(&argc, argv); 8 | return RUN_ALL_TESTS(); 9 | } 10 | -------------------------------------------------------------------------------- /project/generator/tests/test_utils/generated_message_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_GENERATOR_TESTS_TEST_UTILS_GENERATED_MESSAGE_UTILS_HPP_ 2 | #define SIMULATOR_GENERATOR_TESTS_TEST_UTILS_GENERATED_MESSAGE_UTILS_HPP_ 3 | 4 | #include 5 | 6 | #include "core/domain/party.hpp" 7 | 8 | namespace simulator::generator { 9 | 10 | using namespace ::testing; 11 | 12 | MATCHER_P(GeneratedParty, party_id, "") { 13 | return ExplainMatchResult( 14 | Eq(party_id), arg.party_id(), result_listener) && 15 | ExplainMatchResult(Eq(PartyRole::Option::ExecutingFirm), 16 | arg.role().value(), 17 | result_listener) && 18 | ExplainMatchResult(Eq(PartyIdSource::Option::Proprietary), 19 | arg.source().value(), 20 | result_listener); 21 | } 22 | 23 | } // namespace simulator::generator 24 | 25 | #endif // SIMULATOR_GENERATOR_TESTS_TEST_UTILS_GENERATED_MESSAGE_UTILS_HPP_ 26 | -------------------------------------------------------------------------------- /project/generator/tests/unit_tests/historical/mapping/source_column_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ih/historical/mapping/specification.hpp" 4 | 5 | namespace simulator::generator::historical::mapping::test { 6 | namespace { 7 | 8 | TEST(GeneratorHistoricalMappingSourceColumn, StoresAssignedIndex) { 9 | constexpr SourceColumn source_column{42}; 10 | ASSERT_EQ(source_column.index(), 42); 11 | } 12 | 13 | TEST(GeneratorHistoricalMappingSourceColumn, NumberIsOneMoreThanIndex) { 14 | constexpr SourceColumn source_column{42}; 15 | ASSERT_EQ(source_column.number(), 43); 16 | } 17 | 18 | } // namespace 19 | } // namespace simulator::generator::historical::mapping::test -------------------------------------------------------------------------------- /project/http/ih/constants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_CONSTANTS_HPP_ 2 | #define SIMULATOR_HTTP_IH_CONSTANTS_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::http::constant { 7 | 8 | constexpr std::string_view PxSeedDbConnSetting{"SeedPriceDatabaseConnection"}; 9 | 10 | } // namespace simulator::http::constant 11 | 12 | #endif // SIMULATOR_HTTP_IH_CONSTANTS_HPP_ 13 | -------------------------------------------------------------------------------- /project/http/ih/controllers/trading_controller.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_CONTROLLERS_TRADING_CONTROLLER_HPP_ 2 | #define SIMULATOR_HTTP_IH_CONTROLLERS_TRADING_CONTROLLER_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace simulator::http { 10 | 11 | class TradingController { 12 | public: 13 | using Result = std::pair; 14 | 15 | [[nodiscard]] 16 | auto halt(const std::string& body) const -> Result; 17 | 18 | [[nodiscard]] 19 | auto resume() const -> Result; 20 | 21 | [[nodiscard]] 22 | auto store_market_state() const -> Result; 23 | 24 | [[nodiscard]] 25 | auto recover_market_state() const -> Result; 26 | }; 27 | 28 | } // namespace simulator::http 29 | 30 | #endif // SIMULATOR_HTTP_IH_CONTROLLERS_TRADING_CONTROLLER_HPP_ 31 | -------------------------------------------------------------------------------- /project/http/ih/data_bridge/operation_failure.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_DATA_BRIDGE_OPERATION_FAILURE_HPP_ 2 | #define SIMULATOR_HTTP_IH_DATA_BRIDGE_OPERATION_FAILURE_HPP_ 3 | 4 | namespace simulator::http::data_bridge { 5 | 6 | enum class Failure : std::uint8_t { 7 | MalformedInput, 8 | DatabaseConnectionError, 9 | ResponseDecodingError, 10 | ResponseCardinalityError, 11 | DataIntegrityViolationError, 12 | UnknownError 13 | }; 14 | 15 | struct FailureInfo { 16 | Failure failure; 17 | std::string message; 18 | }; 19 | 20 | } // namespace simulator::http::data_bridge 21 | 22 | #endif // SIMULATOR_HTTP_IH_DATA_BRIDGE_OPERATION_FAILURE_HPP_ 23 | -------------------------------------------------------------------------------- /project/http/ih/headers/x_api_version.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_HEADERS_X_API_VERSION_HPP_ 2 | #define SIMULATOR_HTTP_IH_HEADERS_X_API_VERSION_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace simulator::http { 10 | 11 | class XApiVersion final : public Pistache::Http::Header::Header { 12 | public: 13 | NAME("X-API-Version") 14 | 15 | auto parse(const std::string& data) -> void override { 16 | if (!data.empty()) { 17 | version_ = data; 18 | } 19 | } 20 | 21 | auto write(std::ostream& ostream) const -> void override { 22 | if (version_) { 23 | ostream << version_.value(); 24 | } 25 | } 26 | 27 | auto version() const -> std::optional { return version_; } 28 | 29 | private: 30 | std::optional version_; 31 | }; 32 | 33 | } // namespace simulator::http 34 | #endif // SIMULATOR_HTTP_IH_HEADERS_X_API_VERSION_HPP_ 35 | -------------------------------------------------------------------------------- /project/http/ih/marshalling/json/detail/utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_MARSHALLING_JSON_DETAIL_UTILS_HPP_ 2 | #define SIMULATOR_HTTP_IH_MARSHALLING_JSON_DETAIL_UTILS_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace simulator::http::json { 11 | 12 | inline auto encode(const rapidjson::Document& document) -> std::string { 13 | rapidjson::StringBuffer buffer{}; 14 | rapidjson::Writer writer{buffer}; 15 | 16 | document.Accept(writer); 17 | 18 | return {buffer.GetString(), buffer.GetSize()}; 19 | } 20 | 21 | inline auto make_key(std::string_view key) { 22 | return rapidjson::StringRef(key.data(), key.size()); 23 | } 24 | 25 | } // namespace simulator::http::json 26 | 27 | #endif // SIMULATOR_HTTP_IH_MARSHALLING_JSON_DETAIL_UTILS_HPP_ 28 | -------------------------------------------------------------------------------- /project/http/ih/marshalling/json/halt.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_MARSHALLING_JSON_HALT_HPP_ 2 | #define SIMULATOR_HTTP_IH_MARSHALLING_JSON_HALT_HPP_ 3 | 4 | #include 5 | 6 | #include "protocol/admin/trading_phase.hpp" 7 | 8 | namespace simulator::http::json { 9 | 10 | class HaltUnmarshaller { 11 | public: 12 | static auto unmarshall(std::string_view json, 13 | protocol::HaltPhaseRequest& request) -> void; 14 | }; 15 | 16 | } // namespace simulator::http::json 17 | 18 | #endif // SIMULATOR_HTTP_IH_MARSHALLING_JSON_HALT_HPP_ 19 | -------------------------------------------------------------------------------- /project/http/ih/marshalling/json/listing.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_MARSHALLING_JSON_LISTING_HPP_ 2 | #define SIMULATOR_HTTP_IH_MARSHALLING_JSON_LISTING_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "data_layer/api/models/listing.hpp" 11 | 12 | namespace simulator::http::json { 13 | 14 | class ListingMarshaller { 15 | public: 16 | static auto marshall(const data_layer::Listing& listing) -> std::string; 17 | 18 | static auto marshall(const std::vector& listings) 19 | -> std::string; 20 | 21 | private: 22 | static auto marshall(const data_layer::Listing& listing, 23 | rapidjson::Document& dest) -> void; 24 | }; 25 | 26 | class ListingUnmarshaller { 27 | public: 28 | static auto unmarshall(std::string_view json, 29 | data_layer::Listing::Patch& dest) -> void; 30 | }; 31 | 32 | } // namespace simulator::http::json 33 | 34 | #endif // SIMULATOR_HTTP_IH_MARSHALLING_JSON_LISTING_HPP_ 35 | -------------------------------------------------------------------------------- /project/http/ih/marshalling/json/price_seed.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_MARSHALLING_JSON_PRICE_SEED_HPP_ 2 | #define SIMULATOR_HTTP_IH_MARSHALLING_JSON_PRICE_SEED_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "data_layer/api/models/price_seed.hpp" 11 | 12 | namespace simulator::http::json { 13 | 14 | class PriceSeedMarshaller { 15 | public: 16 | static auto marshall(const data_layer::PriceSeed& seed) -> std::string; 17 | 18 | static auto marshall(const std::vector& seeds) 19 | -> std::string; 20 | 21 | private: 22 | static auto marshall(const data_layer::PriceSeed& seed, 23 | rapidjson::Document& dest) -> void; 24 | }; 25 | 26 | class PriceSeedUnmarshaller { 27 | public: 28 | static auto unmarshall(std::string_view json, 29 | data_layer::PriceSeed::Patch& dest) -> void; 30 | }; 31 | 32 | } // namespace simulator::http::json 33 | 34 | #endif // SIMULATOR_HTTP_IH_MARSHALLING_JSON_PRICE_SEED_HPP_ 35 | -------------------------------------------------------------------------------- /project/http/ih/marshalling/json/setting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_MARSHALLING_JSON_SETTING_HPP_ 2 | #define SIMULATOR_HTTP_IH_MARSHALLING_JSON_SETTING_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "data_layer/api/models/setting.hpp" 9 | 10 | namespace simulator::http::json { 11 | 12 | class SettingMarshaller { 13 | public: 14 | static auto marshall(const std::vector& settings) 15 | -> std::string; 16 | }; 17 | 18 | class SettingUnmarshaller { 19 | public: 20 | static auto unmarshall(std::string_view json, 21 | std::vector& dest) -> void; 22 | }; 23 | 24 | } // namespace simulator::http::json 25 | 26 | #endif // SIMULATOR_HTTP_IH_MARSHALLING_JSON_SETTING_HPP_ 27 | -------------------------------------------------------------------------------- /project/http/ih/processors/delete_processor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_PROCESSORS_DELETE_PROCESSOR_HPP_ 2 | #define SIMULATOR_HTTP_IH_PROCESSORS_DELETE_PROCESSOR_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "ih/controllers/price_seed_controller.hpp" 10 | 11 | namespace simulator::http { 12 | 13 | class DeleteProcessor { 14 | public: 15 | explicit DeleteProcessor( 16 | const PriceSeedController& price_seed_controller) noexcept; 17 | 18 | auto delete_price_seed(const Pistache::Rest::Request& request, 19 | Pistache::Http::ResponseWriter response) -> void; 20 | 21 | private: 22 | static auto respond(const Pistache::Rest::Request& request, 23 | Pistache::Http::ResponseWriter& response, 24 | Pistache::Http::Code code, 25 | const std::string& body) -> void; 26 | 27 | std::reference_wrapper price_seed_controller_; 28 | }; 29 | 30 | } // namespace simulator::http 31 | 32 | #endif // SIMULATOR_HTTP_IH_PROCESSORS_DELETE_PROCESSOR_HPP_ 33 | -------------------------------------------------------------------------------- /project/http/ih/redirect/destination.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_REDIRECT_DESTINATION_HPP_ 2 | #define SIMULATOR_HTTP_IH_REDIRECT_DESTINATION_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace simulator::http::redirect { 8 | 9 | class Destination { 10 | public: 11 | Destination() = delete; 12 | 13 | Destination(std::string host, int port) noexcept 14 | : host_{std::move(host)}, port_{port} {} 15 | 16 | auto host() const noexcept -> const std::string& { return host_; } 17 | 18 | auto port() const noexcept -> int { return port_; } 19 | 20 | private: 21 | std::string host_; 22 | int port_; 23 | }; 24 | 25 | } // namespace simulator::http::redirect 26 | 27 | #endif // SIMULATOR_HTTP_IH_REDIRECT_DESTINATION_HPP_ 28 | -------------------------------------------------------------------------------- /project/http/ih/redirect/redirector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_REDIRECT_REDIRECTOR_HPP_ 2 | #define SIMULATOR_HTTP_IH_REDIRECT_REDIRECTOR_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "ih/redirect/request.hpp" 8 | #include "ih/redirect/result.hpp" 9 | 10 | namespace simulator::http::redirect { 11 | 12 | class Redirector { 13 | public: 14 | enum class Status : std::uint8_t { Success, ConnectionFailed, UnknownError }; 15 | 16 | virtual ~Redirector() = default; 17 | 18 | using RedirectionResult = std::pair, Status>; 19 | 20 | virtual auto redirect(const Request& request) const noexcept 21 | -> RedirectionResult = 0; 22 | }; 23 | 24 | } // namespace simulator::http::redirect 25 | 26 | #endif // SIMULATOR_HTTP_IH_REDIRECT_REDIRECTOR_HPP_ 27 | -------------------------------------------------------------------------------- /project/http/ih/redirect/request_redirector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_REDIRECT_REQUEST_REDIRECTOR_HPP_ 2 | #define SIMULATOR_HTTP_IH_REDIRECT_REQUEST_REDIRECTOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/redirect/redirector.hpp" 7 | 8 | namespace simulator::http::redirect { 9 | 10 | class RequestRedirector final : public Redirector { 11 | public: 12 | auto redirect(const Request& request) const noexcept 13 | -> RedirectionResult override; 14 | 15 | static auto create() -> std::shared_ptr; 16 | }; 17 | 18 | } // namespace simulator::http::redirect 19 | 20 | #endif // SIMULATOR_HTTP_IH_REDIRECT_REQUEST_REDIRECTOR_HPP_ 21 | -------------------------------------------------------------------------------- /project/http/ih/redirect/resolver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_REDIRECT_RESOLVER_HPP_ 2 | #define SIMULATOR_HTTP_IH_REDIRECT_RESOLVER_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "ih/redirect/destination.hpp" 8 | 9 | namespace simulator::http::redirect { 10 | 11 | class Resolver { 12 | public: 13 | enum class Status : std::uint8_t { 14 | Success, 15 | NonexistentInstance, 16 | ResolvingFailed, 17 | UnknownError 18 | }; 19 | 20 | using ResolvingResult = std::pair, Status>; 21 | 22 | virtual ~Resolver() = default; 23 | 24 | virtual auto resolve_by_venue_id(const std::string& venue_id) const noexcept 25 | -> ResolvingResult = 0; 26 | }; 27 | 28 | } // namespace simulator::http::redirect 29 | 30 | #endif // SIMULATOR_HTTP_IH_REDIRECT_RESOLVER_HPP_ 31 | -------------------------------------------------------------------------------- /project/http/ih/redirect/result.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_REDIRECT_RESPONSE_HPP_ 2 | #define SIMULATOR_HTTP_IH_REDIRECT_RESPONSE_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace simulator::http::redirect { 10 | 11 | class Result { 12 | public: 13 | Result() = delete; 14 | 15 | explicit Result(Pistache::Http::Code code) noexcept : code_{code} {} 16 | 17 | auto http_code() const noexcept { return code_; } 18 | 19 | auto has_body_content() const noexcept -> bool { return !body_.empty(); } 20 | 21 | auto body_content() const noexcept -> const std::string& { return body_; } 22 | 23 | void set_body_content(std::string body_content) noexcept { 24 | body_ = std::move(body_content); 25 | } 26 | 27 | private: 28 | std::string body_; 29 | Pistache::Http::Code code_; 30 | }; 31 | 32 | } // namespace simulator::http::redirect 33 | 34 | #endif // SIMULATOR_HTTP_IH_REDIRECT_RESPONSE_HPP_ 35 | -------------------------------------------------------------------------------- /project/http/ih/server.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_IH_SERVER_HPP_ 2 | #define SIMULATOR_HTTP_IH_SERVER_HPP_ 3 | 4 | #include 5 | 6 | #include "data_layer/api/database/context.hpp" 7 | #include "http/http.hpp" 8 | 9 | namespace simulator::http { 10 | 11 | struct Server::Implementation { 12 | public: 13 | Implementation(std::uint16_t accept_port, 14 | data_layer::database::Context database); 15 | 16 | auto launch() -> void; 17 | 18 | auto terminate() -> void; 19 | 20 | private: 21 | static auto create_endpoint(std::uint16_t accept_port) 22 | -> std::unique_ptr; 23 | 24 | auto setup_handler(data_layer::database::Context database) -> void; 25 | 26 | std::unique_ptr endpoint_; 27 | }; 28 | 29 | } // namespace simulator::http 30 | 31 | #endif // SIMULATOR_HTTP_IH_SERVER_HPP_ 32 | -------------------------------------------------------------------------------- /project/http/include/http/http.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_HTTP_HPP_ 2 | #define SIMULATOR_HTTP_HTTP_HPP_ 3 | 4 | #include 5 | 6 | #include "data_layer/api/database/context.hpp" 7 | 8 | namespace simulator::http { 9 | 10 | struct Server { 11 | struct Implementation; 12 | 13 | explicit Server(std::unique_ptr impl) noexcept; 14 | Server(const Server&) = delete; 15 | Server(Server&&) noexcept; 16 | ~Server() noexcept; 17 | 18 | auto operator=(const Server&) -> Server& = delete; 19 | auto operator=(Server&&) noexcept -> Server&; 20 | 21 | auto implementation() noexcept -> Implementation&; 22 | 23 | private: 24 | std::unique_ptr impl_; 25 | }; 26 | 27 | auto create_http_server(data_layer::database::Context db) -> Server; 28 | 29 | auto launch_http_server(Server& server) -> void; 30 | 31 | auto terminate_http_server(Server& server) noexcept -> void; 32 | 33 | } // namespace simulator::http 34 | 35 | #endif // SIMULATOR_HTTP_HTTP_HPP_ 36 | -------------------------------------------------------------------------------- /project/http/src/marshalling/json/halt.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/marshalling/json/halt.hpp" 2 | 3 | #include 4 | 5 | #include "ih/marshalling/json/detail/unmarshaller.hpp" 6 | 7 | namespace simulator::http::json { 8 | 9 | auto HaltUnmarshaller::unmarshall( 10 | std::string_view json, protocol::HaltPhaseRequest& request) 11 | -> void { 12 | rapidjson::Document document; 13 | document.Parse(json.data()); 14 | if (!document.IsObject()) { 15 | throw std::runtime_error{"failed to parse Halt JSON object"}; 16 | } 17 | 18 | Unmarshaller unmarshaller{document}; 19 | if (!unmarshaller("allowCancels", request.allow_cancels)) { 20 | throw std::invalid_argument{"missing required field \"allowCancels\""}; 21 | } 22 | } 23 | 24 | } // namespace simulator::http::json 25 | -------------------------------------------------------------------------------- /project/http/tests/mocks/redirector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_TESTS_MOCKS_REDIRECTOR_HPP_ 2 | #define SIMULATOR_HTTP_TESTS_MOCKS_REDIRECTOR_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "ih/redirect/redirector.hpp" 10 | #include "ih/redirect/result.hpp" 11 | 12 | namespace simulator::http::mock { 13 | 14 | class Redirector : public redirect::Redirector { 15 | public: 16 | MOCK_METHOD(RedirectionResult, 17 | redirect, 18 | (const redirect::Request&), 19 | (const, noexcept, override)); 20 | 21 | static auto make_output(redirect::Result result) -> RedirectionResult { 22 | return std::make_pair(std::make_optional(std::move(result)), 23 | Redirector::Status::Success); 24 | } 25 | 26 | static auto make_output(Redirector::Status status) -> RedirectionResult { 27 | return std::make_pair(std::nullopt, status); 28 | } 29 | }; 30 | 31 | } // namespace simulator::http::mock 32 | 33 | #endif // SIMULATOR_HTTP_TESTS_MOCKS_REDIRECTOR_HPP_ 34 | -------------------------------------------------------------------------------- /project/http/tests/mocks/resolver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_HTTP_TESTS_MOCKS_RESOLVER_HPP_ 2 | #define SIMULATOR_HTTP_TESTS_MOCKS_RESOLVER_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "ih/redirect/destination.hpp" 10 | #include "ih/redirect/resolver.hpp" 11 | 12 | namespace simulator::http::mock { 13 | 14 | class Resolver : public redirect::Resolver { 15 | public: 16 | MOCK_METHOD(ResolvingResult, 17 | resolve_by_venue_id, 18 | (const std::string&), 19 | (const, noexcept, override)); 20 | 21 | static auto make_output(redirect::Destination destination) 22 | -> redirect::Resolver::ResolvingResult { 23 | return std::make_pair(std::make_optional(std::move(destination)), 24 | redirect::Resolver::Status::Success); 25 | } 26 | 27 | static auto make_output(redirect::Resolver::Status status) 28 | -> redirect::Resolver::ResolvingResult { 29 | return std::make_pair(std::nullopt, status); 30 | } 31 | }; 32 | 33 | } // namespace simulator::http::mock 34 | 35 | #endif // SIMULATOR_HTTP_TESTS_MOCKS_RESOLVER_HPP_ 36 | -------------------------------------------------------------------------------- /project/http/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | int main(int argc, char** argv) { 6 | simulator::cfg::init(); 7 | testing::InitGoogleTest(&argc, argv); 8 | return RUN_ALL_TESTS(); 9 | } -------------------------------------------------------------------------------- /project/http/tests/unit_tests/headers/x_api_version_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "ih/headers/x_api_version.hpp" 6 | 7 | namespace simulator::http::test { 8 | namespace { 9 | 10 | using namespace ::testing; // NOLINT 11 | 12 | TEST(XApiVersion, StoresNoValueIfHeaderIsAbsent) { 13 | XApiVersion header; 14 | 15 | header.parse(std::string{}); 16 | 17 | ASSERT_FALSE(header.version().has_value()); 18 | } 19 | 20 | TEST(XApiVersion, ParsesToString) { 21 | XApiVersion header; 22 | 23 | header.parse("version_42"); 24 | 25 | ASSERT_THAT(header.version(), Optional(Eq("version_42"))); 26 | } 27 | 28 | } // namespace 29 | } // namespace simulator::http::test 30 | -------------------------------------------------------------------------------- /project/http/tests/unit_tests/marshalling/json/halt_unmarshalling_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ih/marshalling/json/halt.hpp" 4 | #include "protocol/admin/trading_phase.hpp" 5 | 6 | namespace simulator::http::json::test { 7 | namespace { 8 | 9 | TEST(HttpMarshallingJsonHalt, ThrowsExceptionOnAllowCancelsNotSet) { 10 | const std::string json = R"({"notAllowCancels": true})"; 11 | protocol::HaltPhaseRequest request; 12 | 13 | EXPECT_ANY_THROW(HaltUnmarshaller::unmarshall(json, request)); 14 | } 15 | 16 | TEST(HttpMarshallingJsonHalt, UnmarshallsAllowCancels) { 17 | const std::string json = R"({"allowCancels": true})"; 18 | protocol::HaltPhaseRequest request; 19 | 20 | HaltUnmarshaller::unmarshall(json, request); 21 | EXPECT_TRUE(request.allow_cancels); 22 | } 23 | 24 | } // namespace 25 | } // namespace simulator::http::json::test 26 | -------------------------------------------------------------------------------- /project/http/tests/unit_tests/redirect/result_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ih/redirect/result.hpp" 4 | 5 | namespace simulator::http::redirect::test { 6 | namespace { 7 | 8 | TEST(HttpRedirectResult, StoresHttpCode) { 9 | const Result result{Pistache::Http::Code::Ok}; 10 | ASSERT_EQ(result.http_code(), Pistache::Http::Code::Ok); 11 | } 12 | 13 | TEST(HttpRedirectResult, StoresBodyContent) { 14 | Result result{Pistache::Http::Code::Ok}; 15 | const std::string body_content{"Test body content"}; 16 | result.set_body_content(body_content); 17 | 18 | ASSERT_TRUE(result.has_body_content()); 19 | ASSERT_EQ(result.body_content(), body_content); 20 | } 21 | 22 | TEST(HttpRedirectResult, DoesNotHaveBodyContentIfItIsNotSet) { 23 | const Result result{Pistache::Http::Code::Ok}; 24 | ASSERT_FALSE(result.has_body_content()); 25 | } 26 | 27 | TEST(HttpRedirectResult, DoesNotHaveBodyContentIfItIsEmpty) { 28 | Result result{Pistache::Http::Code::Ok}; 29 | result.set_body_content(""); 30 | ASSERT_FALSE(result.has_body_content()); 31 | } 32 | 33 | } // namespace 34 | } // namespace simulator::http::redirect::test 35 | -------------------------------------------------------------------------------- /project/log/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(log 2 | LANGUAGES CXX 3 | DESCRIPTION 4 | "Logger for the whole project") 5 | 6 | #------------------------------------------------------------------------------# 7 | 8 | ensure_project_dependency_exist(spdlog::spdlog) 9 | ensure_project_dependency_exist(simulator::cfg) 10 | 11 | #------------------------------------------------------------------------------# 12 | 13 | add_static_library( 14 | NAME ${PROJECT_NAME} 15 | ALIAS simulator::log 16 | HEADERS 17 | ih/factories/logger_factory.hpp 18 | ih/factories/sink_factory.hpp 19 | ih/custom_spd_flags.hpp 20 | ih/util.hpp 21 | include/log/logging.hpp 22 | include/log/logger.hpp 23 | SOURCES 24 | src/factories/logger_factory.cpp 25 | src/custom_spd_flags.cpp 26 | src/logger.cpp 27 | src/util.cpp 28 | PUBLIC_INCLUDE_DIRECTORIES 29 | ${PROJECT_SOURCE_DIR}/include 30 | PRIVATE_INCLUDE_DIRECTORIES 31 | ${PROJECT_SOURCE_DIR}/include/log 32 | ${PROJECT_SOURCE_DIR} 33 | PUBLIC_DEPENDENCIES 34 | fmt::fmt 35 | spdlog::spdlog) 36 | 37 | #------------------------------------------------------------------------------# 38 | 39 | add_subdirectory(tests) -------------------------------------------------------------------------------- /project/log/ih/custom_spd_flags.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_LOG_IH_CUSTOM_SPD_FLAGS_HPP_ 2 | #define SIMULATOR_LOG_IH_CUSTOM_SPD_FLAGS_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::log { 7 | 8 | class EscapedPayloadFlag final : public spdlog::custom_flag_formatter { 9 | public: 10 | auto format(const spdlog::details::log_msg& msg, 11 | const std::tm& tm_time, 12 | spdlog::memory_buf_t& dest) -> void override; 13 | 14 | [[nodiscard]] 15 | auto clone() const -> std::unique_ptr override; 16 | }; 17 | 18 | } // namespace simulator::log 19 | 20 | #endif // SIMULATOR_LOG_IH_CUSTOM_SPD_FLAGS_HPP_ 21 | -------------------------------------------------------------------------------- /project/log/ih/factories/logger_factory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_LOG_IH_FACTORIES_LOGGER_FACTORY_HPP_ 2 | #define SIMULATOR_LOG_IH_FACTORIES_LOGGER_FACTORY_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::log { 7 | 8 | auto create_default_logger(spdlog::sink_ptr sink) 9 | -> std::shared_ptr; 10 | 11 | auto create_app_logger(std::string_view log_level, spdlog::sink_ptr sink) 12 | -> std::shared_ptr; 13 | 14 | } // namespace simulator::log 15 | 16 | #endif // SIMULATOR_LOG_IH_FACTORIES_LOGGER_FACTORY_HPP_ 17 | -------------------------------------------------------------------------------- /project/log/ih/util.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_LOG_IH_UTIL_HPP_ 2 | #define SIMULATOR_LOG_IH_UTIL_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace simulator::log::util { 10 | 11 | auto get_app_logger_name() -> const std::string&; 12 | 13 | auto get_log_pattern() -> const std::string&; 14 | 15 | auto get_default_filename() -> const std::string&; 16 | 17 | inline auto env_logging_dir = []() -> const char* { 18 | return std::getenv("LOG_DIR"); 19 | }; 20 | 21 | auto get_logging_dir(const char* (*func)() = env_logging_dir) 22 | -> std::filesystem::path; 23 | 24 | auto make_log_file_path(const std::filesystem::path& directory, 25 | std::string_view file_prefix, 26 | std::string_view file_name) -> std::filesystem::path; 27 | 28 | auto make_level(std::string_view level) -> spdlog::level::level_enum; 29 | 30 | } // namespace simulator::log::util 31 | 32 | #endif // SIMULATOR_LOG_IH_UTIL_HPP_ 33 | -------------------------------------------------------------------------------- /project/log/src/custom_spd_flags.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/custom_spd_flags.hpp" 2 | 3 | #include 4 | 5 | namespace simulator::log { 6 | 7 | auto EscapedPayloadFlag::format(const spdlog::details::log_msg& msg, 8 | const std::tm& tm_time, 9 | spdlog::memory_buf_t& dest) -> void { 10 | // Debug fmt format. The string is quoted and special characters escaped: 11 | // a message with "quotation marks" -> "a message with \"quotation marks\"" 12 | const auto quoted_escaped_payload = fmt::format("{:?}", msg.payload); 13 | // Append without quotation marks at the beginning and end of the string that 14 | // fmt adds. 15 | dest.append( 16 | quoted_escaped_payload.data() + 1, 17 | quoted_escaped_payload.data() + quoted_escaped_payload.size() - 1); 18 | } 19 | 20 | auto EscapedPayloadFlag::clone() const 21 | -> std::unique_ptr { 22 | return spdlog::details::make_unique(); 23 | } 24 | 25 | } // namespace simulator::log -------------------------------------------------------------------------------- /project/log/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET 3 | ${PROJECT_NAME} 4 | HEADERS 5 | test_utils/matchers.hpp 6 | test_utils/rapidjson_utils.hpp 7 | UNIT_TESTS 8 | unit_tests/factories/logger_factory_tests.cpp 9 | unit_tests/factories/sink_factory_tests.cpp 10 | unit_tests/custom_spd_flags_tests.cpp 11 | unit_tests/logger_tests.cpp 12 | unit_tests/logging_tests.cpp 13 | unit_tests/util_tests.cpp 14 | DEPENDENCIES 15 | RapidJSON::RapidJSON) -------------------------------------------------------------------------------- /project/log/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char** argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/log/tests/test_utils/matchers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_LOG_TESTS_TEST_UTILS_MATCHERS_HPP_ 2 | #define SIMULATOR_LOG_TESTS_TEST_UTILS_MATCHERS_HPP_ 3 | 4 | namespace simulator::log::test { 5 | 6 | using namespace ::testing; 7 | 8 | MATCHER_P2(HasString, key, expected, "") { 9 | auto iter = arg.FindMember(key); 10 | return ExplainMatchResult(Ne(arg.MemberEnd()), iter, result_listener) && 11 | ExplainMatchResult(IsTrue, iter->value.IsString(), result_listener) && 12 | ExplainMatchResult( 13 | StrEq(expected), iter->value.GetString(), result_listener); 14 | } 15 | 16 | MATCHER_P2(HasStringMatches, key, matcher, "") { 17 | auto iter = arg.FindMember(key); 18 | return ExplainMatchResult(Ne(arg.MemberEnd()), iter, result_listener) && 19 | ExplainMatchResult(IsTrue, iter->value.IsString(), result_listener) && 20 | ExplainMatchResult(matcher, iter->value.GetString(), result_listener); 21 | } 22 | 23 | } // namespace simulator::log::test 24 | 25 | #endif // SIMULATOR_LOG_TESTS_TEST_UTILS_MATCHERS_HPP_ 26 | -------------------------------------------------------------------------------- /project/log/tests/test_utils/rapidjson_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_LOG_TESTS_TEST_UTILS_RAPIDJSON_PRINTER_HPP_ 2 | #define SIMULATOR_LOG_TESTS_TEST_UTILS_RAPIDJSON_PRINTER_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace rapidjson { 10 | 11 | inline auto PrintTo(const Document& document, std::ostream* os) -> void { 12 | StringBuffer buffer; 13 | Writer writer(buffer); 14 | document.Accept(writer); 15 | *os << buffer.GetString(); 16 | } 17 | 18 | } // namespace rapidjson 19 | 20 | #endif // SIMULATOR_LOG_TESTS_TEST_UTILS_RAPIDJSON_PRINTER_HPP_ 21 | -------------------------------------------------------------------------------- /project/log/tests/unit_tests/factories/sink_factory_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ih/factories/sink_factory.hpp" 4 | 5 | namespace simulator::log::test { 6 | namespace { 7 | 8 | using namespace ::testing; 9 | 10 | TEST(SinkFactory, CreatesFileSink) { 11 | const auto sink = create_file_sink("/tmp"); 12 | 13 | ASSERT_THAT(sink, NotNull()); 14 | ASSERT_THAT(sink->filename(), std::filesystem::path("/tmp/simulator.log")); 15 | } 16 | 17 | TEST(SinkFactory, CreatesRotatingSink) { 18 | const auto sink = 19 | create_rotating_sink({.log_file_prefix = "prefix", 20 | .log_file_name = "name", 21 | .log_level = {}, 22 | .log_file_size = FileSize::megabytes(10), 23 | .log_files_count = 5}, 24 | "/tmp"); 25 | 26 | ASSERT_THAT(sink, NotNull()); 27 | ASSERT_THAT(sink->filename(), std::filesystem::path("/tmp/prefixname.log")); 28 | } 29 | 30 | } // namespace 31 | } // namespace simulator::log::test 32 | -------------------------------------------------------------------------------- /project/log/tests/unit_tests/logger_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "include/log/logger.hpp" 4 | 5 | namespace simulator::log::test { 6 | namespace { 7 | 8 | TEST(LoggerFileSize, ConvertsMegabytesIntoBytes) { 9 | constexpr auto mb = static_cast(FileSize::megabytes(5)); 10 | ASSERT_EQ(mb, 5 * 1024 * 1024); 11 | } 12 | 13 | } // namespace 14 | } // namespace simulator::log::test 15 | -------------------------------------------------------------------------------- /project/log/tests/unit_tests/logging_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "include/log/logging.hpp" 4 | 5 | namespace simulator::log::test { 6 | namespace { 7 | 8 | TEST(LocationConverter, ConvertsFromStdSourceLocationToSpdlogSourceLoc) { 9 | constexpr std::source_location location = std::source_location::current(); 10 | constexpr spdlog::source_loc spdlog_location = 11 | details::convert_location(location); 12 | 13 | ASSERT_EQ(spdlog_location.filename, location.file_name()); 14 | ASSERT_EQ(spdlog_location.line, location.line()); 15 | ASSERT_EQ(spdlog_location.funcname, location.function_name()); 16 | } 17 | 18 | } // namespace 19 | } // namespace simulator::log::test 20 | -------------------------------------------------------------------------------- /project/middleware/include/middleware/channels/detail/receiver.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_CHANNELS_DETAIL_RECEIVER_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_CHANNELS_DETAIL_RECEIVER_HPP_ 3 | 4 | namespace simulator::middleware::detail { 5 | 6 | struct Receiver { 7 | Receiver() = default; 8 | Receiver(const Receiver&) = default; 9 | Receiver(Receiver&&) = default; 10 | virtual ~Receiver() = default; 11 | 12 | auto operator=(const Receiver&) -> Receiver& = default; 13 | auto operator=(Receiver&&) -> Receiver& = default; 14 | }; 15 | 16 | } // namespace simulator::middleware::detail 17 | 18 | #endif // SIMULATOR_MIDDLEWARE_CHANNELS_DETAIL_RECEIVER_HPP_ -------------------------------------------------------------------------------- /project/middleware/include/middleware/channels/trading_session_event_channel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_CHANNELS_TRADING_SESSION_EVENT_CHANNEL_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_CHANNELS_TRADING_SESSION_EVENT_CHANNEL_HPP_ 3 | 4 | #include 5 | 6 | #include "middleware/channels/detail/receiver.hpp" 7 | #include "protocol/app/session_terminated_event.hpp" 8 | 9 | namespace simulator::middleware { 10 | 11 | struct TradingSessionEventListener : public detail::Receiver { 12 | virtual auto on_event(const protocol::SessionTerminatedEvent& event) 13 | -> void = 0; 14 | }; 15 | 16 | auto bind_trading_session_event_channel( 17 | std::shared_ptr listener) -> void; 18 | 19 | auto release_trading_session_event_channel() noexcept -> void; 20 | 21 | } // namespace simulator::middleware 22 | 23 | #endif // SIMULATOR_MIDDLEWARE_CHANNELS_TRADING_SESSION_EVENT_CHANNEL_HPP_ -------------------------------------------------------------------------------- /project/middleware/include/middleware/routing/errors.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_ROUTING_ERRORS_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_ROUTING_ERRORS_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::middleware { 7 | 8 | struct ChannelUnboundError : public std::exception {}; 9 | 10 | } // namespace simulator::middleware 11 | 12 | #endif // SIMULATOR_MIDDLEWARE_ROUTING_ERRORS_HPP_ -------------------------------------------------------------------------------- /project/middleware/include/middleware/routing/generator_admin_channel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_ROUTING_GENERATOR_ADMIN_CHANNEL_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_ROUTING_GENERATOR_ADMIN_CHANNEL_HPP_ 3 | 4 | #include "middleware/routing/errors.hpp" 5 | #include "protocol/admin/generator.hpp" 6 | 7 | namespace simulator::middleware { 8 | 9 | auto send_admin_request(const protocol::GenerationStatusRequest& request, 10 | protocol::GenerationStatusReply& reply) -> void; 11 | 12 | auto send_admin_request(const protocol::StartGenerationRequest& request, 13 | protocol::StartGenerationReply& reply) -> void; 14 | 15 | auto send_admin_request(const protocol::StopGenerationRequest& request, 16 | protocol::StopGenerationReply& reply) -> void; 17 | 18 | } // namespace simulator::middleware 19 | 20 | #endif // SIMULATOR_MIDDLEWARE_ROUTING_GENERATOR_ADMIN_CHANNEL_HPP_ -------------------------------------------------------------------------------- /project/middleware/include/middleware/routing/trading_admin_channel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_ROUTING_TRADING_PHASE_ADMIN_CHANNEL_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_ROUTING_TRADING_PHASE_ADMIN_CHANNEL_HPP_ 3 | 4 | #include "middleware/routing/errors.hpp" 5 | #include "protocol/admin/market_state.hpp" 6 | #include "protocol/admin/trading_phase.hpp" 7 | 8 | namespace simulator::middleware { 9 | 10 | auto send_admin_request(const protocol::HaltPhaseRequest& request, 11 | protocol::HaltPhaseReply& reply) -> void; 12 | 13 | auto send_admin_request(const protocol::ResumePhaseRequest& request, 14 | protocol::ResumePhaseReply& reply) -> void; 15 | 16 | auto send_admin_request(const protocol::StoreMarketStateRequest& request, 17 | protocol::StoreMarketStateReply& reply) -> void; 18 | 19 | auto send_admin_request(const protocol::RecoverMarketStateRequest& request, 20 | protocol::RecoverMarketStateReply& reply) -> void; 21 | 22 | } // namespace simulator::middleware 23 | 24 | #endif // SIMULATOR_MIDDLEWARE_ROUTING_TRADING_PHASE_ADMIN_CHANNEL_HPP_ 25 | -------------------------------------------------------------------------------- /project/middleware/include/middleware/routing/trading_session_event_channel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_ROUTING_TRADING_SESSION_EVENT_CHANNEL_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_ROUTING_TRADING_SESSION_EVENT_CHANNEL_HPP_ 3 | 4 | #include "middleware/routing/errors.hpp" 5 | #include "protocol/app/session_terminated_event.hpp" 6 | 7 | namespace simulator::middleware { 8 | 9 | auto emit_trading_session_event(const protocol::SessionTerminatedEvent& event) 10 | -> void; 11 | 12 | } // namespace simulator::middleware 13 | 14 | #endif // SIMULATOR_MIDDLEWARE_ROUTING_TRADING_SESSION_EVENT_CHANNEL_HPP_ -------------------------------------------------------------------------------- /project/middleware/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${PROJECT_NAME} 3 | HEADERS 4 | mocks/generator_admin_receiver_mock.hpp 5 | mocks/trading_admin_receiver_mock.hpp 6 | mocks/trading_reply_receiver_mock.hpp 7 | mocks/trading_request_receiver_mock.hpp 8 | mocks/trading_session_event_listener_mock.hpp 9 | test_utils/protocol_utils.hpp 10 | UNIT_TESTS 11 | unit_tests/generator_admin_channel_tests.cpp 12 | unit_tests/trading_admin_channel_tests.cpp 13 | unit_tests/trading_reply_channel_tests.cpp 14 | unit_tests/trading_request_channel_tests.cpp 15 | unit_tests/trading_session_event_channel_tests.cpp) -------------------------------------------------------------------------------- /project/middleware/tests/mocks/trading_request_receiver_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_TESTS_MOCKS_TRADING_REQUEST_RECEIVER_MOCK_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_TESTS_MOCKS_TRADING_REQUEST_RECEIVER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "middleware/channels/trading_request_channel.hpp" 7 | 8 | namespace simulator::middleware::test { 9 | 10 | struct TradingRequestReceiverMock : public TradingRequestReceiver { 11 | // clang-format off 12 | MOCK_METHOD(void, process, (protocol::OrderPlacementRequest), (override)); 13 | MOCK_METHOD(void, process, (protocol::OrderModificationRequest), (override)); 14 | MOCK_METHOD(void, process, (protocol::OrderCancellationRequest), (override)); 15 | MOCK_METHOD(void, process, (protocol::MarketDataRequest), (override)); 16 | MOCK_METHOD(void, process, (protocol::SecurityStatusRequest), (override)); 17 | 18 | MOCK_METHOD(void, process, (const protocol::InstrumentStateRequest&, protocol::InstrumentState&), (override)); 19 | // clang-format on 20 | }; 21 | 22 | } // namespace simulator::middleware::test 23 | 24 | #endif // SIMULATOR_MIDDLEWARE_TESTS_MOCKS_TRADING_REQUEST_RECEIVER_MOCK_HPP_ -------------------------------------------------------------------------------- /project/middleware/tests/mocks/trading_session_event_listener_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_TESTS_MOCKS_TRADING_SESSION_EVENT_LISTENER_MOCK_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_TESTS_MOCKS_TRADING_SESSION_EVENT_LISTENER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "middleware/channels/trading_session_event_channel.hpp" 7 | 8 | namespace simulator::middleware::test { 9 | 10 | struct TradingSessionEventListenerMock : public TradingSessionEventListener { 11 | MOCK_METHOD(void, 12 | on_event, 13 | (const protocol::SessionTerminatedEvent&), 14 | (override)); 15 | }; 16 | 17 | } // namespace simulator::middleware::test 18 | 19 | #endif // SIMULATOR_MIDDLEWARE_TESTS_MOCKS_TRADING_SESSION_EVENT_LISTENER_MOCK_HPP_ -------------------------------------------------------------------------------- /project/middleware/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | auto main(int argc, char** argv) -> int { 6 | testing::InitGoogleTest(&argc, argv); 7 | 8 | simulator::cfg::init(); 9 | 10 | return RUN_ALL_TESTS(); 11 | } -------------------------------------------------------------------------------- /project/middleware/tests/test_utils/protocol_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MIDDLEWARE_TESTS_TEST_UTILS_PROTOCOL_UTILS_HPP_ 2 | #define SIMULATOR_MIDDLEWARE_TESTS_TEST_UTILS_PROTOCOL_UTILS_HPP_ 3 | 4 | #include "protocol/types/session.hpp" 5 | 6 | namespace simulator::middleware::test { 7 | 8 | template 9 | auto make_app_message() -> Message { 10 | return Message{protocol::Session{protocol::generator::Session{}}}; 11 | } 12 | 13 | template 14 | auto make_session_event() -> Event { 15 | return Event{protocol::Session{protocol::generator::Session{}}}; 16 | } 17 | 18 | } // namespace simulator::middleware::test 19 | 20 | #endif // SIMULATOR_MIDDLEWARE_TESTS_TEST_UTILS_PROTOCOL_UTILS_HPP_ -------------------------------------------------------------------------------- /project/protocol/include/protocol/app/market_data_reject.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_PROTOCOL_APP_MARKET_DATA_REJECT_HPP_ 2 | #define SIMULATOR_PROTOCOL_APP_MARKET_DATA_REJECT_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "core/domain/attributes.hpp" 9 | #include "protocol/types/session.hpp" 10 | 11 | namespace simulator::protocol { 12 | 13 | struct MarketDataReject { 14 | explicit MarketDataReject(Session protocol_session) noexcept; 15 | 16 | Session session; 17 | std::optional request_id; 18 | std::optional reject_text; 19 | std::optional reject_reason; 20 | }; 21 | 22 | } // namespace simulator::protocol 23 | 24 | template <> 25 | struct fmt::formatter { 26 | using formattable = simulator::protocol::MarketDataReject; 27 | 28 | constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } 29 | 30 | auto format(const formattable& message, format_context& context) const 31 | -> decltype(context.out()); 32 | }; 33 | 34 | #endif // SIMULATOR_PROTOCOL_APP_MARKET_DATA_REJECT_HPP_ 35 | -------------------------------------------------------------------------------- /project/protocol/include/protocol/app/session_terminated_event.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_PROTOCOL_APP_SESSION_TERMINATED_EVENT_HPP_ 2 | #define SIMULATOR_PROTOCOL_APP_SESSION_TERMINATED_EVENT_HPP_ 3 | 4 | #include 5 | 6 | #include "protocol/types/session.hpp" 7 | 8 | namespace simulator::protocol { 9 | 10 | struct SessionTerminatedEvent { 11 | explicit SessionTerminatedEvent(Session terminated_session) noexcept; 12 | 13 | Session session; 14 | }; 15 | 16 | } // namespace simulator::protocol 17 | 18 | template <> 19 | struct fmt::formatter { 20 | using formattable = simulator::protocol::SessionTerminatedEvent; 21 | 22 | constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } 23 | 24 | auto format(const formattable& event, format_context& context) const 25 | -> decltype(context.out()); 26 | }; 27 | 28 | #endif // SIMULATOR_PROTOCOL_APP_SESSION_TERMINATED_EVENT_HPP_ -------------------------------------------------------------------------------- /project/protocol/include/protocol/types/json/session.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_PROTOCOL_TYPES_JSON_SESSION_HPP_ 2 | #define SIMULATOR_PROTOCOL_TYPES_JSON_SESSION_HPP_ 3 | 4 | #include "core/common/json/type.hpp" 5 | #include "protocol/types/session.hpp" 6 | 7 | namespace simulator::core::json { 8 | 9 | template <> 10 | struct Type { 11 | [[nodiscard]] 12 | static auto read_json_value(const rapidjson::Value& json_value) 13 | -> simulator::protocol::fix::Session; 14 | 15 | static auto write_json_value(rapidjson::Value& json_value, 16 | rapidjson::Document::AllocatorType& allocator, 17 | const simulator::protocol::fix::Session& value) 18 | -> void; 19 | }; 20 | 21 | } // namespace simulator::core::json 22 | 23 | #endif // SIMULATOR_PROTOCOL_TYPES_JSON_SESSION_HPP_ 24 | -------------------------------------------------------------------------------- /project/protocol/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${PROJECT_NAME} 3 | UNIT_TESTS 4 | unit_tests/types/session_tests.cpp) -------------------------------------------------------------------------------- /project/protocol/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char** argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } 7 | -------------------------------------------------------------------------------- /project/trading_system/components/common/include/common/json/trade.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_JSON_TRADE_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_JSON_TRADE_HPP_ 3 | 4 | #include "common/trade.hpp" 5 | #include "core/common/json/type.hpp" 6 | 7 | namespace simulator::core::json { 8 | 9 | template <> 10 | struct Type { 11 | [[nodiscard]] 12 | static auto read_json_value(const rapidjson::Value& json_value) 13 | -> simulator::trading_system::Trade; 14 | 15 | static auto write_json_value(rapidjson::Value& json_value, 16 | rapidjson::Document::AllocatorType& allocator, 17 | const simulator::trading_system::Trade& value) 18 | -> void; 19 | }; 20 | 21 | } // namespace simulator::core::json 22 | 23 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_JSON_TRADE_HPP_ 24 | -------------------------------------------------------------------------------- /project/trading_system/components/common/include/common/market_state/json/instrument_info.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_INSTRUMENT_INFO_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_INSTRUMENT_INFO_HPP_ 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "core/common/json/type_struct.hpp" 6 | 7 | template <> 8 | struct simulator::core::json::Struct< 9 | simulator::trading_system::market_state::InstrumentInfo> { 10 | static constexpr auto fields = std::make_tuple( 11 | Field(&simulator::trading_system::market_state::InstrumentInfo::low_price, 12 | "low_price"), 13 | Field( 14 | &simulator::trading_system::market_state::InstrumentInfo::high_price, 15 | "high_price")); 16 | }; 17 | 18 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_INSTRUMENT_INFO_HPP_ 19 | -------------------------------------------------------------------------------- /project/trading_system/components/common/include/common/market_state/json/order_book.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_ORDER_BOOK_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_ORDER_BOOK_HPP_ 3 | 4 | #include "common/market_state/json/limit_order.hpp" 5 | #include "common/market_state/snapshot.hpp" 6 | #include "core/common/json/type_container.hpp" 7 | #include "core/common/json/type_struct.hpp" 8 | 9 | template <> 10 | struct simulator::core::json::Struct< 11 | simulator::trading_system::market_state::OrderBook> { 12 | static constexpr auto fields = std::make_tuple( 13 | Field( 14 | &simulator::trading_system::market_state::OrderBook::buy_orders, 15 | "buy_orders"), 16 | Field( 17 | &simulator::trading_system::market_state::OrderBook::sell_orders, 18 | "sell_orders")); 19 | }; 20 | 21 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_ORDER_BOOK_HPP_ 22 | -------------------------------------------------------------------------------- /project/trading_system/components/common/include/common/market_state/json/session.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_SESSION_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_SESSION_HPP_ 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "core/common/json/type_struct.hpp" 6 | #include "protocol/types/json/session.hpp" 7 | #include "protocol/types/session.hpp" 8 | 9 | template <> 10 | struct simulator::core::json::Struct< 11 | simulator::trading_system::market_state::Session> { 12 | static constexpr auto fields = std::make_tuple( 13 | Field(&simulator::trading_system::market_state::Session::type, 14 | "type"), 15 | Field(&simulator::trading_system::market_state::Session::fix_session, 16 | "fix_session")); 17 | }; 18 | 19 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_SESSION_HPP_ 20 | -------------------------------------------------------------------------------- /project/trading_system/components/common/include/common/market_state/json/snapshot.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_SNAPSHOT_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_SNAPSHOT_HPP_ 3 | 4 | #include "common/market_state/json/instrument_state.hpp" 5 | #include "common/market_state/snapshot.hpp" 6 | #include "core/common/json/type_struct.hpp" 7 | 8 | template <> 9 | struct simulator::core::json::Struct< 10 | simulator::trading_system::market_state::Snapshot> { 11 | static constexpr auto fields = std::make_tuple( 12 | Field(&simulator::trading_system::market_state::Snapshot::venue_id, 13 | "venue_id"), 14 | Field(&simulator::trading_system::market_state::Snapshot::instruments, 15 | "instruments")); 16 | }; 17 | 18 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_COMMON_MARKET_STATE_JSON_SNAPSHOT_HPP_ 19 | -------------------------------------------------------------------------------- /project/trading_system/components/common/src/phase.cpp: -------------------------------------------------------------------------------- 1 | #include "common/phase.hpp" 2 | 3 | namespace simulator::trading_system { 4 | 5 | Phase::Phase(TradingPhase phase, 6 | TradingStatus status, 7 | Settings setting) noexcept 8 | : phase_{phase}, status_{status} { 9 | if (phase_ == TradingPhase::Option::Closed) { 10 | status_ = TradingStatus::Option::Halt; 11 | } 12 | 13 | if (phase_ != TradingPhase::Option::Closed && 14 | status_ == TradingStatus::Option::Halt) { 15 | settings_ = setting; 16 | } 17 | } 18 | 19 | auto Phase::phase() const -> TradingPhase { return phase_; } 20 | 21 | auto Phase::status() const -> TradingStatus { return status_; } 22 | 23 | auto Phase::settings() const -> std::optional { 24 | return settings_; 25 | } 26 | 27 | } // namespace simulator::trading_system 28 | -------------------------------------------------------------------------------- /project/trading_system/components/common/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${COMPONENT_NAME} 3 | HEADERS 4 | test_utils/matchers.hpp 5 | UNIT_TESTS 6 | unit_tests/market_state/instrument_info_tests.cpp 7 | unit_tests/market_state/instrument_state_tests.cpp 8 | unit_tests/market_state/limit_order_tests.cpp 9 | unit_tests/market_state/order_book_tests.cpp 10 | unit_tests/market_state/session_tests.cpp 11 | unit_tests/market_state/session_type_tests.cpp 12 | unit_tests/market_state/snapshot_tests.cpp 13 | unit_tests/events_tests.cpp 14 | unit_tests/instrument_test.cpp 15 | unit_tests/phase_test.cpp 16 | unit_tests/trade_tests.cpp) -------------------------------------------------------------------------------- /project/trading_system/components/common/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char** argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/trading_system/components/idgen/ih/sequences/common.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_IDGEN_IH_SEQUENCES_COMMON_HPP_ 2 | #define SIMULATOR_IDGEN_IH_SEQUENCES_COMMON_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::trading_system::idgen { 7 | 8 | template 9 | concept SequenceCounter = std::is_unsigned_v && !std::same_as; 10 | 11 | template 12 | concept Sequence = requires(T sequence) { 13 | typename T::counter_type; 14 | requires SequenceCounter; 15 | { sequence.current() } -> SequenceCounter; 16 | }; 17 | 18 | } // namespace simulator::trading_system::idgen 19 | 20 | #endif // SIMULATOR_IDGEN_IH_SEQUENCES_COMMON_HPP_ 21 | -------------------------------------------------------------------------------- /project/trading_system/components/idgen/include/idgen/errors.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_IDGEN_ERRORS_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_IDGEN_ERRORS_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace simulator::trading_system::idgen { 8 | 9 | enum class GenerationError : std::uint8_t { CollisionDetected }; 10 | 11 | template 12 | using ExpectedId = tl::expected; 13 | 14 | } // namespace simulator::trading_system::idgen 15 | 16 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_IDGEN_ERRORS_HPP_ 17 | -------------------------------------------------------------------------------- /project/trading_system/components/idgen/src/contexts/execution_id_context.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/contexts/execution_id_context.hpp" 2 | 3 | #include 4 | 5 | #include "idgen/execution_id.hpp" 6 | #include "log/logging.hpp" 7 | 8 | namespace simulator::trading_system::idgen { 9 | 10 | ExecutionIdContext::ExecutionIdContext( 11 | std::unique_ptr impl) noexcept 12 | : impl_(std::move(impl)) {} 13 | 14 | ExecutionIdContext::~ExecutionIdContext() noexcept = default; 15 | 16 | ExecutionIdContext::ExecutionIdContext(ExecutionIdContext&&) noexcept = default; 17 | 18 | auto ExecutionIdContext::implementation() & noexcept -> Implementation& { 19 | if (impl_) [[likely]] { 20 | return *impl_; 21 | } 22 | 23 | // This is a fatal idgen-internal error, cannot continue execution 24 | log::err( 25 | "CRITICAL: execution id generation context implementation " 26 | "has not been allocated/initialized, the module contains critical bug, " 27 | "can not continue program execution, aborting..."); 28 | std::abort(); 29 | } 30 | 31 | } // namespace simulator::trading_system::idgen -------------------------------------------------------------------------------- /project/trading_system/components/idgen/src/contexts/instrument_id_context.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/contexts/instrument_id_context.hpp" 2 | 3 | #include 4 | 5 | #include "idgen/instrument_id.hpp" 6 | #include "log/logging.hpp" 7 | 8 | namespace simulator::trading_system::idgen { 9 | 10 | InstrumentIdContext::InstrumentIdContext( 11 | std::unique_ptr impl) noexcept 12 | : impl_(std::move(impl)) {} 13 | 14 | InstrumentIdContext::~InstrumentIdContext() noexcept { impl_.reset(); } 15 | 16 | auto InstrumentIdContext::implementation() & noexcept -> Implementation& { 17 | if (impl_) [[likely]] { 18 | return *impl_; 19 | } 20 | 21 | log::err( 22 | "CRITICAL: instrument id generation context implementation " 23 | "has not been allocated/initialized, the module contains critical bug, " 24 | "can not continue program execution, aborting..."); 25 | 26 | // This is a fatal idgen-internal error, cannot continue execution 27 | std::abort(); 28 | } 29 | 30 | } // namespace simulator::trading_system::idgen -------------------------------------------------------------------------------- /project/trading_system/components/idgen/src/contexts/order_id_context.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/contexts/order_id_context.hpp" 2 | 3 | #include 4 | 5 | #include "idgen/order_id.hpp" 6 | #include "log/logging.hpp" 7 | 8 | namespace simulator::trading_system::idgen { 9 | 10 | OrderIdContext::OrderIdContext(std::unique_ptr impl) noexcept 11 | : impl_(std::move(impl)) {} 12 | 13 | OrderIdContext::~OrderIdContext() noexcept = default; 14 | 15 | auto OrderIdContext::implementation() & noexcept -> Implementation& { 16 | if (impl_) [[likely]] { 17 | return *impl_; 18 | } 19 | 20 | // This is a fatal idgen-internal error, cannot continue execution 21 | log::err( 22 | "CRITICAL: order id generation context implementation has not " 23 | "been allocated/initialized, the module contains critical bug, can not " 24 | "continue program execution, aborting..."); 25 | std::abort(); 26 | } 27 | 28 | } // namespace simulator::trading_system::idgen -------------------------------------------------------------------------------- /project/trading_system/components/idgen/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${COMPONENT_NAME} 3 | API_TESTS 4 | api_tests/api_test.cpp 5 | UNIT_TESTS 6 | unit_tests/generation/execution_id_generation_tests.cpp 7 | unit_tests/generation/instrument_id_generation_tests.cpp 8 | unit_tests/generation/market_entry_id_generation_tests.cpp 9 | unit_tests/generation/order_id_generation_tests.cpp 10 | unit_tests/sequences/chrono_sequence_tests.cpp 11 | unit_tests/sequences/numeric_sequence_tests.cpp 12 | DEPENDENCIES 13 | simulator::cfg) -------------------------------------------------------------------------------- /project/trading_system/components/idgen/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char **argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/trading_system/components/ies/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(COMPONENT_NAME ${PROJECT_NAME}_ies) 2 | 3 | #------------------------------------------------------------------------------# 4 | 5 | add_static_library( 6 | NAME ${COMPONENT_NAME} 7 | ALIAS ts::ies 8 | HEADERS 9 | ih/phases/phase_scheduler.hpp 10 | ih/phases/states.hpp 11 | ih/controller_impl.hpp 12 | ih/system_tick_controller.hpp 13 | ih/tick_event_factory.hpp 14 | ih/trading_phase_controller.hpp 15 | include/ies/controller.hpp 16 | include/ies/phase_record.hpp 17 | include/ies/phase_schedule.hpp 18 | SOURCES 19 | src/phases/states.cpp 20 | src/controller.cpp 21 | src/phase_schedule.cpp 22 | src/trading_phase_controller.cpp 23 | PUBLIC_INCLUDE_DIRECTORIES 24 | ${CMAKE_CURRENT_SOURCE_DIR}/include 25 | PRIVATE_INCLUDE_DIRECTORIES 26 | ${CMAKE_CURRENT_SOURCE_DIR} 27 | PUBLIC_DEPENDENCIES 28 | ts::common 29 | ts::runtime 30 | fmt::fmt 31 | PRIVATE_DEPENDENCIES 32 | simulator::core 33 | simulator::log) 34 | 35 | #------------------------------------------------------------------------------# 36 | 37 | add_subdirectory(tests) 38 | -------------------------------------------------------------------------------- /project/trading_system/components/ies/ih/system_tick_controller.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_IES_IH_SYSTEM_TICK_CONTROLLER_HPP_ 2 | #define SIMULATOR_IES_IH_SYSTEM_TICK_CONTROLLER_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "common/events.hpp" 8 | #include "log/logging.hpp" 9 | 10 | namespace simulator::trading_system::ies { 11 | 12 | class SystemTickController { 13 | public: 14 | auto bind(std::function handler) -> void { 15 | std::swap(tick_handler_, handler); 16 | } 17 | 18 | auto update(const event::Tick& event) -> void { 19 | log::trace("updating system tick controller triggered by {}", event); 20 | if (tick_handler_) { 21 | tick_handler_(event); 22 | log::trace("reported a system tick event: {}", event); 23 | } else { 24 | log::err("unable to report {}, no handler is bound", event); 25 | } 26 | } 27 | 28 | private: 29 | std::function tick_handler_; 30 | }; 31 | 32 | } // namespace simulator::trading_system::ies 33 | 34 | #endif // SIMULATOR_IES_IH_SYSTEM_TICK_CONTROLLER_HPP_ 35 | -------------------------------------------------------------------------------- /project/trading_system/components/ies/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${COMPONENT_NAME} 3 | UNIT_TESTS 4 | unit_tests/phases/phase_scheduler_test.cpp 5 | unit_tests/phases/states_test.cpp 6 | unit_tests/phase_schedule_test.cpp 7 | unit_tests/tick_event_factory_test.cpp 8 | unit_tests/trading_phase_controller_test.cpp) -------------------------------------------------------------------------------- /project/trading_system/components/ies/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char **argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/trading_system/components/instruments/ih/instruments_matcher.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_INSTRUMENTS_IH_INSTRUMENTS_MATCHER_HPP_ 2 | #define SIMULATOR_INSTRUMENTS_IH_INSTRUMENTS_MATCHER_HPP_ 3 | 4 | #include "common/instrument.hpp" 5 | #include "instruments/matcher.hpp" 6 | 7 | namespace simulator::trading_system::instrument { 8 | 9 | class Matcher::Implementation { 10 | public: 11 | explicit Implementation(const Instrument& instrument); 12 | 13 | auto operator()(const InstrumentDescriptor& descriptor) const 14 | -> tl::expected; 15 | 16 | private: 17 | Instrument instrument_; 18 | }; 19 | 20 | } // namespace simulator::trading_system::instrument 21 | 22 | #endif // SIMULATOR_INSTRUMENTS_IH_INSTRUMENTS_MATCHER_HPP_ 23 | -------------------------------------------------------------------------------- /project/trading_system/components/instruments/include/instruments/lookup_error.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_LOOKUP_ERROR_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_LOOKUP_ERROR_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::trading_system::instrument { 7 | 8 | enum class LookupError : std::uint8_t { 9 | InstrumentNotFound, 10 | MalformedInstrumentDescriptor, 11 | AmbiguousInstrumentDescriptor, 12 | }; 13 | 14 | } // namespace simulator::trading_system::instrument 15 | 16 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_LOOKUP_ERROR_HPP_ 17 | -------------------------------------------------------------------------------- /project/trading_system/components/instruments/include/instruments/view.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_VIEW_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_VIEW_HPP_ 3 | 4 | #include "common/instrument.hpp" 5 | 6 | namespace simulator::trading_system::instrument { 7 | 8 | class View { 9 | public: 10 | View() = delete; 11 | 12 | // NOLINTNEXTLINE(google-explicit-constructor) 13 | View(const Instrument& instrument) : instrument_ptr_{&instrument} {} 14 | 15 | auto instrument() const -> const Instrument& { return *instrument_ptr_; } 16 | 17 | private: 18 | const Instrument* instrument_ptr_ = nullptr; 19 | }; 20 | 21 | } // namespace simulator::trading_system::instrument 22 | 23 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_VIEW_HPP_ 24 | -------------------------------------------------------------------------------- /project/trading_system/components/instruments/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${COMPONENT_NAME} 3 | HEADERS 4 | test_utils/utils.hpp 5 | API_TESTS 6 | api_tests/cache_tests.cpp 7 | api_tests/matcher_tests.cpp 8 | UNIT_TESTS 9 | unit_tests/currency_category_tests.cpp 10 | unit_tests/instruments_cache_test.cpp 11 | unit_tests/instruments_container_test.cpp 12 | unit_tests/instruments_matcher_tests.cpp 13 | unit_tests/lookup_tests.cpp 14 | unit_tests/match_rate_tests.cpp 15 | unit_tests/matchers_tests.cpp 16 | unit_tests/sources_test.cpp 17 | unit_tests/strategies_tests.cpp) -------------------------------------------------------------------------------- /project/trading_system/components/instruments/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | auto main(int argc, char **argv) -> int { 6 | testing::InitGoogleTest(&argc, argv); 7 | 8 | simulator::cfg::init(); 9 | 10 | return RUN_ALL_TESTS(); 11 | } -------------------------------------------------------------------------------- /project/trading_system/components/instruments/tests/test_utils/utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_TEST_UTILS_UTILS_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_TEST_UTILS_UTILS_HPP_ 3 | 4 | #include "common/instrument.hpp" 5 | 6 | namespace simulator::trading_system::instrument::test { 7 | 8 | [[nodiscard]] 9 | inline auto make_instrument(InstrumentId instrument_id) noexcept -> Instrument { 10 | Instrument instrument; 11 | instrument.identifier = instrument_id; 12 | return instrument; 13 | } 14 | 15 | } // namespace simulator::trading_system::instrument::test 16 | 17 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_INSTRUMENTS_TEST_UTILS_UTILS_HPP_ 18 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/commands/client_notification_cache.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_COMMANDS_CLIENT_NOTIFICATION_CACHE_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_COMMANDS_CLIENT_NOTIFICATION_CACHE_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/common/events/client_notification.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine { 9 | 10 | class ClientNotifications { 11 | public: 12 | explicit ClientNotifications(std::vector notifications); 13 | 14 | auto publish() -> void; 15 | 16 | private: 17 | std::vector notifications_; 18 | }; 19 | 20 | class ClientNotificationCache { 21 | public: 22 | auto add(ClientNotification notification) -> void; 23 | 24 | auto collect() -> ClientNotifications; 25 | 26 | private: 27 | std::vector cached_notifications_; 28 | }; 29 | 30 | } // namespace simulator::trading_system::matching_engine 31 | 32 | #endif // SIMULATOR_MATCHING_ENGINE_IH_COMMANDS_CLIENT_NOTIFICATION_CACHE_HPP_ -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/common/abstractions/event_listener.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_COMMON_ABSTRACTIONS_EVENT_LISTENER_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_COMMON_ABSTRACTIONS_EVENT_LISTENER_HPP_ 3 | 4 | namespace simulator::trading_system::matching_engine { 5 | 6 | struct Event; 7 | 8 | class EventListener { 9 | public: 10 | EventListener() = default; 11 | EventListener(const EventListener&) = default; 12 | EventListener(EventListener&&) = default; 13 | virtual ~EventListener() = default; 14 | 15 | auto operator=(const EventListener&) -> EventListener& = default; 16 | auto operator=(EventListener&&) -> EventListener& = default; 17 | 18 | virtual auto on(Event event) -> void = 0; 19 | }; 20 | 21 | } // namespace simulator::trading_system::matching_engine 22 | 23 | #endif // SIMULATOR_MATCHING_ENGINE_IH_COMMON_ABSTRACTIONS_EVENT_LISTENER_HPP_ 24 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/common/abstractions/market_data_publisher.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_COMMON_ABSTRACTIONS_MARKET_DATA_PUBLISHER_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_COMMON_ABSTRACTIONS_MARKET_DATA_PUBLISHER_HPP_ 3 | 4 | namespace simulator::trading_system::matching_engine { 5 | 6 | class MarketDataPublisher { 7 | public: 8 | MarketDataPublisher() = default; 9 | MarketDataPublisher(const MarketDataPublisher&) = default; 10 | MarketDataPublisher(MarketDataPublisher&&) = default; 11 | virtual ~MarketDataPublisher() = default; 12 | 13 | auto operator=(const MarketDataPublisher&) -> MarketDataPublisher& = default; 14 | auto operator=(MarketDataPublisher&&) -> MarketDataPublisher& = default; 15 | 16 | virtual auto publish() -> void = 0; 17 | }; 18 | 19 | } // namespace simulator::trading_system::matching_engine 20 | 21 | #endif // SIMULATOR_MATCHING_ENGINE_IH_COMMON_ABSTRACTIONS_MARKET_DATA_PUBLISHER_HPP_ -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/common/events/event.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_COMMON_EVENTS_EVENT_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_COMMON_EVENTS_EVENT_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "ih/common/events/client_notification.hpp" 9 | #include "ih/common/events/order_book_notification.hpp" 10 | 11 | namespace simulator::trading_system::matching_engine { 12 | 13 | struct Event { 14 | using Category = std::variant; 15 | 16 | template 17 | requires std::constructible_from 18 | explicit Event(EventCategory&& category) 19 | : value(std::forward(category)) {} 20 | 21 | Category value; 22 | }; 23 | 24 | } // namespace simulator::trading_system::matching_engine 25 | 26 | #endif // SIMULATOR_MATCHING_ENGINE_IH_COMMON_EVENTS_EVENT_HPP_ -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/common/validation/conclusion.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_COMMON_VALIDATION_CONCLUSION_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_COMMON_VALIDATION_CONCLUSION_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::trading_system::matching_engine { 7 | 8 | class Conclusion { 9 | public: 10 | [[nodiscard]] 11 | auto failed() const -> bool { 12 | return failed_; 13 | } 14 | 15 | [[nodiscard]] 16 | auto error() const -> std::string_view { 17 | return error_; 18 | } 19 | 20 | [[nodiscard]] 21 | static auto success() -> Conclusion { 22 | return {}; 23 | }; 24 | 25 | [[nodiscard]] 26 | static auto failure(std::string_view reason) -> Conclusion { 27 | Conclusion conclusion; 28 | conclusion.failed_ = true; 29 | conclusion.error_ = reason; 30 | return conclusion; 31 | } 32 | 33 | private: 34 | std::string_view error_; 35 | bool failed_ = false; 36 | }; 37 | 38 | } // namespace simulator::trading_system::matching_engine 39 | 40 | #endif // SIMULATOR_MATCHING_ENGINE_IH_COMMON_VALIDATION_CONCLUSION_HPP_ 41 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/market_data/actions/market_data_recover.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_ACTIONS_MARKET_DATA_RECOVER_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_ACTIONS_MARKET_DATA_RECOVER_HPP_ 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "common/trade.hpp" 6 | #include "ih/common/abstractions/event_listener.hpp" 7 | #include "ih/common/events/event_reporter.hpp" 8 | 9 | namespace simulator::trading_system::matching_engine::mdata { 10 | 11 | class MarketDataRecover : public EventReporter { 12 | public: 13 | explicit MarketDataRecover(EventListener& event_listener); 14 | 15 | auto operator()(std::optional last_trade) -> void; 16 | 17 | auto operator()(std::optional info) -> void; 18 | }; 19 | 20 | } // namespace simulator::trading_system::matching_engine::mdata 21 | 22 | #endif // SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_ACTIONS_MARKET_DATA_RECOVER_HPP_ 23 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/market_data/depth/depth_record.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_DEPTH_DEPTH_RECORD_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_DEPTH_DEPTH_RECORD_HPP_ 3 | 4 | #include 5 | 6 | #include "core/domain/attributes.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine::mdata { 9 | 10 | class DepthRecord { 11 | public: 12 | DepthRecord(MarketEntryId identifier, 13 | const std::optional price, 14 | const MdEntryType type) 15 | : id_(std::move(identifier)), price_(price), type_(type) {} 16 | 17 | auto id() const -> const MarketEntryId& { return id_; } 18 | 19 | auto price() const -> std::optional { return price_; } 20 | 21 | auto type() const -> MdEntryType { return type_; } 22 | 23 | private: 24 | MarketEntryId id_; 25 | std::optional price_; 26 | MdEntryType type_; 27 | }; 28 | 29 | } // namespace simulator::trading_system::matching_engine::mdata 30 | 31 | #endif // SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_DEPTH_DEPTH_RECORD_HPP_ 32 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/market_data/validation/validator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_VALIDATION_VALIDATOR_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_VALIDATION_VALIDATOR_HPP_ 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "ih/common/validation/conclusion.hpp" 6 | 7 | namespace simulator::trading_system::matching_engine::mdata { 8 | 9 | class Validator { 10 | public: 11 | Validator() = default; 12 | Validator(const Validator&) = default; 13 | Validator(Validator&&) = default; 14 | virtual ~Validator() = default; 15 | 16 | auto operator=(const Validator&) -> Validator& = default; 17 | auto operator=(Validator&&) -> Validator& = default; 18 | 19 | virtual auto validate(const market_state::InstrumentInfo& instrument_info) 20 | const -> Conclusion = 0; 21 | 22 | virtual auto validate(const Trade& trade) const -> Conclusion = 0; 23 | }; 24 | 25 | } // namespace simulator::trading_system::matching_engine::mdata 26 | 27 | #endif // SIMULATOR_MATCHING_ENGINE_IH_MARKET_DATA_VALIDATION_VALIDATOR_HPP_ 28 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/orders/actions/limit_order_recover.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_ORDERS_ACTIONS_LIMIT_ORDER_RECOVER_HPP 2 | #define SIMULATOR_MATCHING_ENGINE_IH_ORDERS_ACTIONS_LIMIT_ORDER_RECOVER_HPP 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "ih/common/abstractions/event_listener.hpp" 6 | #include "ih/common/events/event_reporter.hpp" 7 | #include "ih/orders/book/order_book.hpp" 8 | 9 | namespace simulator::trading_system::matching_engine { 10 | 11 | class LimitOrderRecover : private EventReporter { 12 | public: 13 | LimitOrderRecover(EventListener& event_listener, OrderBook& order_book); 14 | 15 | LimitOrderRecover(const LimitOrderRecover&) = delete; 16 | ~LimitOrderRecover() override = default; 17 | 18 | auto operator=(const LimitOrderRecover&) -> LimitOrderRecover& = delete; 19 | 20 | auto operator()(market_state::LimitOrder order_state) -> void; 21 | 22 | private: 23 | OrderBook& order_book_; 24 | }; 25 | 26 | } // namespace simulator::trading_system::matching_engine 27 | 28 | #endif // SIMULATOR_MATCHING_ENGINE_IH_ORDERS_ACTIONS_LIMIT_ORDER_RECOVER_HPP 29 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/orders/tools/id_conversion.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_ORDERS_TOOLS_ID_CONVERSION_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_ORDERS_TOOLS_ID_CONVERSION_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "common/attributes.hpp" 9 | #include "core/domain/attributes.hpp" 10 | 11 | namespace simulator::trading_system::matching_engine::order { 12 | 13 | [[nodiscard]] 14 | auto stringify_order_id(OrderId order_id) -> std::string; 15 | 16 | [[nodiscard]] 17 | auto parse_order_id(std::string_view source) -> std::optional; 18 | 19 | [[nodiscard]] 20 | auto to_venue_order_id(OrderId order_id) -> VenueOrderId; 21 | 22 | [[nodiscard]] 23 | auto to_venue_order_id(std::optional order_id) 24 | -> std::optional; 25 | 26 | [[nodiscard]] 27 | auto to_order_id(const VenueOrderId& venue_order_id) -> std::optional; 28 | 29 | } // namespace simulator::trading_system::matching_engine::order 30 | 31 | #endif // SIMULATOR_MATCHING_ENGINE_IH_ORDERS_TOOLS_ID_CONVERSION_HPP_ 32 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/orders/tools/order_book_state_converter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_ORDERS_TOOLS_PERSISTENT_STATE_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_ORDERS_TOOLS_PERSISTENT_STATE_HPP_ 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "ih/orders/book/order_book.hpp" 6 | 7 | namespace simulator::trading_system::matching_engine { 8 | 9 | auto store_order_book_state(OrderBook& order_book, 10 | market_state::OrderBook& state) -> void; 11 | 12 | } // namespace simulator::trading_system::matching_engine 13 | 14 | #endif // SIMULATOR_MATCHING_ENGINE_IH_ORDERS_TOOLS_PERSISTENT_STATE_HPP_ 15 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/orders/tools/order_lookup.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_TOOLS_ORDER_RESOLVER_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_TOOLS_ORDER_RESOLVER_HPP_ 3 | 4 | #include "ih/orders/book/order_book.hpp" 5 | #include "ih/orders/book/order_updates.hpp" 6 | 7 | namespace simulator::trading_system::matching_engine { 8 | 9 | struct AmendLmtOrder; 10 | struct CancelOrder; 11 | 12 | } // namespace simulator::trading_system::matching_engine 13 | 14 | namespace simulator::trading_system::matching_engine { 15 | 16 | [[nodiscard]] 17 | auto find_target_limit_order(OrderPage& page, const LimitUpdate& update) 18 | -> LimitOrdersContainer::iterator; 19 | 20 | [[nodiscard]] 21 | auto find_target_limit_order(OrderPage& page, const OrderCancel& cancel) 22 | -> LimitOrdersContainer::iterator; 23 | 24 | } // namespace simulator::trading_system::matching_engine 25 | 26 | #endif // SIMULATOR_MATCHING_ENGINE_IH_TOOLS_ORDER_RESOLVER_HPP_ -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/ih/orders/validation/order_book_side.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_IH_ORDERS_VALIDATION_ORDER_BOOK_SIDE_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_IH_ORDERS_VALIDATION_ORDER_BOOK_SIDE_HPP_ 3 | 4 | #include 5 | 6 | namespace simulator::trading_system::matching_engine::order { 7 | 8 | enum class OrderBookSide : std::uint8_t { Buy, Sell }; 9 | 10 | } // namespace simulator::trading_system::matching_engine::order 11 | 12 | #endif // SIMULATOR_MATCHING_ENGINE_IH_ORDERS_VALIDATION_ORDER_BOOK_SIDE_HPP_ 13 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/src/market_data/actions/market_data_recover.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/market_data/actions/market_data_recover.hpp" 2 | 3 | namespace simulator::trading_system::matching_engine::mdata { 4 | 5 | MarketDataRecover::MarketDataRecover(EventListener& event_listener) 6 | : EventReporter{event_listener} {} 7 | 8 | auto MarketDataRecover::operator()(std::optional last_trade) -> void { 9 | emit(OrderBookNotification{LastTradeRecover{std::move(last_trade)}}); 10 | } 11 | 12 | auto MarketDataRecover::operator()( 13 | std::optional info) -> void { 14 | emit(OrderBookNotification{InstrumentInfoRecover{std::move(info)}}); 15 | } 16 | 17 | } // namespace simulator::trading_system::matching_engine::mdata 18 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/src/market_data/tools/market_entry_id_generator.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/market_data/tools/market_entry_id_generator.hpp" 2 | 3 | #include "idgen/market_entry_id.hpp" 4 | 5 | namespace simulator::trading_system::matching_engine::mdata { 6 | 7 | namespace { 8 | 9 | class IdgenImplementation : public MarketEntryIdGenerator { 10 | public: 11 | IdgenImplementation() 12 | : generation_ctx_(idgen::make_market_entry_id_generation_ctx()) {} 13 | 14 | auto operator()() -> MarketEntryId override { 15 | return idgen::generate_new_id(generation_ctx_); 16 | } 17 | 18 | private: 19 | idgen::MarketEntryIdContext generation_ctx_; 20 | }; 21 | 22 | } // namespace 23 | 24 | auto MarketEntryIdGenerator::create() 25 | -> std::unique_ptr { 26 | return std::make_unique(); 27 | } 28 | 29 | } // namespace simulator::trading_system::matching_engine::mdata -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/src/orders/tools/order_id_generator.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/orders/tools/order_id_generator.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include "idgen/order_id.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine::order { 9 | 10 | namespace { 11 | 12 | class IdgenOrderIdImplementation : public OrderIdGenerator { 13 | public: 14 | IdgenOrderIdImplementation() 15 | : gen_context_(idgen::make_order_id_generation_ctx()) {} 16 | 17 | auto operator()() -> OrderId override { 18 | return idgen::generate_new_id(gen_context_); 19 | } 20 | 21 | private: 22 | idgen::OrderIdContext gen_context_; 23 | }; 24 | 25 | } // namespace 26 | 27 | auto OrderIdGenerator::create() -> std::unique_ptr { 28 | return std::make_unique(); 29 | } 30 | 31 | auto generate_order_id(OrderIdGenerator& generator) -> OrderId { 32 | return std::invoke(generator); 33 | } 34 | 35 | } // namespace simulator::trading_system::matching_engine::order -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/actions/save_copy_constructible.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_ACTIONS_SAVE_COPY_CONSTRUCTIBLE_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_ACTIONS_SAVE_COPY_CONSTRUCTIBLE_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace simulator::trading_system::matching_engine::test { 10 | 11 | template 12 | struct SaveMoveConstructibleAction { 13 | std::unique_ptr& pointer_ref; 14 | 15 | template 16 | void operator()(const Args&... args) const { 17 | pointer_ref = std::make_unique(std::get(std::tie(args...))); 18 | } 19 | }; 20 | 21 | template 22 | auto save_copy_constructible(std::unique_ptr& pointer) 23 | -> SaveMoveConstructibleAction { 24 | return {pointer}; 25 | } 26 | 27 | } 28 | 29 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_ACTIONS_SAVE_COPY_CONSTRUCTIBLE_HPP_ -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/mocks/event_listener_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_EVENT_LISTENER_MOCK_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_EVENT_LISTENER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/common/abstractions/event_listener.hpp" 7 | #include "ih/common/events/event.hpp" 8 | 9 | namespace simulator::trading_system::matching_engine { 10 | 11 | class EventListenerMock : public EventListener { 12 | public: 13 | MOCK_METHOD(void, on, (Event), (override)); 14 | }; 15 | 16 | } // namespace simulator::trading_system::matching_engine 17 | 18 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_EVENT_LISTENER_MOCK_HPP_ 19 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/mocks/market_data_publisher_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MARKET_DATA_PUBLISHER_MOCK_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MARKET_DATA_PUBLISHER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/common/abstractions/market_data_publisher.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine { 9 | 10 | struct MarketDataPublisherMock : public MarketDataPublisher { 11 | MOCK_METHOD(void, publish, (), (override)); 12 | }; 13 | 14 | } // namespace simulator::trading_system::matching_engine 15 | 16 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MARKET_DATA_PUBLISHER_MOCK_HPP_ 17 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/mocks/mock_execution_reports_listener.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MOCK_EXECUTION_REPORTS_LISTENER_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MOCK_EXECUTION_REPORTS_LISTENER_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/common/abstractions/event_listener.hpp" 7 | #include "ih/common/events/event.hpp" 8 | #include "protocol/app/execution_report.hpp" 9 | 10 | namespace simulator::trading_system::matching_engine { 11 | 12 | struct MockExecutionReportsListener : public EventListener { 13 | std::vector reports; 14 | 15 | private: 16 | auto on(Event event) -> void override; 17 | }; 18 | 19 | } // namespace simulator::trading_system::matching_engine 20 | 21 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MOCK_EXECUTION_REPORTS_LISTENER_HPP_ 22 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/mocks/mock_market_entry_id_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MOCK_MARKET_ENTRY_ID_GENERATOR_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MOCK_MARKET_ENTRY_ID_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/market_data/tools/market_entry_id_generator.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine { 9 | 10 | class MockMarketEntryIdGenerator : public mdata::MarketEntryIdGenerator { 11 | public: 12 | MOCK_METHOD(MarketEntryId, generate, ()); 13 | 14 | private: 15 | auto operator()() -> MarketEntryId override { return generate(); } 16 | }; 17 | 18 | } // namespace simulator::trading_system::matching_engine 19 | 20 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_MOCK_MARKET_ENTRY_ID_GENERATOR_HPP_ 21 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/mocks/mock_order_id_generator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_PROJECT_V2_TRADING_SYSTEM_COMPONENTS_MATCHING_ENGINE_TESTS_MOCKS_MOCK_ORDER_ID_GENERATOR_HPP_ 2 | #define SIMULATOR_PROJECT_V2_TRADING_SYSTEM_COMPONENTS_MATCHING_ENGINE_TESTS_MOCKS_MOCK_ORDER_ID_GENERATOR_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/orders/tools/order_id_generator.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine { 9 | 10 | class MockOrderIdGenerator : public order::OrderIdGenerator { 11 | public: 12 | MOCK_METHOD(OrderId, generate, (), (const)); 13 | 14 | private: 15 | auto operator()() -> OrderId override; 16 | }; 17 | 18 | } // namespace simulator::trading_system::matching_engine 19 | 20 | #endif // SIMULATOR_PROJECT_V2_TRADING_SYSTEM_COMPONENTS_MATCHING_ENGINE_TESTS_MOCKS_MOCK_ORDER_ID_GENERATOR_HPP_ 21 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/mocks/order_event_handler_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_ORDER_EVENT_HANDLER_MOCK_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_ORDER_EVENT_HANDLER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/common/abstractions/order_event_handler.hpp" 7 | 8 | namespace simulator::trading_system::matching_engine { 9 | 10 | class OrderEventHandlerMock : public OrderEventHandler { 11 | public: 12 | MOCK_METHOD(void, handle, (const event::Tick& tick), (override)); 13 | MOCK_METHOD(void, 14 | handle, 15 | (const event::PhaseTransition& phase_transition), 16 | (override)); 17 | MOCK_METHOD(void, 18 | handle_disconnection, 19 | (const protocol::Session& session), 20 | (override)); 21 | }; 22 | 23 | } // namespace simulator::trading_system::matching_engine 24 | 25 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_MOCKS_ORDER_EVENT_HANDLER_MOCK_HPP_ 26 | -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char **argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/trading_system/components/matching_engine/tests/tools/protocol_test_tools.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_MATCHING_ENGINE_TESTS_TOOLS_PROTOCOL_TOOLS_HPP_ 2 | #define SIMULATOR_MATCHING_ENGINE_TESTS_TOOLS_PROTOCOL_TOOLS_HPP_ 3 | 4 | #include "common/market_state/snapshot.hpp" 5 | #include "protocol/types/session.hpp" 6 | 7 | namespace simulator::trading_system::matching_engine { 8 | 9 | template 10 | auto make_message() -> MessageType { 11 | return MessageType{protocol::Session{protocol::generator::Session{}}}; 12 | } 13 | 14 | template <> 15 | inline auto make_message() -> market_state::LimitOrder { 16 | return {}; 17 | } 18 | 19 | } // namespace simulator::trading_system::matching_engine 20 | 21 | #endif // SIMULATOR_MATCHING_ENGINE_TESTS_TOOLS_PROTOCOL_TOOLS_HPP_ 22 | -------------------------------------------------------------------------------- /project/trading_system/components/runtime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(COMPONENT_NAME ${PROJECT_NAME}_runtime) 2 | 3 | #------------------------------------------------------------------------------# 4 | 5 | add_static_library( 6 | NAME ${COMPONENT_NAME} 7 | ALIAS ts::runtime 8 | HEADERS 9 | ih/chained_mux.hpp 10 | ih/loop_impl.hpp 11 | ih/mux_impl.hpp 12 | ih/one_second_rate_loop.hpp 13 | ih/simple_thread_pool.hpp 14 | ih/thread_pool_impl.hpp 15 | include/runtime/loop.hpp 16 | include/runtime/mux.hpp 17 | include/runtime/service.hpp 18 | include/runtime/thread_pool.hpp 19 | SOURCES 20 | src/chained_mux.cpp 21 | src/one_second_rate_loop.cpp 22 | src/runtime.cpp 23 | src/simple_thread_pool.cpp 24 | PUBLIC_INCLUDE_DIRECTORIES 25 | ${CMAKE_CURRENT_SOURCE_DIR}/include 26 | PRIVATE_INCLUDE_DIRECTORIES 27 | ${CMAKE_CURRENT_SOURCE_DIR} 28 | PRIVATE_DEPENDENCIES 29 | simulator::log 30 | Microsoft.GSL::GSL) 31 | 32 | #------------------------------------------------------------------------------# 33 | 34 | add_subdirectory(tests) 35 | -------------------------------------------------------------------------------- /project/trading_system/components/runtime/ih/loop_impl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_RUNTIME_IH_LOOP_IMPL_HPP_ 2 | #define SIMULATOR_RUNTIME_IH_LOOP_IMPL_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "runtime/loop.hpp" 8 | 9 | namespace simulator::trading_system::runtime { 10 | 11 | class Loop::Implementation { 12 | public: 13 | Implementation() = default; 14 | Implementation(const Implementation&) = delete; 15 | Implementation(Implementation&&) noexcept = delete; 16 | virtual ~Implementation() noexcept = default; 17 | 18 | auto operator=(const Implementation&) -> Implementation& = delete; 19 | auto operator=(Implementation&&) noexcept -> Implementation& = delete; 20 | 21 | virtual auto add(std::function task) -> void = 0; 22 | 23 | virtual auto run() -> void = 0; 24 | 25 | virtual auto terminate() -> void = 0; 26 | }; 27 | 28 | } // namespace simulator::trading_system::runtime 29 | 30 | #endif // SIMULATOR_RUNTIME_IH_LOOP_IMPL_HPP_ 31 | -------------------------------------------------------------------------------- /project/trading_system/components/runtime/ih/mux_impl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_RUNTIME_IH_MUX_IMPL_HPP_ 2 | #define SIMULATOR_RUNTIME_IH_MUX_IMPL_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "runtime/mux.hpp" 8 | #include "runtime/service.hpp" 9 | 10 | namespace simulator::trading_system::runtime { 11 | 12 | class Mux::Implementation { 13 | public: 14 | explicit Implementation(Service& executor) noexcept : executor_(&executor) {} 15 | 16 | Implementation() = delete; 17 | Implementation(const Implementation&) = delete; 18 | Implementation(Implementation&&) noexcept = delete; 19 | virtual ~Implementation() noexcept = default; 20 | 21 | auto operator=(const Implementation&) -> Implementation& = delete; 22 | auto operator=(Implementation&&) noexcept -> Implementation& = delete; 23 | 24 | virtual auto post(std::function task) -> void = 0; 25 | 26 | protected: 27 | gsl::not_null executor_; 28 | }; 29 | 30 | } // namespace simulator::trading_system::runtime 31 | 32 | #endif // SIMULATOR_RUNTIME_IH_MUX_IMPL_HPP_ 33 | -------------------------------------------------------------------------------- /project/trading_system/components/runtime/include/runtime/loop.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_RUNTIME_LOOP_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_RUNTIME_LOOP_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace simulator::trading_system::runtime { 9 | 10 | class Loop { 11 | public: 12 | class Implementation; 13 | 14 | [[nodiscard]] 15 | static auto create_one_second_rate_loop() -> Loop; 16 | 17 | explicit Loop(std::unique_ptr impl); 18 | 19 | Loop() = delete; 20 | Loop(const Loop&) = delete; 21 | Loop(Loop&&) noexcept; 22 | ~Loop() noexcept; 23 | 24 | auto operator=(const Loop&) -> Loop& = delete; 25 | auto operator=(Loop&&) noexcept -> Loop&; 26 | 27 | auto add(std::function task) -> void; 28 | 29 | auto run() -> void; 30 | auto terminate() -> void; 31 | 32 | private: 33 | std::unique_ptr impl_; 34 | }; 35 | 36 | } // namespace simulator::trading_system::runtime 37 | 38 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_RUNTIME_LOOP_HPP_ 39 | -------------------------------------------------------------------------------- /project/trading_system/components/runtime/include/runtime/mux.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_COMPONENTS_RUNTIME_MUX_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_COMPONENTS_RUNTIME_MUX_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "runtime/service.hpp" 8 | 9 | namespace simulator::trading_system::runtime { 10 | 11 | class Mux : public Service { 12 | public: 13 | class Implementation; 14 | 15 | [[nodiscard]] 16 | static auto create_chained_mux(Service& executor) -> Mux; 17 | 18 | explicit Mux(std::unique_ptr impl); 19 | 20 | Mux() = delete; 21 | Mux(const Mux&) = delete; 22 | Mux(Mux&&) noexcept; 23 | ~Mux() noexcept override; 24 | 25 | auto operator=(const Mux&) -> Mux& = delete; 26 | auto operator=(Mux&&) noexcept -> Mux&; 27 | 28 | auto execute(std::function task) -> void override; 29 | 30 | private: 31 | std::unique_ptr impl_; 32 | }; 33 | 34 | } // namespace simulator::trading_system::runtime 35 | 36 | #endif // SIMULATOR_TRADING_SYSTEM_COMPONENTS_RUNTIME_MUX_HPP_ 37 | -------------------------------------------------------------------------------- /project/trading_system/components/runtime/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET ${COMPONENT_NAME} 3 | UNIT_TESTS 4 | unit_tests/chained_mux_test.cpp 5 | unit_tests/one_second_rate_loop_test.cpp 6 | unit_tests/simple_thread_pool_test.cpp 7 | DEPENDENCIES 8 | fmt::fmt) -------------------------------------------------------------------------------- /project/trading_system/components/runtime/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto main(int argc, char **argv) -> int { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } -------------------------------------------------------------------------------- /project/trading_system/components/runtime/tests/unit_tests/one_second_rate_loop_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/one_second_rate_loop.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std::chrono_literals; 12 | 13 | namespace simulator::trading_system::runtime { 14 | namespace { 15 | 16 | TEST(OneSecondRateLoopDeathTest, TerminatesWhenTerminatedInLoopThread) { 17 | ASSERT_EXIT( 18 | { 19 | OneSecondRateLoop loop; 20 | loop.add([&] { loop.terminate(); }); 21 | loop.run(); 22 | // suspend the main to let the loop thread try to join itself 23 | std::this_thread::sleep_for(1s); 24 | }, 25 | ::testing::KilledBySignal(SIGABRT), 26 | ""); 27 | } 28 | 29 | TEST(OneSecondRateLoopTest, ThrowsWhenAddingTaskWhileRunning) { 30 | OneSecondRateLoop loop; 31 | 32 | loop.add([] {}); 33 | loop.run(); 34 | 35 | ASSERT_THROW(loop.add([] {}), std::logic_error); 36 | } 37 | 38 | } // namespace 39 | } // namespace simulator::trading_system::runtime -------------------------------------------------------------------------------- /project/trading_system/ih/config/venue_entry_reader.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_IH_CONFIG_VENUE_ENTRY_READER_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_IH_CONFIG_VENUE_ENTRY_READER_HPP_ 3 | 4 | #include 5 | 6 | #include "data_layer/api/models/venue.hpp" 7 | #include "ih/config/config.hpp" 8 | 9 | namespace simulator::trading_system { 10 | 11 | class VenueEntryReader { 12 | public: 13 | explicit VenueEntryReader(Config& destination) : destination_(&destination) {} 14 | 15 | VenueEntryReader() = delete; 16 | VenueEntryReader(const VenueEntryReader&) = delete; 17 | VenueEntryReader(VenueEntryReader&&) = delete; 18 | ~VenueEntryReader() = default; 19 | 20 | auto operator()(const data_layer::Venue& record) const -> void; 21 | 22 | private: 23 | 24 | gsl::not_null destination_; 25 | }; 26 | 27 | } // namespace simulator::trading_system 28 | 29 | #endif // SIMULATOR_TRADING_SYSTEM_IH_CONFIG_VENUE_ENTRY_READER_HPP_ 30 | -------------------------------------------------------------------------------- /project/trading_system/ih/state_persistence/serializer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_IH_STATE_PERSISTENCE_SERIALIZER_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_IH_STATE_PERSISTENCE_SERIALIZER_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "common/market_state/snapshot.hpp" 9 | 10 | namespace simulator::trading_system { 11 | 12 | struct Serializer { 13 | virtual auto serialize(const market_state::Snapshot& snapshot, 14 | std::ostream& os) const -> bool = 0; 15 | 16 | virtual auto deserialize(std::istream& is) const 17 | -> tl::expected = 0; 18 | 19 | virtual ~Serializer() = default; 20 | }; 21 | 22 | class JsonSerializer : public Serializer { 23 | public: 24 | auto serialize(const market_state::Snapshot& snapshot, std::ostream& os) const 25 | -> bool override; 26 | 27 | [[nodiscard]] 28 | auto deserialize(std::istream& is) const 29 | -> tl::expected override; 30 | }; 31 | 32 | } // namespace simulator::trading_system 33 | 34 | #endif // SIMULATOR_TRADING_SYSTEM_IH_STATE_PERSISTENCE_SERIALIZER_HPP_ 35 | -------------------------------------------------------------------------------- /project/trading_system/src/repository/repository_accessor.cpp: -------------------------------------------------------------------------------- 1 | #include "ih/repository/repository_accessor.hpp" 2 | 3 | #include "ih/repository/trading_engines_repository.hpp" 4 | 5 | namespace simulator::trading_system { 6 | 7 | namespace { 8 | 9 | class TradingEngineRepositoryAccessor : public RepositoryAccessor { 10 | public: 11 | explicit TradingEngineRepositoryAccessor( 12 | const TradingEnginesRepository& repository) 13 | : repository_(repository) {} 14 | 15 | private: 16 | auto unicast_impl(InstrumentId instrument_id, 17 | Action action) const -> void override { 18 | action(repository_.find_instrument_engine(instrument_id)); 19 | } 20 | 21 | auto broadcast_impl(Action action) const -> void override { 22 | repository_.for_each_engine(action); 23 | } 24 | 25 | const TradingEnginesRepository& repository_; 26 | }; 27 | 28 | } // namespace 29 | 30 | auto RepositoryAccessor::create(const TradingEnginesRepository& repository) 31 | -> std::unique_ptr { 32 | return std::make_unique(repository); 33 | } 34 | 35 | } // namespace simulator::trading_system -------------------------------------------------------------------------------- /project/trading_system/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_target_tests( 2 | TARGET 3 | ${PROJECT_NAME} 4 | HEADERS 5 | mocks/executor_mock.hpp 6 | mocks/instrument_resolver_mock.hpp 7 | mocks/repository_accessor_mock.hpp 8 | mocks/serializer_mock.hpp 9 | mocks/trading_engine_mock.hpp 10 | mocks/trading_reply_receiver_mock.hpp 11 | UNIT_TESTS 12 | unit_tests/config/phase_entry_reader_tests.cpp 13 | unit_tests/config/venue_entry_reader_tests.cpp 14 | unit_tests/execution/execution_system_tests.cpp 15 | unit_tests/execution/reject_notifier_tests.cpp 16 | unit_tests/repository/trading_engines_repository_tests.cpp 17 | unit_tests/state_persistence/market_state_persistence_controller_tests.cpp 18 | unit_tests/state_persistence/serializer_tests.cpp 19 | unit_tests/tools/instrument_resolver_tests.cpp 20 | DEPENDENCIES 21 | simulator::cfg) 22 | -------------------------------------------------------------------------------- /project/trading_system/tests/mocks/instrument_resolver_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_INSTRUMENT_RESOLVER_MOCK_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_INSTRUMENT_RESOLVER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "core/domain/instrument_descriptor.hpp" 9 | #include "ih/tools/instrument_resolver.hpp" 10 | #include "instruments/lookup_error.hpp" 11 | #include "instruments/view.hpp" 12 | 13 | namespace simulator::trading_system::test { 14 | 15 | struct InstrumentResolverMock : public InstrumentResolver { 16 | using ReturnType = tl::expected; 17 | 18 | MOCK_METHOD(ReturnType, 19 | resolve_instrument, 20 | (const InstrumentDescriptor&), 21 | (const, override)); 22 | MOCK_METHOD(ReturnType, 23 | resolve_instrument, 24 | (const Instrument&), 25 | (const, override)); 26 | }; 27 | 28 | } // namespace simulator::trading_system::test 29 | 30 | #endif // SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_INSTRUMENT_RESOLVER_MOCK_HPP_ 31 | -------------------------------------------------------------------------------- /project/trading_system/tests/mocks/repository_accessor_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_REQUEST_EXECUTOR_MOCK_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_REQUEST_EXECUTOR_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/repository/repository_accessor.hpp" 7 | 8 | namespace simulator::trading_system::test { 9 | 10 | struct RepositoryAccessorMock : public RepositoryAccessor { 11 | // clang-format off 12 | MOCK_METHOD(void, unicast_impl, (InstrumentId, tl::function_ref), (const override)); 13 | MOCK_METHOD(void, broadcast_impl, (tl::function_ref), (const override)); 14 | // clang-format on 15 | }; 16 | 17 | } // namespace simulator::trading_system::test 18 | 19 | #endif // SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_REQUEST_EXECUTOR_MOCK_HPP_ 20 | -------------------------------------------------------------------------------- /project/trading_system/tests/mocks/serializer_mock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_SERIALIZER_MOCK_HPP_ 2 | #define SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_SERIALIZER_MOCK_HPP_ 3 | 4 | #include 5 | 6 | #include "ih/state_persistence/serializer.hpp" 7 | 8 | namespace simulator::trading_system::test { 9 | 10 | struct SerializerMock : public simulator::trading_system::Serializer { 11 | MOCK_METHOD( 12 | bool, 13 | serialize, 14 | (const simulator::trading_system::market_state::Snapshot& snapshot, 15 | std::ostream& os), 16 | (const, override)); 17 | MOCK_METHOD((tl::expected), 19 | deserialize, 20 | (std::istream & is), 21 | (const, override)); 22 | }; 23 | 24 | } // namespace simulator::trading_system::test 25 | 26 | #endif // SIMULATOR_TRADING_SYSTEM_TESTS_MOCKS_SERIALIZER_MOCK_HPP_ 27 | -------------------------------------------------------------------------------- /project/trading_system/tests/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "cfg/api/cfg.hpp" 4 | 5 | auto main(int argc, char **argv) -> int { 6 | testing::InitGoogleTest(&argc, argv); 7 | 8 | simulator::cfg::init(); 9 | 10 | return RUN_ALL_TESTS(); 11 | } -------------------------------------------------------------------------------- /template/cfg/configSim.txt: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | ConnectionType=acceptor 3 | SocketAcceptPort=9051 4 | SocketReuseAddress=Y 5 | SocketNodelay=Y 6 | AppDataDictionary=/market-simulator/quod/data/cfg/default/FIX50SP2_marketsimulator.xml 7 | TransportDataDictionary=/market-simulator/quod/data/cfg/default/FIXT11_marketsimulator.xml 8 | StartTime=00:00:00 9 | EndTime=00:00:00 10 | HeartBtInt=30 11 | 12 | [SESSION] 13 | BeginString=FIXT.1.1 14 | SenderCompID=SIM_XETRA 15 | TargetCompID=CLIENT_XETRA 16 | DefaultApplVerID=9 17 | PersistMessages=Y 18 | FileStorePath=/market-simulator/quod/data/files_store_path_common 19 | ResetOnLogon=Y 20 | RefreshOnLogon=N 21 | --------------------------------------------------------------------------------