tidyverseを使ってFX(ドル円)分析

誰でも夢見る不労所得

寝ているだけでお金が増える、そんなことを目指して?FXのデータを分析してみます。

データの取得先

forextester.jp



データ数が多すぎて開くのに時間がかかるのでコマンドラインから見てみます

〜
$ head ./USDJPY.txt
<TICKER>,<DTYYYYMMDD>,<TIME>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL>
USDJPY,20010102,230300,114.43,114.43,114.43,114.43,4
USDJPY,20010102,230400,114.44,114.44,114.44,114.44,4
USDJPY,20010102,230500,114.44,114.44,114.44,114.44,4
USDJPY,20010102,230700,114.44,114.44,114.44,114.44,4
USDJPY,20010102,230800,114.44,114.44,114.44,114.44,4
USDJPY,20010102,230900,114.44,114.44,114.44,114.44,4
USDJPY,20010102,231100,114.44,114.45,114.44,114.45,4
USDJPY,20010102,231200,114.45,114.45,114.45,114.45,4
USDJPY,20010102,231300,114.45,114.45,114.43,114.43,4
〜



今回は機械学習などを使わない、1次分析までしてみます。

  • 1分ごとだとデータが多いので、1時間ごとの平均の終値<CLOSE>)を求める。
  • 24データ/日の日付のみ抽出する。
  • 25日、75日、200日移動曲線をプロットする。



必要なライブラリを読み込み

〜
> library("forecast")
> library("tidyverse")
> library("xts")
> library("TTR")
〜



csvをロードしてカラム名を修正

〜
> # csvロード
> df_input <- read.csv("/Users/Shared/work/tmp/USDJPY.txt")

> # カラム名修正
> colnames(df_input) <- c("TICKER", "DTYYYYMMDD", "TIME", "OPEN", "HIGH", "LOW", "CLOSE", "VOL")

> head(df_input)
  TICKER DTYYYYMMDD   TIME   OPEN   HIGH    LOW  CLOSE VOL
1 USDJPY   20010102 230300 114.43 114.43 114.43 114.43   4
2 USDJPY   20010102 230400 114.44 114.44 114.44 114.44   4
3 USDJPY   20010102 230500 114.44 114.44 114.44 114.44   4
4 USDJPY   20010102 230700 114.44 114.44 114.44 114.44   4
5 USDJPY   20010102 230800 114.44 114.44 114.44 114.44   4
6 USDJPY   20010102 230900 114.44 114.44 114.44 114.44   4
〜



毎時ごとに集計しプロット

〜
> ### 毎時でデータをgroup by、値は平均で出す
> df_input2 <- df_input %>%
+     # hourを追加(前ゼロパディング)
+     dplyr::mutate(p_hour=str_sub(str_sub(str_c("00", TIME),start=-6, end=-1), start=1, end=2)) %>%
+     # 日付とhourを結合
+     dplyr::mutate(p_date_hour=str_c(DTYYYYMMDD, p_hour)) %>%
+     # p_date_hourでgroup by、平均求める
+     dplyr::group_by(p_date_hour) %>%
+     dplyr::summarise(value=mean(CLOSE)) %>%
+     # 日付、時刻のレコード追加
+     dplyr::mutate(p_date=str_sub(p_date_hour, start=1, end=8)) %>%
+     dplyr::mutate(p_hour=str_sub(p_date_hour, start=9, end=10))

> # データ数が24の日付のみ抽出
> count_check <- df_input2 %>%
+     # 日付でgroup by,count
+     dplyr::group_by(p_date) %>%
+     dplyr::summarise(n=n()) %>%
+     # n=24のみ抽出
+     dplyr::filter(n==24)

> # 日付とinner joinで対象の日付のみ抽出
> df_input3 <- dplyr::inner_join(df_input2, count_check, by=c("p_date"="p_date"))
> 
> df_input4 <- df_input3 %>%
+     # 日付加工
+     dplyr::mutate(ts=str_c(str_c(p_date, p_hour),"0000")) %>%
+     dplyr::select(ts, value)
> # フォーマット変換
> df_input4$ts <- as.POSIXct(df_input4$ts, format="%Y%m%d%H%M%S")
> df_input4 <- as.data.frame(df_input4)

> # データフレームのデータプロット
> ggplot(data=df_input4, aes(x=ts, y=value, colour="value")) +
+     geom_line()
〜


f:id:engi229:20191214204123p:plain
plot1



2001年頃からのラインチャートがプロットできました。
2012年頃がバコーンと下がっていますが、結構規則性があるような気もします。

25日、75日、200日の移動曲線をプロット

〜
> # 移動平均を求める関数定義
> def_sma <- function(ts, n_size) {
+     # 移動平均を計算
+     df_sma <- as.data.frame(SMA(ts, n=n_size))
+     # 行ラベルを取得し、初期化
+     colname_sma <- rownames(df_sma)
+     rownames(df_sma) <- NULL
+     # データフレーム、列カラム名設定
+     rtn_df <- cbind(colname_sma, df_sma)
+     colnames(rtn_df) <- c("datetime", paste("sma", n_size/24, sep="_"))
+     # 型変換
+     rtn_df$datetime <- as.POSIXct(rtn_df$datetime)
+     # 戻り値定義
+     return(rtn_df)
+ }
> 

> # 関数に投げるため、xtsに変換
> ts_data <- as.xts(read.zoo(df_input4))

> # 25日移動曲線
> sma_25 <- def_sma(ts_data, 600)
> # 75日移動曲線
> sma_75 <- def_sma(ts_data, 1800)
> # 200日移動曲線
> sma_200 <- def_sma(ts_data, 4800)

> # join
> df_output <- dplyr::left_join(df_input4, sma_25, by=c("ts"="datetime"))
> df_output <- dplyr::left_join(df_output, sma_75, by=c("ts"="datetime"))
> df_output <- dplyr::left_join(df_output, sma_200, by=c("ts"="datetime"))

> # 2018~現在までのデータをプロット
> df_plot <- dplyr::filter(df_output, ts>="2018-01-01 00:00:00")
> ggplot(df_plot) +
+     geom_line(aes(x=ts, y=value, colour="value")) +
+     geom_line(aes(x=ts, y=sma_25, colour="sma_25")) +
+     geom_line(aes(x=ts, y=sma_75, colour="sma_75")) +
+     geom_line(aes(x=ts, y=sma_200, colour="sma_200"))
〜


f:id:engi229:20191214204201p:plain
plot2


デッドクロスゴールデンクロスは信憑性ある……?ことがなんとなく見えます。
時間が会ったら、時系列分析もしてみたいですね。