@pipsend/charts 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @license
3
- * Pipsend Charts v2.0.0-dev+202608130142
3
+ * Pipsend Charts v2.1.0
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -17550,6 +17550,164 @@
17550
17550
  };
17551
17551
  }
17552
17552
 
17553
+ function isOhlc(bar) {
17554
+ return bar !== null
17555
+ && bar !== undefined
17556
+ && typeof bar.close === 'number';
17557
+ }
17558
+ /**
17559
+ * Turns raw OHLC bars into Heikin Ashi ones.
17560
+ *
17561
+ * Heikin Ashi is a price transform, not an overlay: each candle averages itself
17562
+ * with the one before it, which drops most of the single-bar noise and leaves
17563
+ * runs of same-coloured bodies while a trend holds.
17564
+ *
17565
+ * ```
17566
+ * close = (O + H + L + C) / 4
17567
+ * open = (previous open + previous close) / 2 // first bar: (O + C) / 2
17568
+ * high = max(H, open, close)
17569
+ * low = min(L, open, close)
17570
+ * ```
17571
+ *
17572
+ * Because every bar folds in the one before it, the result depends on where the
17573
+ * data starts: the same bar computed from a longer history differs slightly.
17574
+ * The difference decays over a few bars, so pass the whole series rather than a
17575
+ * recent window when you can.
17576
+ *
17577
+ * Whitespace items are passed through untouched, and do not advance the
17578
+ * running open/close — a gap in the data is not a bar.
17579
+ *
17580
+ * @param bars - Source bars, ordered oldest to newest.
17581
+ * @returns The transformed bars, one per input item.
17582
+ */
17583
+ function calculateHeikinAshi(bars) {
17584
+ const result = [];
17585
+ let previousOpen = null;
17586
+ let previousClose = null;
17587
+ for (const bar of bars) {
17588
+ if (!isOhlc(bar)) {
17589
+ if (bar !== null && bar !== undefined) {
17590
+ result.push({ time: bar.time, customValues: bar.customValues });
17591
+ }
17592
+ continue;
17593
+ }
17594
+ const haClose = (bar.open + bar.high + bar.low + bar.close) / 4;
17595
+ const haOpen = previousOpen === null || previousClose === null
17596
+ ? (bar.open + bar.close) / 2
17597
+ : (previousOpen + previousClose) / 2;
17598
+ result.push({
17599
+ time: bar.time,
17600
+ open: haOpen,
17601
+ high: Math.max(bar.high, haOpen, haClose),
17602
+ low: Math.min(bar.low, haOpen, haClose),
17603
+ close: haClose,
17604
+ customValues: bar.customValues,
17605
+ });
17606
+ previousOpen = haOpen;
17607
+ previousClose = haClose;
17608
+ }
17609
+ return result;
17610
+ }
17611
+ /**
17612
+ * Draw a source series as Heikin Ashi candles.
17613
+ *
17614
+ * The source series is left in place holding its real prices — it is only
17615
+ * hidden — so indicators bound to it keep computing on the true OHLC, and
17616
+ * `remove()` puts the chart back exactly as it was. That makes this usable as a
17617
+ * chart-type toggle:
17618
+ *
17619
+ * ```js
17620
+ * const ha = applyHeikinAshi(candleSeries, chart);
17621
+ * // …back to regular candles:
17622
+ * ha.remove();
17623
+ * ```
17624
+ *
17625
+ * @param series - Source OHLC series (a candlestick or bar series).
17626
+ * @param chart - Chart instance.
17627
+ * @param options - Heikin Ashi configuration options.
17628
+ * @returns The Heikin Ashi candlestick series, plus live control over its options.
17629
+ */
17630
+ function applyHeikinAshi(series, chart, options = {}) {
17631
+ const resolved = {
17632
+ paneIndex: options.paneIndex ?? 0,
17633
+ upColor: options.upColor ?? '#26a69a',
17634
+ downColor: options.downColor ?? '#ef5350',
17635
+ borderVisible: options.borderVisible ?? true,
17636
+ borderUpColor: options.borderUpColor ?? '#26a69a',
17637
+ borderDownColor: options.borderDownColor ?? '#ef5350',
17638
+ wickVisible: options.wickVisible ?? true,
17639
+ wickUpColor: options.wickUpColor ?? '#26a69a',
17640
+ wickDownColor: options.wickDownColor ?? '#ef5350',
17641
+ hideSource: options.hideSource ?? true,
17642
+ };
17643
+ const sourceOptions = series.options();
17644
+ // Same price scale and the same formatting as the source: the candles are a
17645
+ // restatement of that series, not a second instrument, so they must not
17646
+ // autoscale on their own axis or round to a different precision.
17647
+ const haSeries = chart.addSeries(candlestickSeries, {
17648
+ upColor: resolved.upColor,
17649
+ downColor: resolved.downColor,
17650
+ borderVisible: resolved.borderVisible,
17651
+ borderUpColor: resolved.borderUpColor,
17652
+ borderDownColor: resolved.borderDownColor,
17653
+ wickVisible: resolved.wickVisible,
17654
+ wickUpColor: resolved.wickUpColor,
17655
+ wickDownColor: resolved.wickDownColor,
17656
+ priceScaleId: sourceOptions.priceScaleId,
17657
+ priceFormat: sourceOptions.priceFormat,
17658
+ }, resolved.paneIndex);
17659
+ const sourceWasVisible = sourceOptions.visible;
17660
+ if (resolved.hideSource === true) {
17661
+ series.applyOptions({ visible: false });
17662
+ }
17663
+ const runtime = bindIndicator({
17664
+ _internal_source: series,
17665
+ _internal_chart: chart,
17666
+ _internal_outputs: [haSeries],
17667
+ _internal_label: 'Heikin Ashi',
17668
+ _internal_options: resolved,
17669
+ // Every option here is a colour or a toggle on the series itself, so a
17670
+ // change never needs the transform run again.
17671
+ _internal_recomputeOn: [],
17672
+ _internal_compute: (data) => [
17673
+ [haSeries, calculateHeikinAshi(data)],
17674
+ ],
17675
+ _internal_applyStyle: (current) => {
17676
+ haSeries.applyOptions({
17677
+ upColor: current.upColor,
17678
+ downColor: current.downColor,
17679
+ borderVisible: current.borderVisible,
17680
+ borderUpColor: current.borderUpColor,
17681
+ borderDownColor: current.borderDownColor,
17682
+ wickVisible: current.wickVisible,
17683
+ wickUpColor: current.wickUpColor,
17684
+ wickDownColor: current.wickDownColor,
17685
+ });
17686
+ series.applyOptions({
17687
+ visible: current.hideSource === true ? false : sourceWasVisible,
17688
+ });
17689
+ },
17690
+ });
17691
+ const handle = {
17692
+ _internal_series: haSeries,
17693
+ options: runtime.options,
17694
+ applyOptions: runtime.applyOptions,
17695
+ recalculate: runtime.recalculate,
17696
+ remove: () => {
17697
+ runtime.remove();
17698
+ // The source outlives the indicator, so its visibility is ours to put
17699
+ // back — otherwise removing a Heikin Ashi overlay leaves a blank chart.
17700
+ try {
17701
+ series.applyOptions({ visible: sourceWasVisible });
17702
+ }
17703
+ catch (error) {
17704
+ // The series may already be gone if the chart was disposed
17705
+ }
17706
+ },
17707
+ };
17708
+ return handle;
17709
+ }
17710
+
17553
17711
  /**
17554
17712
  * Apply RSI indicator to a series
17555
17713
  * @param series - Source series to calculate RSI from
@@ -29608,7 +29766,7 @@
29608
29766
  * Returns the current version as a string. For example `'1.0.0'`.
29609
29767
  */
29610
29768
  function version() {
29611
- return "2.0.0-dev+202608130142";
29769
+ return "2.1.0";
29612
29770
  }
29613
29771
 
29614
29772
  var PipsendChartsModule = /*#__PURE__*/Object.freeze({
@@ -29665,6 +29823,7 @@
29665
29823
  applyCCI: applyCCI,
29666
29824
  applyDonchianChannels: applyDonchianChannels,
29667
29825
  applyEMA: applyEMA,
29826
+ applyHeikinAshi: applyHeikinAshi,
29668
29827
  applyIchimoku: applyIchimoku,
29669
29828
  applyKeltnerChannels: applyKeltnerChannels,
29670
29829
  applyMACD: applyMACD,
@@ -29680,6 +29839,7 @@
29680
29839
  applyVolume: applyVolume,
29681
29840
  applyWMA: applyWMA,
29682
29841
  applyWilliamsR: applyWilliamsR,
29842
+ calculateHeikinAshi: calculateHeikinAshi,
29683
29843
  calculatePipConfig: calculatePipConfig,
29684
29844
  coordinateFromTime: coordinateFromTime,
29685
29845
  createArrowTool: createArrowTool,
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @license
3
- * Pipsend Charts v2.0.0-dev+202608130142
3
+ * Pipsend Charts v2.1.0
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -17547,6 +17547,164 @@ function applyPivotPoints(series, chart, options = {}) {
17547
17547
  };
17548
17548
  }
17549
17549
 
17550
+ function isOhlc(bar) {
17551
+ return bar !== null
17552
+ && bar !== undefined
17553
+ && typeof bar.close === 'number';
17554
+ }
17555
+ /**
17556
+ * Turns raw OHLC bars into Heikin Ashi ones.
17557
+ *
17558
+ * Heikin Ashi is a price transform, not an overlay: each candle averages itself
17559
+ * with the one before it, which drops most of the single-bar noise and leaves
17560
+ * runs of same-coloured bodies while a trend holds.
17561
+ *
17562
+ * ```
17563
+ * close = (O + H + L + C) / 4
17564
+ * open = (previous open + previous close) / 2 // first bar: (O + C) / 2
17565
+ * high = max(H, open, close)
17566
+ * low = min(L, open, close)
17567
+ * ```
17568
+ *
17569
+ * Because every bar folds in the one before it, the result depends on where the
17570
+ * data starts: the same bar computed from a longer history differs slightly.
17571
+ * The difference decays over a few bars, so pass the whole series rather than a
17572
+ * recent window when you can.
17573
+ *
17574
+ * Whitespace items are passed through untouched, and do not advance the
17575
+ * running open/close — a gap in the data is not a bar.
17576
+ *
17577
+ * @param bars - Source bars, ordered oldest to newest.
17578
+ * @returns The transformed bars, one per input item.
17579
+ */
17580
+ function calculateHeikinAshi(bars) {
17581
+ const result = [];
17582
+ let previousOpen = null;
17583
+ let previousClose = null;
17584
+ for (const bar of bars) {
17585
+ if (!isOhlc(bar)) {
17586
+ if (bar !== null && bar !== undefined) {
17587
+ result.push({ time: bar.time, customValues: bar.customValues });
17588
+ }
17589
+ continue;
17590
+ }
17591
+ const haClose = (bar.open + bar.high + bar.low + bar.close) / 4;
17592
+ const haOpen = previousOpen === null || previousClose === null
17593
+ ? (bar.open + bar.close) / 2
17594
+ : (previousOpen + previousClose) / 2;
17595
+ result.push({
17596
+ time: bar.time,
17597
+ open: haOpen,
17598
+ high: Math.max(bar.high, haOpen, haClose),
17599
+ low: Math.min(bar.low, haOpen, haClose),
17600
+ close: haClose,
17601
+ customValues: bar.customValues,
17602
+ });
17603
+ previousOpen = haOpen;
17604
+ previousClose = haClose;
17605
+ }
17606
+ return result;
17607
+ }
17608
+ /**
17609
+ * Draw a source series as Heikin Ashi candles.
17610
+ *
17611
+ * The source series is left in place holding its real prices — it is only
17612
+ * hidden — so indicators bound to it keep computing on the true OHLC, and
17613
+ * `remove()` puts the chart back exactly as it was. That makes this usable as a
17614
+ * chart-type toggle:
17615
+ *
17616
+ * ```js
17617
+ * const ha = applyHeikinAshi(candleSeries, chart);
17618
+ * // …back to regular candles:
17619
+ * ha.remove();
17620
+ * ```
17621
+ *
17622
+ * @param series - Source OHLC series (a candlestick or bar series).
17623
+ * @param chart - Chart instance.
17624
+ * @param options - Heikin Ashi configuration options.
17625
+ * @returns The Heikin Ashi candlestick series, plus live control over its options.
17626
+ */
17627
+ function applyHeikinAshi(series, chart, options = {}) {
17628
+ const resolved = {
17629
+ paneIndex: options.paneIndex ?? 0,
17630
+ upColor: options.upColor ?? '#26a69a',
17631
+ downColor: options.downColor ?? '#ef5350',
17632
+ borderVisible: options.borderVisible ?? true,
17633
+ borderUpColor: options.borderUpColor ?? '#26a69a',
17634
+ borderDownColor: options.borderDownColor ?? '#ef5350',
17635
+ wickVisible: options.wickVisible ?? true,
17636
+ wickUpColor: options.wickUpColor ?? '#26a69a',
17637
+ wickDownColor: options.wickDownColor ?? '#ef5350',
17638
+ hideSource: options.hideSource ?? true,
17639
+ };
17640
+ const sourceOptions = series.options();
17641
+ // Same price scale and the same formatting as the source: the candles are a
17642
+ // restatement of that series, not a second instrument, so they must not
17643
+ // autoscale on their own axis or round to a different precision.
17644
+ const haSeries = chart.addSeries(candlestickSeries, {
17645
+ upColor: resolved.upColor,
17646
+ downColor: resolved.downColor,
17647
+ borderVisible: resolved.borderVisible,
17648
+ borderUpColor: resolved.borderUpColor,
17649
+ borderDownColor: resolved.borderDownColor,
17650
+ wickVisible: resolved.wickVisible,
17651
+ wickUpColor: resolved.wickUpColor,
17652
+ wickDownColor: resolved.wickDownColor,
17653
+ priceScaleId: sourceOptions.priceScaleId,
17654
+ priceFormat: sourceOptions.priceFormat,
17655
+ }, resolved.paneIndex);
17656
+ const sourceWasVisible = sourceOptions.visible;
17657
+ if (resolved.hideSource === true) {
17658
+ series.applyOptions({ visible: false });
17659
+ }
17660
+ const runtime = bindIndicator({
17661
+ _internal_source: series,
17662
+ _internal_chart: chart,
17663
+ _internal_outputs: [haSeries],
17664
+ _internal_label: 'Heikin Ashi',
17665
+ _internal_options: resolved,
17666
+ // Every option here is a colour or a toggle on the series itself, so a
17667
+ // change never needs the transform run again.
17668
+ _internal_recomputeOn: [],
17669
+ _internal_compute: (data) => [
17670
+ [haSeries, calculateHeikinAshi(data)],
17671
+ ],
17672
+ _internal_applyStyle: (current) => {
17673
+ haSeries.applyOptions({
17674
+ upColor: current.upColor,
17675
+ downColor: current.downColor,
17676
+ borderVisible: current.borderVisible,
17677
+ borderUpColor: current.borderUpColor,
17678
+ borderDownColor: current.borderDownColor,
17679
+ wickVisible: current.wickVisible,
17680
+ wickUpColor: current.wickUpColor,
17681
+ wickDownColor: current.wickDownColor,
17682
+ });
17683
+ series.applyOptions({
17684
+ visible: current.hideSource === true ? false : sourceWasVisible,
17685
+ });
17686
+ },
17687
+ });
17688
+ const handle = {
17689
+ _internal_series: haSeries,
17690
+ options: runtime.options,
17691
+ applyOptions: runtime.applyOptions,
17692
+ recalculate: runtime.recalculate,
17693
+ remove: () => {
17694
+ runtime.remove();
17695
+ // The source outlives the indicator, so its visibility is ours to put
17696
+ // back — otherwise removing a Heikin Ashi overlay leaves a blank chart.
17697
+ try {
17698
+ series.applyOptions({ visible: sourceWasVisible });
17699
+ }
17700
+ catch (error) {
17701
+ // The series may already be gone if the chart was disposed
17702
+ }
17703
+ },
17704
+ };
17705
+ return handle;
17706
+ }
17707
+
17550
17708
  /**
17551
17709
  * Apply RSI indicator to a series
17552
17710
  * @param series - Source series to calculate RSI from
@@ -29605,7 +29763,7 @@ const customSeriesDefaultOptions = {
29605
29763
  * Returns the current version as a string. For example `'1.0.0'`.
29606
29764
  */
29607
29765
  function version() {
29608
- return "2.0.0-dev+202608130142";
29766
+ return "2.1.0";
29609
29767
  }
29610
29768
 
29611
- export { areaSeries as AreaSeries, ArrowTool, barSeries as BarSeries, baselineSeries as BaselineSeries, BrushTool, candlestickSeries as CandlestickSeries, CircleTool, ColorType, CrossLineTool, CrosshairMode, DEFAULT_SESSIONS, DraggablePriceLine, DrawingToolsManager, EXTENDED_FIBONACCI_RATIOS, FibonacciCalculator, FibonacciExtensionTool, FibonacciFanTool, FibonacciTool, GanttTool, histogramSeries as HistogramSeries, HorizontalLineTool, InteractiveLineManager, LastPriceAnimationMode, lineSeries as LineSeries, LineStyle, LineType, MismatchDirection, ParallelChannelTool, PitchforkTool, PolygonTool, PositionCalculator, PositionMarkersManager, PositionTool, PriceLineSource, PriceScaleMode, RectangleTool, RulerCalculator, RulerTool, STANDARD_FIBONACCI_RATIOS, TextTool, TickMarkType, TrackingModeExitMode, TradingSessionsIndicator, TrendLineTool, VerticalLineTool, VolumeProfileIndicator, applyADX, applyATR, applyBollingerBands, applyCCI, applyDonchianChannels, applyEMA, applyIchimoku, applyKeltnerChannels, applyMACD, applyMFI, applyOBV, applyParabolicSAR, applyPivotPoints, applyRSI, applySMA, applyStochastic, applySuperTrend, applyVWAP, applyVolume, applyWMA, applyWilliamsR, calculatePipConfig, coordinateFromTime, createArrowTool, createBrushTool, createChart, createChartEx, createCircleTool, createCrossLineTool, createFibonacciExtensionTool, createFibonacciFanTool, createFibonacciTool, createGanttTool, createHorizontalLineTool, createImageWatermark, createInteractiveLineManager, createOptionsChart, createParallelChannelTool, createPitchforkTool, createPolygonTool, createPositionMarkers, createPositionTool, createRectangleTool, createRulerTool, createSeriesMarkers, createTextTool, createTextWatermark, createTradingLine, createTradingSessionsIndicator, createTrendLineTool, createUpDownMarkers, createVerticalLineTool, createVolumeProfileIndicator, createYieldCurveChart, customSeriesDefaultOptions, defaultHorzScaleBehavior, getPipConfig, isBusinessDay, isUTCTimestamp, setSeriesVolumes, setVolumeProfileData, timeFromCoordinate, version };
29769
+ export { areaSeries as AreaSeries, ArrowTool, barSeries as BarSeries, baselineSeries as BaselineSeries, BrushTool, candlestickSeries as CandlestickSeries, CircleTool, ColorType, CrossLineTool, CrosshairMode, DEFAULT_SESSIONS, DraggablePriceLine, DrawingToolsManager, EXTENDED_FIBONACCI_RATIOS, FibonacciCalculator, FibonacciExtensionTool, FibonacciFanTool, FibonacciTool, GanttTool, histogramSeries as HistogramSeries, HorizontalLineTool, InteractiveLineManager, LastPriceAnimationMode, lineSeries as LineSeries, LineStyle, LineType, MismatchDirection, ParallelChannelTool, PitchforkTool, PolygonTool, PositionCalculator, PositionMarkersManager, PositionTool, PriceLineSource, PriceScaleMode, RectangleTool, RulerCalculator, RulerTool, STANDARD_FIBONACCI_RATIOS, TextTool, TickMarkType, TrackingModeExitMode, TradingSessionsIndicator, TrendLineTool, VerticalLineTool, VolumeProfileIndicator, applyADX, applyATR, applyBollingerBands, applyCCI, applyDonchianChannels, applyEMA, applyHeikinAshi, applyIchimoku, applyKeltnerChannels, applyMACD, applyMFI, applyOBV, applyParabolicSAR, applyPivotPoints, applyRSI, applySMA, applyStochastic, applySuperTrend, applyVWAP, applyVolume, applyWMA, applyWilliamsR, calculateHeikinAshi, calculatePipConfig, coordinateFromTime, createArrowTool, createBrushTool, createChart, createChartEx, createCircleTool, createCrossLineTool, createFibonacciExtensionTool, createFibonacciFanTool, createFibonacciTool, createGanttTool, createHorizontalLineTool, createImageWatermark, createInteractiveLineManager, createOptionsChart, createParallelChannelTool, createPitchforkTool, createPolygonTool, createPositionMarkers, createPositionTool, createRectangleTool, createRulerTool, createSeriesMarkers, createTextTool, createTextWatermark, createTradingLine, createTradingSessionsIndicator, createTrendLineTool, createUpDownMarkers, createVerticalLineTool, createVolumeProfileIndicator, createYieldCurveChart, customSeriesDefaultOptions, defaultHorzScaleBehavior, getPipConfig, isBusinessDay, isUTCTimestamp, setSeriesVolumes, setVolumeProfileData, timeFromCoordinate, version };