import ta from 'technicalindicators';
import { EventEmitter } from 'events';
import { Num, OHLCV } from 'ccxt';
import { MACDOutput } from 'technicalindicators/declarations/moving_averages/MACD';
import { StochasticRSIOutput } from 'technicalindicators/declarations/momentum/StochasticRSI';
import { BollingerBandsOutput } from 'technicalindicators/declarations/volatility/BollingerBands';
import { IchimokuCloudOutput } from 'technicalindicators/declarations/ichimoku/IchimokuCloud';
import { ADXOutput } from 'technicalindicators/declarations/directionalmovement/ADX';

declare class ChartingSystem {
    transform(rawData: any): ta.CandleList;
}

interface BacktestResults {
    alpha: number;
    beta: number;
    sharpeE: number;
    maxDrawdown: number;
    maxProfit: number;
    profitFactor: number;
    return: number;
    percentageProfitable: number;
    tradeCount: number;
    reportData: {
        trades: Trade[];
        data: DataSource[];
    };
}
interface CandleStickObject {
    open?: Num;
    high?: Num;
    low?: Num;
    close?: Num;
    volume?: Num;
    timestamp?: Num;
}
interface CreateTradeOptions {
    positionType: PositionType;
    orderType: OrderType;
    size: number;
    limitPrice?: number;
    leverage?: number;
    open?: boolean;
    riskOptions?: {
        TP?: number;
        SL?: number;
    };
}
declare enum CryptoPair {
    BTCUSDT = "BTC/USDT",
    ETHUSDT = "ETH/USDT",
    SOLUSDT = "SOL/USDT",
    BNBUSDT = "BNB/USDT",
    LTCUSDT = "LTC/USDT",
    DOGEUSDT = "DOGE/USDT"
}
interface IndicatorOptions {
    name: string;
    description: string;
    key: string;
    indicators?: Indicator[];
}
interface SimulationOptions {
    capital?: number;
    leverage?: number;
    fees?: number;
    pair: CryptoPair;
}
interface StrategyOptions {
    name: string;
    pair: CryptoPair;
    dataLength: number;
    timeFrame: TimeFrame;
    indicators?: Indicator[];
    chartType?: ChartingSystem;
    simulationOptions?: SimulationOptions;
}
interface TimelineManagerSystem extends EventEmitter {
    key: string;
    generate: () => any;
    provide: (data: OHLCV[]) => void;
    feed: (data: OHLCV) => void;
}
interface TimelineProfile {
    key: string;
    data: any[];
}
type TimelineEventsInterface = {
    provided: (data: any[]) => any[];
    fed: (data: any) => any;
    generated: () => any[];
};
declare enum TimelineEvents {
    PROVIDED = "provided",
    FED = "fed",
    GENERATED = "generated"
}
declare enum NumberReturnType {
    RELATIVE = "relative",
    FIXED = "fixed"
}
declare enum OrderType {
    MARKET = "market",
    LIMIT = "limit",
    STOP = "stop"
}
declare enum PositionType {
    LONG = "long",
    SHORT = "short"
}
declare enum TRADE_KEY {
    ID = "id",
    isOpen = "isOpen",
    isClosed = "isClosed",
    PL = "PL",
    TP = "TP",
    SL = "SL",
    positionSize = "size",
    leverage = "leverage",
    drawdown = "drawdown",
    openPrice = "openPrice",
    closePrice = "closePrice",
    fee = "fee",
    pair = "pair",
    blockChainTrack = "blockChainTrack",
    orderType = "orderType",
    positionType = "positionType",
    timestamp = "timestamp"
}
interface TradeData {
    [TRADE_KEY.ID]: string;
    [TRADE_KEY.isOpen]: boolean;
    [TRADE_KEY.isClosed]: boolean;
    [TRADE_KEY.PL]?: number;
    [TRADE_KEY.TP]?: number;
    [TRADE_KEY.SL]?: number;
    [TRADE_KEY.positionSize]: number;
    [TRADE_KEY.leverage]: number;
    [TRADE_KEY.drawdown]: number;
    [TRADE_KEY.openPrice]: undefined;
    [TRADE_KEY.closePrice]: undefined;
    [TRADE_KEY.fee]?: number;
    [TRADE_KEY.blockChainTrack]: number;
    [TRADE_KEY.pair]: CryptoPair;
    [TRADE_KEY.orderType]: OrderType;
    [TRADE_KEY.positionType]: PositionType;
    [TRADE_KEY.timestamp]: number;
}
interface TradeOptions {
    open?: boolean;
    positionSize: number;
    leverage?: number;
    TP?: number;
    SL?: number;
    pair: CryptoPair;
    orderType: OrderType;
    positionType: PositionType;
    isLive?: boolean;
}
interface DataSource {
    name: string;
    type: DataSourceType;
    data: any[];
}
declare enum DataSourceType {
    PRICE = "price",
    FACTOR = "factor"
}
declare enum TimeFrame {
    SECOND = "1s",
    MINUTE = "1m",
    TWO_MINUTES = "2m",
    THREE_MINUTES = "3m",
    FIVE_MINUTES = "5m",
    TEN_MINUTES = "10m",
    FIFTEEN_MINUTES = "15m",
    THIRTY_MINUTES = "30m",
    FORTY_FIVE_MINUTES = "45m",
    HOUR = "1h",
    TWO_HOURS = "2h",
    THREE_HOURS = "3h",
    FOUR_HOURS = "4h",
    DAY = "1d",
    WEEK = "1w",
    MONTH = "1M"
}

declare class Indicator extends EventEmitter {
    protected data: OHLCV[];
    name: string;
    key: string;
    description: string;
    constructor({ name, key, description }: IndicatorOptions);
    provide(data: OHLCV[]): void;
    feed(data: OHLCV): void;
    generate(): any;
    clear(): void;
    on<K extends keyof TimelineEventsInterface>(event: K, listener: TimelineEventsInterface[K]): this;
}

declare class Logger {
    success(payload: string): void;
    debug(payload: any): void;
    info(payload: string): void;
    warn(payload: string): void;
    error(payload: string): void;
}
declare const logger: Logger;

declare class Trade {
    readonly id: string;
    private readonly tradeData;
    constructor(options: TradeOptions);
    open(): void;
    close(): void;
    updateTP(TP?: number): void;
    updateSL(SL?: number): void;
    getData(): TradeData;
    onUpdate(update: OHLCV, updates: OHLCV[]): void;
    getFootprint(): void;
}

declare class TradeManager {
    private trades;
    private strategy;
    constructor(strategy: Strategy);
    onUpdate(update: OHLCV, updates: OHLCV[]): void;
    getTrade(id: string): Trade | null;
    getTrades(): Trade[];
    createTrade(options: CreateTradeOptions): Trade;
    getTradeHistory(): Trade[];
    closeTrade(tradeId: string): void;
    clear(): void;
}

declare class Strategy {
    name: string;
    private data;
    readonly strategyOptions: Required<StrategyOptions>;
    tradeManager: TradeManager;
    indicators: Map<string, any>;
    pairDataPath: string;
    constructor(strategyOptions: StrategyOptions);
    loadData(): Promise<void>;
    private provideAllIndicators;
    private feedAllIndicators;
    backtest({}: SimulationOptions): Promise<BacktestResults>;
    private internalStart;
    private internalUpdate;
    protected live(): void;
    protected onStart(updates: OHLCV[]): void;
    protected onUpdate(update: OHLCV, updates: OHLCV[]): void;
}

declare class ReportManager {
    private readonly app;
    private readonly PORT;
    private readonly viewsPath;
    constructor();
    private initializeApp;
    generateReport(strategy: Strategy, reportData: BacktestResults['reportData']): void;
}

declare class EMA extends Indicator {
    period: number;
    constructor(key: string, options: EMAOptions);
    generate(): number[];
}
interface EMAOptions {
    period?: number;
}

declare class SMA extends Indicator {
    period: number;
    constructor(key: string, options: SMAOptions);
    generate(): number[];
}
interface SMAOptions {
    period?: number;
}

declare class ATR extends Indicator {
    period: number;
    constructor(key: string, options: ATROptions);
    generate(): number[];
}
interface ATROptions {
    period?: number;
}

declare class RSI extends Indicator {
    period: number;
    constructor(key: string, options: RSIOptions);
    generate(): number[];
}
interface RSIOptions {
    period?: number;
}

declare class MACD extends Indicator {
    fastPeriod: number;
    slowPeriod: number;
    signalSmoothing: number;
    MAType: 'EMA' | 'SMA';
    MAOscillatorType: 'EMA' | 'SMA';
    constructor(key: string, options: MACDOptions);
    generate(): MACDOutput[];
}
interface MACDOptions {
    fastPeriod?: number;
    slowPeriod?: number;
    signalSmoothing?: number;
    MAType?: 'EMA' | 'SMA';
    MAOscillatorType?: 'EMA' | 'SMA';
}

declare class StockRSI extends Indicator {
    dPeriod: number;
    kPeriod: number;
    rsiPeriod: number;
    stochasticPeriod: number;
    constructor(key: string, options: StockRSIOptions);
    generate(): StochasticRSIOutput[];
}
interface StockRSIOptions {
    dPeriod: number;
    kPeriod: number;
    rsiPeriod: number;
    stochasticPeriod: number;
}

declare class BB extends Indicator {
    period: number;
    stdDev: number;
    constructor(key: string, options: BBOptions);
    generate(): BollingerBandsOutput[];
}
interface BBOptions {
    period?: number;
    stdDev?: number;
}

declare class IchimokuCloud extends Indicator {
    basePeriod: number;
    conversionPeriod: number;
    spanPeriod: number;
    displacement: number;
    constructor(key: string, options: IchimokuCloudOptions);
    generate(): IchimokuCloudOutput[];
}
interface IchimokuCloudOptions {
    basePeriod: number;
    conversionPeriod: number;
    spanPeriod: number;
    displacement: number;
}

declare class WEMA extends Indicator {
    period: number;
    constructor(key: string, options: WEMAOptions);
    generate(): number[];
}
interface WEMAOptions {
    period?: number;
}

declare class ADX extends Indicator {
    period: number;
    constructor(key: string, options: ADXOptions);
    generate(): ADXOutput[];
}
interface ADXOptions {
    period?: number;
}

declare class VolumeProfile extends Indicator {
    numberOfBars: number;
    constructor(key: string, options: VolumeProfileOptions);
    generate(): number[];
}
interface VolumeProfileOptions {
    numberOfBars?: number;
}

declare class VWAP extends Indicator {
    constructor(key: string);
    generate(): number[];
}

declare class ForceIndex extends Indicator {
    period: number;
    constructor(key: string, options: ForceIndexOptions);
    generate(): number[];
}
interface ForceIndexOptions {
    period: number;
}

type index_ADX = ADX;
declare const index_ADX: typeof ADX;
type index_ADXOptions = ADXOptions;
type index_ATR = ATR;
declare const index_ATR: typeof ATR;
type index_ATROptions = ATROptions;
type index_BB = BB;
declare const index_BB: typeof BB;
type index_BBOptions = BBOptions;
type index_EMA = EMA;
declare const index_EMA: typeof EMA;
type index_EMAOptions = EMAOptions;
type index_ForceIndex = ForceIndex;
declare const index_ForceIndex: typeof ForceIndex;
type index_ForceIndexOptions = ForceIndexOptions;
type index_IchimokuCloud = IchimokuCloud;
declare const index_IchimokuCloud: typeof IchimokuCloud;
type index_IchimokuCloudOptions = IchimokuCloudOptions;
type index_MACD = MACD;
declare const index_MACD: typeof MACD;
type index_MACDOptions = MACDOptions;
type index_RSI = RSI;
declare const index_RSI: typeof RSI;
type index_RSIOptions = RSIOptions;
type index_SMA = SMA;
declare const index_SMA: typeof SMA;
type index_SMAOptions = SMAOptions;
type index_StockRSI = StockRSI;
declare const index_StockRSI: typeof StockRSI;
type index_StockRSIOptions = StockRSIOptions;
type index_VWAP = VWAP;
declare const index_VWAP: typeof VWAP;
type index_VolumeProfile = VolumeProfile;
declare const index_VolumeProfile: typeof VolumeProfile;
type index_VolumeProfileOptions = VolumeProfileOptions;
type index_WEMA = WEMA;
declare const index_WEMA: typeof WEMA;
type index_WEMAOptions = WEMAOptions;
declare namespace index {
  export { index_ADX as ADX, type index_ADXOptions as ADXOptions, index_ATR as ATR, type index_ATROptions as ATROptions, index_BB as BB, type index_BBOptions as BBOptions, index_EMA as EMA, type index_EMAOptions as EMAOptions, index_ForceIndex as ForceIndex, type index_ForceIndexOptions as ForceIndexOptions, index_IchimokuCloud as IchimokuCloud, type index_IchimokuCloudOptions as IchimokuCloudOptions, index_MACD as MACD, type index_MACDOptions as MACDOptions, index_RSI as RSI, type index_RSIOptions as RSIOptions, index_SMA as SMA, type index_SMAOptions as SMAOptions, index_StockRSI as StockRSI, type index_StockRSIOptions as StockRSIOptions, index_VWAP as VWAP, index_VolumeProfile as VolumeProfile, type index_VolumeProfileOptions as VolumeProfileOptions, index_WEMA as WEMA, type index_WEMAOptions as WEMAOptions };
}

export { type BacktestResults, type CandleStickObject, ChartingSystem, type CreateTradeOptions, CryptoPair, type DataSource, DataSourceType, Indicator, type IndicatorOptions, index as Indicators, Logger, NumberReturnType, OrderType, PositionType, ReportManager, type SimulationOptions, Strategy, type StrategyOptions, TRADE_KEY, TimeFrame, TimelineEvents, type TimelineEventsInterface, type TimelineManagerSystem, type TimelineProfile, Trade, type TradeData, TradeManager, type TradeOptions, logger };
