Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/backtest-kit/backtest-ollama-crontab/llms.txt

Use this file to discover all available pages before exploring further.

RiskOutlineContract is the TypeScript type inferred from the Zod schema RiskOutlineFormat. Every Ollama response goes through this schema before being persisted to screen-items. The contract enforces both structural correctness (via Zod’s enum and string constraints) and semantic correctness (via five post-parse validators), ensuring that only well-formed LLM outputs reach the database.

Zod Schema

The full RiskOutlineFormat definition from packages/core/src/contract/RiskOutline.ts:
import { str } from "functools-kit";
import { z } from "zod";

export const RiskOutlineFormat = z.object({
  action: z
    .enum(["skip", "follow"])
    .describe(
      str.newline(
        "Решение об открытии позиции:",
        "follow — открыть позицию в направлении канала (direction из draft signal)",
        "skip — пропустить сигнал, не открывать позицию",
      )
    ),
  sure_level: z
    .enum(["low", "low_medium", "medium", "medium_high", "high"])
    .describe(
      str.newline(
        "Уровень уверенности в наличии манипуляции в свечах (для audit log):",
        "low — следов нет, структура объёма органична",
        "low_medium — одна свежая аномалия без смещения",
        "medium — одна аномалия давно или со смещением цены",
        "medium_high — повторяющееся накопление",
        "high — множественное накопление с явным смещением цены",
      )
    ),
  confidence: z
    .enum(["reliable", "not_reliable"])
    .describe(
      str.newline(
        "Уверенность в оценке (для audit log):",
        "reliable — данные однозначны",
        "not_reliable — данные противоречивы, слабые или отсутствуют",
      )
    ),
  description: z
    .string()
    .describe(
      str.newline(
        "Краткое объяснение action для трейдера (2-3 предложения).",
        "Назови применённое правило и числа. Пример:",
        "'Action skip. SHORT на спящем активе (avgRangePct 0.045% < 0.07%) — stop-hunt мишень. Sure_level high, confidence reliable.'"
      )
    ),
  reasoning: z
    .string()
    .describe(
      str.newline(
        "Детальное обоснование (одна строка с переводами через \\n, НЕ объект, НЕ массив):",
        "Шаг 1: avgRangePct=X%, momentum24hPct=Y% (из метрик)",
        "Шаг 2: применённое правило → action",
        "Шаг 3: sure_level и confidence",
      )
    ),
});

export type RiskOutlineContract = z.infer<typeof RiskOutlineFormat>;

Fields

action
"skip" | "follow"
required
Trading decision returned by the LLM. follow instructs the system to open a position in the signal’s direction (as specified by direction in the draft signal). skip instructs the system to discard this signal entirely. This is the only field that affects pipeline behavior — all other fields are audit data.
sure_level
"low" | "low_medium" | "medium" | "medium_high" | "high"
required
LLM’s confidence that the candle data shows signs of market manipulation. This is an audit-only field and does not affect the action decision directly.
confidence
"reliable" | "not_reliable"
required
Data quality assessment for the LLM’s input. reliable means ≥60 one-minute candles were available and metrics are unambiguous. not_reliable means the candle data was contradictory, sparse, or absent. This is an audit-only field — it does not gate the pipeline.
description
string
required
A 2–3 sentence human-readable verdict intended for the trader. Must name the applied rule with specific numeric values. Minimum 30 characters. Example output:
"Action skip. SHORT на спящем активе (avgRangePct 0.045% < 0.07%) — stop-hunt мишень. Sure_level high, confidence reliable."
reasoning
string
required
A single flat string (not a JSON object, not an array) containing newline-separated steps that show the LLM’s full decision process. Minimum 80 characters. Expected format:
Шаг 1: avgRangePct=X%, momentum24hPct=Y% (из метрик)
Шаг 2: применённое правило → action
Шаг 3: sure_level и confidence

Validators

After Zod parses the raw LLM JSON, five additional validation rules are applied. If any rule fails the isValid flag is false and error contains the failure message — the row is not written to screen-items.
#FieldRule
1actionMust be one of ["skip", "follow"]
2sure_levelMust be one of ["low", "low_medium", "medium", "medium_high", "high"]
3confidenceMust be one of ["reliable", "not_reliable"]
4descriptionMust be a string with ≥ 30 characters
5reasoningMust be a string with ≥ 80 characters
All five validators correspond directly to Zod’s own constraints. They serve as an explicit guard layer that surfaces clear error messages when the LLM produces truncated or malformed output that still parses as valid JSON.

Enums

Three TypeScript enums are used alongside RiskOutlineContract to identify the outline, its advisors, and its completion strategies:
// OutlineName — identifies the outline registered in agent-swarm-kit
export enum OutlineName {
  RiskOutline = "risk_outline",
}

// AdvisorName — identifies the advisors that supply candle data to the outline
export enum AdvisorName {
  StockData15mAdvisor = "stock_data_15m_advisor",
  StockData1mAdvisor  = "stock_data_1m_advisor",
}

// CompletionName — identifies the Ollama completion strategies
export enum CompletionName {
  OllamaOutlineToolCompletion   = "ollama_outline_tool_completion",
  OllamaOutlineFormatCompletion = "ollama_outline_format_completion",
}
OllamaOutlineFormatCompletion uses Ollama’s structured-output (format) mode to enforce the RiskOutlineFormat schema directly at the model level, providing a first line of defence before the Zod validators run.

Usage

SignalLogicService invokes the outline via json() from agent-swarm-kit. The call passes the symbol, direction, target prices, and stop-loss from the IParserRow as positional arguments:
type Symbol    = string;
type Direction = "short" | "long";
type Targets   = number[];
type StopLoss  = number;

type Args = [Symbol, Direction, Targets, StopLoss];

const { data, error, isValid } = await json<RiskOutlineContract, Args>(
  OutlineName.RiskOutline,
  row.symbol,
  row.direction,
  row.targets,
  row.stoploss,
);

if (!isValid) {
  throw new Error(error);
}

// data is now a fully-validated RiskOutlineContract
The returned data object is then mapped field-by-field onto IScreenDto and persisted to screen-items:
return {
  parserItemId:    row.id,
  // ... identity fields from the parser row ...
  riskSureLevel:   data.sure_level,
  riskConfidence:  data.confidence,
  riskAction:      data.action,
  riskDescription: data.description,
  riskReasoning:   data.reasoning,
  // ...
};

Build docs developers (and LLMs) love