Files
signal-platform/frontend/src/lib/recommendation.ts
T
dennisthiessenandClaude Fable 5 d3eb8a2b97
Deploy / lint (push) Successful in 5s
Deploy / test (push) Successful in 32s
Deploy / deploy (push) Successful in 22s
Fix scoring/recommendation correctness and calibration
Triggered by CNC showing "LONG (High Confidence)" with SHORT reasoning
and no long setup.

- A: recommendation action + reasoning are ticker-level and identical
  on both setups; reasoning always matches the shown action
- B: recommended_action only picks a direction with a tradeable setup;
  strong bias with no setup (e.g. price at ATH) → NEUTRAL with an
  explanatory reason instead of a fake LONG_HIGH
- C: confidence is a directional-agreement model — opposing signals push
  it below 50 (SHORT on a 92-technical/99-momentum stock ~0%, not 55%)
- D: fundamental score requires >=2 real metrics (market-cap-only no
  longer yields a high score)
- E: RSI score peaks at healthy momentum (~60) and penalizes
  overbought/oversold extremes instead of treating RSI 90 as maximal
- F: fundamentals chain merges fields across providers (FMP market cap
  + Finnhub P/E) instead of stopping at the first with any field
- NEUTRAL label: "No Clear Setup" (covers untradeable-bias case)

Scores recompute on next scan/scoring run; C and E shift score
distributions intentionally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 15:34:36 +02:00

47 lines
1.8 KiB
TypeScript

import type { TradeSetup } from './types';
export type RecommendationAction = NonNullable<TradeSetup['recommended_action']>;
export const RECOMMENDATION_ACTION_LABELS: Record<RecommendationAction, string> = {
LONG_HIGH: 'LONG (High Confidence)',
LONG_MODERATE: 'LONG (Moderate Confidence)',
SHORT_HIGH: 'SHORT (High Confidence)',
SHORT_MODERATE: 'SHORT (Moderate Confidence)',
NEUTRAL: 'NEUTRAL (No Clear Setup)',
};
export const RECOMMENDATION_ACTION_GLOSSARY: Array<{ action: RecommendationAction; description: string }> = [
{
action: 'LONG_HIGH',
description: 'Ticker bias favors LONG strongly. LONG confidence is above the high threshold and clearly above SHORT.',
},
{
action: 'LONG_MODERATE',
description: 'Ticker bias favors LONG, but with moderate conviction.',
},
{
action: 'SHORT_HIGH',
description: 'Ticker bias favors SHORT strongly. SHORT confidence is above the high threshold and clearly above LONG.',
},
{
action: 'SHORT_MODERATE',
description: 'Ticker bias favors SHORT, but with moderate conviction.',
},
{
action: 'NEUTRAL',
description: 'No actionable setup — either signals are mixed, or the favored direction has no tradeable setup (e.g. price extended with no target). See the reasoning for which.',
},
];
export function recommendationActionLabel(action: TradeSetup['recommended_action']): string {
if (!action) return RECOMMENDATION_ACTION_LABELS.NEUTRAL;
return RECOMMENDATION_ACTION_LABELS[action] ?? RECOMMENDATION_ACTION_LABELS.NEUTRAL;
}
export function recommendationActionDirection(action: TradeSetup['recommended_action']): 'long' | 'short' | 'neutral' {
if (!action || action === 'NEUTRAL') return 'neutral';
if (action.startsWith('LONG')) return 'long';
if (action.startsWith('SHORT')) return 'short';
return 'neutral';
}