Ik had afgelopen dagen beloofd om een stukje code te plaatsen wat ik gebruik bij dit onderzoek.
Het idee kwam niet van mezelf, u kan het lezen in het werk van Henry Ludwell Moore en om precies te zijn in zijn in 1914 geschreven boek: 'Economic Cycles: Their Law and Couse'.
Op pagina 12 en 13 vind u zijn uitwerking van het idee van Fourier.
A0, A1 en B1 zijn de formules die ik gebruik in dit stukje code.
Ik zag dat dit boekwerk niet meer te vinden is onder bovenstaande link.
Omdat het boek vrij beschikbaar is in: -the public domain- heb ik het op mijn website gezet als een pdf.
De pdf start met een zwart scherm / pagina.
Met deze code moet u niet gaan handelen, het is alleen maar bedoelt om een idee te geven, het moet verder uitgewerkt worden voordat u er echt wat mee kan.
Ook het input filter wat ik in deze versie gebruik zal ik waarschijnlijk gaan vervangen door iets anders, ik loop te kijken op de wikipedia site:
Hieronder het stukje code, bedenk dat ik niet kan programmeren maar net zolang knutsel totdat er iets uitkomt
Er kunnen stukjes in de code staan die niet meer gebruikt worden maar een restant zijn van eerder stukje code.
Code: Selecteer alles
{- Filename: FFT-proef -}
// Fast Fourier transformatie
// ideeën voor verdere uitwerking
// www.jstas.com
// versie 1.00
// 06-09-2015
Type
TStrength = record
Index: integer;
Value: real;
End;
TTabelStrength = array of TStrength;
Var
Tllr,MaxCycle,Squelch : Integer;
SquelchNiv : Real;
HpsC, FiltC : TSeries;
OutputFilter : Boolean;
TabelA1 : Array [0..300] Of Extended;
TabelB1 : Array [0..300] Of Extended;
TopValue : Array[0..300] Of Integer;
Spectrum,Spectrum2,sHulp : TSeries;
StrengthUnSort,TabelStrength: TTabelStrength;
//******************************************************************************
Procedure Init(DatB,DatE:TDateTime);
Begin
With Indicator Do
Begin
RequiredBars := 2*Trunc(DatE-DatB);
If (RequiredBars<600) Then RequiredBars := 600;
End;
End;
//******************************************************************************
Function A_zero(DatB,DatE:TDateTime):Real;
Var
i : Integer;
Begin
Tllr := 0;
For i := 1 To BarCount-1 Do
Begin
If (DateTime[i] >= DatB) And (DateTime[i]<= DatE)Then
Begin
If IsValid(FiltC[i]) Then
Begin
Tllr := Tllr+1;
Result := (Result + FiltC[i]);
End;
End;
End;
If (Tllr>0) Then Result := Result/Tllr;
End;
//******************************************************************************
Function A_one(Mcycle,Cycle:Integer;DatB,DatE:TDateTime):Real;
Var
i,Sample: Integer;
Begin
For i := 0 To BarCount-1 Do
Begin
If (DateTime[i] >= DatB) And (DateTime[i]<= DatE) Then
Begin
Result := Result+((2/Mcycle)*FiltC[i]*Cos((2*Pi*Sample/Cycle)));
Sample := Sample+1;
End;
End;
Result := Result/Cycle;
End;
//******************************************************************************
Function B_one(Mcycle,Cycle:Integer;DatB,DatE:TDateTime):Real;
Var
i,Sample : Integer;
Begin
For i:= 0 To BarCount-1 Do
Begin
If (DateTime[i] >= DatB) And (DateTime[i]<= DatE) Then
Begin
Result := Result+((2/Mcycle)*FiltC[i]*Sin((2*Pi*Sample/Cycle)));
Sample := Sample +1;
End;
End;
Result := Result/Cycle;
End;
//******************************************************************************
Procedure QSortTabel(Tabel: TTabelStrength;Left,Right:Integer);
Var
Pivot: TStrength;
p_ptr, l_ptr, r_ptr: integer;
Begin
l_ptr := left;
r_ptr := right;
pivot := Tabel[left];
While left < right do
Begin
While (Tabel[right].Value <= pivot.Value) and (left < right) do dec(right);
If left <> right Then
Begin
Tabel[left] := Tabel[right];
inc(left);
End;
While (Tabel[left].Value >= pivot.Value) and (left < right) do inc(left);
If left <> right Then
Begin
Tabel[right] := Tabel[left];
dec(right);
End;
End;
Tabel[left] := pivot;
p_ptr := left;
left := l_ptr;
right := r_ptr;
If left < p_ptr Then QSortTabel(Tabel, left, p_ptr-1);
If right > p_ptr Then QSortTabel(Tabel, p_ptr+1, right);
End;
//******************************************************************************
Procedure SortTabel(Var Tabel: TTabelStrength);
Var
lTabel: Integer;
Begin
lTabel := GetArrayLength(Tabel);
If lTabel > 0 Then QSortTabel(Tabel, 0, lTabel-1);
End;
//*****************************************************************************
Function Sinus(Per:Integer;Ampl,Fase:Real):TSeries;
Var
i : Integer;
Begin
For i := 0 To BarCount-1 Do
Begin
Result[i] := Sin(2*Pi*(i+fase)/Per)*Ampl;
End;
End;
//******************************************************************************
Function Ehlersband(sData:TSeries;SelectFilter,vHp,vLp:Integer):Tseries;
Var
i : Integer;
c1,c2,c3,Alpha1,PerLl : Double;
Begin
HpsC := FillSeries(CreateSeries(BarCount),0);
PerLl := 1/vLp;
Alpha1 := (Cos(Sqrt(2)*Pi/vHp)+Sin(Sqrt(2)*Pi/vHp)-1)/Cos(Sqrt(2)*Pi/vHp);
c1 := (1-2*Exp(-PerLl*Sqrt(2)*Pi)*Cos(PerLl*Sqrt(2)*Pi)
+Sqr(Exp(-PerLl*Sqrt(2)*Pi)));
c2 := 2*Exp(-PerLl*Sqrt(2)*Pi)*Cos(PerLl* Sqrt(2)*Pi);
c3 := Sqr(Exp(-PerLl*Sqrt(2)*Pi));
If (SelectFilter=0) Or (SelectFilter=1)Then
Begin
For i := 2 To BarCount-1 Do
Begin
HpsC[i] := Sqr(1-Alpha1/2)*(sData[i]-2*sData[i-1] + sData[i-2])+
2*(1-Alpha1)*HpsC[i-1]-Sqr(1-Alpha1)*HpsC[i-2];
End;
End;
If (SelectFilter=2) Then HpsC := sData;
If (SelectFilter=0) Or (SelectFilter=2) Then
Begin
For i := 3 To BarCount-1 Do
Begin
Result[i] := c1*0.5*(HpsC[i]+HpsC[i-1])+c2*FiltC[i-1]-c3*FiltC[i-2];
End;
End;
If (SelectFilter=1) Then Result := HpsC;
End;
//******************************************************************************
Procedure FillTables_A1_A2(DatB,DatE:TDateTime);
Var
j,n: Integer;
hlpA,HlpB : Extended;
Begin
HlpA:=0;
HlpB:=0;
For j := 3 To MaxCycle Do
Begin
N := Trunc(Tllr/j)*j;
If N<1 Then N:=1;
TabelA1[j]:=A_one(N,j,DatB,DatE);
TabelB1[j]:=B_one(N,j,DatB,DatE);
TabelStrength[j].Index := j;
StrengthUnSort[j].Index := j;
TabelStrength[j].Value := Sqrt(Sqr(TabelA1[j])+Sqr(TabelB1[j]));
StrengthUnSort[j].Value := Sqrt(Sqr(TabelA1[j])+Sqr(TabelB1[j]));
End;
End;
//******************************************************************************
Procedure SpecTrumWeergHor(Display:Integer);
Var
Hulp,i,j : Integer;
Deler : Real;
Weergave : Array[1..300] Of TDateTime;
Begin
If (Display=0) Then sHulp := MultiplySeriesBy(RSI(C,14),(MaxCycle/100));
Deler := TabelStrength[0].Value/300;
If (Deler <=0) Then Deler := 1;
j:= 300;
If BarCount>=300 Then Begin
For i := BarCount-300 To BarCount-1 Do
Begin
Weergave[j] := DateTime[i];
j := j-1;
End;
End;
For j := 3 To MaxCycle Do
Begin
Hulp := Trunc(Ceil(StrengthUnSort[j].Value/Deler));
If (Hulp>-0) And (Hulp<=300) Then
CreateTrendLine(now ,StrengthUnSort[j].index,
Weergave[Hulp] ,StrengthUnsort[j].Index);
End;
End;
//******************************************************************************
Procedure FillTopValueTable_sSpectrum(Display:Integer);
Var
Hlp2 : Real;
Hlp3 : Boolean;
Hlp4,i,j : Integer;
Begin
For j:= 0 To 300 Do
Begin
TopValue[j] := -1;
End;
j := 3;
If (BarCount>=MaxCycle) Then
Begin
For i := (BarCount-MaxCycle) To BarCount-1 Do
Begin
If (i=(BarCount-MaxCycle)) Then Hlp4 := i;
Spectrum[i] := StrengthUnsort[j].Value;
j := j +1;
End;
For i := (BarCount-(MaxCycle-1)) To BarCount-1 Do
Begin
If Spectrum[i] > Spectrum[i-1] Then
Begin
Hlp2 := Spectrum[i];
Hlp3 := True;
End;
If (Spectrum[i] < Spectrum[i-1]) And (Hlp3) Then
Begin
Spectrum2[i-1] := Hlp2;
Hlp3 := False;
End;
End;
End;
SquelchNiv := Squelch/100 * TabelStrength[0].Value;
If (Display=1) Then
With CreateTrendLine(0,SquelchNiv,0,SquelchNiv) Do
Begin
Color := ClRed;
X1Pct := 0;
X2Pct := 100;
End;
For i := 1 To BarCount-1 Do
Begin
If IsValid(Spectrum2[i]) Then
Begin
TopValue[i-Hlp4+3] := 1;
If (Display=1) Then
Begin
With CreateText(DateTime[i],0,IntToStr(i-Hlp4+3)) Do
Begin
Color := ClRed;
Font.Size := 8;
End;
End;
End;
End;
End;
//******************************************************************************
Function Compositie(DatB:TDateTime):TSeries;
Var
DTimeLast,cDate,rDate : TDateTime;
ValueLast : Real;
Hulp : Real;
hulpi : Boolean;
DatBi : Integer;
Sample,i,j,fhelp : Integer;
CycleDisplay,sResultA: TSeries;
FutureTable : Array[0..50] Of Real;
Begin
CycleDisplay := FillSeries(CreateSeries(BarCount+50+2),0);
Sample := 0;
sResultA := FillSeries(CreateSeries(BarCount+50+2),0);
Hulpi :=True;
For i:= 1 To BarCount-1 Do
Begin
If (DateTime[i]>=DatB) And Hulpi Then
Begin
DatBi:= i;
Hulpi := False;
End;
End;
For j := 1 To MaxCycle Do //300
Begin
Hulp :=Abs(TabelA1[j])+Abs(TabelB1[j]);
If (TopValue[j]=1) And (Hulp >=SquelchNiv) Then
Begin
For i := 0 To (BarCount-1+50+2) Do
Begin
If (i>=DatBi) THen
Begin
CycleDisplay[i] := (TabelA1[j]*Cos((2*Pi*Sample/j)))
+ (TabelB1[j]*Sin((2*Pi*Sample/j)));
CycleDisplay[i] := CycleDisplay[i] * StrengthUnsort[j].Value;
sResultA[i] := sResultA[i] + CycleDisPlay[i];
Sample := Sample +1;
End;
If (i=BarCount-1) Then DTimeLast := DateTime[i];
If (i=BarCount-1) Then ValueLast := sResultA[i];
End;
End; //topvalue
End; //j
For i := 0 To BarCount-1 Do
Begin
Result[i] := sResultA[i];
End;
For i:= BarCount To (BarCount-1+50) Do
Begin
fhelp := i-BarCount+1;
FutureTable[fhelp] := sResultA[i];
End;
/////////////////
FutureTable[0] := ValueLast;
cDate := DTimeLast;
rDate := cDate+1;
If (DayOfWeek(cDate)=6) Then rDate := cDate+3;
For i := 0 To 49 Do
Begin
With CreateTrendLine(cDate,FutureTable[i] ,rDate,FutureTable[i+1]) Do
Begin
Color := ClGreen;
Width := 2;
End;
cDate := cDate+1;
If (DayOfWeek(cDate)=7) Then CDate := cDate+2;
rDate := rDate+1;
If (DayOfWeek(rDate)=7) Then rDate := rDate+2;
End;
End;
//******************************************************************************
Procedure Series_Weergave(sSinus1,sSinus2,sSinusTot,sSpecWrgv,
sSpecWrgv2,DisplayComp,sHulp:TSeries);
//Var
//per : Integer;
Begin
With CreateLine(sSinus1) Do
Begin
Name := 'Sinus1';
Color := ClBlue;
End;
With CreateLine(sSinus2) Do
Begin
Name := 'Sinus2';
Color := ClRed;
End;
With CreateLine(sSinusTot) Do
Begin
Name := 'SinusTot';
Color := ClBlack;
End;
With CreateLine(sSpecWrgv) Do
Begin
Color := ClGray;
LineType := LtBar;
End;
With CreateLine(sSpecWrgv2) Do
Begin
Color := ClRed;
LineType := LtBar;
End;
With CreateLine(DisplayComp) Do
Begin
Color := ClPurple;
Name := 'Compositie';
End;
With CreateLine(sHulp) Do
Begin
Color := ClWhite;
Name := 'hulplijn';
End;
End;
//******************************************************************************
// **************** MAIN ************************
Var
DatBeg, DatEnd : TDateTime;
WgvSin1, WgvSin2, WgvSinT : Boolean;
sSpecWrgv, sSpecWrgv2, DisplayComp, sSinus1,
sSinus2, sSinusTot, sData1, sData2, sDataTot : TSeries;
Venster, DataKeuze, FilterKeuze, EhlerFilter : String;
Datachoice, FilterChoice, BandFilter, ValHp,
ValLp, MAper, Display, PerSin1, PerSIn2 : Integer;
A0,AmpSin1,AmpSIn2,FasSin1,FasSin2 : Real;
Begin
SetArrayLength(TabelStrength ,300);
SetArrayLength(StrengthUnSort,300);
Spectrum := CreateSeries(BarCount);
Spectrum2 := CreateSeries(BarCount);
sSpecWrgv := CreateSeries(BarCount);
sSpecWrgv2 := CreateSeries(BarCount);
sHulp := CreateSeries(BarCount);
DisplayComp := CreateSeries(BarCount);
sSinus1 := CreateSeries(BarCount);
sSinus2 := CreateSeries(BarCount);
sSinusTot := CreateSeries(BarCount);
FiltC := FillSeries(CreateSeries(BarCount),0);
sData1 := FillSeries(CreateSeries(BarCount),0);
sData2 := FillSeries(CreateSeries(BarCount),0);
sDataTot := FillSeries(CreateSeries(BarCount),0);
DataKeuze := 'Koers Fonds/Index ' #9
'Enkelvoudige Sinus' #9
'Twee-voudige Sinus' ;
FilterKeuze := 'Geen ' #9
'Ehlers band-doorlaat' #9
'MA ' ;
EhlerFilter := 'HighPass + LowPass'#9
'HighPass ' #9
'LowPass ' ;
Venster := 'Spectrum Horizontaal'#9
'Spectrum Verticaal '#9
'Sinus en/of Composite';
DatBeg := CreateParameterDate('StartDatum',EncodeDate(2013,8,20));
DatEnd := CreateParameterDate('EindDatum',Now);
Display := CreateParameterSelect('Weergave in venster:',Venster,1,False);
DataChoice :=
CreateParameterSelect('Welke Data te analyseren:',DataKeuze,0,False);
FilterChoice :=
CreateParameterSelect('Te gebruiken filter',Filterkeuze,1,False);
BandFilter :=
CreateParameterSelect('Stel Ehler filter in:',EhlerFilter,0,False);
OutputFilter := CreateParameterBoolean('Output filter gebruiken?',False,False);
ValHp := CreateParameterInteger('Waarde HighPass filter:',15,200,48,False);
ValLp := CreateParameterInteger('WaardeLowPass filter:',3,20,10,False);
MAper := CreateParameterInteger('Moving Average Period:',0,200,14,False);
Squelch := CreateParameterInteger('Squelch in % ',0,100,80,False);
WgvSin1 := CreateParameterBoolean('Sinus-1 Weergeven?',True,False);
WgvSin2 := CreateParameterBoolean('Sinus-2 Weergeven?',True,False);
WgvSinT := CreateParameterBoolean('Sinus-Opgeteld Weergeven?',True,False);
PerSin1 := CreateParameterInteger('Periode Sinus-1:',1,300,30,False);
AmpSin1 := CreateParameterReal('Amplitude Sinus-1:',0.1,10000,100,False);
FasSin1 := CreateParameterReal('Fase Sinus-1:',0,1000,0,False);
PerSIn2 := CreateParameterInteger('Periode Sinus-2:',1,300,52,False);
AmpSIn2 := CreateparameterReal('Amplitude Sinus-2:',0.1,10000,100,False);
FasSin2 := CreateParameterReal('Fase Sinus-2:',0,1000,0,False);
Case DataChoice Of
0: sDataTot := C;
1: Begin
sData1 := Sinus(PerSin1,AmpSin1,FasSin1);
sDataTot := sData1;
If WgvSin1 And (Display=2) Then sSinus1 := sData1;
End;
2: Begin
sData1 := Sinus(PerSin1,AmpSin1,FasSin1);
sData2 := Sinus(PerSin2,AmpSin2,FasSin2);
sDataTot := AddSeries(sData1,sData2);
If (Display=2) Then
Begin
If WgvSin1 Then sSinus1 := sData1;
If WgvSin2 Then sSinus2 := sData2;
If WgvSinT Then sSinusTot := sDataTot;
End;
End;
End;
Case FilterChoice Of
0 : FiltC := sDataTot;
1 : FiltC := EhlersBand(sDataTot,BandFilter,ValHp,ValLp);
2 : FiltC := MA(sDataTot,MAWeighted,MAper);
End;
Init(DatBeg,DatEnd);
A0 := A_zero(DatBeg,DatEnd); //return Tllr
MaxCycle := CreateParameterInteger('Maximale cycl:',3,300,100,False);
If (MaxCycle>(Tllr/2)) Then MaxCycle := Trunc(Tllr/2);
If (MaxCycle<1) Then MaxCycle := 3;
FillTables_A1_A2(DatBeg,DatEnd);
SortTabel(TabelStrength);
FillTopValueTable_sSpectrum(Display);
Case Display Of
0 : SpectrumWeergHor(Display);
1 : Begin
sSpecWrgv := Spectrum ;
sSpecWrgv2 := Spectrum2;
End;
2 : DisplayComp := Compositie(DatBeg);
End;
Series_Weergave(sSinus1, sSinus2, sSinusTot, sSpecWrgv,
sSpecWrgv2, DisplayComp, sHulp);
End.
.