バックナンバーはこちら。
https://www.simulationroom999.com/blog/stock-predict-matlabpython-backnumber/
はじめに
前回までで、MATLAB、Python(Numpy)ともに個別株チャートに対して、フーリエ変換、逆フーリエ変換が可能なことを確認。
今回からはFFT,IFFTでやったのと同じように極値を特定する話となる。
登場人物
博識フクロウのフクさん
イラスト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]を抽出した上での極値特定 MATLAB版
さて、今回からは極大値、極小値の特定をしていくわけだが。
太郎くんの方でコードはできた?
い、一応できた・・・。
なんか問題とかあった?
簡単に動確した範囲では大丈夫そうだったかなぁ。
FFT、IFFTでやっていたことをフーリエ変換、逆フーリエ変換に置き換えることで
コード上の辻褄合わせが必要になるかと思ってたけど、
それほど弄ることはなかったかな。
フクさんの方で、ここらへんを気にして調整してくれていたってのがわかったかな。
そうそう。
可能な限りめんどくさくないよう気を付けてたつもりだ。
MATLABコード
作って来たMATLABコードはこれ。
L=pi; % 波形の期間(-L~L)
w_max = 13; % 取りたい最大周波数
stock=csvread('TM1.csv'); % 同定波形読み込み
N=length(stock); % 波形のplot数取得
ft=stock-mean(stock); % 波形を行ベクトルへ
ft=ft';
dt=2*L/N; % dt
dw=w_max/(N/2); % dω 取りたい最大周波数から逆算
% 無限長、無限次元の関数同士の内積を実現するため、
% 時間領域関数と周波数領域関数は同じ要素にするに必要あり。
w=linspace(-dw*N/2,dw*N/2,N); % ω_n
t=linspace(-L,L,N); % t_n
Fw = zeros(1,length(ft)); % F(ω) フーリエ変換後の関数格納用
% F(ω)=∫f(t)e^(-iωt)dt
cnt=1;
for tn = t
Fw(cnt)=ft*exp(-1j*w*tn)'*dt;
cnt = cnt+1;
end
FwTmp = Fw;
Low = 8.4;
High = 11.8;
Fw( (0 <= abs(w) & abs(w) < Low) | High < abs(w) )=0;
fx = zeros(1,length(Fw)); % f(x) 逆フーリエ変換後の関数格納用
% f(x)=(1/2π)∫F(ω)e^(iωt)dω
cnt=1;
x=t;
for wn = w
fx(cnt)=Fw*exp(1j*wn*x)'*dw/(2*pi);
cnt = cnt+1;
end
c=fix(length(w)/2);
subplot(3,1,1);
plot(w(c:end),abs(FwTmp(c:end)),'b','LineWidth',3);
xlim([w(c),w(end)]);
grid();
subplot(3,1,2);
plot(w(c:end),abs(Fw(c:end)),'b','LineWidth',3);
xlim([w(c),w(end)]);
grid();
subplot(3,1,3);
hold on;
%plot(t,ft,'b','LineWidth',5);
fx=real(fx);
max_fx=max(fx);
max_ft=max(ft);
plot(t, ft,'k');
plot(t,fx*(max_ft/max_fx),'r','LineWidth',2);
xlim([t(1),t(end)]);
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);
mode = 1;
end
fxTmp=fx(i);
end
if mode == 1
if fx(i)<fxTmp
maxima(i)=ft(i);
mode = 0;
end
fxTmp=fx(i);
end
end
maxima(maxima==0)=NaN; % 極大値だけを残す
minima(minima==0)=NaN; % 極小値だけを残す
plot(t, maxima,'ro') % 極大値をplot
plot(t, 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);
stock_maxima=stock(maxima_index); % 極大値要素のみ抽出
stock_minima=stock(minima_index); % 極大値要素のみ抽出
format longG
fprintf('stock_maxima value: ');
disp(round(stock_maxima'*127)); % $1=\127
fprintf('stock_minima value: ');
disp(round(stock_minima'*127)); % $1=\127
format
コードを見て
うん。
いいんじゃん?
極値特定は以前のコードをほぼコピペだねー。
まぁコピペするにも、どこで何してるか分からないと難しいもんだねー。
そりゃそうだろうね。
小規模なコードではあるが、
やってる内容としてはそこそこのことしてるからね。
コード量より扱ってるデータの規模の方がコード難易度に跳ね返り易い。
なるほど。
言われてみるとそんな気がしてきた。
次回はこれの動確だな。
まとめ
まとめだよ。
- 個別株チャート 8.4[Hz]から11.8[Hz]を抽出した上での極値特定 MATLAB版を作成。
- 基本、FFT,IFFTで極値特定のロジックをコピペ。
- ただし、コード内のどこで何をやってるか分かって無いとコピペもできない。
- コードの難易度はコード量よりデータ規模の方に相関性がある。
バックナンバーはこちら。
コメント