build_visuals và Giai Đoạn Render ctx
Giữ build_visuals chỉ để render — những gì thuộc về đây, những gì không, và mẫu khởi đầu render-only với cấu hình frame.attrs.
Giữ build_visuals(...) Chỉ Để Render#
Những gì thuộc về đây#
Đọc các hàng cuối, chọn điểm neo, giải nén cấu hình attrs tĩnh, và phát ra các intent ctx.* hoặc ctx.atk.*.
Những gì không thuộc về đây#
Gọi TA, resampling, logic groupby, thay đổi frame, và bất kỳ bước chuẩn bị nào có thể được thực hiện một cách xác định trong frame builder.
Kiểm tra thực tế: nếu bạn có thể xóa build_visuals mà vẫn giữ nguyên tất cả các column đã tính toán và strategy
intent, thì việc phân chia giai đoạn của bạn có lẽ đúng. Nếu xóa nó làm mất tính toán, thì những tính toán đó thuộc về
giai đoạn trước trong build_indicator_frame.
Mẫu Khởi Đầu Render-Only#
def build_indicator_frame(df, params=None):
frame = df.copy().reset_index(drop=True)
frame["ema_fast"] = ta.ema(frame["close"], 20)
frame["buy_signal"] = ta.crossover(frame["close"], frame["ema_fast"]).fillna(False)
frame.attrs["label_style"] = {"color": "#2962ff", "style": "label_down"}
return frame
def build_visuals(frame, params=None, ctx=None):
if frame is None or frame.empty or ctx is None:
return None
last = frame.iloc[-1]
style = dict(frame.attrs.get("label_style") or {})
if bool(last.get("buy_signal", False)):
return ctx.label.new(
key="last_buy_label",
x=int(last["index"]),
y=float(last["low"]),
text="BUY",
**style,
)
return Noneframe.attrs cho Cấu Hình Tĩnh#
Quy tắc an toàn rất đơn giản: màu sắc, tiêu đề, nhãn, và các cấu hình ổn định khác có thể nằm trong frame.attrs.
Tọa độ, điểm neo dẫn xuất từ tail, và hình học của slice hiện tại nên được lấy từ frame truyền vào
build_visuals. Nếu không, quá trình render lịch sử hoặc render theo slice có thể tái sử dụng payload cũ.