mirror of
https://github.com/laoxong/nofx.git
synced 2026-06-04 01:48:22 +08:00
1744e7f38e
- Chart improvements: professional styling, popular symbols quick selection, simplified B/S legend - Data source migration: use CoinAnk API exclusively for all kline data - Code cleanup: remove Binance WebSocket cache and related code (websocket_client.go, combined_streams.go, monitor.go) - Log optimization: reduce hook spam, suppress 404 errors, increase P&L diff threshold - Lighter integration: add order sync functionality, fix market order precision - Remove ticker merge logic for simplicity
142 lines
3.7 KiB
Go
142 lines
3.7 KiB
Go
package main
|
||
|
||
import (
|
||
"flag"
|
||
"fmt"
|
||
"log"
|
||
"nofx/store"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
)
|
||
|
||
func main() {
|
||
var dbPath string
|
||
var dryRun bool
|
||
|
||
flag.StringVar(&dbPath, "db", "./data/data.db", "数据库文件路径")
|
||
flag.BoolVar(&dryRun, "dry-run", false, "只检查不修复(预览模式)")
|
||
flag.Parse()
|
||
|
||
// 确保数据库文件存在
|
||
absPath, err := filepath.Abs(dbPath)
|
||
if err != nil {
|
||
log.Fatalf("❌ 无效的数据库路径: %v", err)
|
||
}
|
||
|
||
if _, err := os.Stat(absPath); os.IsNotExist(err) {
|
||
log.Fatalf("❌ 数据库文件不存在: %s", absPath)
|
||
}
|
||
|
||
fmt.Printf("📂 数据库路径: %s\n", absPath)
|
||
|
||
// 打开数据库
|
||
s, err := store.New(absPath)
|
||
if err != nil {
|
||
log.Fatalf("❌ 无法打开数据库: %v", err)
|
||
}
|
||
defer s.Close()
|
||
|
||
db := s.DB()
|
||
|
||
fmt.Println("\n🔍 检查需要修复的订单...")
|
||
|
||
// 1. 修复缺少 filled_at 的 FILLED 订单(使用 updated_at 或 created_at)
|
||
var needFixFilledAt int
|
||
err = db.QueryRow(`
|
||
SELECT COUNT(*)
|
||
FROM trader_orders
|
||
WHERE status = 'FILLED' AND (filled_at IS NULL OR filled_at = '')
|
||
`).Scan(&needFixFilledAt)
|
||
if err != nil {
|
||
log.Fatalf("❌ 查询失败: %v", err)
|
||
}
|
||
|
||
fmt.Printf(" 📋 缺少成交时间的订单: %d 条\n", needFixFilledAt)
|
||
|
||
// 2. 修复 avg_fill_price = 0 的 FILLED 订单(使用 price 字段)
|
||
var needFixAvgPrice int
|
||
err = db.QueryRow(`
|
||
SELECT COUNT(*)
|
||
FROM trader_orders
|
||
WHERE status = 'FILLED' AND (avg_fill_price = 0 OR avg_fill_price IS NULL) AND price > 0
|
||
`).Scan(&needFixAvgPrice)
|
||
if err != nil {
|
||
log.Fatalf("❌ 查询失败: %v", err)
|
||
}
|
||
|
||
fmt.Printf(" 💰 成交价为0的订单: %d 条\n", needFixAvgPrice)
|
||
|
||
if needFixFilledAt == 0 && needFixAvgPrice == 0 {
|
||
fmt.Println("\n✅ 没有需要修复的订单!")
|
||
return
|
||
}
|
||
|
||
if dryRun {
|
||
fmt.Println("\n⚠️ 预览模式(--dry-run),不会修改数据")
|
||
fmt.Println(" 运行 'go run scripts/fix_order_data.go' 来执行实际修复")
|
||
return
|
||
}
|
||
|
||
fmt.Println("\n🔧 开始修复...")
|
||
|
||
// 修复缺少 filled_at 的订单
|
||
if needFixFilledAt > 0 {
|
||
result, err := db.Exec(`
|
||
UPDATE trader_orders
|
||
SET filled_at = COALESCE(updated_at, created_at)
|
||
WHERE status = 'FILLED' AND (filled_at IS NULL OR filled_at = '')
|
||
`)
|
||
if err != nil {
|
||
log.Fatalf("❌ 修复成交时间失败: %v", err)
|
||
}
|
||
rows, _ := result.RowsAffected()
|
||
fmt.Printf(" ✅ 修复了 %d 条订单的成交时间\n", rows)
|
||
}
|
||
|
||
// 修复 avg_fill_price = 0 的订单
|
||
if needFixAvgPrice > 0 {
|
||
result, err := db.Exec(`
|
||
UPDATE trader_orders
|
||
SET avg_fill_price = price,
|
||
filled_quantity = quantity
|
||
WHERE status = 'FILLED'
|
||
AND (avg_fill_price = 0 OR avg_fill_price IS NULL)
|
||
AND price > 0
|
||
`)
|
||
if err != nil {
|
||
log.Fatalf("❌ 修复成交价失败: %v", err)
|
||
}
|
||
rows, _ := result.RowsAffected()
|
||
fmt.Printf(" ✅ 修复了 %d 条订单的成交价\n", rows)
|
||
}
|
||
|
||
// 验证修复结果
|
||
fmt.Println("\n🔍 验证修复结果...")
|
||
time.Sleep(100 * time.Millisecond)
|
||
|
||
var stillMissingFilledAt int
|
||
db.QueryRow(`
|
||
SELECT COUNT(*)
|
||
FROM trader_orders
|
||
WHERE status = 'FILLED' AND (filled_at IS NULL OR filled_at = '')
|
||
`).Scan(&stillMissingFilledAt)
|
||
|
||
var stillMissingAvgPrice int
|
||
db.QueryRow(`
|
||
SELECT COUNT(*)
|
||
FROM trader_orders
|
||
WHERE status = 'FILLED' AND (avg_fill_price = 0 OR avg_fill_price IS NULL)
|
||
`).Scan(&stillMissingAvgPrice)
|
||
|
||
fmt.Printf(" 📋 仍缺少成交时间: %d 条\n", stillMissingFilledAt)
|
||
fmt.Printf(" 💰 仍缺少成交价: %d 条\n", stillMissingAvgPrice)
|
||
|
||
if stillMissingFilledAt == 0 && stillMissingAvgPrice == 0 {
|
||
fmt.Println("\n✅ 修复完成!所有订单数据已完整")
|
||
fmt.Println("\n💡 现在刷新图表页面,应该能看到 B/S 标记了")
|
||
} else {
|
||
fmt.Println("\n⚠️ 仍有部分订单无法修复,可能需要手动检查")
|
||
}
|
||
}
|