mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-09 14:00:57 +08:00
fix(trader): stop swallowing critical errors in order paths
- check CancelAllOrders errors in okx/kucoin/bitget/gate open/close paths (aligns with existing binance/hyperliquid/aster/bybit pattern) - log saveDecision failures in auto_trader_loop instead of discarding - remove dead MustNormalizeTimeframe that panicked in market package - web: npm audit fix resolves react-router HIGH CVEs (GHSA-49rj-9fvp-4h2h, GHSA-2j2x-hqr9-3h42, GHSA-8x6r-g9mw-2r78, GHSA-rxv8-25v2-qmq8)
This commit is contained in:
@@ -43,15 +43,6 @@ func TFDuration(tf string) (time.Duration, error) {
|
||||
return supportedTimeframes[norm], nil
|
||||
}
|
||||
|
||||
// MustNormalizeTimeframe is similar to NormalizeTimeframe, but panics when unsupported.
|
||||
func MustNormalizeTimeframe(tf string) string {
|
||||
norm, err := NormalizeTimeframe(tf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return norm
|
||||
}
|
||||
|
||||
// SupportedTimeframes returns all supported timeframes (sorted slice).
|
||||
func SupportedTimeframes() []string {
|
||||
keys := make([]string, 0, len(supportedTimeframes))
|
||||
|
||||
@@ -47,7 +47,9 @@ func (at *AutoTrader) runCycle() error {
|
||||
at.logWarnf("⏸ Risk control: Trading paused, remaining %.0f minutes", remaining.Minutes())
|
||||
record.Success = false
|
||||
record.ErrorMessage = fmt.Sprintf("Risk control paused, remaining %.0f minutes", remaining.Minutes())
|
||||
at.saveDecision(record)
|
||||
if err := at.saveDecision(record); err != nil {
|
||||
at.logWarnf("⚠ Failed to save decision record: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -64,7 +66,9 @@ func (at *AutoTrader) runCycle() error {
|
||||
at.logErrorf("failed to build trading context: %v", err)
|
||||
record.Success = false
|
||||
record.ErrorMessage = fmt.Sprintf("Failed to build trading context: %v", err)
|
||||
at.saveDecision(record)
|
||||
if saveErr := at.saveDecision(record); saveErr != nil {
|
||||
at.logWarnf("⚠ Failed to save decision record: %v", saveErr)
|
||||
}
|
||||
return fmt.Errorf("failed to build trading context: %w", err)
|
||||
}
|
||||
|
||||
@@ -84,7 +88,9 @@ func (at *AutoTrader) runCycle() error {
|
||||
PositionCount: ctx.Account.PositionCount,
|
||||
InitialBalance: at.initialBalance,
|
||||
}
|
||||
at.saveDecision(record)
|
||||
if err := at.saveDecision(record); err != nil {
|
||||
at.logWarnf("⚠ Failed to save decision record: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -157,7 +163,9 @@ func (at *AutoTrader) runCycle() error {
|
||||
}
|
||||
}
|
||||
|
||||
at.saveDecision(record)
|
||||
if saveErr := at.saveDecision(record); saveErr != nil {
|
||||
at.logWarnf("⚠ Failed to save decision record: %v", saveErr)
|
||||
}
|
||||
|
||||
// In safe mode, don't return error — keep the loop running to retry next cycle
|
||||
if at.safeMode {
|
||||
|
||||
@@ -14,7 +14,9 @@ func (t *BitgetTrader) OpenLong(symbol string, quantity float64, leverage int) (
|
||||
symbol = t.convertSymbol(symbol)
|
||||
|
||||
// Cancel old orders first
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
@@ -68,7 +70,9 @@ func (t *BitgetTrader) OpenShort(symbol string, quantity float64, leverage int)
|
||||
symbol = t.convertSymbol(symbol)
|
||||
|
||||
// Cancel old orders first
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
|
||||
@@ -44,7 +44,9 @@ func (t *GateTrader) OpenLong(symbol string, quantity float64, leverage int) (ma
|
||||
symbol = t.convertSymbol(symbol)
|
||||
|
||||
// Cancel old orders first
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
@@ -102,7 +104,9 @@ func (t *GateTrader) OpenShort(symbol string, quantity float64, leverage int) (m
|
||||
symbol = t.convertSymbol(symbol)
|
||||
|
||||
// Cancel old orders first
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
|
||||
@@ -14,7 +14,9 @@ import (
|
||||
// OpenLong opens long position
|
||||
func (t *KuCoinTrader) OpenLong(symbol string, quantity float64, leverage int) (map[string]interface{}, error) {
|
||||
// Cancel old orders
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
@@ -69,7 +71,9 @@ func (t *KuCoinTrader) OpenLong(symbol string, quantity float64, leverage int) (
|
||||
// OpenShort opens short position
|
||||
func (t *KuCoinTrader) OpenShort(symbol string, quantity float64, leverage int) (map[string]interface{}, error) {
|
||||
// Cancel old orders
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
@@ -218,7 +222,9 @@ func (t *KuCoinTrader) CloseLong(symbol string, quantity float64) (map[string]in
|
||||
logger.Infof("✓ KuCoin closed long position: %s", symbol)
|
||||
|
||||
// Cancel pending orders
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel pending orders: %v", err)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"orderId": result.OrderId,
|
||||
@@ -299,7 +305,9 @@ func (t *KuCoinTrader) CloseShort(symbol string, quantity float64) (map[string]i
|
||||
logger.Infof("✓ KuCoin closed short position: %s", symbol)
|
||||
|
||||
// Cancel pending orders
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel pending orders: %v", err)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"orderId": result.OrderId,
|
||||
|
||||
@@ -12,7 +12,9 @@ import (
|
||||
// OpenLong opens long position
|
||||
func (t *OKXTrader) OpenLong(symbol string, quantity float64, leverage int) (map[string]interface{}, error) {
|
||||
// Cancel old orders
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
@@ -91,7 +93,9 @@ func (t *OKXTrader) OpenLong(symbol string, quantity float64, leverage int) (map
|
||||
// OpenShort opens short position
|
||||
func (t *OKXTrader) OpenShort(symbol string, quantity float64, leverage int) (map[string]interface{}, error) {
|
||||
// Cancel old orders
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel old pending orders (may not have any): %v", err)
|
||||
}
|
||||
|
||||
// Set leverage
|
||||
if err := t.SetLeverage(symbol, leverage); err != nil {
|
||||
@@ -269,7 +273,9 @@ func (t *OKXTrader) CloseLong(symbol string, quantity float64) (map[string]inter
|
||||
logger.Infof("✓ OKX closed long position successfully: %s", symbol)
|
||||
|
||||
// Cancel pending orders after closing position
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel pending orders: %v", err)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"orderId": orders[0].OrdId,
|
||||
@@ -383,7 +389,9 @@ func (t *OKXTrader) CloseShort(symbol string, quantity float64) (map[string]inte
|
||||
logger.Infof("✓ OKX closed short position successfully: %s, ordId=%s", symbol, orders[0].OrdId)
|
||||
|
||||
// Cancel pending orders after closing position
|
||||
t.CancelAllOrders(symbol)
|
||||
if err := t.CancelAllOrders(symbol); err != nil {
|
||||
logger.Infof(" ⚠ Failed to cancel pending orders: %v", err)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"orderId": orders[0].OrdId,
|
||||
|
||||
14
web/package-lock.json
generated
14
web/package-lock.json
generated
@@ -7039,9 +7039,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.13.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.2.tgz",
|
||||
"integrity": "sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz",
|
||||
"integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "^1.0.1",
|
||||
@@ -7061,12 +7061,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "7.13.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.2.tgz",
|
||||
"integrity": "sha512-aR7SUORwTqAW0JDeiWF07e9SBE9qGpByR9I8kJT5h/FrBKxPMS6TiC7rmVO+gC0q52Bx7JnjWe8Z1sR9faN4YA==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz",
|
||||
"integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-router": "7.13.2"
|
||||
"react-router": "7.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
|
||||
Reference in New Issue
Block a user