Chuyển đến nội dung chính
ATK Pine Script®

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 None

frame.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ũ.