"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.DEFAULT_TWEEZER_TOP_CONFIG = void 0;
exports.tweezertop = tweezertop;
var _CandlestickFinder = _interopRequireWildcard(require("./CandlestickFinder"));
var _AverageLoss = require("../Utils/AverageLoss");
var _AverageGain = require("../Utils/AverageGain");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
/**
 * Configuration interface for TweezerTop pattern.
 * Only requires scale parameter since this pattern uses direct price comparisons.
 */

/**
 * Default configuration for TweezerTop pattern.
 */
const DEFAULT_TWEEZER_TOP_CONFIG = exports.DEFAULT_TWEEZER_TOP_CONFIG = {
  ..._CandlestickFinder.DEFAULT_CANDLESTICK_CONFIG
};
class TweezerTop extends _CandlestickFinder.default {
  constructor(config) {
    const finalConfig = {
      ...DEFAULT_TWEEZER_TOP_CONFIG,
      ...config
    };
    super(finalConfig);
    this.name = 'TweezerTop';
    this.requiredCount = 5;
  }
  logic(data) {
    // Validate data integrity first
    for (let i = 0; i < data.close.length; i++) {
      if (!this.validateOHLC(data.open[i], data.high[i], data.low[i], data.close[i])) {
        return false;
      }
    }
    return this.upwardTrend(data) && this.hasTweezerTopPattern(data);
  }
  upwardTrend(data) {
    // Ensure we have enough data
    if (data.close.length < 3) {
      return false;
    }

    // Analyze trends in closing prices of the first three candlesticks (oldest)
    // For ascending order data, take the first 3 elements
    let gains = (0, _AverageGain.averagegain)({
      values: data.close.slice(0, 3),
      period: 2
    });
    let losses = (0, _AverageLoss.averageloss)({
      values: data.close.slice(0, 3),
      period: 2
    });

    // Get the latest values from the arrays
    let latestGain = gains.length > 0 ? gains[gains.length - 1] : 0;
    let latestLoss = losses.length > 0 ? losses[losses.length - 1] : 0;

    // Additional validation: ensure there's actual price movement
    let closeSlice = data.close.slice(0, 3);
    let priceRange = Math.max(...closeSlice) - Math.min(...closeSlice);
    let minMovement = priceRange * 0.01; // At least 1% movement

    // Upward trend, so more gains than losses, and significant movement
    return latestGain > latestLoss && latestGain > minMovement;
  }
  hasTweezerTopPattern(data) {
    // Ensure we have enough data for the pattern
    if (data.close.length < 5) {
      return false;
    }

    // For ascending order data, the last two candles are at the end
    let len = data.close.length;
    let firstCandle = {
      open: data.open[len - 2],
      close: data.close[len - 2],
      low: data.low[len - 2],
      high: data.high[len - 2]
    };
    let secondCandle = {
      open: data.open[len - 1],
      close: data.close[len - 1],
      low: data.low[len - 1],
      high: data.high[len - 1]
    };

    // Both candles should have approximately equal highs (the "tweezer" effect)
    // Note: approximateEqual uses scale for price comparison precision
    let hasEqualHighs = this.approximateEqual(firstCandle.high, secondCandle.high);

    // Additional criteria for a stronger pattern (all use relative percentages, no scale dependency):
    // 1. Both candles should have meaningful bodies (not dojis) - relaxed requirement
    let firstBodySize = Math.abs(firstCandle.close - firstCandle.open);
    let secondBodySize = Math.abs(secondCandle.close - secondCandle.open);
    let firstRange = firstCandle.high - firstCandle.low;
    let secondRange = secondCandle.high - secondCandle.low;

    // More lenient body size requirement (5% instead of 10%) - relative percentage, no scale dependency
    let hasMeaningfulBodies = firstBodySize >= firstRange * 0.05 && secondBodySize >= secondRange * 0.05;

    // 2. The second candle should ideally be bearish (reversal signal)
    let secondIsBearish = secondCandle.close < secondCandle.open;

    // 3. The highs should be significant resistance levels (higher than recent prices)
    let resistanceLevel = Math.max(firstCandle.high, secondCandle.high);
    // Check against earlier candles (before the tweezer pattern)
    let recentHighs = data.high.slice(0, len - 2);
    let isSignificantResistance = recentHighs.length === 0 || recentHighs.every(high => high <= resistanceLevel);
    return hasEqualHighs && hasMeaningfulBodies && (secondIsBearish || isSignificantResistance);
  }
}

/**
 * Detects TweezerTop candlestick pattern.
 *
 * A TweezerTop is a bearish reversal pattern that occurs at the end of an uptrend.
 * It consists of two or more candles with approximately equal highs, suggesting
 * resistance at that price level.
 *
 * @param data - Stock data containing OHLC values
 * @param config - Configuration options for the pattern detection
 * @returns True if TweezerTop pattern is detected, false otherwise
 *
 * @example
 * ```typescript
 * const data = { open: [...], high: [...], low: [...], close: [...] };
 * const isPattern = tweezertop(data, { scale: 0.001 });
 * ```
 */
exports.default = TweezerTop;
function tweezertop(data, config = DEFAULT_TWEEZER_TOP_CONFIG) {
  return new TweezerTop(config).hasPattern(data);
}
//# sourceMappingURL=TweezerTop.js.map