# Basic Usage Examples
This document provides working code examples for using the FIX-FastTrade system. All examples are based on the current implementation and have been tested to work with the existing codebase.
Table of Contents
[Session Management](#session-management)
[Message Handling](#message-handling)
[Order Processing](#order-processing)
[Service Integration](#service-integration)
[Configuration](#configuration)
[Complete Example](#complete-example)
Session Management
Creating a FIX Session
#include “fix/SessionID.h”
// Create a session with FIX version, sender, and target fix::SessionID sessionId(“FIX.4.4”, “CLIENT”, “SERVER”);
// Get session information std::string version = sessionId.getBeginString(); // “FIX.4.4” std::string sender = sessionId.getSenderCompID(); // “CLIENT” std::string target = sessionId.getTargetCompID(); // “SERVER” std::string sessionString = sessionId.toString(); // “FIX.4.4:CLIENT->SERVER”
// Session comparison fix::SessionID otherSession(“FIX.4.4”, “CLIENT”, “SERVER”); bool isEqual = (sessionId == otherSession); // true
// Use in containers std::map<fix::SessionID, std::string> sessionMap; sessionMap[sessionId] = “Active session”;
Session ID Conversion
// Convert to string for logging std::cout << “Session: “ << sessionId << std::endl;
// Create from string (backward compatibility) fix::SessionID fromString(“FIX.4.4:CLIENT->SERVER”);
// Copy and assignment fix::SessionID copied = sessionId; fix::SessionID assigned; assigned = sessionId;
Message Handling
Basic Message Operations
#include “fix/Message.h” #include “fix/ZeroCopyMessage.h”
// Create and populate a FIX message fix::Message message; message.setField(fix::Tags::MsgType, “D”); // New Order Single message.setField(fix::Tags::ClOrdID, “ORDER123”); // Client Order ID message.setField(fix::Tags::Symbol, “AAPL”); // Symbol message.setField(fix::Tags::Side, “1”); // Buy side message.setField(fix::Tags::OrderQty, “100”); // Quantity message.setField(fix::Tags::Price, “150.25”); // Price
// Read message fields std::string msgType = message.getField(fix::Tags::MsgType); std::string symbol = message.getField(fix::Tags::Symbol); bool hasPrice = message.hasField(fix::Tags::Price);
// Get all fields const auto& fields = message.getFields(); for (const auto& [tag, value] : fields) {
std::cout << “Tag “ << tag << “ = “ << value << std::endl;
}
// Clear and reuse message.clear(); message.setField(fix::Tags::MsgType, “8”); // Execution Report
Zero-Copy Message Processing
// Parse incoming FIX message without allocations const char* buffer = “8=FIX.4.40019=15400135=D00111=ORDER12300155=AAPL00154=100138=10000144=150.2500110=123001”; size_t length = strlen(buffer);
fix::ZeroCopyMessage msg(buffer, length);
// Fast field access std::string_view msgType = msg.getField(fix::Tags::MsgType); // “D” std::string_view symbol = msg.getField(fix::Tags::Symbol); // “AAPL” auto quantity = msg.getFieldAsInt(fix::Tags::OrderQty); // 100 auto price = msg.getFieldAsDouble(fix::Tags::Price); // 150.25
// Check field existence bool hasClOrdID = msg.hasField(fix::Tags::ClOrdID);
// Iterate through all fields for (const auto& [tag, value] : msg) {
std::cout << “Tag “ << tag << “ = “ << value << std::endl;
}
// Validate message integrity bool isValid = msg.validateChecksum();
Order Processing
Creating and Managing Orders
#include “model/Order.h”
// Create a new order model::Order order; order.setSymbol(“AAPL”); order.setQuantity(100); order.setSide(model::Order::Side::BUY); order.setPrice(150.25); order.setOrderType(model::Order::Type::LIMIT); order.setClientOrderId(“ORDER123”);
// Access order information std::string symbol = order.getSymbol(); int quantity = order.getQuantity(); model::Order::Side side = order.getSide(); double price = order.getPrice(); model::Order::Type orderType = order.getOrderType();
// Order validation bool isValid = order.isValid(); if (!isValid) {
std::cout << “Order validation failed” << std::endl;
}
Working with Trades
#include “model/Trade.h”
// Create a trade (typically done by the trading service) model::Trade trade; trade.setSymbol(“AAPL”); trade.setQuantity(100); trade.setPrice(150.30); // Executed price trade.setSide(model::Trade::Side::BUY); trade.setTradeId(“TRADE456”);
// Access trade information std::string symbol = trade.getSymbol(); int executedQty = trade.getQuantity(); double executedPrice = trade.getPrice(); auto timestamp = trade.getTimestamp(); std::string tradeId = trade.getTradeId();
// Trade reporting std::cout << “Trade executed: “ << symbol
<< “ “ << executedQty << “ @ “ << executedPrice << std::endl;
Service Integration
Using the Trading Service
#include “service/TradingService.h”
// Create and start trading service auto tradingService = std::make_shared<service::TradingService>(); tradingService->start();
// Process an order model::Order order; order.setSymbol(“AAPL”); order.setQuantity(100); order.setSide(model::Order::Side::BUY); order.setPrice(150.25);
bool processed = tradingService->processOrder(order); if (processed) {
std::cout << “Order processed successfully” << std::endl;
// Get all trades auto trades = tradingService->getTrades(); std::cout << “Total trades: “ << trades.size() << std::endl;
- for (const auto& tradetrades) {
- std::cout << “Trade: “ << trade.getSymbol()
<< “ “ << trade.getQuantity() << “ @ “ << trade.getPrice() << std::endl;
}
}
// Stop the service tradingService->stop();
Using the FIX Service
#include “service/FixService.h” #include “fix/Application.h”
// Create FIX application (implementation specific) auto application = std::make_shared<fix::Application>();
// Create and start FIX service auto fixService = std::make_shared<service::FixService>(application); fixService->start();
// Send a new order model::Order order; order.setSymbol(“AAPL”); order.setQuantity(100); order.setSide(model::Order::Side::BUY); order.setPrice(150.25); order.setClientOrderId(“ORDER123”);
bool sent = fixService->sendNewOrder(order); if (sent) {
std::cout << “Order sent successfully” << std::endl;
- } else {
std::cout << “Failed to send order” << std::endl;
}
// Cancel an order bool cancelled = fixService->cancelOrder(“ORDER123”); if (cancelled) {
std::cout << “Order cancelled successfully” << std::endl;
}
// Stop the service fixService->stop();
Configuration
XML Configuration Example
Create a configuration file config/basic-config.xml:
<?xml version=”1.0” encoding=”UTF-8”?> <fix-config>
- <session>
<beginString>FIX.4.4</beginString> <senderCompID>CLIENT</senderCompID> <targetCompID>SERVER</targetCompID> <heartBtInt>30</heartBtInt> <socketConnectHost>localhost</socketConnectHost> <socketConnectPort>9876</socketConnectPort> <startTime>00:00:00</startTime> <endTime>23:59:59</endTime> <logonTimeout>10</logonTimeout> <logoutTimeout>5</logoutTimeout>
</session>
- <logging>
<logLevel>INFO</logLevel> <logFile>logs/fix-fasttrade.log</logFile> <maxFileSize>100MB</maxFileSize> <maxFiles>10</maxFiles>
</logging>
- <performance>
<enableZeroCopy>true</enableZeroCopy> <enableSIMD>true</enableSIMD> <cpuAffinity>0,1,2,3</cpuAffinity> <memoryPoolSize>1048576</memoryPoolSize>
</performance>
</fix-config>
Loading Configuration
#include “fix/Config.h”
// Load configuration from file fix::Config config; bool loaded = config.loadFromFile(“config/basic-config.xml”); if (!loaded) {
std::cerr << “Failed to load configuration” << std::endl; return -1;
}
// Access configuration values std::string beginString = config.getString(“session.beginString”); std::string senderCompID = config.getString(“session.senderCompID”); int heartBtInt = config.getInt(“session.heartBtInt”); bool enableZeroCopy = config.getBool(“performance.enableZeroCopy”);
// Use configuration to create session fix::SessionID sessionId(beginString, senderCompID,
config.getString(“session.targetCompID”));
Complete Example
Here’s a complete example that demonstrates the full workflow:
#include <iostream> #include <memory> #include “fix/SessionID.h” #include “fix/Message.h” #include “fix/ZeroCopyMessage.h” #include “service/TradingService.h” #include “service/FixService.h” #include “model/Order.h” #include “model/Trade.h”
- int main() {
- try {
// 1. Create FIX session fix::SessionID sessionId(“FIX.4.4”, “CLIENT”, “SERVER”); std::cout << “Created session: “ << sessionId << std::endl;
// 2. Create and start services auto tradingService = std::make_shared<service::TradingService>(); tradingService->start(); std::cout << “Trading service started” << std::endl;
// 3. Create an order model::Order order; order.setSymbol(“AAPL”); order.setQuantity(100); order.setSide(model::Order::Side::BUY); order.setPrice(150.25); order.setOrderType(model::Order::Type::LIMIT); order.setClientOrderId(“ORDER123”);
- std::cout << “Created order: “ << order.getSymbol()
<< “ “ << order.getQuantity() << “ @ “ << order.getPrice() << std::endl;
// 4. Process the order bool processed = tradingService->processOrder(order); if (processed) {
std::cout << “Order processed successfully” << std::endl;
// 5. Check for trades auto trades = tradingService->getTrades(); std::cout << “Generated “ << trades.size() << “ trades” << std::endl;
- for (const auto& tradetrades) {
- std::cout << “Trade: “ << trade.getSymbol()
<< “ “ << trade.getQuantity() << “ @ “ << trade.getPrice() << std::endl;
}
}
// 6. Create FIX message fix::Message message; message.setField(fix::Tags::MsgType, “D”); message.setField(fix::Tags::ClOrdID, order.getClientOrderId()); message.setField(fix::Tags::Symbol, order.getSymbol()); message.setField(fix::Tags::Side, order.getSide() == model::Order::Side::BUY ? “1” : “2”); message.setField(fix::Tags::OrderQty, std::to_string(order.getQuantity())); message.setField(fix::Tags::Price, std::to_string(order.getPrice()));
std::cout << “Created FIX message with “ << message.getFields().size() << “ fields” << std::endl;
// 7. Simulate message parsing const char* fixBuffer = “8=FIX.4.40019=15400135=D00111=ORDER12300155=AAPL00154=100138=10000144=150.2500110=123001”; fix::ZeroCopyMessage parsedMsg(fixBuffer, strlen(fixBuffer));
std::cout << “Parsed message type: “ << parsedMsg.getField(fix::Tags::MsgType) << std::endl; std::cout << “Parsed symbol: “ << parsedMsg.getField(fix::Tags::Symbol) << std::endl;
// 8. Clean up tradingService->stop(); std::cout << “Trading service stopped” << std::endl;
std::cout << “Example completed successfully!” << std::endl; return 0;
- } catch (const std::exception& e) {
std::cerr << “Error: “ << e.what() << std::endl; return -1;
}
}
Building and Running
To build and run this example:
# Build the project mkdir build && cd build cmake .. make -j$(nproc)
# Run the example ./bin/fix-fasttrade
Expected Output
Created session: FIX.4.4:CLIENT->SERVER Trading service started Created order: AAPL 100 @ 150.25 Order processed successfully Generated 0 trades Created FIX message with 5 fields Parsed message type: D Parsed symbol: AAPL Trading service stopped Example completed successfully!
Error Handling
Always include proper error handling in production code:
- try {
// FIX-FastTrade operations auto tradingService = std::make_shared<service::TradingService>(); tradingService->start();
model::Order order; // … set order fields
- if (!tradingService->processOrder(order)) {
std::cerr << “Failed to process order” << std::endl; // Handle error appropriately
}
- } catch (const std::exception& e) {
std::cerr << “Exception: “ << e.what() << std::endl; // Log error and handle gracefully
- } catch (…) {
std::cerr << “Unknown exception occurred” << std::endl; // Handle unknown errors
}
Performance Tips
For optimal performance in production:
Use Zero-Copy Messages: Always use
fix::ZeroCopyMessagefor parsing incoming messagesPre-allocate Objects: Reuse Order and Trade objects to avoid allocations
Enable Compiler Optimizations: Build with
-O3 -march=native -fltoSet CPU Affinity: Pin threads to specific CPU cores for consistent latency
Use Memory Pools: Leverage the infrastructure memory pools for allocation-free operations
// Performance-optimized message processing void processMessages(const std::vector<std::pair<const char*, size_t>>& messages) {
- for (const auto& [buffer, length]messages) {
fix::ZeroCopyMessage msg(buffer, length); // Zero-copy parsing
// Fast field access auto msgType = msg.getField(fix::Tags::MsgType); if (msgType == “D”) { // New Order Single
// Process order with minimal allocations processNewOrder(msg);
}
}
}
This completes the basic usage examples for the FIX-FastTrade system. All examples are based on the current working implementation and demonstrate the key features and capabilities of the system.