【連続系】MATLAB、Pythonで株価予測 その84【フーリエ変換㉑】

【連続系】MATLAB、Pythonで株価予測 その84【フーリエ変換㉑】 株価予測
【連続系】MATLAB、Pythonで株価予測 その84【フーリエ変換㉑】

バックナンバーはこちら。
https://www.simulationroom999.com/blog/stock-predict-matlabpython-backnumber/

はじめに

前回は、個別株チャート 8.4[Hz]から11.8[Hz]を抽出した上での極値特定 MATLAB版 動作確認実施。
波形、極大値、極小値特定はすべてOK。

(めんどくさいが)これのPython版を作成する。

登場人物

博識フクロウのフクさん

指差しフクロウ

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1

エンジニア歴8年の太郎くん

技術者太郎

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1

個別株チャート 8.4[Hz]から11.8[Hz]を抽出した上での極値特定 Python(Numpy)版

フクさん
フクさん

前回はMATLABによる個別株チャートの極大値、極小値の特定までできた。
というわけで今回は、これのPython(Numpy)版だな。

太郎くん
太郎くん

こ、これも
い、一応作って来た。

フクさん
フクさん

特に問題は無いと思って良いかな?

太郎くん
太郎くん

そうだねー。
MATLABと同じく、過去のコードを組み合わせで作ってるから大丈夫だとは思うんだけど。
一応、簡単な動確まではやったし。

フクさん
フクさん

なら、おおよそ問題は無いと思って良いだろう。

コード

太郎くん
太郎くん

実際のコードはこれになるよ。

import numpy as np
import matplotlib.pyplot as plt

VTI=np.loadtxt('VTI3.csv',delimiter=',') # 変換用波形読み込み
N=len(VTI)
L=N/2
x=np.linspace(-L,L-1,N)
ft=VTI-np.mean(VTI)

fig = plt.figure()

# 変換前波形
ax1 = fig.add_subplot(5, 1, 1)
ax1.plot(x,ft)
ax1.set_title('f(t)')
ax1.grid()

# FFT後にローテーション
Fw=np.fft.fft(ft)
Fw_tmp = np.roll(Fw,int(L))
ax2 = fig.add_subplot(5, 1, 2)
mask = (-50<=x) & (x<=50)
ax2.plot(x[mask],np.abs(Fw_tmp[mask]))
ax2.set_title(r'$F(\omega)$')
ax2.grid()

# 拡大
ax3 = fig.add_subplot(5, 1, 3)
mask = (0<=x) & (x<=10)
ax3.plot(x[mask],np.abs(Fw_tmp[mask]))
ax3.set_title(r'$F(\omega)$ expansion')
ax3.grid()

# 特定周波数のみ抽出
Fw_Filter=Fw_tmp;
Hz = 4;
Low = Hz-2.1;
High = Hz+2.1;
Fw_Filter[ ((0 <= np.abs(x)) & (np.abs(x) < Low)) | (High < np.abs(x))]=0;

ax4 = fig.add_subplot(5, 1, 4)
mask = (-10<=x) & (x<=10);
ax4.plot(x[mask],np.abs(Fw_Filter[mask]))
ax4.set_title(r'$F(\omega)$ Filter')
ax4.grid()

# IFFT前にローテーション
fx=np.fft.ifft(np.roll(Fw_Filter,int(L)))
ax5 = fig.add_subplot(5, 1, 5)
ax5.plot(fx.real)
max_fx=np.max(fx.real)
max_ft=np.max(ft)
ax5.plot(ft*(max_fx/max_ft))
ax5.set_title('f(x)')
ax5.grid()

# 極大値、極小値特定
maxima = np.zeros(N)
minima = np.zeros(N)
fxTmp=fx[0]
mode = 0
for i in range(1,N):
    if mode == 0:
        if fx[i]>fxTmp:
            minima[i]=ft[i]*(max_fx/max_ft)
            mode = 1
        fxTmp=fx[i]
    if mode == 1:
        if fx[i]<fxTmp:
            maxima[i]=ft[i]*(max_fx/max_ft)
            mode = 0
        fxTmp=fx[i];

maxima[maxima==0]=np.nan # 極大値だけを残す
minima[minima==0]=np.nan # 極小値だけを残す
ax5.plot(maxima,'ro')  # 極大値をplot
ax5.plot(minima,'bo')  # 極大値をplot
maxima_index=np.where(~np.isnan(maxima))
minima_index=np.where(~np.isnan(minima))
print('maxima_index:', end='')
print(maxima_index)
print('minima_index:', end='')
print(minima_index)
VTImaxima=VTI[maxima_index] # 極大値要素のみ抽出
VTIminima=VTI[minima_index] # 極大値要素のみ抽出

print('VTI maxima value:', end='')
print(np.round(VTImaxima*127)) # $1=\127
print('VTI minima value:', end='')
print(np.round(VTIminima*127)) # $1=\127

plt.show()

コード見ての感想

太郎くん
太郎くん

まぁMATLABと流れは合わしてるし、
使用する変数も列ベクトル、行ベクトルではなく、ベクトルに統一してされていたから、
コードのコピペ&結合もほぼ苦労は無かったかな。

フクさん
フクさん

まぁ実験コードだから、そういった調整無視で作るのも良いのだが、
なんだかんだで使いまわすことになるからな。
統一し易い構造ってのを先に考えておいた方が、その分、楽ができるってことだな。

太郎くん
太郎くん

そうだよねー。
パッと作った方が楽な気がするけど、
細かく刻んで動確していったりすることを想定すると、
どう刻んでいくかを考えた上でコードを起こさないと結局楽ができないもんね。

フクさん
フクさん

というわけで、次回は動作確認。

太郎くん
太郎くん

(きっと今回でコーディングするのは終わりのはずだ・・・はずだ・・・。)

まとめ

フクさん
フクさん

まとめだよ。

  • 個別株チャート 8.4[Hz]から11.8[Hz]を抽出した上での極値特定 Python(Numpy)版を作成。
    • 過去コードを元にコピペ&結合。
      • 実験コードであっても、先にロードマップを決めておくと、コード構成が決め易い。
      • これにより、トータルでは楽ができるコード構成にすることも可能。

バックナンバーはこちら。

コメント

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