280 lines
6.6 KiB
C++
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
|