mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-11 06:46:59 +08:00
feat(gate): complete Gate.io exchange integration with trader refactoring
Gate.io Integration: - Add Gate trader with full Trader interface implementation - Add order_sync.go for background trade synchronization - Fix quantity display (convert contracts to actual tokens via quanto_multiplier) - Fix fill price return in OpenLong/OpenShort/CloseLong/CloseShort - Add Gate-specific CoinAnk K-line data source support - Add Gate to supported exchanges in frontend and backend - Add Gate/KuCoin logo SVG icons Trader Package Refactoring: - Move exchange-specific code into subdirectories (binance/, bybit/, okx/, bitget/, hyperliquid/, aster/, lighter/, gate/) - Create types/ package for shared types to avoid circular dependencies - Move TraderTestSuite to trader/testutil package to avoid import cycles - Update market.GetWithExchange to support exchange-specific data
This commit is contained in:
@@ -3,161 +3,19 @@ package trader
|
||||
import (
|
||||
"fmt"
|
||||
"nofx/logger"
|
||||
"time"
|
||||
"nofx/trader/types"
|
||||
)
|
||||
|
||||
// ClosedPnLRecord represents a single closed position record from exchange
|
||||
type ClosedPnLRecord struct {
|
||||
Symbol string // Trading pair (e.g., "BTCUSDT")
|
||||
Side string // "long" or "short"
|
||||
EntryPrice float64 // Entry price
|
||||
ExitPrice float64 // Exit/close price
|
||||
Quantity float64 // Position size
|
||||
RealizedPnL float64 // Realized profit/loss
|
||||
Fee float64 // Trading fee/commission
|
||||
Leverage int // Leverage used
|
||||
EntryTime time.Time // Position open time
|
||||
ExitTime time.Time // Position close time
|
||||
OrderID string // Close order ID
|
||||
CloseType string // "manual", "stop_loss", "take_profit", "liquidation", "unknown"
|
||||
ExchangeID string // Exchange-specific position ID
|
||||
}
|
||||
|
||||
// TradeRecord represents a single trade/fill from exchange
|
||||
// Used for reconstructing position history with unified algorithm
|
||||
type TradeRecord struct {
|
||||
TradeID string // Unique trade ID from exchange
|
||||
Symbol string // Trading pair (e.g., "BTCUSDT")
|
||||
Side string // "BUY" or "SELL"
|
||||
PositionSide string // "LONG", "SHORT", or "BOTH" (for one-way mode)
|
||||
OrderAction string // "open_long", "open_short", "close_long", "close_short" (from exchange Dir field)
|
||||
Price float64 // Execution price
|
||||
Quantity float64 // Executed quantity
|
||||
RealizedPnL float64 // Realized PnL (non-zero for closing trades)
|
||||
Fee float64 // Trading fee/commission
|
||||
Time time.Time // Trade execution time
|
||||
}
|
||||
|
||||
// Trader Unified trader interface
|
||||
// Supports multiple trading platforms (Binance, Hyperliquid, etc.)
|
||||
type Trader interface {
|
||||
// GetBalance Get account balance
|
||||
GetBalance() (map[string]interface{}, error)
|
||||
|
||||
// GetPositions Get all positions
|
||||
GetPositions() ([]map[string]interface{}, error)
|
||||
|
||||
// OpenLong Open long position
|
||||
OpenLong(symbol string, quantity float64, leverage int) (map[string]interface{}, error)
|
||||
|
||||
// OpenShort Open short position
|
||||
OpenShort(symbol string, quantity float64, leverage int) (map[string]interface{}, error)
|
||||
|
||||
// CloseLong Close long position (quantity=0 means close all)
|
||||
CloseLong(symbol string, quantity float64) (map[string]interface{}, error)
|
||||
|
||||
// CloseShort Close short position (quantity=0 means close all)
|
||||
CloseShort(symbol string, quantity float64) (map[string]interface{}, error)
|
||||
|
||||
// SetLeverage Set leverage
|
||||
SetLeverage(symbol string, leverage int) error
|
||||
|
||||
// SetMarginMode Set position mode (true=cross margin, false=isolated margin)
|
||||
SetMarginMode(symbol string, isCrossMargin bool) error
|
||||
|
||||
// GetMarketPrice Get market price
|
||||
GetMarketPrice(symbol string) (float64, error)
|
||||
|
||||
// SetStopLoss Set stop-loss order
|
||||
SetStopLoss(symbol string, positionSide string, quantity, stopPrice float64) error
|
||||
|
||||
// SetTakeProfit Set take-profit order
|
||||
SetTakeProfit(symbol string, positionSide string, quantity, takeProfitPrice float64) error
|
||||
|
||||
// CancelStopLossOrders Cancel only stop-loss orders (BUG fix: don't delete take-profit when adjusting stop-loss)
|
||||
CancelStopLossOrders(symbol string) error
|
||||
|
||||
// CancelTakeProfitOrders Cancel only take-profit orders (BUG fix: don't delete stop-loss when adjusting take-profit)
|
||||
CancelTakeProfitOrders(symbol string) error
|
||||
|
||||
// CancelAllOrders Cancel all pending orders for this symbol
|
||||
CancelAllOrders(symbol string) error
|
||||
|
||||
// CancelStopOrders Cancel stop-loss/take-profit orders for this symbol (for adjusting stop-loss/take-profit positions)
|
||||
CancelStopOrders(symbol string) error
|
||||
|
||||
// FormatQuantity Format quantity to correct precision
|
||||
FormatQuantity(symbol string, quantity float64) (string, error)
|
||||
|
||||
// GetOrderStatus Get order status
|
||||
// Returns: status(FILLED/NEW/CANCELED), avgPrice, executedQty, commission
|
||||
GetOrderStatus(symbol string, orderID string) (map[string]interface{}, error)
|
||||
|
||||
// GetClosedPnL Get closed position PnL records from exchange
|
||||
// startTime: start time for query (usually last sync time)
|
||||
// limit: max number of records to return
|
||||
// Returns accurate exit price, fees, and close reason for positions closed externally
|
||||
GetClosedPnL(startTime time.Time, limit int) ([]ClosedPnLRecord, error)
|
||||
|
||||
// GetOpenOrders Get open/pending orders from exchange
|
||||
// Returns stop-loss, take-profit, and limit orders that haven't been filled
|
||||
GetOpenOrders(symbol string) ([]OpenOrder, error)
|
||||
}
|
||||
|
||||
// OpenOrder represents a pending order on the exchange
|
||||
type OpenOrder struct {
|
||||
OrderID string `json:"order_id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"` // BUY/SELL
|
||||
PositionSide string `json:"position_side"` // LONG/SHORT
|
||||
Type string `json:"type"` // LIMIT/STOP_MARKET/TAKE_PROFIT_MARKET
|
||||
Price float64 `json:"price"` // Order price (for limit orders)
|
||||
StopPrice float64 `json:"stop_price"` // Trigger price (for stop orders)
|
||||
Quantity float64 `json:"quantity"`
|
||||
Status string `json:"status"` // NEW
|
||||
}
|
||||
|
||||
// LimitOrderRequest represents a limit order request for grid trading
|
||||
type LimitOrderRequest struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"` // BUY/SELL
|
||||
PositionSide string `json:"position_side"` // LONG/SHORT (for hedge mode)
|
||||
Price float64 `json:"price"` // Limit price
|
||||
Quantity float64 `json:"quantity"`
|
||||
Leverage int `json:"leverage"`
|
||||
PostOnly bool `json:"post_only"` // Maker only order
|
||||
ReduceOnly bool `json:"reduce_only"` // Reduce position only
|
||||
ClientID string `json:"client_id"` // Client order ID for tracking
|
||||
}
|
||||
|
||||
// LimitOrderResult represents the result of placing a limit order
|
||||
type LimitOrderResult struct {
|
||||
OrderID string `json:"order_id"`
|
||||
ClientID string `json:"client_id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
PositionSide string `json:"position_side"`
|
||||
Price float64 `json:"price"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
Status string `json:"status"` // NEW, PARTIALLY_FILLED, FILLED, CANCELED
|
||||
}
|
||||
|
||||
// GridTrader extends Trader interface with limit order support for grid trading
|
||||
// Exchanges that support grid trading should implement this interface
|
||||
type GridTrader interface {
|
||||
Trader
|
||||
|
||||
// PlaceLimitOrder places a limit order at specified price
|
||||
// Returns order ID and status
|
||||
PlaceLimitOrder(req *LimitOrderRequest) (*LimitOrderResult, error)
|
||||
|
||||
// CancelOrder cancels a specific order by ID
|
||||
CancelOrder(symbol, orderID string) error
|
||||
|
||||
// GetOrderBook gets current order book (for price validation)
|
||||
// Returns best bid/ask prices
|
||||
GetOrderBook(symbol string, depth int) (bids, asks [][]float64, err error)
|
||||
}
|
||||
// Re-export types for backward compatibility
|
||||
type (
|
||||
ClosedPnLRecord = types.ClosedPnLRecord
|
||||
TradeRecord = types.TradeRecord
|
||||
Trader = types.Trader
|
||||
OpenOrder = types.OpenOrder
|
||||
LimitOrderRequest = types.LimitOrderRequest
|
||||
LimitOrderResult = types.LimitOrderResult
|
||||
GridTrader = types.GridTrader
|
||||
)
|
||||
|
||||
// GridTraderAdapter wraps a basic Trader to provide GridTrader interface
|
||||
// Uses stop orders as a fallback when limit orders aren't directly available
|
||||
|
||||
Reference in New Issue
Block a user