import pandas as pd
import numpy as np
import MetaTrader5 as mt5
from datetime import datetime
import pytz
from scipy.stats import poisson
from scipy.special import logsumexp
import matplotlib.pyplot as plt

# Инициализация MT5 
if not mt5.initialize():
    print("initialize() failed")
    quit()

timezone = pytz.timezone("Etc/UTC")
target_date = (2026, 4, 23) 

utc_from = datetime(*target_date, 12, 0, 0, tzinfo=timezone)
utc_to = datetime(*target_date, 12, 10, 0, tzinfo=timezone)

# Загружаем тики
ticks = mt5.copy_ticks_range("EURUSD", utc_from, utc_to, mt5.COPY_TICKS_ALL)
mt5.shutdown()

# Создаем DataFrame и считаем тики в минуту
df = pd.DataFrame(ticks)
df['time'] = pd.to_datetime(df['time'], unit='s')
df.set_index('time', inplace=True)
# Группируем по минутам
minute_counts = df.resample('1min').count()['ask'].values

print(f"Данные (количество тиков в минуту): {minute_counts}")

sum_x = np.sum(minute_counts)
n = len(minute_counts)

# 1. Сетка гипотез
theta_grid = np.arange(1, 301)

# 2. Априор 
prior = poisson.pmf(theta_grid, mu=150)
prior /= prior.sum()

# 3. Правдоподобие
log_likelihood = sum_x * np.log(theta_grid) - n * theta_grid

# 4. Считаем логарифм числителя (Правдоподобие + Априор)
log_numerator = log_likelihood + np.log(prior + 1e-12) # вектор из 300 элементов

# 5. Находим логарифм полной вероятности P(D) через LogSumExp
log_evidence = logsumexp(log_numerator)

# 6. Получаем нормированный логарифм апостериора
log_posterior = log_numerator - log_evidence

# 7. Финальный результат в обычных вероятностях
posterior = np.exp(log_posterior)

print(f"Сумма вероятностей: {np.sum(posterior)}")
print(f"Логарифм свидетельства (Evidence): {log_evidence:.4f}")

# Нормировка правдоподобия для визуализации
log_evidence_likelihood = logsumexp(log_likelihood)
likelihood_norm = np.exp(log_likelihood - log_evidence_likelihood)

# --- Визуализация ---
plt.figure(figsize=(10, 5))

# Априор 
plt.plot(theta_grid, prior, label='Prior',color='blue', linestyle='--', alpha=0.6)

# Правдоподобие 
plt.plot(theta_grid, likelihood_norm, label='Likelihood (Normalized Data)', 
         color='green', linewidth=1, alpha=0.8)

# Апостериор 
plt.plot(theta_grid, posterior, label='Posterior', color='red', linewidth=2)

plt.fill_between(theta_grid, posterior, color='red', alpha=0.1)

# Оценка MLE
plt.axvline(sum_x/n, color='green', linestyle=':', alpha=0.8,label=f'Data Mean: {sum_x/n:.2f}')

plt.title(f"Discrete Bayesian Inference (EURUSD)\nMinutes: {n}, Total Ticks: {sum_x}", fontsize=12)
plt.xlabel("Ticks per Minute (θ)")
plt.ylabel("Probability")
plt.legend()
plt.grid(True, alpha=0.2)
plt.show()

print(f"Среднее по данным (MLE): {sum_x/n:.2f}")
print(f"Наиболее вероятное значение (MAP): {theta_grid[np.argmax(posterior)]}")