An intraday vwap indicator created by AI
import {
IndicatorImplementation,
TIndexBuffer,
TDrawStyle,
TPenStyle,
TimeZoneMode,
TOptionType
} from 'forex-tester-custom-indicator-api';
export class IntradayVWAP extends IndicatorImplementation {
// 缓冲区用于存储VWAP值
private vwapBuffer: TIndexBuffer = this.api.CreateIndexBuffer();
// 每日累计值
private sumPV: number = 0; // 价格*成交量的总和
private sumVol: number = 0; // 成交量总和
private currentDate: string = '';
// 参数:自定义开始时间
private startHour = this.api.createTOptValue_number(9); // 默认9点开始
private startMinute = this.api.createTOptValue_number(0); // 默认0分
Init(): void {
// 设置指标名称
this.api.IndicatorShortName("Intraday VWAP");
// 设置缓冲区
this.api.IndicatorBuffers(1);
this.api.SetIndexBuffer(0, this.vwapBuffer);
// 设置线条样式
this.api.SetIndexStyle(0, TDrawStyle.LINE, TPenStyle.SOLID, 2, "#0066FF");
this.api.SetIndexLabel(0, "VWAP");
// 注册参数
this.api.RegOption("Start Hour", TOptionType.INTEGER, this.startHour);
this.api.RegOption("Start Minute", TOptionType.INTEGER, this.startMinute);
// 设置参数范围
this.api.SetOptionRange("Start Hour", 0, 23);
this.api.SetOptionRange("Start Minute", 0, 59);
}
Calculate(index: number): void {
// 只在日线以下的时间周期显示
if (this.api.Timeframe() >= 1440) {
this.vwapBuffer.setValue(index, NaN);
return;
}
const time = this.api.Time(index);
const currentDate = `${time.yearOf()}-${time.monthOf()}-${time.dayOfMonth()}`;
// 检查是否是新的一天或会话开始
const isSessionStart =
time.hour() === this.startHour.value &&
time.minute() === this.startMinute.value;
// 如果是新的一天或会话开始,重置累计值
if (currentDate !== this.currentDate || isSessionStart) {
this.sumPV = 0;
this.sumVol = 0;
this.currentDate = currentDate;
}
// 计算当前bar的典型价格和成交量
const typicalPrice = (this.api.High(index) + this.api.Low(index) + this.api.Close(index)) / 3;
const volume = this.api.Volume(index);
// 累加价格成交量
this.sumPV += typicalPrice * volume;
this.sumVol += volume;
// 计算并设置VWAP值
if (this.sumVol > 0) {
const vwap = this.sumPV / this.sumVol;
this.vwapBuffer.setValue(index, vwap);
} else {
this.vwapBuffer.setValue(index, NaN);
}
}
}
export const indicator = new IntradayVWAP();Hi, I created it using AI in cursor. And built the
`my-indicator-project.js`. However, after I uploaded it, nothing had happend….. no response at all. Is there anything wrong with the codes?
- How does this impact your experience?
Comments7
Serhii S.
May 27, 2025
Hi @User Thank you for waiting. Please check your mailbox. We have just sent you an email.
Liwei Gao
May 27, 2025
Thank you so much!
Serhii S.
May 27, 2025
You're welcome! If you have any other questions or need help with anything else, just let me know.
Liwei Gao
Jun 3, 2025
Hi, now the vwap works almost perfectly, but there are still some small issues,
1. When I zoom in, the vwap channels just become parallels
2.When vwap anchor point is not in my screen, the vwap lines of that day are just hugely skewed as in the second graph.
These two problems all happen after the corresponding anchor points are no more in the current screen.
Serhii S.
Jun 3, 2025
Hi! Thanks for the detailed feedback and the screenshots!
I’ll share this with our dev team so we can dig into the display logic and see how we can improve it. If you notice any patterns (like specific zoom levels or symbols where it's worse), let me know.
Thanks for catching these!
Serhii S.
May 27, 2025
Hi @User Thanks for sharing your intraday VWAP indicator idea and the code sample. Our developers will take a closer look. This might take a bit, but we’ll keep you posted!
Liwei Gao
May 27, 2025
// VWAP Indicator with Custom Start Time and Only for Intraday Timeframes import { IndicatorImplementation, TIndexBuffer, TDrawStyle, TPenStyle, TimeZoneMode, TOptionType } from 'forex-tester-custom-indicator-api'; export class IntradayVWAP extends IndicatorImplementation { // Buffer for storing VWAP values private vwapBuffer: TIndexBuffer = this.api.CreateIndexBuffer(); // Daily accumulated values private sumPV: number = 0; // Sum of price * volume private sumVol: number = 0; // Sum of volume private currentDate: string = ''; // Parameters: Custom session start time private startHour = this.api.createTOptValue_number(9); // Default: 9 AM private startMinute = this.api.createTOptValue_number(0); // Default: 0 minute Init(): void { // Set indicator name this.api.IndicatorShortName("Intraday VWAP"); // Configure buffer this.api.IndicatorBuffers(1); this.api.SetIndexBuffer(0, this.vwapBuffer); // Set line style this.api.SetIndexStyle(0, TDrawStyle.LINE, TPenStyle.SOLID, 2, "#0066FF"); this.api.SetIndexLabel(0, "VWAP"); // Register parameters this.api.RegOption("Start Hour", TOptionType.INTEGER, this.startHour); this.api.RegOption("Start Minute", TOptionType.INTEGER, this.startMinute); // Set parameter ranges this.api.SetOptionRange("Start Hour", 0, 23); this.api.SetOptionRange("Start Minute", 0, 59); } Calculate(index: number): void { // Only show on timeframes below daily if (this.api.Timeframe() >= 1440) { this.vwapBuffer.setValue(index, NaN); return; } const time = this.api.Time(index); const currentDate = `${time.yearOf()}-${time.monthOf()}-${time.dayOfMonth()}`; // Check if it's a new day or session start const isSessionStart = time.hour() === this.startHour.value && time.minute() === this.startMinute.value; // Reset accumulated values on new day or session start if (currentDate !== this.currentDate || isSessionStart) { this.sumPV = 0; this.sumVol = 0; this.currentDate = currentDate; } // Calculate typical price and volume for current bar const typicalPrice = (this.api.High(index) + this.api.Low(index) + this.api.Close(index)) / 3; const volume = this.api.Volume(index); // Accumulate price-volume values this.sumPV += typicalPrice * volume; this.sumVol += volume; // Calculate and set VWAP value if (this.sumVol > 0) { const vwap = this.sumPV / this.sumVol; this.vwapBuffer.setValue(index, vwap); } else { this.vwapBuffer.setValue(index, NaN); } } } export const indicator = new IntradayVWAP();English Comments