Tham chiếu ctx.atk.* Bridge
Tham chiếu cho namespace bridge ctx.atk.* trong ATK PyneScript V6 — table, rectangle, shape text, polyline, candlestick, volume profile, và fill_between.
Tổng quan ctx.atk.*#
Bridge ctx.atk.* cung cấp các bộ render hỗn hợp gốc ATK vượt xa khả năng của các khai báo plot tĩnh. Tất cả lệnh gọi bridge chỉ thuộc về bên trong build_visuals(frame, params, ctx).
| Helper | Dùng cho |
|---|---|
ctx.atk.table | Dashboard và thẻ tóm tắt. Xây dựng payload trong frame builder và render tại đây. |
ctx.atk.rectangles | Nhóm các vùng hỗ trợ, kháng cự, hoặc regime thuộc cùng một batch. |
ctx.atk.volume_profile | Render payload volume profile đã được tính toán trước. Không tự tính toán profile. |
ctx.atk.shape_text | Hình dạng mũi tên với nhãn văn bản tại tọa độ được chỉ định. |
ctx.atk.polyline | Đường dẫn đa điểm được kết nối. |
ctx.atk.rectangle_ray | Hình chữ nhật chiếu kéo dài đến cạnh phải. |
ctx.atk.plot_line | Đường bridge ATK liên kết với cột frame, có thể dùng với fill_between. |
ctx.atk.fill_between | Tô giữa hai đường bridge ATK được tạo bởi ctx.atk.plot_line. |
ctx.atk.candlestick | Render candle OHLCV đầy đủ thông qua bridge ATK. |
ctx.atk.horizontal_bar | Thanh profile ngang tại các mức giá được chỉ định. |
ctx.atk.dual_horizontal_bar_fixed | Hai lớp thanh profile ngang chồng lên nhau tại tọa độ x cố định. |
Hợp đồng build_visuals#
def build_visuals(frame, params=None, ctx=None):
if frame is None or frame.empty or ctx is None:
return None
table_payload = dict(frame.attrs.get("visual_table_payload") or {})
zone_payload = dict(frame.attrs.get("visual_zone_payload") or {})
profile_payload = dict(frame.attrs.get("volume_profile_payload") or {})
outputs = []
if table_payload:
outputs.append(ctx.atk.table(key="summary_table", **table_payload))
if zone_payload:
outputs.append(ctx.atk.rectangles(key="zone_batch", **zone_payload))
if profile_payload:
outputs.append(ctx.atk.volume_profile(profile_payload, key="volume_profile", orient="right"))
return outputsctx.atk.table#
Xây dựng payload trong build_indicator_frame, lưu vào frame.attrs, sau đó render trong build_visuals.
frame.attrs["visual_table_payload"] = {
"position": "top-left",
"title": "Signal Summary",
"columns": 2,
"rows": 3,
"cells": [
{"column": 0, "row": 0, "text": "Metric", "text_color": "#ffffff", "bgcolor": "#0f172a"},
{"column": 1, "row": 0, "text": "Value", "text_color": "#ffffff", "bgcolor": "#0f172a"},
{"column": 0, "row": 1, "text": "Close"},
{"column": 1, "row": 1, "text": f"{float(last['close']):.2f}", "text_color": "#00c853"},
],
}
# In build_visuals:
return ctx.atk.table(key="annotated_dashboard", **payload)ctx.atk.shape_text, polyline, rectangles, rectangle_ray#
# In build_visuals — all geometry prepared in frame builder:
return [
ctx.atk.shape_text(
key="atk_shape_marks",
points=[(float(last["index"]), float(last["close"]))],
shapes=[Shape.ArrowUp],
shape_sizes=[12.0],
shape_colors=["#2962ff"],
texts=["LONG"],
text_sizes=[9.0],
text_colors=["#ffffff"],
fonts=["Arial"],
weights=[500],
locations=[Location.Above],
positions=[Position.AboveBar],
),
ctx.atk.polyline(
key="atk_polyline_path",
points=[
(float(first["index"]), float(first["close"])),
(float(prev["index"]), float(prev["high"])),
(float(last["index"]), float(last["close"])),
],
line_color="#ffd600",
line_width=1.0,
show_points=True,
),
ctx.atk.rectangles(
key="atk_rectangles_zone",
data={
"rectangles": [(float(prev["index"]), float(prev["low"] - 0.2),
float(last["index"]), float(last["high"] + 0.2))],
"line_colors": ["#00c853"],
"line_widths": [1.0],
"fill_colors": ["#00c853"],
"fill_alphas": [26],
},
),
ctx.atk.rectangle_ray(
key="atk_rectangle_ray_zone",
x=float(prev["index"]),
h1=float(prev["low"] - 0.3),
h2=float(last["high"] + 0.3),
border_color="#ff6d00",
fill_color="#ff6d00",
border_width=1,
),
]ctx.atk.plot_line và fill_between#
def build_visuals(frame, params=None, ctx=None):
return [
ctx.atk.plot_line(key="atk_fast_line", source="fast", color="#00c853"),
ctx.atk.plot_line(key="atk_slow_line", source="slow", color="#f23645"),
ctx.atk.fill_between(
key="atk_fast_slow_fill",
line1="atk_fast_line",
line2="atk_slow_line",
color="rgba(41,98,255,0.12)",
fill_alpha=31,
),
]ctx.atk.volume_profile#
# In build_indicator_frame:
try:
payload = calculate_volume_profile(frame.copy(), look_back, row_size, value_area_pct)
except Exception:
payload = {}
frame.attrs["volume_profile_payload"] = dict(payload or {})
# In build_visuals:
payload = dict(frame.attrs.get("volume_profile_payload") or {})
return ctx.atk.volume_profile(
payload,
key="dual_volume_profile",
orient="right",
up_color="#0126A0",
down_color="#ffa32b",
value_area_title="VA",
poc_title="POC",
)build_visuals chỉ dùng để render. Không bao giờ tính toán TA, gọi request.security, hoặc thay đổi frame bên trong build_visuals. Chuẩn bị mọi thứ trong build_indicator_frame hoặc build_signal_frame, lưu config tĩnh vào frame.attrs, sau đó lấy các điểm neo hiện tại từ lát cắt frame trực tiếp được truyền vào.
Công thức chart.point#
chart.point tạo các điểm neo tọa độ cho các hình ảnh kiểu đối tượng. Dùng from_index cho các neo theo vị trí bar và from_time cho các neo theo dấu thời gian tuyệt đối.
from source import box, chart, line
# Index-based anchors — easiest for local bar objects.
trend = line.new(
chart.point.from_index(10, 100.0),
chart.point.from_index(20, 105.0),
key="trend_line",
color="#2962ff",
)
# Time-based anchor update.
line.set_xy2(trend, chart.point.from_time(1700000600, 106.0))
zone = box.new(
chart.point.from_index(12, 108.0),
chart.point.from_index(20, 99.0),
key="zone_box",
text="ZONE",
bgcolor="rgba(41,98,255,0.08)",
)Công thức line, label, box#
| Namespace | Các phương thức khởi đầu tốt nhất | Điều cần nhớ |
|---|---|---|
line | new, set_xy1, set_xy2, set_color | Dùng key ổn định nếu cùng một đối tượng khái niệm cần tồn tại và cập nhật. |
label | new, set_text, set_color | Chọn label khi một điểm cần thông điệp, không chỉ là dấu hiệu. |
box | new, set_lefttop, set_rightbottom, set_bgcolor | Box phù hợp nhất cho vùng và phạm vi, không phải chú thích đơn điểm. |
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]
anchor = frame.iloc[max(len(frame) - 10, 0)]
ctx.label.new(
key="last_close_label",
x=int(last["index"]),
y=float(last["close"]),
text="LAST",
color="#2962ff",
style="label_down",
)
range_box = ctx.box.new(
key="recent_range_box",
left=int(anchor["index"]),
top=float(last["high"]),
right=int(last["index"]),
bottom=float(last["low"]),
bgcolor="rgba(41,98,255,0.08)",
)
ctx.box.set_lefttop(range_box, x=int(anchor["index"]), y=float(last["high"] + 0.5))
return ctx.line.new(
key="close_slope_line",
x1=int(anchor["index"]),
y1=float(anchor["close"]),
x2=int(last["index"]),
y2=float(last["close"]),
color="#ffd600",
)Xem thêm: