mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-12 07:16:56 +08:00
fix(trader): harden API calls with timeouts, strict balance parsing, error context
- binance/bybit/gate: SDK default http.DefaultClient has no timeout; use a dedicated 30s-timeout client so a hung connection cannot stall the loop - bybit: stop mutating http.DefaultClient.Transport, which leaked the referer header into every other HTTP request in the process - add types.ParseFloatField: empty exchange fields stay zero, but malformed numeric values now surface as errors instead of silently becoming zero balances (applied to GetBalance across 8 exchanges) - wrap order/market-data errors in auto_trader_orders and okx cancel paths with symbol context; log per-order cancel failures in okx CancelAllOrders
This commit is contained in:
@@ -3,6 +3,7 @@ package gate
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"nofx/trader/types"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -34,6 +35,9 @@ type GateTrader struct {
|
||||
func NewGateTrader(apiKey, secretKey string) *GateTrader {
|
||||
config := gateapi.NewConfiguration()
|
||||
config.AddDefaultHeader("X-Gate-Channel-Id", "nofx")
|
||||
// The SDK default HTTP client has no timeout — a hung connection would
|
||||
// stall the trading loop indefinitely.
|
||||
config.HTTPClient = &http.Client{Timeout: 30 * time.Second}
|
||||
client := gateapi.NewAPIClient(config)
|
||||
|
||||
ctx := context.WithValue(context.Background(),
|
||||
|
||||
@@ -27,9 +27,18 @@ func (t *GateTrader) GetBalance() (map[string]interface{}, error) {
|
||||
return nil, fmt.Errorf("failed to get balance: %w", err)
|
||||
}
|
||||
|
||||
total, _ := strconv.ParseFloat(accounts.Total, 64)
|
||||
available, _ := strconv.ParseFloat(accounts.Available, 64)
|
||||
unrealizedPnl, _ := strconv.ParseFloat(accounts.UnrealisedPnl, 64)
|
||||
total, err := types.ParseFloatField("total", accounts.Total)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
available, err := types.ParseFloatField("available", accounts.Available)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unrealizedPnl, err := types.ParseFloatField("unrealisedPnl", accounts.UnrealisedPnl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := map[string]interface{}{
|
||||
"totalWalletBalance": total,
|
||||
|
||||
Reference in New Issue
Block a user