统一单入口 Go 工程与前端依赖目录,增加后台供应商配置、候选审核、计划预算、成交冲正、持仓复盘和站内通知。接入策略版本、Python 回测、可配置 A 股公开行情及 zap 文件轮转日志,补充迁移、契约与验证。
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.sundynix.cn/Blizzard/Veyra/internal/model"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMarketPrecisionAndTimestamp(t *testing.T) {
|
||||
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, `{"rc":0,"data":{"total":1,"diff":{"0":{"f12":"600000","f13":1,"f14":"fixture","f2":1001,"f124":1700000000,"f152":2}}}}`)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := &Client{http: server.Client()}
|
||||
rows, e := client.Snapshot(context.Background(), model.ProviderConfig{BaseURL: server.URL, ID: "source", Version: 3})
|
||||
if e != nil || len(rows) != 1 {
|
||||
t.Fatalf("snapshot: %v", e)
|
||||
}
|
||||
if rows[0].Price != "10.01" || rows[0].ObservedAt.Unix() != 1700000000 || rows[0].SourceVersion != 3 {
|
||||
t.Fatal("lost integer precision or provider timestamp")
|
||||
}
|
||||
}
|
||||
func TestHistoryOHLCAndDates(t *testing.T) {
|
||||
response := `{"rc":0,"data":{"code":"600000","name":"fixture","klines":["2025-01-02,10.01,10.11,10.21,9.99,100,1"]}}`
|
||||
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Query().Get("fqt") != "0" {
|
||||
t.Error("adjustment changed")
|
||||
}
|
||||
fmt.Fprint(w, response)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := &Client{http: server.Client()}
|
||||
input := model.ProviderConfig{HistoryBaseURL: server.URL, Version: 4}
|
||||
data, e := client.History(context.Background(), input, "600000", "SSE", "2025-01-01", "2025-01-03")
|
||||
if e != nil || len(data.Bars) != 1 || data.Bars[0].Close != "10.11" || data.Adjustment != "unadjusted" {
|
||||
t.Fatalf("history: %v", e)
|
||||
}
|
||||
response = `{"rc":0,"data":{"code":"600000","name":"fixture","klines":["2025-01-02,10.01,10.11,10.00,9.99,100,1"]}}`
|
||||
if _, e := client.History(context.Background(), input, "600000", "SSE", "2025-01-01", "2025-01-03"); e == nil {
|
||||
t.Fatal("invalid high accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSinaQuotesKeepVendorDate(t *testing.T) {
|
||||
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/quotes_service/api/json_v2.php/Market_Center.getHQNodeData":
|
||||
fmt.Fprint(w, `[{"symbol":"sh600000","code":"600000","name":"fixture"}]`)
|
||||
case "/list=sh600000":
|
||||
fmt.Fprint(w, `var hq_str_sh600000="fixture,10.000,10.000,10.010,10.100,9.900,10.000,10.010,100,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2025-01-02,15:00:00,00";`)
|
||||
default:
|
||||
t.Errorf("unexpected route %s", r.URL.Path)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
client := &Client{http: server.Client()}
|
||||
rows, e := client.Snapshot(context.Background(), model.ProviderConfig{MarketAdapter: "sina_public", BaseURL: server.URL, QuoteBaseURL: server.URL})
|
||||
if e != nil || len(rows) != 1 || rows[0].Price != "10.01" || rows[0].ObservedAt.Format("2006-01-02T15:04:05Z") != "2025-01-02T07:00:00Z" {
|
||||
t.Fatalf("quote validation: %+v, %v", rows, e)
|
||||
}
|
||||
}
|
||||
func TestPublicPricesRejectRounding(t *testing.T) {
|
||||
for _, v := range []string{"10.001", "1e2", "NaN"} {
|
||||
if _, e := exactPublicPrice(v); e == nil {
|
||||
t.Fatalf("rounded or invalid price %s", v)
|
||||
}
|
||||
}
|
||||
if v, e := exactPublicPrice("10.010"); e != nil || v != 1001 {
|
||||
t.Fatal("exact extra zero rejected")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user