import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import MetaTrader5 as mt5

# Параметры
SYMBOL = "EURUSD"
TERMINAL_PATH = r"C:/Program Files/RoboForex MT5 Terminal/terminal64.exe"
START_DATE = datetime(2014, 1, 1)
END_DATE = datetime(2025, 1, 1)
WINDOW_BARS = 10

def get_data():
    """Получает данные из MT5"""
    if not mt5.initialize(path=TERMINAL_PATH):
        print("MT5 initialization error")
        return None
    
    rates = mt5.copy_rates_range(SYMBOL, mt5.TIMEFRAME_H1, START_DATE, END_DATE)
    mt5.shutdown()
    
    if rates is None or len(rates) == 0:
        print("No data")
        return None
    
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    return df

def calculate_returns(df, window):
    """Вычисляет доходности на скользящем окне"""
    returns = []
    
    for i in range(len(df) - window):
        price_start = df['close'].iloc[i + window]
        price_end = df['close'].iloc[i]
        
        if price_start > 0:
            ret = (price_end - price_start) / price_start
            returns.append(ret)
    
    return np.array(returns)

def plot_histogram(returns):
    """Строит гистограмму распределения"""
    fig = plt.figure(figsize=(7, 5), dpi=100)
    ax = fig.add_subplot(111)
    
    ax.hist(returns * 100, bins=100, edgecolor='black', alpha=0.7, color='steelblue')
    ax.set_xlabel('Return (%)', fontsize=12, fontweight='bold')
    ax.set_ylabel('Frequency', fontsize=12, fontweight='bold')
    ax.set_title(f'{SYMBOL} Return Distribution (Window: {WINDOW_BARS} bars)', 
                 fontsize=13, fontweight='bold')
    ax.axvline(x=0, color='red', linestyle='--', linewidth=2, label='Zero return')
    ax.grid(True, alpha=0.3)
    ax.legend(fontsize=10)
    
    # Статистика на графике
    textstr = f'Mean: {np.mean(returns)*100:.4f}%\nStd: {np.std(returns)*100:.4f}%\nN: {len(returns)}'
    props = dict(boxstyle='round', facecolor='wheat', alpha=0.8)
    ax.text(0.02, 0.98, textstr, transform=ax.transAxes, fontsize=10,
            verticalalignment='top', bbox=props)
    
    plt.tight_layout()
    plt.savefig('histogram_700px.png', dpi=100, bbox_inches='tight')
    print("Saved: histogram_700px.png")
    plt.close()

def plot_cumulative(returns):
    """Строит кумулятивное распределение"""
    fig = plt.figure(figsize=(7, 5), dpi=100)
    ax = fig.add_subplot(111)
    
    sorted_returns = np.sort(returns) * 100
    cumulative = np.arange(1, len(sorted_returns) + 1) / len(sorted_returns)
    
    ax.plot(sorted_returns, cumulative, linewidth=2.5, color='darkblue', label='Cumulative probability')
    ax.set_xlabel('Return (%)', fontsize=12, fontweight='bold')
    ax.set_ylabel('Cumulative Probability', fontsize=12, fontweight='bold')
    ax.set_title(f'{SYMBOL} Cumulative Distribution (Window: {WINDOW_BARS} bars)', 
                 fontsize=13, fontweight='bold')
    ax.axvline(x=0, color='red', linestyle='--', linewidth=2, label='Zero return')
    ax.grid(True, alpha=0.3)
    ax.legend(fontsize=10)
    
    # Перцентили на графике
    percentiles = [10, 50, 90]
    for p in percentiles:
        val = np.percentile(returns * 100, p)
        prob = p / 100
        ax.plot(val, prob, 'ro', markersize=8)
        ax.text(val, prob + 0.05, f'P{p}\n{val:.3f}%', 
                ha='center', fontsize=9, bbox=dict(boxstyle='round', facecolor='yellow', alpha=0.7))
    
    plt.tight_layout()
    plt.savefig('cumulative_700px.png', dpi=100, bbox_inches='tight')
    print("Saved: cumulative_700px.png")
    plt.close()

def print_statistics(returns):
    """Выводит статистику распределения"""
    print("\n" + "="*60)
    print("RETURN DISTRIBUTION STATISTICS")
    print("="*60)
    print(f"Symbol: {SYMBOL}")
    print(f"Period: {START_DATE.date()} - {END_DATE.date()}")
    print(f"Window: {WINDOW_BARS} bars")
    print(f"Observations: {len(returns)}")
    print("-"*60)
    print(f"Mean: {np.mean(returns)*100:.4f}%")
    print(f"Median: {np.median(returns)*100:.4f}%")
    print(f"Std Dev: {np.std(returns)*100:.4f}%")
    print(f"Min: {np.min(returns)*100:.4f}%")
    print(f"Max: {np.max(returns)*100:.4f}%")
    print(f"Skewness: {pd.Series(returns).skew():.4f}")
    print(f"Kurtosis: {pd.Series(returns).kurtosis():.4f}")
    print("-"*60)
    print("PERCENTILES:")
    for p in [10, 20, 30, 40, 50, 60, 70, 80, 90]:
        val = np.percentile(returns * 100, p)
        print(f"  P{p}: {val:.4f}%")
    print("="*60 + "\n")

if __name__ == "__main__":
    print("Loading data from MT5...")
    df = get_data()
    
    if df is None:
        print("Failed to retrieve data")
        exit(1)
    
    print(f"Loaded {len(df)} bars")
    
    print(f"Calculating returns with window {WINDOW_BARS} bars...")
    returns = calculate_returns(df, WINDOW_BARS)
    
    print_statistics(returns)
    
    print("Building charts...")
    plot_histogram(returns)
    plot_cumulative(returns)
    
    print("\nDone!")
