ეს ანგარიში წარმოგიდგენთ ახალ მიდგომას კრიპტოვალუტით ვაჭრობისადმი ტრანსფორმერზე დაფუძნებული Deep Reinforcement Learning (DRL) აგენტის გამოყენებით. სისტემა იყენებს თანამედროვე NLP ინსპირირებულ არქიტექტურებს (ტრანსფორმერები), ორმაგ DQN (DDQN), ხმაურიანი ქსელები და დაბალი რანგის ადაპტაცია (LoRA) ტესტის დროში ტრენინგისთვის (TTT). ამ კომპონენტების კომბინაციით, აგენტი აჩვენებს გაუმჯობესებულ ადაპტირებას, სტაბილურ პოლიტიკის ფორმირებას და მნიშვნელოვნად გაზრდილ მომგებიანობას ისტორიულ BTC/USDT მონაცემებზე. მიუხედავად იმისა, რომ წინასწარია, ეს შედეგები ვარაუდობს, რომ მეთოდი შეიძლება გაფართოვდეს უფრო რთულ მონაცემთა ნაკრებებზე (მაგ., შეკვეთების წიგნის დონეზე) და აქტივების მრავალ კლასზე, რაც უზრუნველყოფს ინსტიტუციური დონის სავაჭრო სტრატეგიების მასშტაბურ საფუძველს.
რედაქტორის შენიშვნა: ეს სტატია მხოლოდ საინფორმაციო მიზნებისთვისაა და არ წარმოადგენს საინვესტიციო რჩევას. კრიპტოვალუტები არის სპეკულაციური, რთული და შეიცავს მაღალ რისკებს. ეს შეიძლება ნიშნავს მაღალი ფასების ცვალებადობას და თქვენი საწყისი ინვესტიციის პოტენციურ დაკარგვას. თქვენ უნდა გაითვალისწინოთ თქვენი ფინანსური მდგომარეობა, საინვესტიციო მიზნები და გაიაროთ კონსულტაცია ფინანსურ მრჩეველთან რაიმე საინვესტიციო გადაწყვეტილების მიღებამდე. HackerNoon-ის სარედაქციო გუნდმა გადაამოწმა ამბავი მხოლოდ გრამატიკული სიზუსტისთვის და არ ადასტურებს ან გარანტიას არ აძლევს ამ სტატიაში მითითებული ინფორმაციის სიზუსტეს, სანდოობას ან სისრულეს. #DYOR
რატომ ტრანსფორმატორები, რატომ DRL და რატომ უნდა იზრუნოთ
ტრანსფორმერები: დაბადებულები NLP სამყაროში, ისინი გამოირჩევიან მიმდევრობის გაშიფვრაში. ბაზრები უბრალოდ დროის სერიების თავსატეხებია. ტრანსფორმატორები კითხულობენ მათ, როგორც ისტორიები, ელიან სიუჟეტური ცვლილებების მოლოდინში (ფასის მოძრაობებს) სანამ თქვენი საშუალო რაოდენობა მოციმციმეს.
ორმაგი DQN (DDQN): აღარ არის Q-მნიშვნელობის ცალმხრივი შეფასება. DDQN ამცირებს ამ ყბადაღებულ ზედმეტ შეფასებას, რაც თქვენს სავაჭრო პოლიტიკას აძლევს სანდოობას, რომელიც მას სჭირდება ხარის რთული ხაფანგებისა და დათვების დარბევისთვის.
Noisy Nets ხელს უწყობს დათვალიერებას პარამეტრირებული ხმაურის პირდაპირ ქსელის წონებზე დამატებით.
LoRA საშუალებას აძლევს ტესტის დროში ვარჯიშს (TTT) მინიმალური ზედნადებით, რაც საშუალებას აძლევს მოდელს სწრაფად მოერგოს ახალ საბაზრო პირობებს სრული გადამზადების ციკლის გარეშე.
ტესტ-დროის ტრენინგი (TTT): ბაზრები იცვლება, ვითარდება, გაოცება. TTT საშუალებას აძლევს ამ მოდელს სწრაფად მოერგოს, არეგულირებს სტრატეგიებს ფრენის დროს, თითქოს დღეს კითხულობს ხვალინდელ სათაურებს.
კოდი ჩართულია
ამ ჩარჩოში იქმნება სისტემა, სადაც სასწავლო აგენტი ურთიერთქმედებს სიმულირებულ სავაჭრო გარემოსთან, ხელმძღვანელობს თანამედროვე ტრანსფორმერზე დაფუძნებული არქიტექტურით. თავის არსში, სისტემა ცდილობს გააუმჯობესოს სავაჭრო გადაწყვეტილებები დროთა განმავლობაში, დახვეწოს თავისი სტრატეგია გაძლიერებული სწავლის გზით და სწრაფად მოერგოს ახალ საბაზრო პირობებს.
ჯერ განვიხილოთ ტრანსფორმატორის მოდელი . ტრადიციულად, ტრანსფორმერებმა მოახდინეს რევოლუცია ისეთი სფეროებში, როგორიცაა ბუნებრივი ენის დამუშავება სიტყვების ან ნიშნების თანმიმდევრობის ინტერპრეტაციით. აქ იგივე პრინციპები გამოიყენება დროის სერიების ფასების მონაცემებზე. სიტყვების ნაცვლად, მოდელი იღებს ბაზრის ისტორიულ მახასიათებლებს - ფასებს, მოცულობას, ტექნიკურ ინდიკატორებს - და ცდილობს მნიშვნელოვანი დროებითი დამოკიდებულებების ამოღებას. კოდში განსაზღვრული TransformerNetwork
კლასი ასახავს ამ მიდგომას. დააკვირდით, როგორ აპროექტებს კონსტრუქტორი ნედლი შეყვანის მახასიათებლებს უფრო მაღალი განზომილებიანი წარმოდგენით და შემდეგ გადასცემს მათ ტრანსფორმატორის ენკოდერის მრავალ ფენაში:
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
. ეს დიზაინი საშუალებას აძლევს მოდელს აწონ-დაწონოს მოვლენები დროის სხვადასხვა მომენტში, გამოავლინოს განმეორებადი შაბლონები ან ანომალიები, რომლებიც შეიძლება მიუთითებდეს მომგებიან შესაძლებლობებზე.
თუ ტრანსფორმატორის მოდელი უზრუნველყოფს აგენტის „თვალებს“ და „ყურებს“, 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
აქ გარემო ქმნის მდიდარ მდგომარეობას, რომელიც მოიცავს პოზიციის ინფორმაციას და მახასიათებლების ისტორიულ ფანჯარას. ამ ფანჯრის პერსპექტივის უზრუნველყოფით, ტრანსფორმერს შეუძლია დროებითი შაბლონების მოდელირება. გარემოში ყოველი ნაბიჯი განაახლებს პოზიციებს, ითვლის მოგებას ან ზარალს და უბრუნებს ახალ მდგომარეობას და ჯილდოს აგენტისთვის. ეს ციკლური გაცვლა ხელს უწყობს უკუკავშირის ციკლს, რაც საშუალებას აძლევს აგენტს გაიგოს რა მუშაობს და რა არა.
გადაწყვეტილების მიმღები ძრავა მდებარეობს DiscreteDDQNAgent კლასში, რომელიც ახორციელებს Double DQN მიდგომას. ორმაგი DQN გვეხმარება Q- სწავლაში ცნობილი გადაჭარბებული შეფასების მიკერძოების მოგვარებაში მოქმედების შერჩევისა და ღირებულების შეფასებისთვის ცალკეული ქსელების გამოყენებით. აგენტი ინახავს ტრანსფორმერზე დაფუძნებული მოდელის online_net
და target_net
მაგალითებს და იყენებს განმეორებითი ბუფერს წარსული გამოცდილების შესამოწმებლად. ტრენინგის დროს, ის აახლებს თავის პარამეტრებს, მინიმალურად ამცირებს განსხვავებას პროგნოზირებულ 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()
ეს დამხმარე განახლების რუტინა, რომელიც ამოქმედდა ტესტის დროს, აჩვენებს სისტემის ადაპტირებას. აგენტი განზრახ ნიღბავს შეყვანის ზოგიერთ მახასიათებელს და ცდილობს მათ რეკონსტრუქციას, გააუმჯობესოს მისი შიდა წარმომადგენლობა მიმდინარე ბაზრის რეჟიმის შესახებ. ამით მას შეუძლია სწრაფად რეაგირება მონაცემთა ცვლაზე და შეინარჩუნოს მომგებიანი სტრატეგიები მუდმივად ცვალებად ლანდშაფტში.
საერთო ჯამში, ამ კომპონენტებს შორის ურთიერთქმედება ქმნის ძლიერ და მოქნილ სავაჭრო მანქანას. ტრანსფორმერზე დაფუძნებული მოდელი უზრუნველყოფს ბაზრის სიგნალების მდიდარ, კონტექსტზე მგრძნობიარე გაგებას. TradingEnv სიმულაციას უკეთებს რეალისტურ პირობებს და უკუკავშირის მარყუჟებს. ორმაგი DQN ჩარჩო უზრუნველყოფს სამოქმედო ღირებულებების სტაბილურ სწავლას, სავაჭრო გადაწყვეტილებების თანდათანობით დახვეწას. დაბოლოს, TTT საშუალებას აძლევს აგენტს დარჩეს მოქნილი, დაარეგულიროს მისი შიდა პარამეტრები ახალი შაბლონების წინაშე. ეს ელემენტები ერთად ქმნიან საფუძველს სისტემისთვის, რომელიც დახვეწილია შაბლონების ამოცნობაში და გამძლეა ბაზრის გაურკვევლობის პირობებში, სთავაზობს დამაჯერებელ ხედვას შემდეგი თაობის სავაჭრო სტრატეგიებისთვის.
რა არის შედეგი?
შემდეგი დონის პოტენციალი
დაწერეთ კომენტარი, ჩაერთეთ, შესთავაზეთ გარიგება 🤯
არ დაუშვათ, რომ ეს იყოს წარმავალი ცნობისმოყვარეობა. კომენტარები, კრიტიკა, დასვით კითხვები. თუ გაინტერესებთ, როგორ შეცვალოთ თქვენი სტრატეგია, ან როგორ ჩართოთ მოქნილი DRL გადაწყვეტა თქვენს არსებულ სტეკში, დატოვეთ კომენტარი.