Running the Flox Engine
This guide explains how to initialize and run the Flox engine using a custom IEngineBuilder
implementation.
Structure
To launch the engine, you are expected to:
- Implement the
IEngineBuilder
interface - Provide subsystems, connectors, and strategies
- Return a fully initialized
Engine
instance
Example
Here’s a simplified version based on DemoEngineBuilder
:
class DemoEngineBuilder : public IEngineBuilder {
public:
DemoEngineBuilder(const EngineConfig &config)
: _config(config) {}
std::unique_ptr<Engine> build() override {
auto registry = std::make_unique<SymbolRegistry>();
auto mdb = std::make_unique<MarketDataBus>();
// Register exchange connectors
ConnectorFactory::instance().registerConnector("bybit",
[mdb = mdb.get(), registry = registry.get()](const std::string &symbolStr) {
auto symbolId = registry->getSymbolId("bybit", symbolStr);
auto conn = std::make_shared<BybitExchangeConnector>(symbolStr, *symbolId);
conn->setCallbacks(
[mdb](const BookUpdate &b) { mdb->onBookUpdate(b); },
[mdb](const Trade &t) { mdb->onTrade(t); });
return conn;
});
std::vector<std::shared_ptr<ExchangeConnector>> connectors;
std::vector<std::unique_ptr<ISubsystem>> subsystems;
// Register symbols and connectors
for (const auto &ex : _config.exchanges) {
for (const auto &sym : ex.symbols) {
auto id = registry->registerSymbol(ex.name, sym.symbol);
auto conn = ConnectorFactory::instance().createConnector(ex.name, sym.symbol);
if (conn) connectors.push_back(conn);
}
}
auto strategyMgr = std::make_unique<StrategyManager>();
// Subscribe strategies to market data
for (const auto &symbol : registry->getAllSymbolIds()) {
mdb->subscribeToBookUpdates(symbol, [strategyMgrRaw = strategyMgr.get()](const BookUpdate &b) {
strategyMgrRaw->onBookUpdate(b);
});
mdb->subscribeToTrades(symbol, [strategyMgrRaw = strategyMgr.get()](const Trade &t) {
strategyMgrRaw->onTrade(t);
});
}
// Load strategies from config
auto strategies = ImpulseBreakoutStrategyFactory::createStrategiesFromFile(
"impulse_breakout_config.json", registry.get());
for (const auto &strat : strategies) {
auto executor = std::make_unique<SimulatedOrderExecutor>();
strat->setOrderExecutor(executor.get());
strategyMgr->addStrategy(strat);
subsystems.push_back(std::move(executor));
}
subsystems.push_back(std::move(mdb));
subsystems.push_back(std::move(strategyMgr));
subsystems.push_back(std::make_unique<Subsystem<SymbolRegistry>>(std::move(registry)));
return std::make_unique<Engine>(_config, std::move(subsystems), std::move(connectors));
}
private:
EngineConfig _config;
};
Notes
- Use
Subsystem<T>
to wrap all non-ISubsystem components - Strategy implementations and symbol registration should be dynamic
- Execution is triggered via:
auto engine = builder.build();
engine->start();
Refer to your implementation of EngineBuilder
to control strategy loading and exchange support.