"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccumulatorBot = void 0;
const BaseBot_1 = require("../BaseBot");
/**
 * AccumulatorBot - Slow, consistent buyer
 *
 * Characteristics:
 * - Primarily buys
 * - Builds support levels
 * - Creates upward pressure
 * - Patient and methodical
 * - Accumulates at lower prices
 */
class AccumulatorBot extends BaseBot_1.BaseBot {
    constructor(config) {
        super({
            ...config,
            personality: "ACCUMULATOR",
            tradeFrequency: "LOW",
        });
        // Accumulator-specific settings
        this.buyBias = 0.9; // 90% chance to buy vs sell
        this.maxAccumulationPercent = 2; // Max 2% above target to accumulate
        this.supportBuildingStrength = 1.5; // Multiplier for support level orders
        // Accumulation tracking
        this.totalAccumulated = BigInt(0);
        this.accumulationSessions = 0;
    }
    /**
     * Accumulator decision logic - consistently buy
     */
    decideTrade(context) {
        if (!this.canTrade()) {
            return { shouldTrade: false, reason: "Cannot trade" };
        }
        const currentPriceNum = Number(context.currentPrice) / 1e18;
        const targetPriceNum = Number(context.targetPrice) / 1e18;
        const priceDiff = ((targetPriceNum - currentPriceNum) / currentPriceNum) * 100;
        // Accumulators prefer to buy when price is below target
        const isBelowTarget = currentPriceNum < targetPriceNum;
        // Don't accumulate if price is too far above target
        if (priceDiff < -this.maxAccumulationPercent) {
            return {
                shouldTrade: false,
                reason: `Price too far above target (${priceDiff.toFixed(2)}%)`,
            };
        }
        // Random chance with buy bias
        const shouldBuy = Math.random() < this.buyBias;
        if (!shouldBuy) {
            // Rarely sell - only for rebalancing
            if (this.totalAccumulated > BigInt(0) && Math.random() < 0.1) {
                return this.createSellOrder(context, "Rebalancing small amount");
            }
            return { shouldTrade: false, reason: "Skipping - accumulator prefers buying" };
        }
        // Check if near support level
        const nearSupport = currentPriceNum <= context.priceRangeLow * 1.05;
        // Buy more aggressively near support
        const sizeMultiplier = nearSupport ? this.supportBuildingStrength : 1;
        const price = this.calculatePrice(context, "BUY");
        const baseAmount = this.calculateOrderSize(context);
        const amount = BigInt(Math.floor(Number(baseAmount) * sizeMultiplier));
        this.accumulationSessions++;
        return {
            shouldTrade: true,
            side: "BUY",
            price,
            amount,
            purpose: isBelowTarget ? "PRICE_PUSH" : "LIQUIDITY",
            confidence: 0.7 + (isBelowTarget ? 0.2 : 0),
            reason: nearSupport
                ? "Building support level"
                : `Accumulating (session ${this.accumulationSessions})`,
        };
    }
    /**
     * Create rare sell order for rebalancing
     */
    createSellOrder(context, reason) {
        const price = this.calculatePrice(context, "SELL");
        const amount = this.calculateOrderSize(context);
        // Sell only a small portion
        const sellAmount = BigInt(Math.floor(Number(amount) * 0.3));
        return {
            shouldTrade: true,
            side: "SELL",
            price,
            amount: sellAmount,
            purpose: "LIQUIDITY",
            confidence: 0.4,
            reason,
        };
    }
    /**
     * Calculate order size - consistent but varied
     */
    calculateOrderSize(context) {
        const currentPriceNum = Number(context.currentPrice) / 1e18;
        const targetPriceNum = Number(context.targetPrice) / 1e18;
        // Accumulate more when price is below target
        let sizeMultiplier = 1;
        if (currentPriceNum < targetPriceNum * 0.98) {
            sizeMultiplier = 1.3; // 30% more when significantly below target
        }
        const baseSize = this.config.avgOrderSize * sizeMultiplier;
        const variedSize = this.addVariance(baseSize, 0.25);
        return BigInt(Math.floor(variedSize * 1e18));
    }
    /**
     * Calculate buy price - slightly below current for better fills
     */
    calculatePrice(context, side) {
        const currentPriceNum = Number(context.currentPrice) / 1e18;
        if (side === "BUY") {
            // Accumulators place bids below current price
            const offset = 0.001 + Math.random() * 0.002; // 0.1% to 0.3%
            const price = currentPriceNum * (1 - offset);
            return BigInt(Math.floor(price * 1e18));
        }
        else {
            // Rare sells at or above current price
            const offset = Math.random() * 0.002; // 0% to 0.2%
            const price = currentPriceNum * (1 + offset);
            return BigInt(Math.floor(price * 1e18));
        }
    }
    /**
     * Record trade and track accumulation
     */
    recordTradeResult(pnl) {
        super.recordTradeResult(pnl);
        // Track accumulated amount (simplified)
        if (pnl > 0) {
            this.totalAccumulated += BigInt(Math.floor(pnl * 1e18));
        }
    }
    /**
     * Long cooldown - accumulators are patient
     */
    getCooldownTime() {
        return 120000; // 2 minutes
    }
    /**
     * Get accumulation stats
     */
    getAccumulationStats() {
        return {
            totalAccumulated: (Number(this.totalAccumulated) / 1e18).toFixed(8),
            sessions: this.accumulationSessions,
        };
    }
}
exports.AccumulatorBot = AccumulatorBot;
exports.default = AccumulatorBot;
