FXボーグ | テクニカル実験室

テクニカル分析を使った自動売買プログラムの開発に挑戦!

スポンサーリンク

SSAトレンド・インジケーターをアップしました。

SSAトレンド・インジケーターをアップしました。SSAのトレンド成分を自動抽出します。詳しくは前回の記事をご覧ください。USDJPY4Hだとこんな感じです。

f:id:fxborg:20170929040642p:plain

  1. 【設定値】
  2. ・N・・・・・時系列データの長さ (1000)
  3. ・L・・・・・キャタピラーのウインドウ長(120)
  4. ・ω0・・・・トレンド成分判定用のしきい値(0.01)
  5. ・max_ET・・成分数の上限(32)

 

Caterpiller-SSAアプローチ

今回のインジケーターはこちらのMATLABコードをC++/opencvで再実装したものですが、サイトにはCaterpiller-SSA アプローチを使用していますと記されています。

http://www.pdmi.ras.ru/~theo/autossa/english/index.htm

キャタピラーについて調べてみると以下のペーパーにこう書かれていました。

The SSA method has also been called Cadzow filtering (Trickett, 2008) or the Caterpillar method (Golyandina et al., 2001). All this techniques are equivalent, but they arise from different fields.For instance, the Cadzow method was proposed as a general framework for denoising images (Cadzow, 1988),and the Caterpillar method also arises from time series analysis (Nekrutkin, 1996).

https://era.library.ualberta.ca/files/qj72p8105/Thesis_Vicente_Oropeza.pdf p5 より引用)

(以下、勝手訳)

SSA法はCadzow法やCaterpillar法とも呼ばれています。これらの技術は全て同じですが異なる分野から発生しました。

例えば、画像をノイズ除去するための一般的なフレームワークとしてCadzow法が提案されました。また、時系列解析からはCaterpillar法が生じました。

具体的には時系列データをハンケル行列に詰め込んで、特異値分解(SVD)を行なうことにより各成分に分離するという手順を行ないます。  

f:id:fxborg:20170929120233p:plain

Singular spectrum analysis - Wikipedia より引用)

ハンケル行列の可視化

式だけでは分かりづらいので、実際のデータを使ってハンケル行列を可視化してみました。以下はUSDJPY4時間足です。

f:id:fxborg:20170929043131p:plain

これをハンケル行列に詰め込んでプロットするとこのように表示されます。

時系列データが対角線上に並んでいて、中央に近いほど厚みがあるグラフが現れました。(なんだかくしゃくしゃになったネクタイのようですね。)

f:id:fxborg:20170929043046p:plain

以下は特異値分解後のU(左特異ベクトル)です。MATLABでは「 [U,S,V] = svd(X) 」とするだけです。これで一気に各成分に分離されます。特異値分解 - MATLAB svd - MathWorks 日本を参考)

f:id:fxborg:20170929045043p:plain

後はUの成分をひとつずつフーリエ分解し、しきい値(ω0)以下の低周波を見つけるだけです。

STLのvalarray

 STLにはvalarrayという数値に特化した配列ライクなライブラリがあるのですが、これまでその存在すら知りませんでした。使ってみると非常に便利で性能的にも優れているそうです。

  1. valarray - cpprefjp C++日本語リファレンス
  2. std::valarrayの使い方 - Qiita
  3. 不遇の標準ライブラリ - valarray

フーリエ分解に使用してみました。記述性がよいですね。

double CSSA::periodogram(const std::valarray& F, const int k)
{

	int N = F.size();
	double w = (k - 1.0) / N;
	std::valarray T(N);
	for (int i = 0; i < N; ++i) T[i] = (double)i;

	double c = (F * cos(2.0*M_PI*T*w)).sum(); //<---- valarrayをcos()
	double s = (F * sin(2.0*M_PI*T*w)).sum(); //<---- valarrayをsin()
	double Pi = c*c + s*s;
	Pi = Pi * 2.0 / N;

	if (k == 1 || k == floor(N / 2) + 1) Pi = Pi / 2;
	return Pi;
}

最後に

今回はAutoSSAで示されたフーリエ分解によるトレンド抽出をC++/opencvで再実装しインジケータ化してみました。

まだまだ速度的にチューニングが必要ですが、長期トレンドの判定などには利用できそうです。あと今回のインジケーターはリペイントします。その点はご留意ください。

こちらからどうぞ
/Libraries/ssa.dll Kaspersky VirusDesk にて検査済み)
/Indicators/ssa.mq4
ssa.zip