3Qu
3Qu личный блог
25 апреля 2026, 14:40

Нейросеть в качестве стратегии. Очередная попытка.

Раз в несколько лет мне надоедает писать стратегии. Дело это, в общем, несложное, но, уж, очень долгое. А хочется, чтобы загрузил историю, прогнал, через нейросеть (НС) и пользуйся. Уже несколько раз пробовал — ничего путного из этого не получается, и, видимо, и не получится. Но, все же, раз в несколько лет бывают обострения, и, после длительного перерыва решил попробовать еще раз, на новом (для меня) софте — 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)
Собственно, остальное — обучение, работа и пр. — стандартные процедуры, не заслуживающие внимания.
Как видите, вот, собственно, и вся стратегия. Все получилось очень простенько, как и требовалось.
Теперь качаем историю, готовим данные для обучения и посмотрим, что в итоге получится из нашего безнадежного дела. Наверное, через пару недель получим результаты. Думаю, скорее, отрицательные, но чем черт не шутит.
50 Комментариев
  • Михаил Михалев
    25 апреля 2026, 14:57
    Но, все же, раз в несколько лет бывают обострения
    Может просто один раз объяснить себе, почему не должно ничего получиться?:)
    На первый вгляд такая простая нейросеть, но она имеет чудовищную ёмкость и ей проще запомнить, чем создать внутри себя аналитические структуры… но неинструментированная нейросеть не может в принципе провести статистический аналилиз, сделать выводы, схитрить, провести бэктесты, измерить деградации стратегий и т.п.
  • Vkt
    25 апреля 2026, 14:58
    И что в итоге делает этот код, в чем идея не очень понятно.
  • Михаил
    25 апреля 2026, 15:24
    А чем какие тут новые фишки и возможности? Кажется это все давно устаревшие решения, которыми никто не пользуется
  • А. Г.
    25 апреля 2026, 15:44
    Цены лучше не подавать, а индикаторы перед подачей проверить на стационарность. Иначе на обучении получите «круто», а на реальной торговле ерунду. 

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн