Skip to content

Commit edfc39e

Browse files
JohnCCarterclaude
andcommitted
fix(research): polish BTC MTF confluence atlas card
Two visual-only polish fixes to the c001 confluence card (no behaviour change): - title: show the cluster id once (drop the "c001 (c001)" duplication; only append the resolved id when it differs from the signature label). - members: replace the near-coincident stacked per-line labels with a compact top-left member table (TF / ratio / price / short fib id) so every member stays source-traceable while the level lines stay clean. Render-only; summary contract + golden snapshot unchanged. ruff + full suite green (403 passed). PNGs gitignored, none committed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 12ce7c9 commit edfc39e

1 file changed

Lines changed: 44 additions & 23 deletions

File tree

src/fibengine/research/mtf_confluence_atlas.py

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,37 @@ def _annotate_metadata(ax, card_meta: dict) -> None:
284284
)
285285

286286

287+
def _short_fib(fib_id: str) -> str:
288+
"""Compact member id: drop the ``fib_BTC-USD_<tf>_`` prefix, keep the timestamp tail."""
289+
return fib_id.split("_")[-1]
290+
291+
292+
def _annotate_member_table(ax, band: list[LevelRow]) -> None:
293+
"""Top-left member table (TF / ratio / price / short fib id) — replaces stacked labels.
294+
295+
Because the four members sit within ~$36 their per-line labels would overlap and hide
296+
each other; a compact table keeps every member individually source-traceable while the
297+
level lines stay clean.
298+
"""
299+
lines = ["member levels (fixed-band)", "TF ratio price fib"]
300+
for r in band:
301+
lines.append(
302+
f"{r.timeframe:<3} {r.ratio:<5g} {r.level_price:>7,.0f} {_short_fib(r.fib_id)}"
303+
)
304+
ax.text(
305+
0.012,
306+
0.985,
307+
"\n".join(lines),
308+
transform=ax.transAxes,
309+
fontsize=8,
310+
family="monospace",
311+
va="top",
312+
ha="left",
313+
bbox=dict(boxstyle="round,pad=0.35", fc="white", ec="#888888", alpha=0.9),
314+
zorder=7,
315+
)
316+
317+
287318
def _draw_card(
288319
df: pd.DataFrame,
289320
band: list[LevelRow],
@@ -299,7 +330,9 @@ def _draw_card(
299330
300331
``show_members=False`` (clean): candle backdrop + shaded ``[min,max]`` confluence band
301332
+ representative-price line + metadata box. ``show_members=True`` (levels): adds one
302-
horizontal line per member level, coloured by timeframe, labelled ``TF ratio price id``.
333+
horizontal line per member level, coloured by timeframe, plus a top-left member table
334+
(TF / ratio / price / short fib id) so every member stays source-traceable without the
335+
near-coincident per-line labels overlapping.
303336
"""
304337
fig, ax = _candle_backdrop(df, title, fig_w)
305338

@@ -314,38 +347,19 @@ def _draw_card(
314347
ls="-",
315348
alpha=0.85,
316349
zorder=3,
317-
label=f"repr {cluster.representative_price:,.0f}",
318350
)
319351

320352
if show_members:
321-
x_right = len(df) - 1
322-
seen_tf: set[str] = set()
323353
for r in band:
324-
color = _TF_COLORS.get(r.timeframe, "#555555")
325354
ax.axhline(
326355
r.level_price,
327-
color=color,
356+
color=_TF_COLORS.get(r.timeframe, "#555555"),
328357
lw=1.2,
329358
ls="--",
330359
alpha=0.9,
331360
zorder=4,
332-
label=r.timeframe if r.timeframe not in seen_tf else None,
333361
)
334-
seen_tf.add(r.timeframe)
335-
ax.annotate(
336-
f"{r.timeframe} {r.ratio:g} @ {r.level_price:,.0f} {r.fib_id}",
337-
xy=(x_right, r.level_price),
338-
xytext=(-4, 3),
339-
textcoords="offset points",
340-
fontsize=7,
341-
fontweight="bold",
342-
color=color,
343-
va="bottom",
344-
ha="right",
345-
bbox=dict(boxstyle="round,pad=0.2", fc="white", ec=color, alpha=0.85),
346-
zorder=6,
347-
)
348-
ax.legend(loc="upper left", fontsize=7, framealpha=0.85, title="member TF")
362+
_annotate_member_table(ax, band)
349363

350364
_annotate_metadata(ax, card_meta)
351365
fig.savefig(out_path, dpi=120, bbox_inches="tight")
@@ -419,8 +433,15 @@ def render_confluence_card(
419433
fig_w = max(16, min(n // 2, 36))
420434
a_str = f"{df.index[0]:%Y-%m-%d}"
421435
b_str = f"{df.index[-1]:%Y-%m-%d}"
436+
# Show the cluster id once; only append the resolved id when it differs from the
437+
# signature label (avoids the "c001 (c001)" duplication when they coincide).
438+
id_part = (
439+
signature.label
440+
if signature.label == cluster.cluster_id
441+
else f"{signature.label} ({cluster.cluster_id})"
442+
)
422443
base_title = (
423-
f"{symbol} MTF confluence {signature.label} ({cluster.cluster_id}) | "
444+
f"{symbol} MTF confluence {id_part} | "
424445
f"{','.join(cluster.timeframes)} {backdrop_tf} backdrop {a_str}{b_str} (log)"
425446
)
426447
_draw_card(

0 commit comments

Comments
 (0)