Perfect tournament helper guide — consistency blueprint for AI
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_21for EMA20 andema_55for EMA50; others use exact. Standardize via a mapping layer. - Volume fields: some compute
volumeUsd = volume*price, others referencevolume.volumeUsdimplicitly. Useanalysis.volume.volumeUsdeverywhere. - 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:
isBullishAlignmentvshasEmaAlignment;hasSqueezevsisSqueeze; pick one convention. - Reasons/metadata: different phrasing and missing numeric context; standardize
reasons.passed/failed/warningsplus numericmetadata. - 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)
- context:
-
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.
- Provide a mapping layer to normalize series keys:
-
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%).
- stablecoin, missing data, absurdly low liquidity (min
- 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
isPrimedthenisConfirmedflags 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
- Hard no-gos (never relaxed):
-
Telemetry support
- Emit in Analysis a
gatesblock with values and thresholds used, e.g.:- gates:
{ volumeUsd: { value, min }, adx: { value, min }, bbWidthPct: { value, max }, slRiskPct: { value, max }, diGap: { value, min }, … }
- gates:
- Keep names stable for dashboards and leniency decisions.
- Emit in Analysis a
-
Buy/Sell symmetry
- Mirror logic for SELL: invert EMAs, DI bias, MACD/RSI thresholds and breakout directions; keep same field names (
isBearishAlignment, etc.).
- Mirror logic for SELL: invert EMAs, DI bias, MACD/RSI thresholds and breakout directions; keep same field names (
-
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.
- Ensure Analysis provides:
-
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.totalScorein [0, 1] - Provides
context.currentPriceandvolume.volumeUsd - Uses consistent indicator normalization
- Emits gates info for telemetry
- Returns validation with reasons and numeric metadata
- Mirrors buy/sell correctly
- Provides
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.
