首次上传
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import io
|
||||
import logging
|
||||
|
||||
LOGGER = logging.getLogger("onchain_scout.chart_candles")
|
||||
|
||||
|
||||
def daily_candles_png_base64(rows_1d: list[list[str]], symbol: str, max_bars: int = 48) -> str | None:
|
||||
"""
|
||||
生成简易日线蜡烛图 PNG(base64,无 data URL 前缀),供 Ollama 多模态。
|
||||
若 matplotlib 不可用或失败则返回 None。
|
||||
"""
|
||||
try:
|
||||
import matplotlib
|
||||
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Rectangle
|
||||
except ImportError:
|
||||
LOGGER.warning("matplotlib not installed, skip chart image")
|
||||
return None
|
||||
|
||||
o, h, l, c, _ = [], [], [], [], []
|
||||
for item in rows_1d:
|
||||
if len(item) < 6:
|
||||
continue
|
||||
o.append(float(item[1]))
|
||||
h.append(float(item[2]))
|
||||
l.append(float(item[3]))
|
||||
c.append(float(item[4]))
|
||||
n = len(c)
|
||||
if n < 5:
|
||||
return None
|
||||
start = max(0, n - max_bars)
|
||||
o, h, l, c = o[start:], h[start:], l[start:], c[start:]
|
||||
x = list(range(len(c)))
|
||||
|
||||
fig, ax = plt.subplots(figsize=(7, 3), facecolor="#030308")
|
||||
ax.set_facecolor("#050510")
|
||||
for i in x:
|
||||
up = c[i] >= o[i]
|
||||
col = "#00f5d4" if up else "#ff006e"
|
||||
ax.plot([i, i], [l[i], h[i]], color=col, linewidth=0.9, alpha=0.9)
|
||||
body_low = min(o[i], c[i])
|
||||
body_h = abs(c[i] - o[i])
|
||||
if body_h < 1e-12:
|
||||
body_h = (h[i] - l[i]) * 0.08 or 1e-8
|
||||
ax.add_patch(
|
||||
Rectangle(
|
||||
(i - 0.35, body_low),
|
||||
0.7,
|
||||
body_h,
|
||||
facecolor=col,
|
||||
edgecolor=col,
|
||||
linewidth=0.4,
|
||||
alpha=0.85,
|
||||
)
|
||||
)
|
||||
ax.set_title(f"{symbol} 1D", color="#00fff7", fontsize=11, fontfamily="monospace")
|
||||
ax.tick_params(colors="#7dffb3", labelsize=7)
|
||||
for spine in ax.spines.values():
|
||||
spine.set_color("#1b3d2f")
|
||||
ax.grid(True, alpha=0.12, color="#00fff7")
|
||||
plt.tight_layout()
|
||||
buf = io.BytesIO()
|
||||
fig.savefig(buf, format="png", dpi=100, facecolor=fig.get_facecolor())
|
||||
plt.close(fig)
|
||||
buf.seek(0)
|
||||
return base64.b64encode(buf.read()).decode("ascii")
|
||||
Reference in New Issue
Block a user