test(shared): add failing domain schema specs
This commit is contained in:
@@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user