Избранное трейдера Юрий
Чуть больше недели назад выступил на AllDerivatives. Рассказывал о моем личном опыте работы с эволюционирующим ИИ и о попытках применения в торговле. Материала засунул, как сейчас понимаю, избыточно много, в результате выступление получилось слегка скомканным, затянутым и поверхностным, но на удивление, люди, присутствовавшие на выступлении говорят, что получилось интересно.
Во-первых, не ждите глубоких секретов, не ждите граалей. Более того, было больше всего про биологию, меньше про программную реализацию и совсем чуть-чуть про трейдинг.
Во-вторых, это не те дроиды, которых вы ищите это совсем не то, что мы используем, во всяком случае на чужих деньгах в реальной торговле.
Но рассказывал я о том, что реально делал в разное время на протяжении многих лет, что меня давно очень интересует и в чем, смею надеяться, чуть-чуть понимаю ;)
Презу на экране видно плохо, но она есть по ссылке в описании.
--[[ параметры: Procent - процент зигзага --]] Settings={ Name="ZIGZAG_Templ", Procent=2, line= { { Name = "cur1", Type =TYPE_LINE, Width = 2, Color = RGB(0,0, 0) } } } function Init() y1 = nil y2 = nil x1 = 1 x2 = 1 return 1 end function OnCalculate(index) de = Settings.Procent vl = C(index) if index == 1 then y1 = vl y2 = vl else if C(index) > y1*(1+de/100) and y1 < y2 then x2 = x1 y2 = y1 x1 = index y1 = C(index) else if C(index) > y1 and y1 >= y2 then x1 = index y1 = C(index) end end if C(index) < y1*(1-de/100) and y1 > y2 then x2 = x1 y2 = y1 x1 = index y1 = C(index) else if C(index) < y1 and y1 <= y2 then x1 = index y1 = C(index) end end end if x1 ~= index then curfrom = x1 curto = index else curfrom = x2 curto = x1 end if curto ~= curfrom and curfrom ~= nil and curto ~= nil then if C(curto) ~= nil and C(curfrom) ~= nil then k = (C(curto)- C(curfrom))/(curto- curfrom) for i = curfrom, index do curv = i*k + C(curto) - curto*k SetValue(i, 1, curv) end end end return vl end
ВДО становятся если не более значимыми, то более институциональными инструментами российского долгового рынка. С 26 марта Московская биржа начинает расчет и публикацию индекса ВДО – Индекс Мосбиржи ВДО ПИР (https://t.me/moexnews/4013).
На рынке ВДО с 2018 года уже существует индекс Cbonds-CBI RU High Yield. Теперь, когда у индекса появилась альтернатива важно понимать, чем эти индексы отличаются и какие бумаги лежат в основе каждого из них.
Критерии индекса Cbonds:
• Валюта выпуска Рубли РФ
• Фиксированный купон, который равен или выше, чем ставка ЦБ + 5%
• Минимальный срок обращения 182 дня
• Хотя бы треть торговых дней в квартал по бумаге совершались сделки
• Максимальный объём в обращении 2 млрд (до ноября 2019 года 1 млрд)
Критерии индекса МосБиржи ВДО ПИР:
• Эмитент исполнил в полном объеме обязательства по выплате купонного дохода, выкупу по оферте, погашению всех выпусков облигаций, допущенных к торгам
• Национальными рейтинговыми агентствами эмитенту присвоен кредитный рейтинг на уровне не менее ruB- или аналог
• Валютой выпуска являются рубли РФ
• Объем по номинальной стоимости выпуска составляет не менее 200 млн рублей
• Срок до даты погашения составляет не менее 3 месяцев
# В КВИКе запускаем луа-скрипт QuikLuaPython.lua import socket import threading from datetime import datetime, timezone import pandas as pd import finplot as fplt fplt.display_timezone = timezone.utc class DeltaBar(): def __init__(self): self.df = pd.DataFrame(columns='date_time open high low close delta delta_time_sec'.split(' ')) self.df.loc[len(self.df)] = [0, 0, 0, 0, 0, 0, 0] def parser(self, parse): if parse[0] == '1' and parse[1] == 'RIH1': if abs(self.df.iloc[len(self.df) - 1]['delta']) >= 500: self.df.loc[len(self.df)] = [0, 0, 0, 0, 0, 0, 0] # Добавляем строку в DF self.df.iloc[len(self.df) - 1]['close'] = float(parse[4]) # Записываем последнюю цену как цену close бара if self.df.iloc[len(self.df) - 1]['date_time'] == 0: self.df.iloc[len(self.df) - 1]['date_time'] = \ datetime.strptime(f'{parse[7]} {parse[8][0:-1]}', "%d.%m.%Y %H:%M:%S.%f").replace(microsecond=0) if self.df.iloc[len(self.df) - 1]['open'] == 0: self.df.iloc[len(self.df) - 1]['open'] = float(parse[4]) if float(parse[4]) > self.df.iloc[len(self.df) - 1]['high']: self.df.iloc[len(self.df) - 1]['high'] = float(parse[4]) if (float(parse[4]) < self.df.iloc[len(self.df) - 1]['low']) or \ (self.df.iloc[len(self.df) - 1]['low'] == 0): self.df.iloc[len(self.df) - 1]['low'] = float(parse[4]) if parse[5] == '1026': self.df.iloc[len(self.df) - 1]['delta'] += float(parse[6]) if parse[5] == '1025': self.df.iloc[len(self.df) - 1]['delta'] -= float(parse[6]) self.df.iloc[len(self.df) - 1]['delta_time_sec'] = \ datetime.strptime(f'{parse[7]} {parse[8][0:-1]}', "%d.%m.%Y %H:%M:%S.%f") - \ self.df.iloc[len(self.df) - 1]['date_time'] self.df.iloc[len(self.df) - 1]['delta_time_sec'] = self.df.iloc[len(self.df) - 1]['delta_time_sec'].seconds def service(): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('127.0.0.1', 3587)) # Хост-этот компьютер, порт - 3587 while True: res = sock.recv(2048).decode('utf-8') if res == '<qstp>\n': # строка приходит от клиента при остановке луа-скрипта в КВИКе break else: delta_bar.parser(res.split(' ')) # Здесь вызываете свой парсер. Для примера функция: parser (parse) sock.close() def update(): df = delta_bar.df # Меняем индекс и делаем его типом datetime df = df.set_index(pd.to_datetime(df['date_time'], format='%Y-%m-%d %H:%M:%S')) # print(delta_bar.df) # pick columns for our three data sources: candlesticks and TD candlesticks = df['open close high low'.split()] volumes = df['open close delta_time_sec'.split()] if not plots: # first time we create the plots global ax plots.append(fplt.candlestick_ochl(candlesticks)) plots.append(fplt.volume_ocv(volumes, ax=ax.overlay())) else: # every time after we just update the data sources on each plot plots[0].update_data(candlesticks) plots[1].update_data(volumes) if __name__ == '__main__': delta_bar = DeltaBar() # Запускаем сервер в своем потоке t = threading.Thread(name='service', target=service) t.start() plots = [] ax = fplt.create_plot('RIH1', init_zoom_periods=100, maximize=False) update() fplt.timer_callback(update, 2.0) # update (using synchronous rest call) every N seconds fplt.show()
Доходность в долларах США:
29.03% — портфель.
16.83% — индекс SP500.
Макс просадка с начала года:
-24% — портфель.
-30% — индекс SP500.