σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academyロードマップ
Ctrl K
AO
+1.2k 人の学習者
ログイン参加する ↗
ロードマップ
AO
+1.2k 人の学習者
ログイン
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python ロードマップ›モジュール 11 · 本番システムと最先端モデル›トピック 11.12·~2 時間エキスパート

トレーディングのための強化学習

ロードマップ上の位置モジュール 11/11 · トピック 12/13
11.12 トレーディングのための強化学習
—ラボスコア— / 100合計XP—連続日数—

試して学ぶ

教師あり学習では、どの例にも正解が付いています。トレーディングはそうではありません。最適なポジションを教えてくれる人はいません。行動すると、市場が利益か損失で応えます。強化学習はこれを、状態を観測し、行動を取り、報酬を受け取り、新しい状態に移るエージェントとしてモデル化し、時間を通じた報酬の合計を最大化することを目指します。トレーディングでは、状態は直近のリターンや現在のポジション、行動は買い・保有・売り、報酬はそのステップの利益からコストを引いたものです。難しいのは、行動の結果が後で現れ、エージェントが試行によって何が報われるかを見つけなければならない点です。

# Reward of one step: profit from the position held, minus the cost of changing position
def step_reward(position, price_change, previous_position, cost):
    return position * price_change - cost * abs(position - previous_position)

print(round(step_reward(1, 0.5, 0, 0.1), 4))         # 0.4    went long, the price rose 0.5, paid 0.1 to trade
print(round(step_reward(-1, 0.5, 1, 0.1), 4))        # -0.7   flipped from long to short just before a rise: lost 0.5 and paid 0.2
print(step_reward(1, 0.5, 1, 0.1))                   # 0.5    holding the same position costs nothing

Q学習:ある状態での行動の価値

Q学習は表 Q[状態, 行動] を持ちます。その状態でその行動を取り、その後うまく行動した場合に期待される報酬の合計です。各ステップの後、その要素をより良い推定値であるターゲットに近づけます。ターゲットは、いま得た報酬に、次の状態での最良の行動の割引価値を足したもの reward + gamma * max(Q[次の状態]) です。更新は学習率 alpha を使って Q[s, a] += alpha * (ターゲット - Q[s, a]) です。割引率 gamma(0から1)は将来の報酬の重みを表します。gamma = 0 は近視眼的なエージェント、1に近いと辛抱強いエージェントで、系列のリターンは r0 + gamma r1 + gamma^2 r2 + ... です。終端のステップでは次の状態がなく、ターゲットは報酬だけです。

# One Q-learning update on a table of 2 states x 3 actions (short, flat, long)
import numpy as np

def q_update(q, state, action, reward, next_state, alpha, gamma):
    updated = q.copy()
    target = reward if next_state is None else reward + gamma * updated[next_state].max()
    updated[state, action] += alpha * (target - updated[state, action])
    return updated

q = np.zeros((2, 3))
q = q_update(q, 0, 2, 1.0, 1, 0.5, 0.9)               # in state 0 we went long and earned 1.0
print(q[0])                                           # [0.  0.  0.5]   moved halfway (alpha 0.5) toward the target of 1.0
q = q_update(q, 0, 2, 1.0, 1, 0.5, 0.9)
print(q[0])                                           # [0.   0.   0.75]   a second visit moves it further

探索と、動く学習ループの例

常に自分が知っている最良の行動だけを取るエージェントは、別の行動のほうが良いかどうかを知ることができません。イプシロン貪欲法がこれを解決します。確率 epsilon でランダムな行動を探索し、それ以外は Q が最大の行動を活用します(同点なら最初のもの)。epsilon は通常、高く始めて徐々に下げます。ループは、状態を観測し、行動を選び、報酬と次の状態を受け取り、Q を更新し、繰り返す、というものです。上昇日の翌日も上昇しやすいおもちゃの市場では、「昨日は上昇」という状態を見たエージェントが、ロングを保つと報われると学びます。2つの状態と3つの行動の表で十分に示せます。

# A toy market where an up day tends to be followed by another up day; the agent learns to follow the trend
import random
import numpy as np

rng = random.Random(1)
positions = [-1, 0, 1]                                # action 0 = short, 1 = flat, 2 = long
q = np.zeros((2, 3))                                  # state 0 = yesterday down, state 1 = yesterday up
alpha, gamma, cost = 0.1, 0.9, 0.0005
state, previous = 1, 0
for step in range(20000):
    epsilon = max(0.05, 1 - step / 10000)
    u, explore = rng.random(), rng.randrange(3)
    action = explore if u < epsilon else int(np.argmax(q[state]))
    up = rng.random() < (0.65 if state == 1 else 0.35)           # the trend continues 65% of the time
    change = 0.01 if up else -0.01
    reward = positions[action] * change - cost * abs(positions[action] - previous)
    next_state = 1 if up else 0
    target = reward + gamma * q[next_state].max()
    q[state, action] += alpha * (target - q[state, action])
    state, previous = next_state, positions[action]

print(int(np.argmax(q[0])), int(np.argmax(q[1])))     # 0 2   after a down day go short, after an up day go long
# The discounted return: with gamma below 1 a reward now is worth more than the same reward later
def discounted_return(rewards, gamma):
    total = 0.0
    for reward in reversed(rewards):
        total = reward + gamma * total
    return total

rewards = [1.0, 1.0, 1.0]
print(discounted_return(rewards, 0.5))               # 1.75   1 + 0.5 + 0.25
print(discounted_return(rewards, 1.0))               # 3.0    a patient agent: a plain sum
print(discounted_return(rewards, 0.0))               # 1.0    a short-sighted agent: only the first reward counts
学習した方策のバックテストは簡単に欺かれる過去のある期間で学習したエージェントは、そこで報われたパターンを、本物か偶然かを問わず見つけ出します。しかも市場データは少なく非定常で、ある年の教訓が翌年に通用するとは限りません。学習とテストは別の期間で行い(ウォークフォワード)、現実的なコストとスリッページを報酬に織り込み、リスクと大きなポジションに罰則を与え、バイ・アンド・ホールドのような単純なルールと比べ、出来すぎた結果は疑いましょう。ここでの強化学習は、本番戦略というより研究の道具です。
  • エージェントは状態を観測し、行動し、報酬(利益−コスト)を受け取り、どの行動が報われるかを学ぶ。リターンは割引和 r0 + gamma r1 + gamma^2 r2 + ...
  • Q学習は Q[s, a] += alpha * (reward + gamma * max Q[s'] - Q[s, a])(終端ステップでは reward のみ)で更新する。ここでは古い表をその場で書き換えない
  • イプシロン貪欲法は確率 epsilon で探索し、それ以外は最大の Q を活用する。学習とテストは別の期間で行い、現実的なコストを課し、単純なベースラインと比べる

次は最終プロジェクトです。すべてをまとめた、エンドツーエンドの価格評価または戦略ライブラリを作ります。

ラボ:採点される内容

  • choose_action で探索か活用かを選ぶ25点
  • q_update で1ステップから学習する25点
  • step_reward で取引にコストを課す25点
  • discounted_return で将来を足し合わせる25点
エクスプローラー · lab-141-1
▾ lab-141-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-141-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

このトピックをリセットしますか?

lab-141-1 の内容はすべてスターターファイルに戻り、ターミナルも消去されます。現在の解答は失われ、元に戻せません。

リセットされるもの
  • main.py → スターターコード
  • ターミナル履歴とテスト出力
  • 未提出の変更
保持されるもの
  • ラボの最高スコア
  • XPと連続日数
  • 講義の進捗とメモ

コードを実行するにはログインしてください。

レクチャーはすべて無料で読めます。コードの実行、テスト、ラボの提出にはアカウントの作成かログインが必要です。

  • ブラウザ内IDEとbashターミナル。インストール不要
  • 即時採点、XP、ロードマップでの現在地
アカウントを作成ログイン
または
GitHubで続ける