バックナンバーはこちら。
https://www.simulationroom999.com/blog/stock-predict-matlabpython-backnumber/
はじめに
前回までで、プログラム的に極大値と極小値の特定するコードを作成した。
MATLAB、Python共に似た感じのコードとなり、
挙動も同一である。
今回からは実際に極大値、極小値を元にした、売却、買付タイミング時のVTI単価を特定するコードになる。
登場人物
博識フクロウのフクさん
イラスト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
売却、買付タイミング時のVTI単価特定コード(MATLAB版)
で、実際の売却、買付タイミングのVTI単価を特定するコードはできた?
(私が作る前提になってたんか。まぁ作って来たけど。)
MATLABコードとしてはこれになる。
VTI=csvread('VTI3.csv'); % VTIチャート読み込み
N=length(VTI);
L=N/2;
x=linspace(-L,L-1,N);
ft=VTI-mean(VTI);
% 変換前波形
subplot(5,1,1)
plot(ft)
title('f(t)');
grid();
% FFT後にローテーション
Fw=fft(ft);
Fw_tmp=circshift(Fw,L);
subplot(5,1,2);
mask = (-50<=x & x<=50);
plot(x(mask),abs(Fw_tmp(mask)));
title('F(\omega)');
grid();
% 拡大
subplot(5,1,3);
mask = (0<=x & x<=10);
plot(x(mask),abs(Fw_tmp(mask)));
title('F(\omega) expansion');
grid();
% 特定周波数のみ抽出
Fw_Filter=Fw_tmp;
Hz = 4;
Low = Hz-2.1;
High = Hz+2.1;
Fw_Filter( (0 <= abs(x) & abs(x) < Low) | High < abs(x))=0;
subplot(5,1,4);
mask = (-10<=x & x<=10);
plot(x(mask),abs(Fw_Filter(mask)));
title('F(\omega) Filter');
grid();
% IFFT前にローテーション
fx = ifft(circshift(Fw_Filter,L));
subplot(5,1,5);
plot(real(fx),'r');
hold on
max_fx=max(fx);
max_ft=max(ft);
plot(ft*(max_fx/max_ft),'k');
title('f(x)');
grid();
% 極大値、極小値特定
maxima = zeros(1,N);
minima = zeros(1,N);
fxTmp=fx(1);
mode = 0;
for i = 2:N
if mode == 0
if fx(i)>fxTmp
minima(i)=ft(i)*(max_fx/max_ft);
mode = 1;
end
fxTmp=fx(i);
end
if mode == 1
if fx(i)<fxTmp
maxima(i)=ft(i)*(max_fx/max_ft);
mode = 0;
end
fxTmp=fx(i);
end
end
maxima(maxima==0)=NaN; % 極大値だけを残す
minima(minima==0)=NaN; % 極小値だけを残す
plot(maxima,'ro') % 極大値をplot
plot(minima,'bo') % 極小値をplot
maxima_index=find(~isnan(maxima));
minima_index=find(~isnan(minima));
fprintf('maxima_index: ');
disp(maxima_index);
fprintf('minima_index: ');
disp(minima_index);
VTImaxima=VTI(maxima_index); % 極大値要素のみ抽出
VTIminima=VTI(minima_index); % 極大値要素のみ抽出
format longG
fprintf('VTI maxima value: ');
disp(round(VTImaxima'*127)); % $1=\127
fprintf('VTI minima value: ');
disp(round(VTIminima'*127)); % $1=\127
format
コード解説
なんか、徐々に拡張していったから、
あまり気にしてなかったけど、結構長いコードになってきたな・・・。
と言っても、処理の流れとしては一直線だから、コード自体の複雑性はないな。
良く見たら、バンドパスフィルタ相当のところのコードが変わってるね。
Fw_Filter( x< -High | (-Low < x & x <= 0) | (0 <= x & x < Low) | High < x)=0;
↓
Fw_Filter( (0 <= abs(x) & abs(x) < Low) | High < abs(x))=0;
あー、最初から、この書き方にしておけば良かったんだけど、忘れてた。
複素共役を負の周波数側に持ってきているんで、x軸としてはプラスでもマイナスでも同様の範囲になるんで、この書き方ができるんだよね。
まぁ言いたいことはわかるかな。
負の周波数側も絶対値でみたら同じ範囲だし、絶対値化すれば正の周波数と全く同じ評価式が使えるってことだよね。
そうそう。
まぁいままでの書き方でもHigh、Lowが共通で利用出来ていたんで、意味がなかったわけでもないんだけど。
今回の方がシンプルだし、いいんじゃない?
Python(Numpy)側も、このタイミングで修正すると思う。
たぶん似た感じに修正で済むはずだ。
まとめ
まとめだよ。
- 売却、買付タイミング時のVTI単価特定コード(MATLAB版)を作成。
- ついでにバンドパスフィルタの部分をちょい改修。
- Python(Numpy)側のコードも似たような感じで改修予定。
バックナンバーはこちら。
コメント