Skip to main content

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?
Status: Completed7 comments

Comments7

  • Serhii S.

    Team•

    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.

        Team•

        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.

            Team•

            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.

    Team•

    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