Торговий агент на A2C/A3C
A3C (Asynchronous Advantage Actor-Critic) та A2C (його синхронний варіант) — алгоритми паралельного навчання RL від DeepMind (2016). Множина паралельних агентів досліджують різні частини простору станів одночасно. Для трейдингу: паралельне навчання на різних активах/періодах, швидка збіжність.
A3C vs A2C: ключова відмінність
A3C: асинхронний. N робочих потоків паралельно збирають опис та оновлюють глобальну мережу. Немає синхронізації між потоками. CPU-based (не потрібні GPU-exclusive операції).
A2C: синхронний. N паралельних середовищ → чекання всіх → один батч-апдейт. Більш детерміністичний, простіше налагоджувати, краще використовує GPU.
Для більшості торговельних завдань A2C бажаніший — GPU ефективність та воспроизводимость.
Advantage Function
Ключева ідея: оновлювати політику не на сирому reward, а на Advantage A(s,a) = Q(s,a) - V(s). Advantage показує, наскільки дія краща або гірше середнього очікування в даному стані.
GAE (Generalized Advantage Estimation):
def compute_gae(rewards, values, next_value, dones, gamma=0.99, lam=0.95):
advantages = []
gae = 0
for step in reversed(range(len(rewards))):
delta = rewards[step] + gamma * next_value * (1 - dones[step]) - values[step]
gae = delta + gamma * lam * (1 - dones[step]) * gae
advantages.insert(0, gae)
next_value = values[step]
return advantages
λ=0.95 — баланс між bias (λ=0, чисто TD) та variance (λ=1, чисто MC).
Архітектура для торговлі
class A2CTradingNet(nn.Module):
def __init__(self, state_dim, action_dim):
super().__init__()
self.shared = nn.Sequential(
nn.Linear(state_dim, 128), nn.ReLU(),
nn.Linear(128, 128), nn.ReLU()
)
self.actor = nn.Linear(128, action_dim) # logits
self.critic = nn.Linear(128, 1) # V(s)
def forward(self, x):
f = self.shared(x)
logits = self.actor(f)
value = self.critic(f)
return logits, value
def a2c_loss(logits, actions, advantages, values, returns, ent_coef=0.01):
dist = Categorical(logits=logits)
log_probs = dist.log_prob(actions)
actor_loss = -(log_probs * advantages.detach()).mean()
critic_loss = F.mse_loss(values.squeeze(), returns)
entropy_loss = -dist.entropy().mean()
return actor_loss + 0.5 * critic_loss + ent_coef * entropy_loss
Паралелізм для торговлі
A2C/A3C особливо корисні при:
Множина активів: 8 паралельних середовищ, кожне з різним активом (AAPL, MSFT, TSLA, ...). Агент учиться на різноманітних ринкових умовах одночасно. Загальна політика узагальнюється краще.
Множина часових періодів: Паралельні середовища з різними періодами історії. Навчання на bull/bear/sideways ринках одночасно.
Walk-forward паралелізм: Кожен worker обробляє своє часове вікно. Прискорена cross-validation.
from stable_baselines3 import A2C
from stable_baselines3.common.vec_env import SubprocVecEnv
def make_env(ticker, start, end):
return lambda: TradingEnv(ticker, start, end)
# 8 паралельних середовищ
envs = SubprocVecEnv([make_env(t, '2015', '2022') for t in tickers[:8]])
model = A2C(
"MlpPolicy",
envs,
learning_rate=7e-4,
n_steps=5, # короткі rollouts — швидкі апдейти
gamma=0.99,
gae_lambda=1.0,
ent_coef=0.01,
vf_coef=0.25,
max_grad_norm=0.5,
verbose=1
)
model.learn(total_timesteps=1_000_000)
n_steps=5: A2C класично використовує дуже короткі rollouts (5–20 кроків). Це прискорює апдейти але збільшує variance.
Порівняння алгоритмів для торговлі
| Алгоритм | Sample Eff. | Стабільність | Паралелізм | GPU |
|---|---|---|---|---|
| DQN | Висока | Середня | Немає | Так |
| A2C | Середня | Висока | Відличний | Так |
| PPO | Середня | Висока | Хороший | Так |
| SAC | Висока | Висока | Середній | Так |
A2C займає нішу: простіше SAC, паралельніше PPO. Для швидких експериментів з багатьма конфігураціями.
Терміни: 4–8 тижнів
A2C baseline з паралельними середовищами — 3 тижні. LSTM actor, multi-asset з кореляціями, custom reward shaping — 6–8 тижнів.







