Блог им. 3Qu
Раз в несколько лет мне надоедает писать стратегии. Дело это, в общем, несложное, но, уж, очень долгое. А хочется, чтобы загрузил историю, прогнал, через нейросеть (НС) и пользуйся. Уже несколько раз пробовал — ничего путного из этого не получается, и, видимо, и не получится. Но, все же, раз в несколько лет бывают обострения, и, после длительного перерыва решил попробовать еще раз, на новом (для меня) софте — PyTorch, с новыми фишками и возможностями, которых не было у предыдущих софтов проектирования НС. Надежд, немного, но, как и в прошлые попытки, много времени на это тратить не собираюсь.
Естественно, побеседовал на эту тему с ИИ. Наконец, после нескольких продолжительных и безуспешных попыток, в результате совместного творчества пришли к структуре НС под задачу автоматического формирования стратегии. Требования были незамысловаты: если для реализации стратегии требуется где-то не более 10-20 if, и эти if прекрасно справляются со своими задачами, то и НС должна быть несложной. На входы же НС мы подаем сами цены, текущие параметры индикаторов — в общем, все то, что обсчитывает наша рабочая стратегия. Естественно, ожидаем, что НС сама построит стратегию из исходных данных, и результаты будут эквиваленты(а, желательно, и лучше) стратегии, написанной руками.
Ну, а чтобы ИИ не зацикливался на рынке и стандартных методах, которые пробуют все кому не лень, мы с ним занимались прогнозированием дождя на Марсе, о которых мы вообще ничего не знаем.) Вроде, их, дождей, на Марсе вообще не бывает.) Но мы их сделаем из рыночных данных. Было бы желание.)
В итоге, получилась вот такая конструкция НС:
class MarsRainNet(nn.Module):
def __init__(self, input_size, hidden_size=64):
super(MarsRainNet, self).__init__()
# input_size — это общее кол-во фичей (датчики + производные)
self.gru = nn.GRU(input_size, hidden_size, num_layers=2,
batch_first=True, dropout=0.2)
self.classifier = nn.Sequential(
nn.Linear(hidden_size, 32),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(32, 1),
nn.Sigmoid() # На выходе вероятность 0...1
)
def forward(self, x):
# x shape: [batch, 24, features]
# Нам нужен выход GRU только с последнего временного шага
_, h_n = self.gru(x)
# h_n имеет форму [num_layers, batch, hidden_size]
# Берем последний слой:
last_hidden = h_n[-1]
return self.classifier(last_hidden)Собственно, остальное — обучение, работа и пр. — стандартные процедуры, не заслуживающие внимания.
На первый вгляд такая простая нейросеть, но она имеет чудовищную ёмкость и ей проще запомнить, чем создать внутри себя аналитические структуры… но неинструментированная нейросеть не может в принципе провести статистический аналилиз, сделать выводы, схитрить, провести бэктесты, измерить деградации стратегий и т.п.
Правда, я тоже только в 1995-м это нашёл, когда предложили нейросетями цены на фьючерсы прогнозировать.
А в книге, про которую написали, хоть одну формулу в доказательстве этого утверждения видели?
Поэтому и стал копаться в научной литературе и нашёл то, что написал выше.
Я и в этом то обсуждении только и сказал, что на вход не надо подавать цены. А вот при подаче на вход нейросети каких-то индикаторов от них может что-то хорошее и получится. Это я не оспариваю.
А. Г., вот, что ответил ИИ по поводу стационарности для НС
Ключевая фраза здесь:Если есть желание, подискутируйте с ИИ. У него весь инет в качестве мозгов.)
Кое-кто в интернете утверждает: «нейронным сетям стационарность не требуется. Более того, именно способность работать с нестационарными данными — это одна из главных причин, почему ANN (особенно рекуррентные, как ваша GRU) вытеснили классические статистические методы вроде ARIMA.»
Где он может быть не прав? Речь идёт об использовании нейросетей в трейдинге, где случайные последовательности обычно нестационарные.
Михаил Михалев, есть такое. Я в курсе. Но на первый вопрос он отвечает, что написано в источниках.
Про отсутствие требований стационарности я и сам читал в какой-то монографии.
А если так?
Берем значение индикатора(ов) и скалируем его от -10 до 10.
Строим гипотезу, что в следующие 15 мин.(час, день) будет падение если значение ниже 0 и рост если значение выше 0 (это основная стратегия, покупаем если выше 0, продаем если ниже 0).
Прогоняем на истории основную стратегию и получаем сгруппированные данные статистик для значений от -10 до +10 по количеству положительных, отрицательных и суммарному pnl, при условии что следовали основной стратегии.
Смотрим на pnl, если положительный то follow, если отрицательный то invert, относительно основной стратегии. Это уже правила, для основной стратегии.
Прогоняем на истории основную стратегию с правилами. Строим график equity, если равномерный восходящий тренд, то гут. Можно попробовать прогнать на оставшейся части истории, которая не участвовала в определении правил.
Там еще можно много чего прикрутить, типа проводить группировку в зависимости от времени торговой сессии и т.д.
В итоге получаем, что подтвердилась или опроверглась гипотеза, не имеет значения )))
как идет обучение и работа.
Перед обучением шкалируем всю историю, индикаторы и пр. Сохраняем параметры шкалера.
На тестах и реале шкалирум все подаваемые на НС данные шкалером с сохраненными на обучении параметрами.
Иначе, вообще ничего работать не будет.
Пусть на истории данные были в диапазоне 0-100. Для согласования, делим все на 100 — получаем диапазон 0-1.
Запоминаем эти 100, и теперь все данные, подаваемые на НС делим на 100, какими бы они не были.
Значит, таки, можно поймать удачу за хвост?
ЗЫ: все крупные игроки занимаются разработкой и обучением НС. У них огромные объемы данных, причём прилично размеченных. Такие нейронки они используют в качестве тестов :-))))