Pythonでニュース速報と為替レートの関係を調べてみる

  • 27 December 2021
Post image

 FXのシステムトレードについて、私はほぼすべてを信用していない。おそらく巨大なファンドがお金をかけて開発したシステムやごくごく一部の個人トレーダーがひたすら時間をかけて作ったシステムはもしかしたら稼げるのかもわからないが、その他のネット上に転がっている「FX自動売買システム」は誰でも簡単に儲けられるような代物ではないはずだ。つまりほぼ全てが詐欺と考えてもよいだろう。

 また、株や為替のチャートを見てテクニカル分析するってのも正直信じていない。私は投資・投機については素人なので偉そうなことは言えないのだが、仮に、「テクニカル分析が有効」→「それをシステム化することができる」→「自動で取引して複利で爆益」というロジックが成り立つからだ。世の中そんな甘いかぁ?
 「テクニカル分析が有効でない相場があるんだよ!」とか「テクニカル分析は常に正しいわけではなく勝率を上げるためのものだ!」という人がいるが、確率論でものを言うならそれこそシステム化して期待値を1以上にできるから「自動で取引して複利で爆益」が出来ちゃうし、そもそも分析が有効でない相場があって全体として期待値1を超えられないのだとしたら、その「テクニカル分析」って意味あるの?って思ってしまう。

 私はやはりプロトレーダーではないので上記が間違えているかもしれないが、今回書いてみたいのはそんなことではない。プログラマーとしてはシステムの力でトレードの期待値を上げられるかということには興味がある。そしてやる前から書くが、おそらく私には自動で利益を出すようなシステムは作成できない。理由は後述。また、試してみることは何年も前に誰かがやっているであろうことなのでご了承を。


経済ニュースが為替レートを変動させるか

 前述の通りテクニカル分析には懐疑的だ。なのでここでは以下の1つの仮説をたてる。
仮説: 経済情報等が発表された後、その情報を反映した価格へと変動する

 効率的市場仮説ほどではないにしろ、為替レートを変動させているのは経済情報、ニュース、指標速報だと仮定したい。もう少し正しくいうと世界中の経済実態・実情・政策がレートを変動させるはずだが、それらがニュースとして発表されることで世界中のトレーダーが認識してはじめて価格が変動するっていうこと。もしニュースとして公表されるまえに実態を認識できるなら素晴らしいが、私にはそんなことはできない。また、システム的に世界の経済実態を認識・収集することは不可能と思われる。
 なのでまずは経済ニュースが発表されてからレートがどのように変動しているかを調査してみる。


ロ○ター社情報を使って為替レートの統計をとる

 ロ○ターの為替関連情報(2016年~2021年)を持っている。そうあの有名なローター情報だ。いいね?何度も言っておく、ローター情報だ。そしてローターの情報は世界でも最速の部類らしく、今回検証する上で最も適した情報源と思われる。全部で約25,000程度の為替経済情報、ニュース、速報などが含まれる。期間は5年程度とする。多分20年前の為替相場の動向と現在の動向は大きく違うと思われるので、この5年程度に絞ってみる。

 そして次に、ドル円、ユーロ円、ポンド円の1分足情報を手に入れる。ググれば簡単にCSVで手に入る。以下のようなデータだ。

USDJPY,20190212,221000,110.46,110.46,110.46,110.46,4
USDJPY,20190212,221100,110.46,110.46,110.46,110.46,4
USDJPY,20190212,221200,110.46,110.46,110.46,110.46,4
USDJPY,20190212,221300,110.46,110.46,110.46,110.46,4
USDJPY,20190212,221400,110.46,110.46,110.46,110.46,4
USDJPY,20190212,221500,110.46,110.46,110.46,110.46,4

 ドル円相場で2019/2/12の22:10から2019/2/12の22:15の為替レートを表している。これを2016年~2021年末ごろまで用意する。行数でいうとおよそ220万行のcsvだ。これを3つ用意した。

 次にローター情報は扱いやすいようにsqliteにでもぶち込んでみる。あとで機械学習(ディープラーニング)で使うために分かち書きもしておく。

import mojimoji
import MeCab
import sqlite3
def modify_text(text):
  '''
  テキストは全角にして改行やスペースを調整。mecabで分かち書きにする
  '''
  text = mojimoji.han_to_zen(text)
  text = text.lstrip().rstrip()
  text = text.replace('\n','')
  text = text.replace('\r','')
  text = text.replace('\t','')
  text = text.replace(' ','')
  text = text.replace(' ','')
  mecab = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
  mecab.parse('')
  m1 = mecab.parse(text)
  ret = []
  for row in m1.split("\n"):
      word =row.split("\t")[0]
      if word == "EOS":
          continue
      ret.append(word)
  return " ".join(ret)

if __name__ == '__main__':
  dbname = 'fx.db'
  conn = sqlite3.connect(dbname)
  cur = conn.cursor()
  for news in news_list: # 約25000のローターニュースをsqliteに保存
    title = modify_text(news["title"])
    body = modify_text(news["body"])
    datetime = news["datetime"]
    cur.execute(f'INSERT INTO corpus(title, body, date) values("{title}", "{body}", "{datetime}")')
  conn.commit()
  cur.close()
  conn.close()

レートの変動パターンを定義

 5年分のローター情報と為替レートのcsvが用意出来たが、あとはレートの変動パターンを定義する必要がある。ここでは以下と定義する。

パターン0: レートが0.4%以上変動しない
パターン1: レートが0.4%超上がる
パターン2: レートが0.4%超下がる
パターン3: レートが0.4%超上下する

 ここでいう「上がる」は円相場を基準に考えると円安になったという意味だ。また、いずれもスタート時点のレートと比較してn%という意味。なぜ0.4%かっていうと、日本のFXだとレバレッジが25倍までなので、およそ投資額の10%の変動ってかなりデカいと思うからだ。(後で変更してもよい)
 次に情報が出てからどの程度でその情報がレートに反映されるかを仮定する必要もある。今回は以下のように考える。

反映時間: 情報公表から3時間以内

 情報が公表されて3時間もあれば、その情報は完全に織り込まれるでしょっていう仮定だ。当然レート反映に3時間もかからないと思うし、また、3時間以上たってトレンドが継続することはよくある。しかし、どこかで区切らないといけないので3時間とする。

 つまり、まとめると、「情報公表日時から3時間以内に0~3のどのパターンになるか」ってこと。そしてこれがもし情報公表時にどのパターンになるかを知ることができたら、、、億万長者か?


2016年から2021年までデータで調べてみる

 以下のようにして、情報公表からのパターン数をチェックしてみる。

import sqlite3
import csv
def get_csv_data():
    with open(f'USDJPY.txt') as f: # ファイル名を変更して通貨ペアを変更できる
        reader = csv.reader(f)
        ret = []
        for row in reader: ret.append(row)
        return ret

def get_db_data():
    dbname = 'fx.db'
    conn = sqlite3.connect(dbname)
    cur = conn.cursor()
    cur.execute('SELECT id, title, body, date FROM corpus ORDER BY datetime(date)')
    ret = cur.fetchall()
    cur.close()
    conn.close()
    dic = {}
    for d in ret:
        t = d[3].replace(" ", "").replace("-", "").replace(":", "")[:-2] + "00"
        dic[t] = d[1] + ' ' + d[2]
    return dic

def get_type(csv, i):
    start = float(csv[i][3])
    values = []
    # 先3時間の値をセット
    for plus in range(180):
        ind = i + plus
        if ind >= len(csv): break
        values.append(float(csv[ind][3]))
    max_val = max(values)
    min_val = min(values)
    # 0.4%超の変動があったか
    rate = 0.004
    if max_val > (start * (1 + rate)) and min_val < (start * (1 - rate)):
        return 3
    elif max_val > (start * (1 + rate)):
        return 1
    elif min_val < (start * (1 - rate)):
        return 2
    else:
        return 0

if __name__ == '__main__':
    data = get_db_data()
    csv = get_csv_data()
    i = -1
    types = {}
    for c in csv:
        i += 1
        db_data = data.get(c[1] + c[2])
        if db_data is None: continue
        t = get_type(csv, i)
        if types.get(str(t)) is None:
            types[str(t)] = 1
        else:
            types[str(t)] += 1
    print(types)

 ソースコードはかなり汚いけど使い捨てコードなのでお許しを。

ドル円の出力

{'0': 24822, '1': 567, '2': 615, '3': 9}

ユーロ円の出力

{'0': 24050, '1': 753, '2': 767, '3': 15}

ポンド円の出力

{'0': 23019, '1': 1357, '2': 1562, '3': 49}

 わかってはいたことだけど、ボラティリティは、ポンド>ユーロ>ドルってことがよくわかる。そしてほとんどの情報が「変動なし」にあたることが分かった。当然今回用意したローター情報は各通貨ペアのみの情報ではなく、すべての情報が含まれているので全く反応しない情報が大多数であることは想像できる。
 また期間が2016年~2021年と大きな変動がなかった期間だからか、「0.4%超上がる」と「0.4%超下がる」がほぼ同じくらいになっている。まるでコイントスでレートが動いているような感じ。


FXでインサイダー情報は有効か

 では、このデータセットを使って以下の妄想を確かめてみる。

「情報を先に入手できたら大金持ちなのになぁ」

 こんなこと確かめる意味ないけど一応。すべてのニュース公表の1時間前に行動した場合のボラティリティの変動を知ることができる。

for c in csv:
  i += 1
  db_data = data.get(c[1] + c[2])
  if db_data is None: continue
  t = get_type(csv, i - 60) # 1時間前に情報を知ってポジション持つ

ドル円の出力

{'0': 24781, '1': 546, '2': 682, '3': 4}

ユーロ円の出力

{'0': 24069, '1': 721, '2': 777, '3': 18}

ポンド円の出力

{'0': 23074, '1': 1353, '2': 1509, '3': 51}

 これは予想に反して1時間前に行動しても大きくボラティリティは変わらないみたい。経済ニュース速報などがレートの変動に与える影響はかなり小さいということか?つまりローターの情報より1時間も早く情報を掴んだとしても大きく結果は変わらないかもしれないってこと。ただ明らかに反応しない大多数のニュースを含んでいるので、本当のところはわからない。


AIでニュースを解析してFXトレード

 では AI(機械学習のことをAIと呼びたくないけど)で情報を解析して、機械的にポジションを持つことができたら? って考えてしまうよね?AIとか言っているけど、簡単にいうとニュースをコンピュータ的に認識してそれが過去のデータと照らし合わせて上記の4パターンのどれに分類できるかってこと。
 近年では文章をBERTなどで分類し、お問い合わせやチャットの自動返信なども可能になっている。これはつまり文章の特徴量を計算してその特徴量を元にお問い合わせ内容を分類し、予め用意されたそれぞれの分類に対応する返信文章を送信しているってこと。
 実際のトレードにおいては、 ローターから情報をリアルタイムで取得→機械学習に通してパターン0~3に分類→パターンが1か2の場合はポジションを取る。 ってやるとどんどん資産増えるんじゃない?ってこと。続きは機械学習での実装を参照。

You May Also Like

情弱が運営するWordPressサイトを攻撃する

情弱が運営するWordPressサイトを攻撃する

 なんとなく悪いことってのは、魅力的だったりする。 おそらく1970年代~1990年前半に生まれた人で、学生時代にPCを触っていた人ってアングラな世界に1度や2度触れたことがあるのではないでしょうか?特にエロ系ね。私も若かりし頃は、なんとかしてずりネタを確保しようと、意味も分かってなかった通信プロト …

RESTfulなAPI。それは魔法です。

RESTfulなAPI。それは魔法です。

 では最後の工程。何かWebAPIを作ってみる。前回の記事では、pythonでWebAPIのリクエストとレスポンスを作ったけど、今回は一般的なWebAPIの構造をやってみる。 究極魔法「RESTful」  何年か前からWebAPIは、***RESTful(REST)***という構造 …