[Foreign Exchange][FX][為替][USDJPY]ポジションの高値買い、安値売り

close up of twenty dollar bills FX
Photo by Sergei Starostin on Pexels.com

高値買い、安値売り

高値で買ってしまう、あるいは安値で売ってしまうというとき、次の事実はポジションの保有に対して何らかの示唆を与えるかもしれない。

高値買いの場合

その日の高値でドル円のロング(買い)ポジションを保有してしまったとしても当日を含まない\(5\)営業日以内にその高値を超える確率は\(7\)割以上である。具体的には\(1\)営業日以内に超える確率が\(47.3 \%\)、\(2\)営業日以内が\(59.2 \%\)、\(3\)営業日以内が\(65.6 \%\)、\(4\)営業日以内が\(70.0 \%\)、\(5\)営業日以内が\(73.1 \%\)である。簡単に言うと、適当に買ったポジションでも当日を含まない\(5\)営業日以内にその値を超える確率が\(7\)割以上であるということになる。\(10\)営業日以内となると、その確率は約\(8\)割になる。

安値売りの場合

逆に、その日の最安値でドル円のショート(売り)ポジションをほ保有してしまったとしても、当日を含まない\(5\)営業日以内にその安値を下回る確率は、\(7\)割以上である。具体的には\(1\)営業日以内が\(44.7 \%\)、\(2\)営業日以内が\(56.4 \%\)、\(3\)営業日以内が\(63.0 \%\)、\(4\)営業日以内が\(67.1 \%\)、\(5\)営業日以内が\(69.8 \%\)である。簡単に言うと、適当に売ったポジションでも、当日を含まない\(5\)営業日以内にその値を下回る確率が\(7\)割以上ということである。

10日間のグラフ

グラフにすると以下のようになる。横軸が日数、縦軸が買値以上、あるいは売値以下になる確率である。

\(10\)日間のグラフ。

1年間のグラフ

期間を\(1\)年間(約250営業日)にすると、グラフは以下のようになる。

\(1\)年間でのグラフ。

これを見ると、期間が\(200\)日を超えると若干確率が下がっていることが見て取れる。期間が長ければ長いほど、解析対象として取れる区間が少なくなるためであると考えられる。いずれにしろ、\(40\)日程度でsaturationに至るので、ここから示唆を得るとしたら、「ask(買い)で入ったポジションで40営業日後一度もその値よりも高くなっていないポジションがもとの値より高くなる可能性は\(10 \%\)程度」というところになるだろうか。

解析、グラフ描写のpythonコード

コードは以下。”import scraping”というのは自作のLibraryで、ドル円の時系列データを自動でダウンロードするもの。

import pandas as pd
import numpy as np
from scipy import stats
from matplotlib import pylab as plt
import seaborn as sns
sns.set()
import statsmodels.api as sm
import heapq as hp
import scraping

df = scraping.usdjpy_d
opening = np.array(df["opening"])#始値
high = np.array(df["high"])#高値
low = np.array(df["low"])#低値
closing = np.array(df["closing"])#終値
len(df)
length_of_the_analysis = len(df)#解析期間
target_day = 250#解析日数

#空のデータ数長の配列
ask_gain = [0] * (target_day+1)
bid_gain = [0] * (target_day+1)

for i in range(1, target_day+1):
    df["duration_high"] = pd.DataFrame(high).rolling(i, min_periods = 1).max().shift(-i)
    df["duration_low"] = pd.DataFrame(low).rolling(i, min_periods = 1).min().shift(-i)
    df["ask_judge"] = 0
    df["bid_judge"] = 0
    df.loc[df["high"] < df["duration_high"], "ask_judge"] = 1
    df.loc[df["low"] > df["duration_low"], "bid_judge"] = 1
    ask_gain[i] = df["ask_judge"].sum()/length_of_the_analysis*100
    bid_gain[i] = df["bid_judge"].sum()/length_of_the_analysis*100

#グラフの描写
#まとめて選択
plt.plot(ask_gain, color = "skyblue", label = "ask")
plt.plot(bid_gain, color = "orangered", label = "bid")
plt.xticks([20*i for i in range(target_day//20)])
plt.title("ask/bid")
plt.xlabel("days")
plt.ylabel("probability")
plt.legend()

ポイントは

df["duration_high"] = pd.DataFrame(high).rolling(i, min_periods = 1).max().shift(-i)

の部分で、”shilt(-i)”とすることで、当日を含まない未来の\(i\)日の中での最大値を同じ行に配置できる。pandasのデータフレーム操作は重いのでできればnumpyで行いたかったが、numpyではpandasのrollingに相当する良いlibraryがないためやむを得ずpandasで行った。なお、”min_periods”はデータの最小個数を指定する。詳細はこちらのリンクを参照。

Limitationについて

買った翌日に上昇したが、すぐ下落トレンドに入ったなどという例もここには含まれる。興味がある解析として、例えば「\(1\)週間(\(5\)営業日)以降から\(n\)日間の最高値が、買った当日の高値を超えているか」というものが考えられる。これはコードを

df["duration_high"] = pd.DataFrame(high).rolling(i, min_periods = 1).max().shift(-i)

から

df["duration_high"] = pd.DataFrame(high).rolling(i, min_periods = 1).max().shift(-i-5)

に修正すれば解決する。結果としては、ask(買い)の場合、\(1\)営業日以内に超える確率が\(50.8 \%\)、\(2\)営業日以内が\(55.7 \%\)、\(3\)営業日以内が\(59.3 \%\)、\(4\)営業日以内が\(62.4 \%\)、\(5\)営業日以内が\(64.9 \%\)である。翌日以降、という条件に加えてやはり確率は下がるものの、悪くない。\(10\)営業日以内となると、その確率は\(71.3 \%\)になる。

関連記事

FX

基本要約量のバイオリンプロット

Python

データフレームの中から条件を満たす列のIDを取得
numpyでリストごとの大小比較

関連リンク

USD/JPY(米ドル/日本円)
OANDA(オアンダ)が提供するUSD/JPY(米ドル/日本円)リアルタイムチャートです。USD/JPY(米ドル/日本円)のトレードに役立つ「OANDA Labオリジナルツール」やUSD/JPY(米ドル/日本円)に関連するニュースを御覧いただけます。
pandasで窓関数を適用するrollingを使って移動平均などを算出 | note.nkmk.me
pandas.DataFrame, pandas.Seriesに窓関数(Window Function)を適用するにはrolling()を使う。pandas.DataFrame.rolling — pandas 0.23.3 documentation pandas.Series.rolling — pandas 0....

コメント

タイトルとURLをコピーしました