Skip to main content

Perfect tournament helper guide — consistency blueprint for AI

· 3 min read
Max Kaido
Architect

Problem statement

Tournament helpers across strategies drifted in naming, fields, and gating logic, which complicates maintenance and AI authoring. We need a single, consistent blueprint that AI can follow to produce “ideal” helpers: normalized indicators, uniform scoring in [0–1], clear validation gates with reasons/metadata, telemetry for dashboards, and compatibility with consumer-side leniency.

Inconsistencies observed

  • Indicator proxies: some helpers use ema_21 for EMA20 and ema_55 for EMA50; others use exact. Standardize via a mapping layer.
  • Volume fields: some compute volumeUsd = volume*price, others reference volume.volumeUsd implicitly. Use analysis.volume.volumeUsd everywhere.
  • Validation styles: flat required/optional vs state-machine (primed→confirmed) vs rescue logic; unify gating semantics.
  • Risk guards: SL-distance/liquidity floors exist in some, absent in others; define universal hard no-gos.
  • Scoring: component weights/normalizations vary; ensure 0–1 ramps with weights summing to 1, plus bounded bonuses.
  • Naming drift: isBullishAlignment vs hasEmaAlignment; hasSqueeze vs isSqueeze; pick one convention.
  • Reasons/metadata: different phrasing and missing numeric context; standardize reasons.passed/failed/warnings plus numeric metadata.
  • Timeframe usage: H4/H1/D1 presence inconsistent; ensure helpers declare and use configured timeframes.

Guide for AI: “Ideal tournament helper” blueprint

  • Core contract

    • transform(multiTimeframeAnalysis, symbol) → Analysis
    • validate(Analysis) → { action: 'VALID'|'INVALID', confidence: number, reasons: {passed[], failed[], warnings[]}, metadata: Record<string, number> }
    • generateTPSL(Analysis, entryPrice) → { entryPrice, stopLossPrice, takeProfitLevels[], reasoning, metadata }
    • createValidationPrompt(Analysis, entryPrice) → string
    • createComparisonPrompt(AnalysisA, AnalysisB, entryA, entryB) → string
    • Analysis must include:
      • context: { symbol, currentPrice, analysisTimestamp }
      • volume: { currentVolume, volumeSma, volumeUsd, volumeRatio }
      • trend: { adx, plusDi, minusDi, isBullishBias | isBearishBias }
      • momentum: rsi, macd (values + slopes as needed)
      • ema: { ema20, ema50, isBullishAlignment | isBearishAlignment }
      • vwap/cvd/swing/volatility as needed by the strategy
      • states: optional flags for gating (e.g., isSqueeze, isPrimed, isConfirmed)
      • scoring: components + totalScore (0–1)
  • Indicator normalization

    • Provide a mapping layer to normalize series keys:
      • ema20 = values['ema_20'] || values['ema_21']
      • ema50 = values['ema_50'] || values['ema_55']
    • Expose booleans consistently: isBullishAlignment / isBearishAlignment.
  • Scoring specification

    • totalScore in [0, 1], computed as Σ weight_i * feature_i
    • Features normalized with monotonic ramps:
      • ramp(x, from, to) for linear segments; clamp to [0, 1].
      • example: ADX 20→40, RSI 50→70, MACD histogram thresholds, volume ratio 0.5→2.0.
    • Optional small, bounded bonuses/penalties (e.g., +0.03 per optional confirmation; cap totalScore at 1.0).
    • Include component scores in scoring: trendScore, momentumScore, volumeScore, structure/flow scores, optionalBonus, totalScore.
  • Validation policy

    • Hard no-gos (never relaxed):
      • stablecoin, missing data, absurdly low liquidity (min volumeUsd), invalid SL band, extreme risk (e.g., SL > 10%).
    • Gating structure (consistent across tournaments):
      • core gates: AND/OR of primary conditions (e.g., (trend OR momentum) AND volume AND structure)
      • optional confirmations: contribute bonus and “rescue” logic
      • state machine (if needed): define isPrimed then isConfirmed flags from Analysis.states
    • Output:
      • action based primarily on totalScore thresholds with warnings around borders
      • reasons.passed/failed/warnings in consistent language
      • metadata with numeric component qualities
  • Telemetry support

    • Emit in Analysis a gates block with values and thresholds used, e.g.:
      • gates: { volumeUsd: { value, min }, adx: { value, min }, bbWidthPct: { value, max }, slRiskPct: { value, max }, diGap: { value, min }, … }
    • Keep names stable for dashboards and leniency decisions.
  • Buy/Sell symmetry

    • Mirror logic for SELL: invert EMAs, DI bias, MACD/RSI thresholds and breakout directions; keep same field names (isBearishAlignment, etc.).
  • Prompt helpers

    • Always include numeric context in prompts (RSI, MACD, ADX, volume ratio, SL%, R:R) for reproducibility.
    • Use the same comparison schema across tournaments where possible; tailor only the feature list.
  • Null/data safety

    • Default missing numeric inputs to 0, but record failures in reasons; never throw during transform for non-critical gaps.
    • Validate presence of required timeframes per config.
  • Leniency compatibility

    • Ensure Analysis provides:
      • context.currentPrice
      • volume.volumeUsd (or components so the consumer can compute it)
      • scoring.totalScore
      • optional states (e.g., isPrimed) to make leniency meaningful for stateful strategies.
    • Consumer handles leniency; helpers just expose consistent fields.
  • Naming conventions

    • Booleans start with is/has
    • Scores end with Score; totals as totalScore
    • CamelCase keys; units implicit unless ambiguous (use pct for percentages).
  • Minimal skeleton example

export function transformForX(mta, symbol): XAnalysis {
// normalize indicators + compute features
return {
context: { symbol, currentPrice, analysisTimestamp: new Date() },
volume: { currentVolume, volumeSma, volumeUsd, volumeRatio },
trend: { adx, plusDi, minusDi, isBullishBias },
momentum: { rsi: { value, slope }, macd: { histogram, slope } },
ema: { ema20, ema50, isBullishAlignment },
states: { isSqueeze, isPrimed, isConfirmed },
scoring: { trendScore, momentumScore, volumeScore, optionalBonus, totalScore },
gates: { volumeUsd: { value: volumeUsd, min: 1_000_000 }, adx: { value: adx, min: 25 } }
};
}

export function validateForX(analysis: XAnalysis) {
// hard no-gos → INVALID
// core gates + scoring thresholds → VALID/INVALID + warnings
return { action, confidence, reasons, metadata };
}
  • Acceptance checklist per helper
    • Provides analysis.scoring.totalScore in [0, 1]
    • Provides context.currentPrice and volume.volumeUsd
    • Uses consistent indicator normalization
    • Emits gates info for telemetry
    • Returns validation with reasons and numeric metadata
    • Mirrors buy/sell correctly

This guide yields consistent, leniency-compatible helpers that the consumer can use uniformly, while preserving each tournament’s unique logic through standardized analysis, scoring, and gating.