开始使用
步骤 1 — 获取 TradingView Charting Library 访问权限
@iccandle/reactjs-widget 依赖 TradingView Advanced Charts(Charting Library)。请按 TradingView 官方 Get started 申请访问、安装库,并将其作为静态文件托管。
将构建放到应用可加载的路径(例如 Vite 或 Create React App 的 public/charting_library/)。图表库不会打包进 @iccandle/reactjs-widget;运行时通过 widget 选项中的 library_path 加载。
步骤 2 — 安装包
npm install @iccandle/reactjs-widget
# 或
pnpm add @iccandle/reactjs-widget
确保已安装 react 与 react-dom,并满足 peer 版本要求(React 18+)。
步骤 3 — 使用回放辅助函数初始化 TradingView
结果 iframe 的图表回放 / 预测需要配置以下两个辅助函数:
| 辅助函数 | 位置 | 作用 |
|---|---|---|
withPlayChart | datafeed | 包装 subscribeBars,使组件可注入回放 K 线,并在回放期间阻止实时 tick。 |
getCustomIndicators | custom_indicators_getter | 注册 “Generated Candles” 指标,用于绘制预测 OHLC 叠加。 |
getCustomIndicators 的主题("light" / "dark")须与图表主题一致。签名与指标名称见 配置。
import { useEffect, useRef, useState } from "react";
import type {
ChartingLibraryWidgetOptions,
IChartingLibraryWidget,
ResolutionString,
} from "charting_library/charting_library";
import { widget } from "charting_library/charting_library";
import { withPlayChart, getCustomIndicators } from "@iccandle/reactjs-widget";
const LIBRARY_PATH = "/charting_library/";
const containerRef = useRef<HTMLDivElement>(null);
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
null,
);
useEffect(() => {
const el = containerRef.current;
if (!el) return;
const options: ChartingLibraryWidgetOptions = {
container: el,
library_path: LIBRARY_PATH,
symbol: "EURUSD",
interval: "60" as ResolutionString,
datafeed: withPlayChart(yourDatafeed),
locale: "zh",
autosize: true,
drawings_access: {
type: "black",
tools: [{ name: "Date Range" }],
},
custom_indicators_getter: () => getCustomIndicators("light"),
};
const tv = new widget(options);
setChartWidget(tv);
return () => {
try {
tv.remove();
} catch {
/* no-op */
}
setChartWidget(null);
};
}, []);
你必须提供有效的 datafeed、symbol、interval、locale,以及许可证与应用所需的其他选项。widget 与类型的导入路径因项目而异 — 请遵循 TradingView 文档。
若集成仅在 onChartReady 后暴露实例,请在该回调中调用 setChartWidget,而不是在 new widget(...) 后立即调用。
步骤 4 — 用 WidgetIccandle 包裹图表
WidgetIccandle 包裹图表并渲染扫描器浮层与结果 iframe。传入实时 widget 实例(挂载期间可为 null):
import { WidgetIccandle } from "@iccandle/reactjs-widget";
<WidgetIccandle chartWidget={chartWidget} theme="light" language="zh">
<div ref={containerRef} style={{ height: "100%", minHeight: 400 }} />
</WidgetIccandle>
使用 render prop 获取 chart refs
需要 chartRefs(生成 K 线指标 / 回放)时:
<WidgetIccandle chartWidget={chartWidget} theme="dark" language="zh">
{(chartRefs) => (
<ChartHost containerRef={containerRef} chartRefs={chartRefs} onReady={setChartWidget} />
)}
</WidgetIccandle>
若不需要这些 refs,也可直接传入普通 React 节点。
步骤 5 — 启用 Date Range 绘图
扫描器用 TradingView 的 Date Range 工具选择 K 线窗口。请在 drawings_access 中启用:
drawings_access: {
type: "black",
tools: [{ name: "Date Range" }],
},
默认窗口大小为 25 根 K 线。
认证
用户通过嵌入式结果应用登录。成功后,嵌入端发送 sign-in-success,父页面将 iccandle_token 写入 localStorage。扫描缓存与形态追踪 API 使用该令牌作为 Bearer 凭证。
无需向 WidgetIccandle 传入 API 密钥 prop — 认证由 iframe 登录流程处理。
主题与语言
theme="light"/theme="dark"— 强制扫描器与 iframe 使用对应配色。theme="system"— 跟随prefers-color-scheme。language— 可选en、zh、vi、th、ko、ja、mn、ru(默认en)。应用于扫描器 UI 与结果 iframe 语言。
完整示例
import { useEffect, useRef, useState } from "react";
import type {
ChartingLibraryWidgetOptions,
IChartingLibraryWidget,
ResolutionString,
} from "charting_library/charting_library";
import { widget } from "charting_library/charting_library";
import {
WidgetIccandle,
withPlayChart,
getCustomIndicators,
} from "@iccandle/reactjs-widget";
const LIBRARY_PATH = "/charting_library/";
export function ChartWithIccandle() {
const containerRef = useRef<HTMLDivElement>(null);
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
null,
);
return (
<div style={{ height: "100vh", width: "100%" }}>
<WidgetIccandle
chartWidget={chartWidget}
theme="light"
language="zh"
onCloseResult={() => {
/* 可选:嵌入端发送 close-result 时处理 */
}}
>
{(chartRefs) => (
<ChartHost
containerRef={containerRef}
chartRefs={chartRefs}
onReady={setChartWidget}
/>
)}
</WidgetIccandle>
</div>
);
}
function ChartHost({
containerRef,
chartRefs,
onReady,
}: {
containerRef: React.RefObject<HTMLDivElement | null>;
chartRefs: import("@iccandle/reactjs-widget").WidgetIccandleChartRefs;
onReady: (w: IChartingLibraryWidget | null) => void;
}) {
useEffect(() => {
const el = containerRef.current;
if (!el) return;
const options: ChartingLibraryWidgetOptions = {
container: el,
library_path: LIBRARY_PATH,
symbol: "EURUSD",
interval: "60" as ResolutionString,
datafeed: withPlayChart(yourDatafeed),
locale: "zh",
autosize: true,
drawings_access: {
type: "black",
tools: [{ name: "Date Range" }],
},
custom_indicators_getter: () => getCustomIndicators("light"),
};
const tv = new widget(options);
onReady(tv);
return () => {
try {
tv.remove();
} catch {
/* no-op */
}
onReady(null);
};
}, [containerRef, chartRefs, onReady]);
return <div ref={containerRef} style={{ height: "100%", width: "100%" }} />;
}
将 yourDatafeed 与 widget 选项替换为你的真实 datafeed 与 TradingView 配置。
功能概览
形态扫描器
- 订阅图表就绪、品种、周期与绘图事件。
- 管理
date_range多点绘图以选择 K 线窗口。 - 扫描时:将 K 线提交到缓存服务,再用搜索参数导航结果 iframe。
- 可选高级筛选(品种、top-k、回看周期、概率窗口)保存在
localStorage的search-filter下。
结果 iframe
- 默认加载
https://embed-iccandle-app.iccandle.ai/{language}?theme=...。 - 扫描 / 新闻导航后,
src会更新为搜索或相似事件路径。 - iframe 加载后,父页面发送
{ type: "parent-origin", origin },以便 Stripe 结账可返回宿主域名。
形态追踪
用户可从扫描器弹窗打开订阅模态框,追踪自定义形态(名称 + 周期 + 品种)。需要有效的 iccandle_token。
新闻 / 经济事件
- 点击时间轴标记可打开事件信息模态框(货币日历事件;跳过假期 / early / 纯情绪标记)。
- 「查看详情」在 iframe 中加载相似事件,并在图表上绘制垂直线。
- 若 datafeed 实现了
getTimescaleMarks,可通过localStorage键tv:selected-news-events与tv:clicked-news-event驱动标记 — 见 可选:时间轴标记。
常见模式
| 模式 | 做法 |
|---|---|
| 全页图表 + 结果 | 父容器 height: 100vh;WidgetIccandle 填满视口并布局图表与 iframe。 |
| 主题同步 | 从应用壳传入 theme(light / dark / system)。 |
| 语言同步 | 传入 language 以匹配应用语言。 |
| 等 iframe 就绪再扫描 | 结果 iframe 加载完成后传 iframeLoaded={true}(若不需要门控可省略该 prop)。 |
| 时间轴新闻标记 | 实现 getTimescaleMarks 并与 localStorage 同步 — 见 配置。 |