#!/usr/bin/env python
# coding: utf-8
# # システムトレードを始める前に知っておきたかったこと
#
What I wish I I knew when I started automatic Trading.
# # システムトレードを始める上で、
まずすべきことは自動売買ソフトの作成ではない
# # システムトレードを始める上で始めに絶対にしてほしいこと
# ## 自分で価格データを集めること
# - 生データがないと自分がトレードした内容と、実際に検証したデータとの乖離の検証自体ができない。
# - 他から入手したデータはお金を払ったとしても使えないデータであることが多い。
# - 最近の相場であれば、1年間の生データがあるだけで十分使える。
# # バックテスト
# 検証用のデータが入手できれば、次はバックテストと行う。
# ## バックテストで陥りやすいミス
# - 未来の情報を参照してしまっている
# - 始値、終値、高値、安値だけの検証を行ってしまうと、より利益が出やすくなる
# - 再現性の取りにくい方法を取り入れてしまう(累積系の分析等)
# - 約定価格がおかしい
# ## 始値、終値、高値、安値だけのバックテストでハマるミス
# - 買いポジションの指値を定めたとして、高値により決済したと判断したとき、指値から高値までの値幅を利益に含めてしまう
# - バックテスト上で 始値 → 安値 → 高値 → 終値 というような形で価格を流した時、安値で買いエントリーして高値で決済するロジックができやすい。
# - 2つの決済ロジックを導入していると、良い方の価格で決済されてしまう場合がある。
#
# ## 再現性の低いシステムを使ってしまう
# - 累積系の分析等をシステムに組み込んでしまうと、システムを稼働した時期によって差がでてしまい、リアルトレードとバックテストとの差が生じた時の原因究明に大きな支障をきたすことになる。
# - 私は最近、これに嵌まりました。
# - 高速化をするべく、近似した累積移動平均などを使ってしまっていたが、リアルトレードとの差が生じてしまい、損失の原因究明ができなくなってしまった。
#
# #### 再現性の取りにくい方法は使わないこと
# - より限られた条件の中で、より少ない計算量で良質な分析を行えるようにする。
# 自分が使っている検証ソフトの持っている特性と落とし穴をよく知り、その上でより精査なバックテストの検証を行うようにする。
#
# 実際のバックテストは高速化のため、始値ベース、もしくは終値ベースでのバックテストを行うことになるとは思うが、Tickデータ(都度データ)による検証も行い、その2つの差が全く無い、もしくは差の理由が明確に理由付けできるぐらいにはしておく。
# データも集めた。
#
# バックテストを行って詳細な分析もし、リアルトレードソフトもできた。
#
# さぁ、リアルトレード開始だ!
# ## 実運用を始める上で知っておきたいこと
# ## 検証可能な形でトレード履歴を残すこと
# - 自分が注文した価格と、実際に注文が通った価格は必ず残す。
# - その差が致命的な運用損失になっていることもある。
# - 最良値の価格情報も必須。FXでいうところのスプレッド。
# - 約定したときのパラメータ等も履歴に残しているとなお良い。
# - 約定にかかった時間を記録しておく
# ## 連続発注をしてしまうような要素は使わない。
# システム自体に、連続で発注してしまうような要素の組み込みはやめたほうがいい。もちろん、それを考慮したうえでのソフトウェアも可能ではあるが、一瞬で全財産を飛ばすようなシステムに繋がってしまうことがあることは肝に銘じておくこと。
# - 業者によっては、約定が通らないというレスポンスがあって、数時間立った後に「実は通ってました」みたいなことを平然と言ってくるところもある。
# - 約定の安定はソフトウェアの改善より、業者の選定で行ったほうが安心。
# ## あまり複雑なシステムは組まない
# 基本的に一人で開発することになるので、メンテナンスのしにくいソフトは避けるべき。細かい注文を何十回も行うようなシステムは向かない。
# # 実際に遭遇した問題
# ## ドル円のスプレッド 3 問題
# - ドル円のスプレッドは、日本の場合 3 で提示している業者が多いが、スリッページやスプレッドの拡大を考慮すると、実質スプレッドは 5
# - エントリー時 平均スプレッド : 3.8 平均スリッページ : 1.5
# - 決済時 平均スプレッド : 4.9 平均スリッページ : -0.3
# - 実際にデータを記録し続けたから見えた事実。
# - ドル円の場合、スプレッドの考慮値が 3 か 5 かでバックテストへの影響が致命的な差となって現れる。
# - 相対比 1.667倍
# - ユーロドルの場合は 最低スプレッドが 5 で 実質スプレッドは 6.1。相対比 1.2
# - 最初のスプレッドが小さいので、少しの差が致命的な差になりやすい。
# - スプレッド 3 でバックテストをしていると、取引回数が多く、細かく利益を上げるシステムができていたが、スプレッド 5 にしたとたん勝てなくなった。
# In[8]:
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display, HTML, Markdown
import seaborn as sns
get_ipython().run_line_magic('matplotlib', 'inline')
sns.set(style='darkgrid', rc={'figure.facecolor':'white'})
display(Markdown("## USDJPY Spread による違い"))
df = pd.DataFrame()
spread3 = pd.read_csv("./data/USDJPY Spread 3.csv", header=None)
df["Spread 3"] = spread3[0]
spread5 = pd.read_csv("./data/USDJPY Spread 5.csv", header=None)
df["Spread 5"] = spread5[0]
df.plot()
plt.show()
# In[9]:
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display, HTML, Markdown
import seaborn as sns
get_ipython().run_line_magic('matplotlib', 'inline')
sns.set(style='darkgrid', rc={'figure.facecolor':'white'})
display(Markdown("## リアルトレードとの差"))
df = pd.DataFrame()
spread3 = pd.read_csv("./data/bar_web_EURJPY.csv", header=None)
df["FromWeb"] = spread3[0]
spread5 = pd.read_csv("./data/tick_real_EURJPY.csv", header=None)
df["RealData"] = spread5[0]
df.plot()
plt.show()
# ## それでも完全には一致しない。
# # 理想的な状態
# リアルトレードでポジションをとって、決済したとして、その検証のためのバックテストがすぐに行なえ、バックテストでもそのトレードが再現されることが確認できる。
# # 再現性を高めるために最近取り組んだこと
# ## バックテスト環境
# - Python
#
# ## リアルトレード環境
# - Ruby : 価格取得、MT4 のヒストリカルデータ更新、シグナル管理
# - MT4 : チャート分析、シグナル発生
# - Python : 約定実行、価格情報をPython に送信
#
# ### Python と MT4 の運用結果を完全に一致させる必要が出てきた
# - MT4 上から Python の演算関数を呼び出し、MT4 上での計算をさせるのをやめた。
# - `FasterNumpy` 等を作成
# - Linux 上で MT4 を起動して、自動でバックテストを行い、自作バックテストソフトとの結果の一致テストを書いた。
# - 丸め誤差や、アルゴリズムの微妙なずれが生じていることが発覚。
# - ほかにもいくつか不一致、場合によってはバグの発見にも繋がった。
# ### 複数のバックテストソフトを使おう
# 複数のバックテストソフトで同じアルゴリズムを書いてみることで、自分のアルゴリズムの見直しと、動作の確認、そのバックテストソフトの仕様への理解の深まりなど、利点が多くおすすめ。バグの発見にも繋がる。
# # まとめ
# - バックテスト自体の検証力も大事だが、リアルトレードの検証力はもっと大事で、データをしっかり集めていないと難しい。
# - より精度の高い運用を目指すこと。