cd3db8d453
Motivation: 部分 meme 币等标的价格极小(如 0.00000059),原有格式化统一保留两位小数会将其显示为 0.00,导致推送消息中的价格信息失真、误导用户;同时 viper 加载配置时会将嵌套 map 的 key 统一转为小写,导致按大写策略编码配置的策略覆盖项无法命中,仓位倍数、杠杆等覆盖参数失效。 Changes: * 新增价格展示格式化逻辑:绝对值不小于 1 的数值保留两位小数,小于 1 的数值采用最短精确表示,避免极小价格被截断为 0.00 * 策略覆盖查找改为大小写不敏感匹配,兼容 viper 将配置 key 小写化的行为,确保策略编码以任意大小写配置均可生效 * 补充极小价格展示、配置加载解析及策略覆盖匹配的单元测试
82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
package tradesignal
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func ptr(v float64) *float64 { return &v }
|
|
|
|
func TestFormatOpenIncludesPeriodAfterSymbol(t *testing.T) {
|
|
out := Format(&Signal{
|
|
Symbol: "BTCUSDT", Side: "LONG", Action: "OPEN",
|
|
Quantity: ptr(0.01), Price: 64000.5, Leverage: 10,
|
|
Period: "1h", EventTime: "2026-06-23T01:30:00Z",
|
|
})
|
|
if !strings.Contains(out, "多单开仓") || !strings.Contains(out, "交易品种: BTC") {
|
|
t.Fatalf("%s", out)
|
|
}
|
|
idxSym := strings.Index(out, "交易品种: BTC")
|
|
idxPer := strings.Index(out, "周期: 1h")
|
|
idxPx := strings.Index(out, "开仓价格:")
|
|
if idxPer < 0 || idxPer < idxSym || idxPx < idxPer {
|
|
t.Fatalf("period placement:\n%s", out)
|
|
}
|
|
}
|
|
|
|
func TestFormatOmitsEmptyPeriod(t *testing.T) {
|
|
out := Format(&Signal{
|
|
Symbol: "BTCUSDT", Side: "LONG", Action: "OPEN",
|
|
Price: 1, EventTime: "2026-06-23T01:30:00Z",
|
|
})
|
|
if strings.Contains(out, "周期:") {
|
|
t.Fatalf("%s", out)
|
|
}
|
|
}
|
|
|
|
func TestFormatCloseLong(t *testing.T) {
|
|
pnl, bal := 941.0, 74744.90
|
|
out := Format(&Signal{
|
|
Symbol: "BTCUSDT", Side: "LONG", Action: "CLOSE",
|
|
Quantity: ptr(3), Price: 63175.76,
|
|
EventTime: "2026-07-07T05:52:14Z", PnL: &pnl, AccountBalance: &bal,
|
|
})
|
|
for _, want := range []string{"多单平仓", "平仓价格: 63175.76", "平仓盈亏: 941.00"} {
|
|
if !strings.Contains(out, want) {
|
|
t.Fatalf("missing %q in\n%s", want, out)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFormatWithAvgPrice(t *testing.T) {
|
|
avg := 150.0
|
|
out := Format(&Signal{
|
|
Symbol: "BTCUSDT", Side: "LONG", Action: "ADD",
|
|
Quantity: ptr(1), Price: 200, EventTime: "2026-07-07T05:52:14Z",
|
|
}, FormatOptions{AvgPrice: &avg})
|
|
if !strings.Contains(out, "平均单价: 150.00") {
|
|
t.Fatalf("%s", out)
|
|
}
|
|
}
|
|
|
|
func TestFormatTinyPriceKeepsPrecision(t *testing.T) {
|
|
tp, sl := 0.00000061, 0.00000058
|
|
out := Format(&Signal{
|
|
Symbol: "PEPEUSDT", Side: "LONG", Action: "OPEN",
|
|
Price: 0.00000059, TakeProfitPrice: &tp, StopLossPrice: &sl,
|
|
EventTime: "2026-06-23T01:30:00Z",
|
|
})
|
|
for _, want := range []string{
|
|
"开仓价格: 0.00000059\n",
|
|
"止盈价格: 0.00000061\n",
|
|
"止损价格: 0.00000058\n",
|
|
} {
|
|
if !strings.Contains(out, want) {
|
|
t.Fatalf("missing %q in\n%s", want, out)
|
|
}
|
|
}
|
|
if strings.Contains(out, "开仓价格: 0.00\n") {
|
|
t.Fatalf("tiny price rounded to 0.00:\n%s", out)
|
|
}
|
|
}
|