agent_panel: plain-language output — simple, short, no jargon/acronyms
Owner request: panel notes and rationale must read like plain everyday
English for a non-trader. Style rule added to the shared take contract
and synthesizer prompt, all few-shot examples rewritten in the target
voice (examples carry the style), and the Telegram votes line now spells
out full stances ("macro: support") instead of "macro:sup".
Before: "BUY against Bollinger SELL and price above upper band; 4h
neutral, mixed MTF" → After: "The price is above its usual range, and
the bigger picture is not clearly rising, so buying now is risky."
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SisdfkxnXNL9iZsXxN3T15
This commit is contained in:
+15
-4
@@ -77,6 +77,11 @@ geopolitical stress / weak dollar are gold-bullish.
|
|||||||
_TAKE_CONTRACT = """\
|
_TAKE_CONTRACT = """\
|
||||||
Your review is advisory research on an already-generated signal; you are
|
Your review is advisory research on an already-generated signal; you are
|
||||||
one voice on a panel, not the decision maker.
|
one voice on a panel, not the decision maker.
|
||||||
|
Write the note in plain everyday English for someone who has never
|
||||||
|
traded: short simple sentences, no trading jargon, no acronyms, no
|
||||||
|
abbreviations. Say "profit versus loss", not "RR"; "the 4-hour chart",
|
||||||
|
not "H4"; describe what an indicator MEANS ("the price has climbed
|
||||||
|
unusually fast"), never its name or number.
|
||||||
Reply with ONLY JSON:
|
Reply with ONLY JSON:
|
||||||
{"stance": "support"|"oppose"|"neutral", "confidence": <0-100>,
|
{"stance": "support"|"oppose"|"neutral", "confidence": <0-100>,
|
||||||
"note": "<max 25 words>"}
|
"note": "<max 25 words>"}
|
||||||
@@ -98,7 +103,7 @@ high-impact event is a reason for lower confidence, not a direction.
|
|||||||
""" + _GOLD_DOCTRINE + """\
|
""" + _GOLD_DOCTRINE + """\
|
||||||
Example: brief direction BUY, headlines dominated by hawkish Fed
|
Example: brief direction BUY, headlines dominated by hawkish Fed
|
||||||
repricing and a hot CPI print -> {"stance": "oppose", "confidence": 70,
|
repricing and a hot CPI print -> {"stance": "oppose", "confidence": 70,
|
||||||
"note": "hot CPI and hawkish repricing lift real yields against gold"}
|
"note": "Inflation is running hot, so interest rates should stay high — that usually pushes gold down."}
|
||||||
""" + _TAKE_CONTRACT
|
""" + _TAKE_CONTRACT
|
||||||
|
|
||||||
_TECH_SYSTEM = """\
|
_TECH_SYSTEM = """\
|
||||||
@@ -115,7 +120,7 @@ disagreeing, price pressed into a key level, or an exhausted move being
|
|||||||
chased.
|
chased.
|
||||||
Example: brief direction SELL in regime trending_up with H1 and H4 both
|
Example: brief direction SELL in regime trending_up with H1 and H4 both
|
||||||
BUY -> {"stance": "oppose", "confidence": 80,
|
BUY -> {"stance": "oppose", "confidence": 80,
|
||||||
"note": "counter-trend sell against aligned higher timeframes"}
|
"note": "This bets on gold falling while the bigger picture still points up."}
|
||||||
""" + _TAKE_CONTRACT
|
""" + _TAKE_CONTRACT
|
||||||
|
|
||||||
_RISK_SYSTEM = """\
|
_RISK_SYSTEM = """\
|
||||||
@@ -132,7 +137,7 @@ to hit. A missing setup means the signal graded too low for one —
|
|||||||
oppose unless the rest is exceptional.
|
oppose unless the rest is exceptional.
|
||||||
Example: RR 1.4 with volatility extreme and a high-impact event due ->
|
Example: RR 1.4 with volatility extreme and a high-impact event due ->
|
||||||
{"stance": "oppose", "confidence": 65,
|
{"stance": "oppose", "confidence": 65,
|
||||||
"note": "thin reward for extreme volatility into event risk"}
|
"note": "The possible profit is small for such wild price swings, and big economic news is due soon."}
|
||||||
""" + _TAKE_CONTRACT
|
""" + _TAKE_CONTRACT
|
||||||
|
|
||||||
_CONTRARIAN_SYSTEM = """\
|
_CONTRARIAN_SYSTEM = """\
|
||||||
@@ -147,7 +152,7 @@ and "support" when even the skeptic finds nothing that bites.
|
|||||||
""" + _GOLD_DOCTRINE + """\
|
""" + _GOLD_DOCTRINE + """\
|
||||||
Example: a BUY whose own engine lists three bearish reasons and a
|
Example: a BUY whose own engine lists three bearish reasons and a
|
||||||
counter-trend warning -> {"stance": "oppose", "confidence": 60,
|
counter-trend warning -> {"stance": "oppose", "confidence": 60,
|
||||||
"note": "engine's own bearish evidence outweighs the entry trigger"}
|
"note": "The system's own list of negatives looks stronger than its reason to buy."}
|
||||||
""" + _TAKE_CONTRACT
|
""" + _TAKE_CONTRACT
|
||||||
|
|
||||||
_SYNTH_SYSTEM = """\
|
_SYNTH_SYSTEM = """\
|
||||||
@@ -159,6 +164,12 @@ Weigh the takes into ONE consensus on whether to act on the signal:
|
|||||||
or "NEUTRAL" (genuinely split or low conviction). Weigh a high-
|
or "NEUTRAL" (genuinely split or low conviction). Weigh a high-
|
||||||
confidence oppose from any single analyst seriously — one strong veto
|
confidence oppose from any single analyst seriously — one strong veto
|
||||||
can outweigh two lukewarm supports. Do not average blindly.
|
can outweigh two lukewarm supports. Do not average blindly.
|
||||||
|
Write the rationale in plain everyday English for someone who has never
|
||||||
|
traded: short simple sentences, no trading jargon, no acronyms, no
|
||||||
|
abbreviations.
|
||||||
|
Example rationale: "Three of four analysts are against this: the
|
||||||
|
possible profit is too small and the price has already climbed
|
||||||
|
unusually fast. Only the news backdrop supports buying."
|
||||||
Reply with ONLY JSON:
|
Reply with ONLY JSON:
|
||||||
{"verdict": "AGREE"|"NEUTRAL"|"OPPOSE", "confidence": <0-100>,
|
{"verdict": "AGREE"|"NEUTRAL"|"OPPOSE", "confidence": <0-100>,
|
||||||
"rationale": "<max 40 words>"}
|
"rationale": "<max 40 words>"}
|
||||||
|
|||||||
+1
-1
@@ -417,7 +417,7 @@ def format_signal_message(report: SignalReport) -> str:
|
|||||||
f"{_escape_md(report.panel_rationale)}")
|
f"{_escape_md(report.panel_rationale)}")
|
||||||
if report.panel_takes:
|
if report.panel_takes:
|
||||||
votes = " · ".join(
|
votes = " · ".join(
|
||||||
f"{t['persona']}:{t['stance'][:3]}" for t in report.panel_takes)
|
f"{t['persona']}: {t['stance']}" for t in report.panel_takes)
|
||||||
extra.append(f" _{_escape_md(votes)}_")
|
extra.append(f" _{_escape_md(votes)}_")
|
||||||
if extra:
|
if extra:
|
||||||
lines += [""] + extra
|
lines += [""] + extra
|
||||||
|
|||||||
+1
-1
@@ -7252,7 +7252,7 @@ def _():
|
|||||||
msg = tb.format_signal_message(report)
|
msg = tb.format_signal_message(report)
|
||||||
assert "AI Panel" in msg and "OPPOSE" in msg and "(64%)" in msg
|
assert "AI Panel" in msg and "OPPOSE" in msg and "(64%)" in msg
|
||||||
assert "counter-trend against aligned H4" in msg
|
assert "counter-trend against aligned H4" in msg
|
||||||
assert "macro:sup" in msg and "technical:opp" in msg
|
assert "macro: support" in msg and "technical: oppose" in msg
|
||||||
|
|
||||||
|
|
||||||
@test("backtest parity: analyze_from_dataframes never populates panel")
|
@test("backtest parity: analyze_from_dataframes never populates panel")
|
||||||
|
|||||||
Reference in New Issue
Block a user