Избранное трейдера Роман Давыдов
По мотивам поста https://smart-lab.ru/blog/616708.php
Вот и мой велосипед на питоне для получения котировок с Мосбиржи
from urllib import request, error from json import loads import pprint class GetRawDataException(Exception): pass class GetPricesException(Exception): pass def get_prices(start_date: str, end_date: str, ticker: str) -> dict: """ Возвращает словарь: {дата:цена закрытия} """ req = 'https://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/{}.json?from={}&till={}'.format(ticker, start_date, end_date) contents = get_raw_data(req) try: data = loads(contents) prices = {x[1] : x[11] for x in data['history']['data']} return(prices) except Exception as err: raise GetPricesException(err) def get_raw_data(req: str) -> str: """ Возвращает результат запроса к серверу Мосбиржи """ try: contents = request.urlopen(req).read() return(contents) except URLError as err: raise GetRawDataException(err) try: prices = get_prices('2019-05-23', '2019-05-30', 'GAZP') pprint.pprint(prices) except GetRawDataException as err: print('Error getting raw data: ', str(err)) except GetPricesException as err: print('Error parsing json: ', str(err))
Вывод данных происходит с помощью функции get_prices(). Механизм простой: формируется url для GET-запроса. Мосбиржа в ответ присылает json, из которого забираются нужные данные и выводятся на экран.
Есть и другие способы получения данных: yfinance, pandas-datareader и универсальный BeautifulSoup, ещё более универсальный Selenium. Но это уже совсем другая история...
Начинающие (да и не только) инвесторы часто задаются вопросом о том, как отобрать для себя идеальное соотношение активов входящих в портфель. Часто (или не очень, но знаю про двух точно) у некоторых брокеров эту функцию выполняет торговый робот. Но заложенные в них алгоритмы не раскрываются.
В этом посте будет рассмотрено то, как оптимизировать портфель при помощи Python и симуляции Монте Карло. Под оптимизацией портфеля понимается такое соотношение весов, которое будет удовлетворять одному из условий:
Для расчета возьмем девять акций, которые рекомендовал торговый робот одного из брокеров на начало января 2020 года и так же он устанавливал по ним оптимальные веса в портфеле: 'ATVI','BA','CNP','CMA', 'STZ','GPN','MPC','NEM' и 'PKI'. Для анализа будет взяты данные по акциям за последние три года.
#Загружаем библиотеки import pandas as pd import yfinance as yf import numpy as np import matplotlib.pyplot as plt # Получаем данные по акциям ticker = ['ATVI','BA','CNP','CMA', 'STZ','GPN','MPC','NEM', 'PKI'] stock = yf.download(ticker,'2017-01-01', '2019-01-31')
import requests import datetime import pathlib SECIDs = ["GAZP", "BANEP", "LKOH"] DISK = "E" for SECID in SECIDs: from_date = "2020-05-04" to_date = "2005-01-03" while str(to_date) != from_date: to_date = str(to_date) to_date = to_date.split('-') a = datetime.date(int(to_date[0]), int(to_date[1]), int(to_date[2])) b = datetime.timedelta(days=140) to_date = a + b pathlib.Path("{}:/{}/{}".format(DISK, "Database_MOEX", SECID)).mkdir(parents=True, exist_ok=True) filename = SECID + "_" + str(to_date) + ".csv" with requests.get("http://iss.moex.com/iss/history/engines/stock/markets/shares/boards/tqbr/securities/{}.csv?date={}".format(SECID, to_date)) as response: with open("{}:/Database_MOEX/{}/{}".format(DISK, SECID, filename), 'wb') as f: for chunk in response.iter_content(): f.write(chunk)Для начала пройдемся по его плюсам и минусам. Самый главный минус, что этот парсер качает только определенный период, который уникален для каждой акции, судя по всему для увеличения этого периода надо кинуть бирже на лапу:), и то что информация предоставляется за день, теперь перейдем к плюсам: можно выкачивать историю за определенный период для нескольких инструментов сразу (их количество ограничивается лишь количеством инструментов на мосбиржи), есть возможность назначать диск для сохранения информации, быстрота выгрузки данных.
Сегодня сделал извращение на волатильностях Si и RTS. Это были недельные опционы с экспирацией 23/04/2020. На центральном 107500 страйке RTS волатильность была 60 , а на центральном 75000 страйке Si волатильность опустилась до 20.
Волатильность Si я купил, а RTS продал. Сделал я это через стредлы.
Пропорции выбирал следующим образом. Фьючерс RTS в рублях стоит 158709 руб., а фьючерс Si =75000 руб. На один RTS приходится 2,116 Si .
Поскольку Si я покупал, а RTS продавал, то пропорцию взял с запасом 1:3
Дальше подразумевалось дельтахеджирование по следующим правилам:
Когда у RTS дельта становится 1, выравнивать ее в ноль, и в этот же момент выравнивать в ноль позицию Si. Ведущей должна быть проданная позиция.
Позицию я сделал в 12:30, а к 16:20 волатильности немного сошлись. Закрыл позицию с прибылью 5400 руб.
Ждать не стал, поскольку у меня нет математического описания для таких позиций. Делаю я так редко и по интуиции. Но если в рублях выразить центры стредлов, то Si примерно на 18-19 тыс. руб. дешевле, чем RTS. Так что, 5 тысяч мне для получения удовольствия вполне хвалило. Жадничать не надо.