Skip to content

Commit a886623

Browse files
GroverChorizoclaude
andcommitted
feat(viz): price-action sparkline in MarketDataPanel
The DayTrader Market Data panel rendered candles as a number table only. Add a price sparkline from the candle closes (green up / red down) — the Vision "Price Action / Sparklines" MVP feature. Tested via direct render. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 1772292 commit a886623

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""MarketDataPanel renders a price-action sparkline from candle closes."""
2+
3+
from __future__ import annotations
4+
5+
from rich.console import Console
6+
7+
from tui.widgets.market_data_panel import MarketDataPanel
8+
9+
10+
def _text(renderable) -> str:
11+
console = Console(record=True, width=120)
12+
console.print(renderable)
13+
return console.export_text()
14+
15+
16+
def test_market_panel_renders_price_sparkline():
17+
panel = MarketDataPanel()
18+
closes = [100, 102, 101, 105, 108, 107, 110, 109, 113]
19+
panel.render_data(
20+
{
21+
"selected_coin": "BTC",
22+
"candles_1h": [
23+
{"timestamp_ms": i, "close": v} for i, v in enumerate(closes)
24+
],
25+
}
26+
)
27+
out = _text(panel.renderable)
28+
assert any(ch in out for ch in "▁▂▃▄▅▆▇█") # sparkline glyphs present

tui/widgets/market_data_panel.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
muted_line,
1515
panel_header,
1616
)
17+
from tui.render.sparkline import sparkline
1718
from .panel_base import PanelBase
1819

1920

@@ -211,6 +212,18 @@ def _render_candles(
211212
if not isinstance(candles, list) or not candles:
212213
lines.append(muted_line("No candle data.", self.palette))
213214
return
215+
closes = [
216+
c.get("close")
217+
for c in candles
218+
if isinstance(c, dict) and c.get("close") is not None
219+
]
220+
if len(closes) >= 2:
221+
color = (
222+
self.palette.accent.green
223+
if closes[-1] >= closes[0]
224+
else self.palette.accent.red
225+
)
226+
lines.append((f" {sparkline(closes, width=40)}", color))
214227
lines.append(
215228
("Time | Open | High | Low | Close | Vol", self.palette.accent.purple)
216229
)

0 commit comments

Comments
 (0)