Монте-карло, Таттелеком и pythonanywhere
В этой заметке я расскажу, как на бесплатном хостинге для питона использовать метод Монте-Карло для предсказания повышения цены акций Таттелеком на 10% за следующие 30 дней.
Хостинг для питона
На самом деле подойдет любой платный, наверно на всех уже есть питон последних версий. У меня есть платных хостингов и вдс, но в данном случае я использую еще и бесплатный, так как а) не все яйца в одной корзине и б) а зачем платить если есть бесплатно? В общем вот - pythonanywhere.com – регистрируйтесь, заводите акк.
Новичкам там будет не очень понятно (я к своему стыду тоже не сразу разобрался). Но в целом можно потратить время, нелишнее. Вкратце – создаете новое web приложение, закидываете файлы, перезагружаете и смотрите что получилось.
У меня вот тут все сейчас up7.pythonanywhere.com/monte-karlo
Метод Монте-Карло
Метод Монте-Карло — это мощный статистический инструмент, который может помочь трейдеру фондовой биржи в анализе рисков, прогнозировании и принятии решений. Вот несколько способов его применения:
- Оценка рисков и управление капиталом. Метод Монте-Карло позволяет моделировать тысячи возможных сценариев движения цены актива на основе исторической волатильности. Это помогает трейдеру:
- Рассчитать вероятность убытков (Value at Risk, VaR).
- Определить оптимальный размер позиции (позиционирование).
- Оценить, как разные стратегии могут вести себя в экстремальных условиях (стресс-тестирование).
- Тестирование торговых стратегий. Вместо проверки стратегии на ограниченной истории (бэктест), можно сгенерировать множество случайных траекторий цены и проверить, как часто стратегия дает прибыль. Это помогает:
- Избежать переоптимизации (кривой подгонки под исторические данные).
- Увидеть, устойчива ли стратегия к разным рыночным условиям.
- Прогнозирование цен (с осторожностью!). Хотя точный прогноз невозможен, метод Монте-Карло позволяет:
- Смоделировать разные сценарии (например, рост, падение, боковое движение).
- Оценить вероятность достижения ценой определенных уровней (например, тейк-профита или стоп-лосса).
- Оптимизация портфеля. Трейдер может использовать Монте-Карло для:
- Анализа корреляции между активами.
- Поиска оптимального распределения капитала (например, в рамках модели Марковица, но с учетом случайных колебаний).
Допустим, трейдер хочет оценить, какова вероятность того, что акция поднимется на 10% в течение месяца. Метод Монте-Карло может:
- Взять историческую волатильность акции.
- Сгенерировать 10 000 случайных путей цены.
- Посчитать, в каком проценте случаев цена падает на 10%.
- Зависит от качества входных данных (например, если волатильность резко изменится, прогнозы будут неточными).
- Не учитывает черные лебеди (редкие, но катастрофические события).
- Требует вычислительных ресурсов.
Файл app.py (точка входа и роутинг нашего flask сервера)
# -*- coding: utf-8 -*-
import os
import numpy as np
import pandas as pd
from flask import Flask, render_template, request
import io
import base64
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import logging
app = Flask(__name__)
def read_custom_data(ticker):
file_path = f"/home/up7/myflaskapp/static/data/{ticker.lower()}.txt"
logging.debug(f"Читаем данные из файла: {file_path}")
if not os.path.exists(file_path):
raise Exception(f"Файл не найден: {file_path}")
try:
df = pd.read_csv(
file_path,
sep=';',
names=['TICKER', 'PER', 'DATE', 'TIME', 'CLOSE', 'VOL'],
skiprows=1,
encoding='utf-8'
)
except Exception as e:
raise Exception(f"Не удалось обработать файл: {e}")
df['DATE'] = pd.to_datetime(df['DATE'], format='%Y%m%d')
df.set_index('DATE', inplace=True)
df.sort_index(inplace=True)
return df['CLOSE']
def simulate_stock_price(ticker, days=21, simulations=100):
try:
data = read_custom_data(ticker)
except Exception as e:
return {'error': str(e)}
if len(data) < 2:
return {'error': "Недостаточно данных для анализа"}
log_returns = np.log(data / data.shift(1)).dropna()
mu = log_returns.mean()
sigma = log_returns.std()
initial_price = data[-1]
if np.isnan(mu) or np.isnan(sigma) or sigma <= 0:
return {'error': 'Некорректные параметры моделирования'}
shocks = np.random.normal(mu - 0.5 * sigma**2, sigma, size=(days, simulations))
price_paths = np.zeros((days + 1, simulations))
price_paths[0] = initial_price
price_paths[1:] = initial_price * np.cumprod(np.exp(shocks), axis=0)
final_prices = price_paths[-1]
gain_threshold = initial_price * 1.1 # +10% от текущей цены
probability_gain = np.mean(final_prices > gain_threshold) * 100
plot_url = generate_plot(price_paths)
return {
'ticker': ticker,
'initial_price': round(initial_price, 5),
'probability_gain': round(probability_gain, 2),
'plot_url': plot_url
}
def generate_plot(price_paths):
plt.figure(figsize=(10, 6))
plt.plot(price_paths[:, :100], linewidth=1, alpha=0.5)
plt.title("Моделирование цены")
plt.xlabel("Дни")
plt.ylabel("Цена")
plt.grid(True)
img = io.BytesIO()
plt.savefig(img, format='png')
img.seek(0)
plt.close()
return base64.b64encode(img.getvalue()).decode('utf8')
@app.route('/')
def index():
# Главная страница — список ссылок
links = [
{"title": "Монте-Карло", "url": "/monte-karlo"},
{"title": "Страница 2", "url": "#"},
{"title": "Страница 3", "url": "#"}
]
return render_template('main.html', links=links)
@app.route('/monte-karlo', methods=['GET', 'POST'])
def monte_karlo():
result = None
if request.method == 'POST':
ticker = request.form['ticker'].strip().lower()
result = simulate_stock_price(ticker)
return render_template('index.html', result=result)
if __name__ == '__main__':
app.run(debug=True)
Шаблон
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Метод Монте-Карло для акций</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Прогноз цены акций</h1>
<form method="POST">
<input type="text" name="ticker" placeholder="Введите тикер" required>
<input type="submit" value="Анализировать">
</form>
{% if result %}
<div style="margin-top: 20px;">
{% if result.error %}
<p style="color:red;">{{ result.error }}</p>
{% else %}
<p><strong>Тикер:</strong> {{ result.ticker }}</p>
<p><strong>Начальная цена:</strong> {{ result.initial_price }}</p>
<p><strong>Вероятность повышения на 10%:</strong> {{ result.probability_gain }}%</p>
{% if result.plot_url %}
<img src="data:image/png;base64,{{ result.plot_url }}" alt="График">
{% endif %}
{% endif %}
</div>
{% endif %}
</body>
</html>
Что получилось
Узнаем вероятность того, что Таттелеком увеличится на 10% за следующие 30 дней. Вводим тикер ttlk и получаем график с вероятностями. up7.pythonanywhere.com/monte-karlo. Результаты каждый раз будут получаться разные, учтите.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Читайте также:
Программы на заказ
Отзывы
Контакты