From 800c54cbe65a4f988dab3a21b6503e758f7c978d Mon Sep 17 00:00:00 2001 From: Caihaohan Date: Sat, 28 Mar 2026 16:59:15 +0800 Subject: [PATCH] test(shared): add failing domain schema specs --- packages/shared/src/domain/strategy.test.ts | 103 ++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 packages/shared/src/domain/strategy.test.ts diff --git a/packages/shared/src/domain/strategy.test.ts b/packages/shared/src/domain/strategy.test.ts new file mode 100644 index 0000000..d064b75 --- /dev/null +++ b/packages/shared/src/domain/strategy.test.ts @@ -0,0 +1,103 @@ +import { describe, expect, it } from "vitest"; +import { + experimentResultSchema, + marketSnapshotSchema, + modelProfileSchema, + strategyDefinitionSchema, + strategyStateSchema, + tradeRecordSchema +} from "../index"; + +describe("shared domain schemas", () => { + it("accepts supported strategy lifecycle states", () => { + expect(strategyStateSchema.parse("candidate")).toBe("candidate"); + expect(() => strategyStateSchema.parse("live")).toThrow(); + }); + + it("parses an OpenAI-compatible model profile", () => { + const profile = modelProfileSchema.parse({ + name: "signal.fast.v1", + provider: "openai-compatible", + apiBase: "https://example.com/v1", + apiKeyRef: "OPENAI_API_KEY", + model: "gpt-4.1-mini", + temperature: 0.2, + maxTokens: 512, + timeoutMs: 10_000, + capabilities: { + structuredOutputs: true, + jsonMode: true + }, + tags: ["fast", "production"] + }); + + expect(profile.model).toBe("gpt-4.1-mini"); + expect(profile.capabilities.structuredOutputs).toBe(true); + }); + + it("rejects invalid dry-run trade confidence", () => { + expect(() => + tradeRecordSchema.parse({ + id: "trade-1", + strategyId: "strategy-1", + strategyVersion: 1, + mode: "dry-run", + contractId: "btc-10m-updown", + side: "up", + confidence: 1.5, + status: "proposed", + createdAt: "2026-03-28T08:00:00.000Z" + }) + ).toThrow(); + }); + + it("parses market snapshots and experiment results", () => { + const snapshot = marketSnapshotSchema.parse({ + id: "snapshot-1", + symbol: "BTCUSDT", + contractId: "btc-10m-updown", + timeframe: "10m", + observedAt: "2026-03-28T08:00:00.000Z", + price: 87500.25, + volume: 1200.5 + }); + + const strategy = strategyDefinitionSchema.parse({ + id: "strategy-1", + version: 2, + name: "momentum-10m", + state: "dry-run", + agentProfile: { + signal: "signal.fast.v1", + risk: "risk.default.v1", + evaluator: "eval.default.v1", + optimizer: "optimizer.reasoning.v1" + }, + featureConfig: { + windows: ["5m", "15m"] + }, + riskConfig: { + minConfidence: 0.65 + }, + scoringConfig: { + objective: "risk-adjusted-return" + }, + createdAt: "2026-03-28T08:00:00.000Z" + }); + + const result = experimentResultSchema.parse({ + id: "experiment-1", + strategyId: strategy.id, + strategyVersion: strategy.version, + sampleSize: 48, + score: 1.27, + netReturn: 0.13, + maxDrawdown: 0.05, + hitRate: 0.62, + evaluatedAt: "2026-03-28T10:00:00.000Z" + }); + + expect(snapshot.symbol).toBe("BTCUSDT"); + expect(result.score).toBeGreaterThan(1); + }); +});