Files
QTradeProgram/common_structures/TradingStructures.h
2026-02-25 23:01:42 +08:00

280 lines
6.6 KiB
C++

#ifndef TRADING_STRUCTURES_H
#define TRADING_STRUCTURES_H
#include <QString>
#include <QDateTime>
#include <QVariant>
#include <QMap>
#include <QList>
#include <QVector>
#include <QJsonObject>
#include <QJsonArray>
namespace Trading {
// Market types
enum class MarketType {
HK, // Hong Kong
US, // United States
CN, // China
SG, // Singapore
JP, // Japan
Unknown
};
// Data packet types for the data flow
enum class DataPacketType {
RealTimeQuote, // 实时报价
OrderBook, // 实时摆盘
KLine, // 实时K线
Tick, // 实时逐笔
BrokerQueue, // 实时经纪队列
Unknown
};
// Order types
enum class OrderType {
Market,
Limit,
Stop,
StopLimit,
Iceberg,
TWAP,
VWAP,
Unknown
};
// Order status
enum class OrderStatus {
Pending,
Submitted,
PartiallyFilled,
Filled,
Cancelled,
Rejected,
Expired,
Unknown
};
// Order side
enum class OrderSide {
Buy,
Sell,
Short,
Cover,
Unknown
};
// Connection status
enum class ConnectionState {
Disconnected,
Connecting,
Connected,
Degraded,
Failed
};
// Basic stock information
struct StockInfo {
QString symbol;
QString name;
MarketType market;
QString currency;
double pricePrecision = 0.01;
int quantityPrecision = 1;
double minTradeAmount = 0.0;
double maxTradeAmount = 0.0;
bool isTradable = true;
StockInfo() = default;
StockInfo(const QString& sym, const QString& nm, MarketType mkt)
: symbol(sym), name(nm), market(mkt) {}
};
// Data packet structure for the data flow
struct DataPacket {
DataPacketType type;
QString stockCode;
QDateTime timestamp;
QVariant data;
int priority; // Priority 0-9, 9 is highest
DataPacket(DataPacketType t, const QString& code, const QVariant& d, int prio = 5)
: type(t), stockCode(code), timestamp(QDateTime::currentDateTime()), data(d), priority(prio) {}
};
// Real-time quote data
struct QuoteData {
QString symbol;
QDateTime timestamp;
double lastPrice = 0.0;
double openPrice = 0.0;
double highPrice = 0.0;
double lowPrice = 0.0;
double closePrice = 0.0;
double volume = 0.0;
double turnover = 0.0;
double bidPrice = 0.0;
double askPrice = 0.0;
qint64 bidVolume = 0;
qint64 askVolume = 0;
double change = 0.0;
double changePercent = 0.0;
bool isValid() const {
return !symbol.isEmpty() && timestamp.isValid() && lastPrice > 0;
}
};
// Order book level
struct OrderBookLevel {
double price = 0.0;
qint64 volume = 0;
int orderCount = 0;
OrderBookLevel() = default;
OrderBookLevel(double p, qint64 v, int count = 1)
: price(p), volume(v), orderCount(count) {}
};
// Complete order book
struct OrderBook {
QString symbol;
QDateTime timestamp;
QVector<OrderBookLevel> bids; // Buy side, sorted descending by price
QVector<OrderBookLevel> asks; // Sell side, sorted ascending by price
bool isValid() const {
return !symbol.isEmpty() && timestamp.isValid();
}
double getSpread() const {
if (bids.isEmpty() || asks.isEmpty()) return 0.0;
return asks.first().price - bids.first().price;
}
double getMidPrice() const {
if (bids.isEmpty() || asks.isEmpty()) return 0.0;
return (bids.first().price + asks.first().price) / 2.0;
}
};
// Trading order
struct Order {
QString orderId;
QString symbol;
OrderType type = OrderType::Limit;
OrderSide side = OrderSide::Buy;
OrderStatus status = OrderStatus::Pending;
double price = 0.0;
qint64 quantity = 0;
qint64 filledQuantity = 0;
double filledAmount = 0.0;
QDateTime createTime;
QDateTime updateTime;
QString accountId;
QString strategyId;
QVariant customData;
bool isValid() const {
return !orderId.isEmpty() && !symbol.isEmpty() && quantity > 0;
}
double getAveragePrice() const {
return filledQuantity > 0 ? filledAmount / filledQuantity : 0.0;
}
qint64 getRemainingQuantity() const {
return quantity - filledQuantity;
}
};
// Trade execution
struct Trade {
QString tradeId;
QString orderId;
QString symbol;
OrderSide side = OrderSide::Buy;
double price = 0.0;
qint64 quantity = 0;
double amount = 0.0;
QDateTime tradeTime;
QString exchangeId;
bool isValid() const {
return !tradeId.isEmpty() && !orderId.isEmpty() && quantity > 0 && price > 0;
}
};
// System configuration based on design document
struct SystemConfig {
// Connection parameters
QString serverAddress = "localhost";
int serverPort = 8080;
int heartbeatIntervalMs = 5000;
int reconnectTimeoutMs = 10000;
int maxReconnectAttempts = 3;
// Data flow parameters
int dataBufferSize = 10000;
int maxDataRatePerSecond = 1000;
bool enableFlowControl = true;
// Trading parameters
double defaultOrderSize = 1000;
double maxOrderSize = 10000;
double minOrderSize = 100;
int orderTimeoutSeconds = 30;
// Risk parameters
double maxPositionValue = 1000000.0;
double maxDailyLoss = 50000.0;
double maxSingleOrderValue = 100000.0;
// Monitoring parameters
bool enableDebugLog = false;
int logRetentionDays = 30;
QString logLevel = "INFO";
// Data quality parameters
bool enableDataValidation = true;
double maxPriceDeviation = 0.1; // 10%
int maxOrderBookDepth = 10;
};
// Performance metrics
struct PerformanceMetrics {
double totalReturn = 0.0;
double dailyReturn = 0.0;
double sharpeRatio = 0.0;
double maxDrawdown = 0.0;
double winRate = 0.0;
double profitFactor = 0.0;
int totalTrades = 0;
int winningTrades = 0;
int losingTrades = 0;
double averageWin = 0.0;
double averageLoss = 0.0;
QDateTime periodStart;
QDateTime periodEnd;
void updateMetrics(bool isWin, double pnl) {
totalTrades++;
if (isWin) {
winningTrades++;
averageWin = (averageWin * (winningTrades - 1) + pnl) / winningTrades;
} else {
losingTrades++;
averageLoss = (averageLoss * (losingTrades - 1) + pnl) / losingTrades;
}
winRate = static_cast<double>(winningTrades) / totalTrades;
if (losingTrades > 0 && averageLoss != 0) {
profitFactor = (averageWin * winningTrades) / (std::abs(averageLoss) * losingTrades);
}
}
};
} // namespace Trading
#endif // TRADING_STRUCTURES_H