12 Jul 2017, 13:57

USDJPYのヒストリカルデータをダウンロードしてDQN Agentを動かしてみた

前回の続き。

USDJPYでバックテスト

今回は、DukascopyからUSDJPYのヒストリカルデータをダウンロードして、DQN Agentを動かしてみました。

すごく苦労して、なんとかDQN Agentに学習させることに成功した。

ロジックは、前回とほぼ同じです。今回の Jupyter Notebookは以下。

苦労した点

  • はじめ、keras-rlで testメソッドを走らせたあとに、rewardが0になってしまった。いくら論理を見直しても、0になってしまう。
  • 波の形で学習できるときとできないときがあることが分かった。たとえば、サイン波は学習できるがコサイン波は学習できない。
  • 標準化を適用して、なるべくサイン波に近い形にヒストリカルデータを編集した。

11 Jul 2017, 22:55

Dukascopyのヒストリカルデータの日付をpandasでパースする方法

FXのヒストリカルデータを取得するために、私はいつもDukascopyを利用している。

おかしな日付

ダウンロードしたデータをプロットしてみたら、おかしなことになった。

self.csv_data = pd.read_csv(self.csv_path, index_col=0, parse_dates=True, header=0)

dukascopyの日時のフォーマットは、03.07.2017 00:00:00.000 のようになっている。

なので、2017年7月3日をpandasは間違えて 2017年3月7日としてパースしてしまったようだ。

正しい日付にパース

こういう場合は、自前のパーサを作成して、_pandas.readcsv に date_parser optionの引数としてパーサを渡すことで解決する。

f = '%d.%m.%Y %H:%M:%S.%f'
my_parser = lambda date: pd.datetime.strptime(date, f)
self.csv_data = pd.read_csv(self.csv_path, index_col=0, parse_dates=True, header=0,
                           date_parser=my_parser)

11 Jul 2017, 14:02

正弦曲線にしたがう為替の値動きについてDQNでバックテストをしてみた

DQNを勉強しているので、以下の記事に触発されて自分もFXでDQNをしてみたくなった。

2年前、OANDAでのシステムトレードで5万円を損した屈辱を今こそ晴らすのだ!

まずは、GMOの記事でも実施しているように、正弦曲線に従う為替の値動きについて、

DQNを適用してバックテストを行ってみた。

今回のJupyter Notebookは Gistにあげました。

正弦曲線

以下のような正弦曲線について、DQNでバックテストを試みる。

MDP

  • 状態
    • (-1.0, 1.0) の範囲の値
    • 売買のステータス(SELL, NONE, BUY)
  • 行動
    • SELL
    • HOLD
    • BUY
  • 報酬
    • 売買の即時報酬

コード

`import enum
class Action(enum.Enum):
    SELL = 2
    HOLD = 0
    BUY  = 1

class Position():
    def __init__(self):
        self.NONE = 0
        self.BUY = 1
        self.SELL = 2

        self.bid = 0.0
        self.pos_state = self.NONE

    def state(self):
        return np.array([self.bid, self.pos_state])

    def change(self, action, bid):
        self.bid = bid
        self.pos_state = action

    def close(self, action, bid):
        if self.pos_state == action:
            return 0

        self.pos_state = self.NONE
        if action == Action.BUY.value:
            reward = (bid - self.bid) * 1000
        else:
            reward = (self.bid - bid) * 1000
        return reward`

keras-rl を利用するために、環境を OpenAI gym ライクで作成する。

`import gym
import gym.spaces

class FXTrade(gym.core.Env):
    def __init__(self):
        self.action_space = gym.spaces.Discrete(3)
            high = np.array([1.0, 1.0])
            self.observation_space = gym.spaces.Box(low=-high, high=high)

            self._position = Position()

            self._sin_list = []
            for t in np.linspace(0, 48, 240):
                self._sin_list.append(np.sin(t))
            self.cur_id = 0

    def _step(self, action):
        bid = self._sin_list[self.cur_id]
        self.cur_id +=1
        done = True if self.cur_id == 240 else False

        if action == Action.HOLD.value:
            reward = 0
        else:
            if self._position.pos_state == self._position.NONE:
                self._position.change(action, bid)
                reward = 0
            else:
                reward = self._position.close(action, bid)
        return np.array([bid, self._position.pos_state]), reward, done ,{}

    def _reset(self):
        self.cur_id = 0
        self._position = Position()
        return np.array([0.0, 0.0])`

keras-rlの登場

強化学習を笑っちゃうほど簡単に実施するために Keras-rlをつかう。

このライブラリは抽象度が高すぎてもはやなにをやっているのかわからない。

exampleを参考にして、それっぽいコードを書いてみる。

`from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.optimizers import Adam

from rl.agents.dqn import DQNAgent
from rl.policy import BoltzmannQPolicy
from rl.memory import SequentialMemory

nb_actions = env.action_space.n

model = Sequential()
model.add(Flatten(input_shape=(1,) + env.observation_space.shape))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(nb_actions))
model.add(Activation('linear'))
model.summary()

# DQNに必要な Experience Replayのためのメモリ
memory = SequentialMemory(limit=50000, window_length=1)
# ボルツマン分布に従うポリシー
policy = BoltzmannQPolicy()
# DQN Agentの生成
dqn = DQNAgent(model=model, nb_actions=nb_actions, memory=memory,
               target_model_update=1e-2, policy=policy)
# optimizersはAdam, 損失関数は 平均二乗誤差
dqn.compile(Adam(lr=1e-3), metrics=['mae'])

# トレーニングを開始。同じ正弦曲線を9600 = 240 x 400回 回す。
dqn.fit(env, nb_steps=9600, visualize=False, verbose=1)

# トレーニング結果を確認
dqn.test(env, nb_episodes=5, visualize=False)

`

おお、rewardがプラスだ。。

`Testing for 5 episodes ...
Episode 1: reward: 603.962, steps: 240
Episode 2: reward: 603.962, steps: 240
Episode 3: reward: 603.962, steps: 240
Episode 4: reward: 603.962, steps: 240
Episode 5: reward: 603.962, steps: 240`

おわりに

  • 理論を抑えていないので何をやっているのかがいまいちわからないのだけれども、おそらく上がり調子のときは報酬もたくさんもらえるので、買い注文を多くしているのだと思う。
  • keras-rlは非常に強力なライブラリだけれども、抽象度が高すぎてなにやってるのかよくわからない。理解を深めるために numpyで実装してみるのもありかもしれない。
  • 状態は、その時の値のみを扱ったが、過去5bin分の状態を考慮にいれたらどうなるだろうか?いわゆるwindowの概念を強化学習にいれてみると、結果がよくなるだろうか?

25 Dec 2015, 08:20

Udacity で Machine Learning for Trading の講義をきいた

Udacity で Machine Learning for Trading のビデオを見てみた.

これは、coursera にある以下のコンテンツの Part2 になる.

講義内容

3つのパートに分かれている.

  1. Python の numpy, pandas, scipy の使い方
  2. ヘッジファンドについて
  3. 機械学習

1 つめは、python の numpy, pandas ライブラリを用いて 金融データをどうやって扱うかが説明される.

2 つめは、ヘッジファンドの仕組みについて. ここのパートは、coursera の講義内容と内容がかぶってていたので、 飛ばした.

3 つめは、機械学習をシステムトレードに適用する方法について 説明される. 具体的に説明されていたのは、以下のような内容.

  • 線形回帰
  • KKN 法
  • Q 学習(強化学習)

他にも、KKN 法を改良した bagging algorithms や、 Q 学習を改良しした、Dyna-Q 学習 algorithms について解説されていた. 一度ビデオをみただけでは理解できなかった.

それから、この MOOC には提出課題はない. 課題の内容は公開されているのだが、提出が求められていない. Disscussion Board とかもないので、自力で解くのは断念して、課題はやらなかった.

感想

機械学習について、学べると思ったが、正直理解できなかった.

また、Computational Investing Part I に触発されて去年 FX のシステムトレードを したのて、これに機械学習のアイデアを取り入れて改良できればいいなと考えていた のだが、理解できていないので改良できない..

今後について

この講義だけで、機械学習をまなべると思っていたのは舐めていた.

本当に機械学習をシステムトレードに当てはめるためには、 本腰を入れて機械学習を学ばないといけないな. しかも、日本語のリソースで!(英語は理解できない)

機械学習を勉強するには、覚悟を決めて取り組まないと理解できない気がする. お試しで身につくようなものではない. 時間をかけるべきか、悩む.

とりあえず、深追いはせずにここで学習はやめようと思う.

29 Jul 2015, 10:10

FXシストレプログラム AWSでサーバ借りてデビュー

OANDAのREST APIを利用して、 コツコツとFXシストレプログラムをつくってきたのだけれども、 今回ついに、AWS上でデモトレードデビューをした.

ソースコードは公開しています. 誰かの参考になれば…

戦略

以下の売買ルールで勝負した.

仕掛けシグナル

  • 5秒足、25, 75の SMAでクロスしたら売買

仕掛けは、シンプルなロジックで.

手仕舞いシグナル

  • 4回 25, 75の SMA線がクロスしたら手仕舞い
  • 5pip損したら損切り
  • 5pip儲かったら、+1pip or -0.5pipずつ利確の上限を増やしていく. たとえば、5pip儲かったら6piと4.5pippに利確条件を増やす.

動的に利確の条件を増やしていく方法は、 多くのバックテストで、好成績を残した.

他にも、ボリンジャーバンドを利用した手仕舞いや、 線形回帰を利用した手仕舞いを試したのだけれども、 いまいちよい成績がでなかった.

結果

12時間のフォワードテストの結果、-450円!!

今後に向けて

さて、本番環境を試そうとししたところ、 本番口座のパーソナルトークンで通信してもエラーしか帰ってこない.

手順どおりにやってもダメ. サボートに問い合わせてもダメ. なにやってもダメ.

なんと、こんなところでくじけることになろうとは! 今までの努力はなんだったのだろう??

追記

結局、自分のバグだった. チャンチャン.

19 Jul 2015, 06:57

夏休みの自由研究 は OANDA APIを利用して FX システムトレード

夏休みの自由研究として、FX システムトレードをしようと画策中. この記事は、そのスナップショット.

やったこと

OANDA API 、とくに oandapyを利用して、 Pythonから 為替取引ができるようにした. oandapyは python3 で動作するようにフォークした

Dukascopyからヒストリカルデータをダウンロードして(これは手動)、 そのデータを利用して、バックテストを実施. バックテストの結果を matplotlibでグラフ化.

損益のグラフ

移動平行線のクロスで売買するグラフ

参考にしたコード

一人ではとうていできないので、以下のコードを参考にした.

MT4との比較

メリット

  • 好きな言語が使える

    OANDA APIは REST APIなので、どんな言語でも使える. 自分は Python!

  • Linux環境で動作

    Linux環境で動作することで、Amazon AWSの EC2上で動作させることができる.

  • Pythonのデータ解析ライブラリがつかえる

    Pythonを利用しているので、Pythonの便利なデータ解析ライブラリを 利用することができます. Numpy, Pandas, Scipy, Matplotlib…

    ta-libなんという、テクニカル指標に特化したライブラリもある.

デメリット

  • バックテストのデータを自分で用意する必要がある.
  • プラットフォームを自分で実装するのが大変.

    MT4プログラミングはMT4というプラットフォームのおかげで、 用意にコーディングやテストができたけれども、 OANDA APIを利用すると、自前ですべてプログラミングしないといけない.

今後の予定

ようやく動作しそうな?ベースができたので、 これから取引のロジックを考えていこうと思う. ここからが本当の自由研究!

以上、Happy Hacking!!

04 Jul 2015, 14:38

Pythonの テクニカル分析ライブラリ ta-libでバックテストしてみる

FXのテクニカル指標を提供してくれるような、 便利なPythonのライブラリはないかなと探していたら、ありました.

TA-LIBとは、経済データに対するテクニカル分析をするための関数がまとまっ たライブラリ. さっそく試す.

インストール

http://mrjbq7.github.io/ta-lib/install.html

tarをダウンロードして、ビルドする方法もあるけど、 easy_install で入れることができる.

easy_install ta-lib

およそ、100以上の関数が用意されている. 各関数の使い方は github参照.

つかってみる

単純移動平均の関数 SMAを利用して、 為替データでバックテストもどきをしてみる.

  • 5日移動平均が25日移動平均を上回ったら(ゴールデンクロス) 買い
  • 5日移動平均が25日移動平均を下回ったら(デッドクロス) 売り

データは、 MT4のヒストリカルデータより、1分足データをエクスポートした.

import numpy as np
import talib as ta

data = np.loadtxt('150703.csv', delimiter=",", usecols=(2, 3, 4, 5))

tanki = ta.SMA(data[:, 3], timeperiod=5)
tyuki = ta.SMA(data[:, 3], timeperiod=25)

total = 100000
units = 1000

for i in range(len(data)-1):
    if ((tanki[i] < tyuki[i]) and (tanki[i+1] > tyuki[i+1])):
        print("Golden Closs!!")
        total = total - 1000*data[i,3]

    elif ((tanki[i] > tyuki[i]) and (tanki[i+1] < tyuki[i+1])):
        print("Dead Closs!!")
        total = total + 1000*data[i,3]

print(total)

所感

Pythonだと、パラメータ(ここでは、移動平均の5と25)の調整がモンテカルロ法で できそう. パラメータの最適化がしやすいという点は metatraderに比べてメリットだ.

しかし、まだまだ、バックテストのしにくさは Metatraderに比べると大きい. 使えるレベルにするには、そうとうの努力が必要そうだ.

03 Jul 2015, 12:39

OANDA APIをつかって Pythonで 為替レートを取得してみた

少し前に mt4をいじってみたが、その先が取っ掛かりがつかめずにいた.

FXは自分は初心者なのだが、FX単体だと、飽きてしまった. 損してでもいいので、統計学とあわせて勉強できないかと道を探していた.

また、mt4のためのMQL言語は、C言語に近い言語で、拡張性がない. できればpythonを利用したいなーと思っていた.

Rest APIのことを調べていたら、Rest APIで 為替情報を取得できるという おもしろいAPIを OANDA 証券が提供しているのを見つけたので、試してみた.

やってみる

今回は、無料で即日利用できるデモ口座を開設して試す.

口座を開設

右上のデモ口座開設をクリックして、手順にしたがって口座開設.

デモ口座にログインして、APIアクセスの管理を選択し、 Personal Access Tokenを発行.

為替レートを取得

APIのドキュメントは以下にある. なんと日本語! 微妙な訳なので自動翻訳?!

Pythonで動かしてみよう. 為替レートを取得するサンプルは以下にある.

access_token, acount_idを自分のもので置き換えて実行.

[tsu-nera]% python2 streaming.py
{"tick":{"instrument":"EUR_USD","time":"2015-07-03T11:55:53.198067Z","bid":1.10999,"ask":1.11004}}
{"tick":{"instrument":"USD_CAD","time":"2015-07-03T11:55:52.634607Z","bid":1.25685,"ask":1.25712}}
{"tick":{"instrument":"USD_CAD","time":"2015-07-03T11:55:54.816590Z","bid":1.2569,"ask":1.25717}}
{"tick":{"instrument":"USD_CAD","time":"2015-07-03T11:55:58.650057Z","bid":1.25691,"ask":1.25716}}
{"tick":{"instrument":"USD_CAD","time":"2015-07-03T11:55:58.807926Z","bid":1.25688,"ask":1.25714}}
{"tick":{"instrument":"USD_CAD","time":"2015-07-03T11:55:59.070828Z","bid":1.25686,"ask":1.25711}}
{"tick":{"instrument":"EUR_USD","time":"2015-07-03T11:55:59.338964Z","bid":1.10997,"ask":1.11002}}
{"tick":{"instrument":"USD_CAD","time":"2015-07-03T11:56:00.915263Z","bid":1.25685,"ask":1.25711}}

これはすごい…

API Wrapperもある

API Wrapperを利用すれば、rest の知識なしに 操作ができる.

Mastering Python for Financeという本に、 oandapyを利用したトレード方法が書いてある.

oandapyを利用した、為替レート取得.

import oandapy
import time

oanda = oandapy.API(environment="practice", access_token=ACCESS_TOKEN)

while(True):
    time.sleep(1)
    response = oanda.get_prices(instruments="EUR_USD")
    prices = response.get("prices")
    print(prices[0])

おわりに

まずは初めの一歩. 次はバックテストをやってみたいところだ.以下が参考になりそう.

また、このサイトの管理人さんは、OANDAを利用して実際にトレードしているようだ.

Metatrader は 古くからある売買方法だが、 OANDA APIを利用した方法を利用している人はほとんどいないので、 ブルーオーシャンかもしれない. しかし、情報がとても少ないというリスクがある.

この海に飛び込んだらPythonがつかえるというモチベーションの炎が消えて しまわないか心配だ.

Special Thanks