如果你也在做订单流交易,一定知道 POC(Point of Control) 有多重要。ATAS 自带的市场剖面图能显示 POC,但那是整个区间汇总的。有没有办法在每根 K 线上直接画出该 K 线的 POC? 有,而且代码不到一百行。
为什么要看每根 K 线的 POC?
POC(成交量最集中的价格)是订单流分析的基石。在日线上我们知道 POC 在哪儿,但在更细的时间维度——比如 5 分钟 K 线、成交量 K 线——每根 K 线内部也有自己的 POC。
如果你能在每根 K 线上直接看到:
- 该 K 线 POC 是否在逐根上升/下降——趋势强度
- 价格是否远离 POC——偏离过大的区域可能被回补
- POC 与上下影线的关系——实盘多空博弈的痕迹
它是你理解“价格在哪个位置成交最多”的最直观工具。
ATAS 有现成的吗?
没有。ATAS 内建的 Volume Profile 工具本质上是区间级的——你画一个矩形区域,它计算整个区域的 POC。没有一个“逐根 K 线独立显示 POC 横线”的指标。
但是 ATAS 提供了 C# 自定义指标 SDK,我们可以自己写一个。
指标的设计思路
需求很简单:
- 遍历图表上每一根可见的 K 线
- 读取该 K 线的
MaxVolumePriceInfo——ATAS 官方 API 中代表 POC 的字段 - 在 POC 价格位置画一条短横线
- 横线的颜色和粗细可以在设置面板中调整
用到的 ATAS SDK 关键类/方法:
| API | 用途 |
|---|---|
Indicator | 所有自定义指标的基类 |
GetCandle(bar) | 获取某根 K 线的数据对象 |
candle.MaxVolumePriceInfo.Price | 该 K 线的 POC 价格 |
ChartInfo.GetYByPrice(price) | 将价格转换为 Y 像素坐标 |
ChartInfo.GetXByBar(bar) | 将 K 线序号转换为 X 像素坐标 |
RenderContext.DrawLine() | 在图表上绘制线段 |
RenderPen | 画笔(颜色 + 粗细) |
FirstVisibleBarNumber / LastVisibleBarNumber | 当前可见的第一根和最后一根 K 线序号 |
有了这些 API,核心逻辑非常直白。
完整源码
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Drawing;
using ATAS.Indicators;
using ATAS.Indicators.Drawing;
using OFT.Rendering.Context;
using OFT.Rendering.Tools;
namespace POCCandles;
[DisplayName("Candle POC Line")]
[Category("Order Flow")]
[Description("Draws a horizontal line at each candle's POC price.")]
public class CandlePocLine : Indicator
{
private Color _lineColor = Color.White;
private int _lineWidth = 2;
public CandlePocLine()
: base(true)
{
DenyToChangePanel = true;
EnableCustomDrawing = true;
SubscribeToDrawingEvents(DrawingLayouts.Historical | DrawingLayouts.LatestBar);
DataSeries[0].IsHidden = true;
((ValueDataSeries)DataSeries[0]).VisualType = VisualMode.Hide;
}
[Display(Name = "Color", GroupName = "Line", Order = 10)]
public Color LineColor
{
get => _lineColor;
set
{
_lineColor = value;
RedrawChart();
}
}
[Range(1, 10)]
[Display(Name = "Width", GroupName = "Line", Order = 20)]
public int LineWidth
{
get => _lineWidth;
set
{
_lineWidth = Math.Max(1, value);
RedrawChart();
}
}
protected override void OnCalculate(int bar, decimal value)
{
}
protected override void OnRender(RenderContext context, DrawingLayouts layout)
{
if (ChartInfo is null || CurrentBar < 1)
return;
var pen = new RenderPen(_lineColor, _lineWidth);
var firstBar = Math.Max(0, FirstVisibleBarNumber);
var lastBar = Math.Min(CurrentBar - 1, LastVisibleBarNumber);
var halfWidth = Math.Max(1, (int)(ChartInfo.PriceChartContainer.BarsWidth / 2));
for (var bar = firstBar; bar <= lastBar; bar++)
{
var candle = GetCandle(bar);
if (candle is null || candle.MaxVolumePriceInfo is null)
continue;
var pocPrice = candle.MaxVolumePriceInfo.Price;
var y = ChartInfo.GetYByPrice(pocPrice, false);
var x = ChartInfo.GetXByBar(bar, false);
context.DrawLine(pen, x - halfWidth, y, x + halfWidth, y);
}
}
}
几点说明
OnCalculate里面是空的——因为所有工作都在OnRender里直接读取每根 K 线的 POC 并绘制,不需要提前计算和存储中间结果。DataSeries[0].IsHidden = true——每个Indicator默认带一条数值数据线,这里把它藏掉,因为我们要的是自定义绘图。ChartInfo.PriceChartContainer.BarsWidth——获取当前每根 K 线占的像素宽度,用来把横线限制在 K 线范围之内。
怎么编译和使用
编译
在你的项目目录下放一个 .csproj 文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Reference Include="ATAS.Indicators">
<HintPath>C:\Program Files (x86)\ATAS Platform\ATAS.Indicators.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="OFT.Rendering">
<HintPath>C:\Program Files (x86)\ATAS Platform\OFT.Rendering.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Project>
然后用命令行编译:
dotnet build
注意:TargetFramework 版本需要和你的 ATAS 实际版本匹配。我本机 ATAS 是 8.0.13.386,它依赖 .NET 10,所以用的是 net10.0-windows。安装到 ATAS
编译成功后,把生成的 POCCandles.dll 放到 ATAS 指标文件夹,或者在 ATAS 的指标设置窗口里点击左下角"Add custom indicator"按钮,选择这个 DLL。
具体路径:C:\Users\<你的用户名>\AppData\Roaming\ATAS\Indicators\
使用
打开图表的指标设置,在 Order Flow 分类下面找到 Candle POC Line,点 Add 即可。
效果
加上这个指标之后,图表上的每一根 K 线中间都会出现一条短横线,颜色和粗细可以在设置面板里自由调整。默认白色,粗细 2px。
白色短线的位置就是这根 K 线成交量最集中的价位。当价格远离这条线时,说明当前价位成交量稀疏,可能出现"真空地带";当价格持续在 POC 附近博弈时,说明这里是多空真正的战场。
一句话总结
好的工具不一定是复杂的工具。一个不到 90 行的指标,让你对每一根 K 线的"重心"一目了然。如果你用 ATAS 做订单流分析,这个指标值得加到你的默认图表模板里
Discussion