Този доклад представя нов подход към търговията с криптовалута, използвайки базиран на Transformer Deep Reinforcement Learning (DRL) агент. Системата използва модерни архитектури, вдъхновени от NLP (Transformers), Double DQN (DDQN), Noisy Networks и Low-Rank Adaptation (LoRA) за обучение по време на тест (TTT). Чрез комбинирането на тези компоненти, агентът демонстрира подобрена адаптивност, стабилно формиране на политики и значително повишена доходност на исторически данни за BTC/USDT. Макар и предварителни, тези резултати предполагат, че методът може да бъде разширен до по-сложни масиви от данни (напр. ниво на книга с поръчки) и множество класове активи, осигурявайки мащабируема основа за стратегии за търговия от институционален клас.
Бележка на редактора: Тази статия е само за информационни цели и не представлява инвестиционен съвет. Криптовалутите са спекулативни, сложни и включват високи рискове. Това може да означава висока нестабилност на цените и потенциална загуба на първоначалната ви инвестиция. Трябва да обмислите финансовото си състояние, инвестиционните цели и да се консултирате с финансов съветник, преди да вземете инвестиционни решения. Редакционният екип на HackerNoon само е проверил историята за граматическа точност и не одобрява или гарантира точността, надеждността или пълнотата на информацията, посочена в тази статия. #DYOR
Защо Transformers, защо DRL и защо трябва да ви пука
Трансформърс: Родени в света на НЛП, те превъзхождат в дешифрирането на последователности. Пазарите са просто пъзели от времеви серии. Трансформърс ги четат като истории, предвиждайки обрати в сюжета (движения на цените) много преди средното ви количество да мигне.
Двойна DQN (DDQN): Няма повече едностранна оценка на Q-стойността. DDQN намалява тези прословути надценки, давайки на вашата търговска политика надеждността, от която се нуждае, за да се справи с трудни капани за бикове и мечи нападения.
Noisy Nets насърчават изследването чрез добавяне на параметризиран шум директно към теглата на мрежата.
LoRA позволява обучение по време на тест (TTT) с минимални разходи, което позволява на модела да се адаптира бързо към новите пазарни условия без пълен цикъл на преквалификация.
Обучение по време на тест (TTT): Пазарите се променят, развиват се, изненадват. TTT позволява на този модел да се адаптира бързо, като коригира стратегиите по време на полет, сякаш днес чете заглавията на утрешния ден.
Кодът е включен
В тази рамка се създава система, в която обучаващ се агент взаимодейства със симулирана среда за търговия, ръководена от модерна архитектура, базирана на Transformer. В основата си системата се стреми да подобри решенията за търговия с течение на времето, като усъвършенства стратегията си чрез обучение за укрепване и бързо адаптиране към новите пазарни условия.
Разгледайте първо модела на трансформатора . Традиционно Transformers революционизират области като обработката на естествен език чрез интерпретиране на последователности от думи или токени. Тук същите принципи се прилагат към данните за цените във времеви редове. Вместо думи, моделът поглъща исторически характеристики на пазара - цени, обеми, технически индикатори - и се опитва да извлече значими времеви зависимости. Класът TransformerNetwork
, дефиниран в кода, илюстрира този подход. Забележете как конструкторът проектира необработени входни характеристики в представяне с по-високо измерение и след това ги предава през множество слоеве на енкодер на Transformer:
class TransformerNetwork(nn.Module): def __init__(self, state_dim, output_dim, lookback, nhead=8, num_layers=4, model_dim=512, lora_r=8, lora_alpha=1.0, lora_active=False, sigma_init=hyperparameters['SIGMA_INIT']): super(TransformerNetwork, self).__init__() self.model_dim = model_dim self.lookback = lookback self.lora_active = lora_active self.input_fc = NoisyLoRALinear(state_dim, self.model_dim, r=lora_r, alpha=lora_alpha, lora_active=lora_active, sigma_init=sigma_init) encoder_layer = TransformerEncoderLayerRelative(d_model=model_dim, nhead=nhead, lora_r=lora_r, alpha=lora_alpha, lora_active=lora_active, sigma_init=sigma_init) self.transformer = TransformerEncoderRelative(encoder_layer, num_layers=num_layers) self.output_fc = NoisyLoRALinear(self.model_dim, output_dim, r=lora_r, alpha=lora_alpha, lora_active=lora_active, sigma_init=sigma_init) self._initialize_weights() def forward(self, x): x = self.input_fc(x) x = x.permute(1, 0, 2) x = self.transformer(x) x = x.mean(dim=0) output = self.output_fc(x) return output
Този фрагмент подчертава потока: необработените състояния влизат през input_fc
(линеен слой, подобрен с шум и потенциални адаптации от нисък ранг), пътуват през подредени TransformerEncoderLayerRelative
модули, които улавят времева и относителна позиционна информация, и накрая се обобщават в действия от output_fc
. Този дизайн позволява на модела да претегля събития в различни моменти от време, идентифицирайки повтарящи се модели или аномалии, които могат да предложат печеливши възможности.
Ако моделът Transformer предоставя „очите“ и „ушите“ на агента, класът TradingEnv симулира света, с който взаимодейства. Този клас среда, наречен TradingEnv
, определя какво означава да предприемете действие – като отваряне или затваряне на позиции – и как се присвояват награди. В средата агентът наблюдава промените в цените, техническите индикатори и текущите си притежания. Следният откъс показва как средата изгражда състояния от пазарни данни и позиции на агенти:
def get_state(self): states = [] current_timestamp = self.tech_array.iloc[self.time]['timestamp'] weight_long = float(self.stocks_long * self.current_price / self.total_asset) if self.total_asset > 0 else 0.0 weight_short = float(self.stocks_short * self.current_price / self.total_asset) if self.total_asset > 0 else 0.0 for _ in range(self.lookback): row = self.precomputed_tech.get(current_timestamp) if row is not None: features = row.drop(['timestamp', 'date']).astype(np.float32).values state_row = np.concatenate(([weight_long, weight_short], features)).astype(np.float32) else: state_row = np.zeros(self.state_dim, dtype=np.float32) states.append(state_row) current_timestamp -= self.get_timeframe_in_seconds() states = states[::-1] # ensure chronological order state = torch.tensor(np.array(states, dtype=np.float32), dtype=torch.float32).unsqueeze(0).to(self.device) return state
Тук средата формира богато вграждане на състояние, което включва информация за позицията и исторически прозорец от функции. Като предоставя тази прозоречна перспектива, Transformer може да моделира времеви модели. Всяка стъпка в средата актуализира позициите, изчислява печалбата или загубата и връща ново състояние и награда за агента. Този цикличен обмен насърчава обратна връзка, позволявайки на агента да научи какво работи и какво не.
Машината за вземане на решения се намира в класа DiscreteDDQNAgent , който прилага двоен DQN подход. Двойният DQN помага за справяне с добре познатата пристрастност към надценяване в Q-обучението чрез използване на отделни мрежи за избор на действие и оценка на стойността. Агентът поддържа online_net
и target_net
екземпляри на модела, базиран на Transformer, и използва буфер за повторение, за да вземе проби от минали преживявания. По време на обучението той актуализира своите параметри, като минимизира разликата между прогнозираните Q-стойности и целевите Q-стойности, получени от целевата мрежа:
def update(self): self.online_net.train() if len(self.memory) < self.batch_size: return None states, actions, rewards, next_states, dones = self.memory.sample(self.batch_size) q_values = self.online_net(states).gather(1, actions.unsqueeze(1)).squeeze(1) with torch.no_grad(): next_q_values = self.target_net(next_states).gather(1, self.online_net(next_states).argmax(dim=1).unsqueeze(1)).squeeze(1) target_q_values = rewards + self.gamma * next_q_values * (1 - dones) ddqn_loss = self.loss_fn(q_values, target_q_values.detach()) self.optimizer.zero_grad() ddqn_loss.backward() torch.nn.utils.clip_grad_norm_(self.online_net.parameters(), max_norm=1.0) self.optimizer.step() self.soft_update() return ddqn_loss.item()
Този код разкрива внимателна рутинна тренировка: агентът многократно взема проби от мини-партиди от минали преходи, изчислява загубата на DDQN и актуализира online_net
. Периодично той извършва мека актуализация на target_net
, за да проследява бавно подобренията. Чрез комбиниране на възможностите за разпознаване на модели на Transformer със стабилната динамика на обучение на Double DQN, агентът постепенно става по-умел в избора на печеливши сделки.
Пазарните условия обаче никога не стоят неподвижни. Промените в нестабилността, регулаторните промени или внезапните събития с ликвидност могат да превърнат вчерашните печеливши в днешни губещи. За да се справят с такива смени, се въвежда концепцията за обучение по време на тест (TTT) . Вместо да разчита единствено на актуализации, извършени след събиране на голямо количество опит, TTT позволява на определени части от мрежата да се адаптират динамично, когато пристигнат нови състояния, дори по време на извод. Тази бърза адаптация позволява на агента да калибрира отново своите стратегии в движение, като се приспособява към непредвидени обстоятелства, без да чака пълен цикъл на преквалификация.
В този код TTT се улеснява чрез селективно обучение на параметри по време на извод и фокусиране върху малко подмножество от параметри. Агентът може, например, да модифицира част от своята мрежа, за да усвои бързо нови модели. Методите activate_lora()
и deactivate_lora()
(не са показани сега, тъй като се фокусираме върху Transformer, Env, DDQN и TTT логиката) включват и изключват тези адаптивни параметри. Въпреки че този кодов фрагмент конкретно се позовава на LoRA (адаптация от нисък ранг), важи същата философия: TTT означава позволяване на определени части от модела да се учат по време на тестване. Когато режимът TTT е активен, специализиран оптимизатор актуализира тези параметри на място:
def update_auxiliary(self, state): self.autoencoder.train() self.online_net.train() # Ensure noise and adaptive params are active masked_state, target_state = self.mask_input(state) masked_state_flat = masked_state.view(state.size(0), -1) target_state_flat = target_state.view(state.size(0), -1) reconstructed = self.autoencoder(masked_state_flat) aux_loss = F.mse_loss(reconstructed, target_state_flat) self.autoencoder_optimizer.zero_grad() self.ttt_optimizer.zero_grad() aux_loss.backward() torch.nn.utils.clip_grad_norm_(self.autoencoder.parameters(), max_norm=1.0) torch.nn.utils.clip_grad_norm_(filter(lambda p: p.requires_grad, self.online_net.parameters()), max_norm=1.0) self.autoencoder_optimizer.step() self.ttt_optimizer.step() self.autoencoder.eval() return aux_loss.item()
Тази спомагателна рутинна актуализация, задействана по време на тест, демонстрира адаптивността на системата. Агентът умишлено маскира някои входни характеристики и се опитва да ги реконструира, подобрявайки вътрешното си представяне на текущия пазарен режим. Правейки това, той може бързо да реагира на промени в данните и да поддържа печеливши стратегии в непрекъснато променяща се среда.
Накратко, взаимодействието между тези компоненти създава здрава и гъвкава машина за търговия. Базираният на Transformer модел осигурява богато, чувствително към контекста разбиране на пазарните сигнали. TradingEnv симулира реалистични условия и вериги за обратна връзка. Рамката Double DQN осигурява стабилно усвояване на стойности за действие, като постепенно прецизира търговските решения. И накрая, TTT позволява на агента да остане гъвкав, като коригира вътрешните си параметри, когато се сблъска с нови модели. Заедно тези елементи поставят основата за система, която е едновременно усъвършенствана в разпознаването на модели и издръжлива в лицето на несигурността на пазара, предлагайки завладяваща визия за стратегии за търговия от следващо поколение.
Какъв е резултатът?
Потенциал от следващо ниво
Коментирайте, ангажирайте се, предлагайте сделка 🤯
Нека това не е мимолетно любопитство. Коментирайте, критикувайте, задавайте въпроси. Ако се чудите как да промените стратегията си или как да интегрирате гъвкаво DRL решение в съществуващия стек, оставете коментар.