マクロ(独自トレード・システムの作成)
逆ウオッチ曲線(住特金)
ユーザーが自由にトレードシステムを設計出来るよう、Fchartに高度なマクロを搭載しました。
Fchartの上に、新たなシステム記述用言語を搭載し、ユーザーは用意された関数や自由に
定義できる関数などを使用して、独自のトレードシステムを作成することが可能です。
マクロのマニュアルと全サンプル(Macro.chm)
詳しいことは、上記のマニュアルをご覧ください。
Fchartマクロで出来ること
1.ユーザー独自のチャート、指数、テクニカル売買のサインを自由に作成、表示することが可能です。
2.整数、浮動小数点、文字列に対応した、単純変数から2次元、3次元など高次の配列変数、自由な
記述が可能です。
3.数百の組み込み関数に加えて、ユーザー独自の関数の作成が可能です(再帰可)。
4.多数のサンプルを用意しています。
下記はマクロの例です(この他多数のサンプルが上記マニュアルに記載されています)。
9.ランダムウォークによるバーチャル株価による
10.ライフゲーム
マクロ専用メルマガについて
下記はマクロ専用のメールマガジンです。
マクロについての質問やマクロ例などを整理して公開します。
マクロのユーザーはぜひご参加ください。
参加、退会は下記へメールを送るだけです(件名、本文は不要です)。
投稿も可能です。 マクロの情報交換に使って下さい。
/-----------------------------------------------
/
/ P&F(ポイント&フィギュアー)
/
/ スピードボタンの「拡」を押すと拡大されます。
/ 表示範囲の変更は右上のドットボタンで行います。
/ 表示条件は、Init関数内で設定されています。
/ 売買サイン時はマークを赤で表示、その日付と株価を
/ 買いは上部、売りは、下部に表示しています。
/
/ <変数の説明>
/ waku : 転換枠数(デフォルトは3)
/ size : 1枠あたりの株価
/ TenzokoP : 天底株価
/ 枠表示時点の株価をsizeで丸めた株価、
/ この株価とsize*wakuを比較する
/ BeforeUpTenzokoP : 前回の上昇転換時の天底株価
/ BeforeDnTenzokoP : 前回の下降転換時の天底株価
/ Hoko : 現在のトレンド(スタート時=0, 上昇中=1, 下降中=-1)
/ LineNo: 行数, 転換で+1
/ xPos : 表示時点のx軸上の位置
/ IncX : 1行右移行時のドット数
/
/-----------------------------------------------
sisuname:=P&F;
DnoLoop:=off;
/下記をoffにするとローソク足を非表示にします
OrgAllChart:=on;
var xPos,IncX,Size,Waku,
TenzokoP,BeforeUpTenzokoP,BeforeDnTenzokoP,
LineNo,Hoko,w;
begin
/初期設定
Init;
writeData(red,11,10,20,'転換株価='+tostr(size)+'円 転換枠数='+tostr(waku)+'枠');
/ループ
for Dno:=StartDno+1 to EndDno do begin
w:=int(abs(Close[Dno]-TenzokoP)/size);
/下降転換
if (Hoko=1) and (Close[Dno]<=(TenzokoP-size*waku)) then
writePoint(1,blue,w,Close[Dno])
/上昇中
else if ((Hoko=0) or (Hoko=1)) and (Close[Dno]>TenzokoP) and
(w>=1) then
writePoint(2,Gray,w,Close[Dno])
/上昇転換
else if (Hoko=-1) and (Close[Dno]>=(TenzokoP+size*waku))
then
writePoint(3,Gray,w,Close[Dno])
/下降中
else if ((Hoko=0) or (Hoko=-1)) and (TenzokoP>Close[Dno]) and
(w>=1) then
writePoint(4,blue,w,Close[Dno]);
end;
end;
/--------- ユーザー関数 -----------
/初期設定
function init;
begin
/転換枠数
waku:=3;
/1枠サイズ
if Close[EndDno]<100 then size:=2.5
else if Close[EndDno]<200 then size:=5
else if Close[EndDno]<1000 then size:=10
else if Close[EndDno]<5000 then size:=20
else if Close[EndDno]<10000 then size:=100
else if Close[EndDno]<50000 then size:=200
else if Close[EndDno]<100000 then size:=1000
else if Close[EndDno]<500000 then size:=2000
else size:=10000;
/直近の天底、取り合えず初日の株価を使用
if Close[StartDno+1]>=Close[StartDno] then
TenzokoP:=int(Close[StartDno]/Size)*Size
else if Close[StartDno+1]<Close[StartDno] then
TenzokoP:=int(Close[StartDno]/Size+0.999)*Size;
BeforeUpTenzokoP:=0;
BeforeDnTenzokoP:=0;
/株価の方向 上昇中=1 下降中=2 最小は=0
Hoko:=0;
/現在行数 転換改行で+1
LineNo:=1;
/x方向の当初位置
xPos:=getX(StartDno)+200;
/x方向の増加Dot数
IncX:=AshiDot;
if IncX<10 then IncX:=10;
end;
function GetTenzokoP(P);
begin
if P>=Close[Dno-1] then
result:=int(P/Size)*Size
else if P<Close[Dno-1] then
result:=int(P/Size+0.999)*Size;
end;
function writePoint(HokoTmp,Color,w,P);
var i,y,L;
begin
/日付文字列の1/2ドット数
L:=textwidth(DnoDate(Dno),8)/2;
case HokoTmp of
/下降転換
1: begin
xPos:=xPos+IncX+4;
for i:=1 to w do begin
y:=getY(TenzokoP-size*i);
writeCircle(Color,xPos,y);
end;
Hoko:=-1;
LineNo:=LineNo+1;
y:=Random(40);
LineD(red,1,xPos,getY(TenzokoP)-5,xPos,getY(TenzokoP)-20-y);
writeData(red,8,xPos-L,getY(TenzokoP)-20-y,DnoDate(Dno));
BeforeDnTenzokoP:=TenzokoP;
end;
/上昇中
2: begin
for i:=1 to w do begin
y:=getY(TenzokoP+size*i);
if (BeforeDnTenzokoP<>0)
and ((TenzokoP+size*i)>BeforeDnTenzokoP) then begin
writeCross(red,xPos,y);
BeforeDnTenzokoP:=0;
writeData(Gray,8,xPos-L,10,DnoDate(Dno));
writeData(Gray,8,xPos-textwidth(P)/2,20,P);
end
else
writeCross(Color,xPos,y);
end;
Hoko:=1;
end;
/上昇転換
3: begin
xPos:=xPos+IncX+4;
for i:=1 to w do begin
y:=getY(TenzokoP+size*i);
writeCross(Color,xPos,y);
end;
Hoko:=1;
LineNo:=LineNo+1;
y:=Random(40);
LineD(red,1,xPos,getY(TenzokoP)+5,xPos,getY(TenzokoP)+20+y);
writeData(red,8,xPos-L,getY(TenzokoP)+20+y,DnoDate(Dno));
BeforeUpTenzokoP:=TenzokoP;
end;
/下降中
4: begin
for i:=1 to w do begin
y:=getY(TenzokoP-size*i);
if (BeforeUpTenzokoP<>0)
and ((TenzokoP-size*i)<BeforeUpTenzokoP) then begin
writeCircle(red,xPos,y);
BeforeUpTenzokoP:=0;
writeData(Blue,8,xPos-L,ChartH-70,DnoDate(Dno));
writeData(Blue,8,xPos-textwidth(P)/2,ChartH-60,P);
end
else
writeCircle(Color,xPos,y);
end;
Hoko:=-1;
end;
end;
TenzokoP:=GetTenzokoP(P);
end;
function writeCross(color,x,y);
var L;
begin
L:=IncX/2;
LineD(color,1,x-L,y-L,x+L,y+L);
LineD(color,1,x-L,y+L,x+L,y-L);
end;
function writeCircle(color,x,y);
var L;
begin
L:=IncX/2;
CircleD(color,1,x,y,L);
end;
/---------------------------------------
/
/
逆ウオッチ曲線
/
/ グラフ画面へ表示しています。
/ ユーザー定義マクロとしてで実行します。
/
/ 表示ドット数を5以上で実行してください。
/ 表示データ数が多いと表示が遅くなります。
/
/---------------------------------------
Sisuname:=逆ウオッチ曲線;
/決算データを表示するグラフ位置へ表示
UseGraphCanvas:=true;
var cx,cy,sx,sy,step,x,y,xR,yR,
maxD,maxK,
minD,minK,
i,para,
DekiAV,KabuAV;
begin
if not Kabusiki then exit;
{$definit}
cy := GraphH/2;
cx := GraphW-cy-10;
step := cy-10;
/株価、出来高をこのパラメータで移動平均
para := 25;
maxD := 0; maxK := 0;
minD := Maxint; minK := Maxint;
/para日移動平均の最大、最小値を計算、データを保存
for i := StartDno + para to EndDno do begin
DekiAV[i] := CalcAV(Deki,i-para+1,i);
KabuAV[i] := CalcAV(Close,i-para+1,i);
if DekiAV[i]>maxD then maxD := DekiAV[i];
if (DekiAV[i]<>0) and (DekiAV[i]<minD) then minD :=
DekiAV[i];
if KabuAV[i]>maxK then maxK := KabuAV[i];
if (KabuAV[i]<>0) and (KabuAV[i]<minK) then minK :=
KabuAV[i];
end;
/スタート位置(原点が左上なので左下へ変換)
sx := cx-step;
sy := cy+step;
xR := (Step * 2 / (maxD-minD));
yR := (Step * 2 / (maxK-minK));
x := xR * (DekiAV[StartDno+para]-minD);
y := yR * (KabuAV[StartDno+para]-minK);
GFillCircleD(Yellow,1,sx+x,sy-y,3);
GmovetoD(sx+x,sy-y);
Gaxis(cx,cy,-Step,Step,step,-Step,step,step);
Gwritedata(red,10,15,15,'逆ウオッチ曲線');
Gwritedata(green,10,15,35,'開 始 日='+DnoDate(StartDno));
Gwritedata(green,10,15,50,'終 了 日='+DnoDate(EndDno));
Gwritedata(green,10,15,65,'データ数='+tostr(EndDno-StartDno)+'件');
Gwritedata(yellow,10,15,83,'移動平均 = '+tostr(para));
{$defend}
if Dno>(StartDno+para) then begin
x := xR * (DekiAV[Dno]-minD);
y := yR * (KabuAV[Dno]-minK);
GlineToD(red,1,sx+x,sy-y);
end;
end;
/--------------------------------------
/
/
ラリー・ウィリアム
/
/ 相場で設ける法 第10章ゼロ・バランス
/
/--------------------------------------
sisuname:=ゼロ・バランス;
orgIdoHeikin:=Off;
var varA,varB,varC,varD,varE,varF,varG,varH;
begin
/変数初期化
{$definit}
varC:=Maxint;
varE:=0;
/IRフラグ 1で高値決定、2で安値決定
varG:=0;
vara:=0;
{$defend}
/直近安値とその時のDnoを保存
if ((varG=0) or (varG=1)) and (NowL<varC) then begin
varC:=NowL;
varD:=Dno;
end;
/直近高値とその時のDnoを保存
if ((varG=0) or (varG=2)) and (NowH>varE) then begin
varE:=NowH;
varF:=Dno;
end;
/高値、安値決定フラグ
varH:=0;
/過去7日間の安値を下回ったら、IR高値決定
if ((varG=0) or (varG=2))
and (NowL<YasuneL1(7)) then begin
/IR高値保存
varA:=varA+1;
UserTemp1[varA]:=varE;
UserTemp2[varA]:=varF;
/IR作図
line(white,1,Dno,(UserTemp2[varA-1]-Dno)*RosokuW,UserTemp1[varA-1],
(UserTemp2[varA]-Dno)*RosokuW,UserTemp1[varA]);
varG:=1;
varH:=1;
/次回IR候補の安値と位置を保存
varC:=NowE;
varD:=Dno;
/ゼロバランス
if (varA>5) then begin
UserTemp3[varA]:=UserTemp1[varA-2]+UserTemp1[varA-3]-UserTemp1[varA-5];
UserTemp4[varA]:=varF;
line(blue,1,Dno,(UserTemp4[varA-1]-Dno)*RosokuW,UserTemp3[varA-1],
(UserTemp4[varA]-Dno)*RosokuW,UserTemp3[varA]);
end;
end
/過去7日間の高値を上回ったら、IR安値決定
else if ((varG=0) or (varG=1)) and (NowH>TakaneH1(7)) then begin
/IR安値保存
varA:=varA+1;
UserTemp1[varA]:=varC;
UserTemp2[varA]:=varD;
/IR作図
line(white,1,Dno,(UserTemp2[varA-1]-Dno)*RosokuW,UserTemp1[varA-1],
(UserTemp2[varA]-Dno)*RosokuW,UserTemp1[varA]);
varG:=2;
varH:=1;
/次回IR候補の高値と位置を保存
varE:=NowE;
varF:=Dno;
/ゼロバランス
if (varA>5) then begin
UserTemp3[varA]:=UserTemp1[varA-2]+UserTemp1[varA-3]-UserTemp1[varA-5];
UserTemp4[varA]:=varD;
line(blue,1,Dno,(UserTemp4[varA-1]-Dno)*RosokuW,UserTemp3[varA-1],
(UserTemp4[varA]-Dno)*RosokuW,UserTemp3[varA]);
end;
end;
/最終ゼロバランスの作図
/最終x座標位置は未定なので仮に指定(+7,+14)
if (Dno=EndDno) and (varA>5) then begin
/7番目のゼロバランス
varB:=UserTemp1[varA-1]+UserTemp1[varA-2]-UserTemp1[varA-4];
line(blue,1,Dno,(UserTemp4[varA]-Dno)*RosokuW,UserTemp3[varA],
(UserTemp4[varA]-Dno+7)*RosokuW,varB);
/8番目のゼロバランス
varC:=UserTemp1[varA]+UserTemp1[varA-1]-UserTemp1[varA-3];
line(blue,1,Dno,(UserTemp4[varA]-Dno+7)*RosokuW,varB,
(UserTemp4[varA]-Dno+14)*RosokuW,varC);
end;
end;
/------------------------------------------------------
/
/ HLバンドによる、売買シミュレーション
/
/ 組み込み関数を使用せず、独自売買の関数を作成しました
/ 取引の記録、損益計算、出力まで独自に行っています。
/ 新しい機能を追加して拡張してください。
/
/ 組込関数 新規作成関数
/ Buy --> UserBuy
/ Sell -->
UserSell
/ Tenbai --> UserTenbai
/ Kaimodoshi --> UserKaimodoshi
/
/------------------------------------------------------
/---------------------------------
/
環境定義
/---------------------------------
SisuName:=HLバンド+ユーザーBuy,Sell関数;
OrgIdoHeikin:=off;
sisucolor1:=red;
sisucolor2:=green;
sisucolor3:=maroon;
sisucolor4:=blue;
/---------------------------------
/
メイン
/---------------------------------
var count; //取引回数を記録
/取引内容を保存する変数
/torihiki[1,*]:建玉日付
/torihiki[2,*]:手仕舞日付
/torihiki[3,*]:買=1,売=2
/torihiki[4,*]:未処理=0,手仕舞い=1
/torihiki[5,*]:翌日始値の株価
/torihiki[6,*]:手仕舞い株価
/torihiki[7,*]:株数
torihiki;
TejimaiAtEnd, //最終日での手仕舞いフラグ
varA,varB,
i,kabusu,soneki,temp;
begin
/グローバル変数の初期化
{$definit}
InitVar;
{$defend}
/買いのHLバンドを描く(varA,varB)
usersisu1[Dno]:=TakaneH1(varA); //買い線
usersisu2[Dno]:=YasuneL1(varB); //手仕舞い線
/買い株と手仕舞い
if CheckExistBuy(Dno) and (nowH>TakaneH1(varA)) then
UserBuy(Dno,count);
if nowL<YasuneL1(varB) then UserTenbai(Dno,count);
/売りのHLバンドを描く(varA,varB)
/買いと同時に描くと見ずらいので、仮にコメント処理
/usersisu3[Dno]:=YasuneL1(varA); //売り線
/usersisu4[Dno]:=TakaneH1(varB); //手仕舞い線
/売り株と手仕舞い
if CheckExistSell(Dno) and (nowL<YasuneL1(varA)) then
UserSell(Dno,count);
if nowH>TakaneH1(varB) then UserKaimodoshi(Dno,count);
/取引結果の計算と表示
{$defresult}
if TejimaiAtEnd then begin
UserTenbai(Dno,count);
UserKaimodoshi(Dno,count);
end;
writeTorihikiAll(Torihiki,Soneki);
{$defend}
end;
/---------------------------------
/
ユーザー関数
/---------------------------------
/グローバル変数を初期化
function InitVar;
begin
//1000株単位
kabusu:=1000;
/買い仕掛日数
varA:=40;
/仕切り日数
varB:=20;
/最終日での手仕舞い処理のフラグ
TejimaiAtEnd:=true;
end;
/最終取引が未決済でtrue
function CheckExistBuy(Dno);
begin
result:=true;
/最初の取引ならtrue
if count=0 then exit;
/最新取引が手仕舞い済みならtrue
if (torihiki[1,count]<>'') and (torihiki[3,count]=2)
and (torihiki[6,count]<>'') then exit;
result:=false;
end;
/最終取引が未決済でtrue
function CheckExistSell(Dno);
begin
result:=true;
/最初の取引ならtrue
if count=0 then exit;
/最新取引が手仕舞い済みならtrue
if (torihiki[1,count]<>'') and (torihiki[3,count]=1)
and (torihiki[6,count]<>'') then exit;
result:=false;
end;
//買い
function UserBuy(Dno;var count);
begin
count:=count+1;
torihiki[1,count]:=DnoDate(Dno);
torihiki[3,count]:=1;
torihiki[4,count]:=0;
//サインが最終日は株価はゼロ
if Dno=EndDno then
torihiki[5,count]:=0
//最終日以外は、翌日始値
else
torihiki[5,count]:=NowS(Dno+1);
torihiki[7,count]:=kabusu;
writeMark(Dno,1,0);
end;
//買株の転売
function UserTenbai(Dno;var count);
var f,i,Ksum;
begin
/未処理株の手仕舞い
Ksum:=0;
/手仕舞いが1件でも発生したら1に
f:=0;
for i:=1 to count do
if ((torihiki[1,i]<>'')
and (torihiki[3,i]=1) and
(torihiki[4,i]=0))
or (TejimaiAtEnd and (Dno=EndDno))
then begin
torihiki[4,i]:=1;
/手仕舞い株価を翌日始値とする
if Dno<EndDno then torihiki[6,i]:=NowS(Dno+1)
else torihiki[6,i]:=NowE;
torihiki[2,i]:=DnoDate(Dno);
Ksum:=Ksum+(torihiki[6,i]-torihiki[5,i])*torihiki[7,i];
f:=1;
end;
if f=1 then
writeMark(Dno,3,Ksum);
end;
//売り
function UserSell(Dno;var count);
begin
count:=count+1;
torihiki[1,count]:=DnoDate(Dno);
torihiki[3,count]:=2;
torihiki[4,count]:=0;
//サインが最終日は株価はゼロ
if Dno=EndDno then
torihiki[5,count]:=0
//最終日以外は、翌日始値
else
torihiki[5,count]:=NowS(Dno+1);
torihiki[7,count]:=kabusu;
writeMark(Dno,2,0);
end;
//売り株の買戻し
function UserKaimodoshi(Dno;var count);
var f,i,Usum;
begin
/未処理株の手仕舞い
Usum:=0;
/手仕舞いが1件でも発生したら1に
f:=0;
for i:=1 to count do
if ((torihiki[1,i]<>'')
and (torihiki[3,i]=2) and
(torihiki[4,i]=0))
or (TejimaiAtEnd and (Dno=EndDno))
then begin
torihiki[4,i]:=1;
/手仕舞い株価を翌日始値とする
if Dno<EndDno then torihiki[6,i]:=NowS(Dno+1)
else torihiki[6,i]:=NowE;
torihiki[2,i]:=DnoDate(Dno);
Usum:=Usum+(torihiki[5,i]-torihiki[6,i])*torihiki[7,i];
f:=1;
end;
if f=1 then
writeMark(Dno,4,Usum);
end;
/種別毎のマーク
function writeMark(Dno,kind,p);
var x,y;
begin
x:=GetX(Dno);
y:=ChartH*0.15;
case kind of
//UserBuy
1: begin
RectAngleD(red,1,x-4,y-4,x+4,y+4);
lineD(red,1,x,y+4,x,y+10);
end;
//UserSell
2: begin
RectAngleD(green,1,x-4,y-4,x+4,y+4);
lineD(green,1,x,y+4,x,y+10);
end;
//UserTenbai
3: begin
fillRectD(green,1,x-4,y-4,x+4,y+4);
lineD(green,1,x,y+4,x,y+10);
if p<>0 then
writefig(x,y-20,tostr(p/1000));
end;
//UserKaimodoshi
4: begin
fillRectD(red,1,x-4,y-4,x+4,y+4);
lineD(red,1,x,y+4,x,y+10);
if p<>0 then
writefig(x,y-20,tostr(p/1000));
end;
end
end;
/サインの上部に損益を表示
function writeFig(x,y,pstr);
begin
x:=x-textwidth(pstr)/2;
if bkcolor=black then
writedata(white,9,x,y,pstr)
else
writedata(black,9,x,y,pstr)
end;
/取引の内容と損益をmemoへ出力
function writeTorihikiAll(tirihiki; var soneki);
var c,i,w,temp,win,loss;
begin
writememo('建日 買/売 株価 株数 手仕舞日 損益');
soneki:=0;
c:=0;
win:=0;
loss:=0;
for i:=1 to count do
if torihiki[1,i]<>'' then begin
c:=c+1;
temp:=torihiki[1,i]+' ';
if torihiki[3,i]=1 then temp:=temp+'買い '
else temp:=temp+'売り ';
temp:=temp+tostr(torihiki[5,i],8,0)+'
'+tostr(torihiki[7,i],8,0)+' ';
if torihiki[2,i]='' then temp:=temp+' '
else temp:=temp+torihiki[2,i]+' ';
if torihiki[6,i]<>0 then begin
if torihiki[3,i]=1 then begin
temp:=temp+'
'+tostr((torihiki[6,i]-torihiki[5,i])*torihiki[7,i],8,0);
if torihiki[6,i]>torihiki[5,i] then win:=win+1
else loss:=loss+1
end
else begin
temp:=temp+'
'+tostr((torihiki[5,i]-torihiki[6,i])*torihiki[7,i],8,0);
if torihiki[6,i]<torihiki[5,i] then win:=win+1
else loss:=loss+1
end
end;
writememo(temp);
if torihiki[3,i]=1 then
soneki:=soneki+(torihiki[6,i]-torihiki[5,i])*torihiki[7,i]
else
soneki:=soneki+(torihiki[5,i]-torihiki[6,i])*torihiki[7,i];
end;
writememo('');
writememo('総損益 '+tostr(soneki/1000,8,0));
temp:='取引回数 = '+tostr(c)+'回(勝='+tostr(win)+'負='+tostr(loss)
+') 総損益
= '+tostr(soneki/1000)+'千円';
w:=textwidth(temp)/2;
if soneki<0 then
writeData(red,12,chartw/2-w,15,temp)
else
writeData(green,12,chartw/2-w,15,temp);
end;
/------------------------------------------------
/
/ ユーザー関数ライブラリーを使った3点チャージ
/ Fchartの3点チャージと同じです。
/
/------------------------------------------------
/実行条件の定義
SisuName:=3点チャージ(Kairi=25:-15,VR=25:70,RSI=14:25);
/計算開始をDno-50に設定
SetStartDno:=50;
var KairiP,VrP,RsiP;
fnRSI,fnVR,fnKairi;
begin
/----- 初期値設定があればこの中に記載 ----------
{$definit}
KairiP:=26;
VrP :=25;
RsiP :=14;
CalcKairi(KairiP,fnKairi);
CalcVR(VrP,fnVR);
CalcRSI(RsiP,fnRSI);
{$defend}
/----- マクロ本体(Dnoによるループ) --------------
if (fnKairi[Dno]<=-15) and (fnVR[Dno]<=70)
and (fnRSI[Dno]<=25) then writeUnderMark(Dno);
/print(DnoDate,fnKairi[Dno],fnVR[dno],fnRSI[dno]);
end;
/------------------- ユーザー関数 -----------------------
/
/
下記の関数は、ユーザー関数ライブラリーにあるものと同じです。
/
/-------------------------------------------------------
function CalcVR(p;var fnVR);
var stDno,Dn,k,
sumUp,sumD,sumSame;
begin
if (StartDno<=p) then stDno:=p
else stDno:=startDno;
for Dn:=StDno to EndDno do begin
sumUp:=0; sumD:=0; sumSame:=0;
for k:=Dn-p+1 to Dn do begin
sumD:=sumD+Dekidaka(k);
if NowE(k)>NowE(k-1) then
sumUp:=sumUp+Dekidaka(k)
else if NowE(k)=NowE(k-1) then
sumSame:=sumSame+Dekidaka(k);
end;
fnVR[Dn]:=((sumUp+SumSame/2)/sumD)*100;
end;
end;
function CalcKairi(p;var fnKairi);
var stDno,Dn,fnSMA;
begin
CalcSMA(p,fnSMA);
if StartDno<=p then stDno:=p
else stDno:=StartDno;
for Dn:=StDno to EndDno do
fnKairi[Dn]:=((NowE(Dn)-fnSMA[Dn])/fnSMA[Dn])*100;
end;
/単純移動平均
function CalcSMA(p; var fnSMA);
var Dn,stDno;
begin
if StartDno<=p then stDno:=p
else stDno:=StartDno;
for Dn:=StDno to EndDno do
fnSMA[Dn] := CalcAV('close',Dn-p+1,Dn);
end;
/RSIの計算
function CalcRSI(p; var fnRSI);
var i,k,up,sumall;
begin
if p=0 then exit;
for i:=StartDno to EndDno do begin
up:=0;
sumall:=0;
if i>1 then
for k:=i-p+1 to i do begin
if NowE(k)>NowE(k-1) then
up:=up+NowE(k)-NowE(k-1);
sumall:=sumall+abs(NowE(k)-NowE(k-1));
end;
fnRSI[i]:=(up/sumall)*100;
end;
end;
/種別毎のマーク
function writeUnderMark(Dno);
var x,y;
begin
x:=GetX(Dno);
y:=ChartH*0.75;
fillrectD(red,1,x-Dw,y-2,x+Dw,y+2);
end;
ベクトル
/-------------------------------------------------
/ ベクトル
/
/ 株価の変化率を回帰式で計算表示したものです。
/ ベクトルの位置、変化で点底、転換点を判断します。
/ 詳細はインターネットで調べてください。
/
/ これはユーザー定義チャート用ですが、指数マクロ
/ としても表示可能です。
/
/--------------------------------------------------
sisuname:=ベクトル;
SisuDispPos:=Dekidaka;
DispDekidaka:=false;
var a,b;
begin
{$definit}
/パラメータ(5日,13日の2本表示)
a:=5;
b:=13;
{$defend}
usersisu1[Dno]:=CalcVector(a);
usersisu2[Dno]:=CalcVector(b);
/デバッグ用、Runボタンで画面下部へ経過データ表示
/debugout(DnoDate(Dno),' ',usersisu1[Dno],' ',usersisu2[Dno]);
end;
function CalcVector(p);
var a,c,i,ang;
xsum,xxsum,
ysum,yysum,
xysum,
xavr,yavr;
begin
result:=0;
if Dno<=p then exit;
c:=0;
xsum:=0; xxsum:=0;
ysum:=0; yysum:=0;
xysum:=0;
for i:=Dno-p+1 to Dno do begin
c:=c+1;
xsum :=xsum+c;
xxsum:=xxsum+c*c;
ysum :=ysum+Close[i];
yysum:=yysum+Close[i]*Close[i];
xysum:=xysum+c*Close[i];
end;
xavr:=xsum/p;
yavr:=ysum/p;
a:=(xysum-xsum*yavr)/(xxsum-xsum*xavr);
result:=(a/yavr)*1000;
end;
/--------------------------------------------
/ MACDを求める
/ 移動平均・収束・拡散トレーディング手法
/---------------------------------------------
/指数の名前
SisuName:=MACD;
/転換マークの指定
SisuMarkNo:=30,-30;
SisuMemoriNo:=2;
Var varA,varB,varC;
begin
/パラメータの用意
varA:=20;
varB:=42;
varC:=9;
/varAのEMAを求める
/前日EMAがゼロの場合は単純移動平均を使用
if UserTemp1[Dno-1]=0 then
/前日の移動平均
UserTemp1[Dno]:=SumKabuE(varA)/varA
else
/2日以降は前日のEMAを使用
UserTemp1[Dno]:=UserTemp1[Dno-1]+(2/(varA+1))*(NowE-UserTemp1[Dno-1]);
/varBのEMAを求める
/前日EMAがゼロの場合は単純移動平均を使用
if UserTemp2[Dno-1]=0 then
/前日の移動平均
UserTemp2[Dno]:=SumKabuE(varB)/varB
else
/2日以降は前日のEMAを使用
UserTemp2[Dno]:=UserTemp2[Dno-1]+(2/(varB+1))*(NowE-UserTemp2[Dno-1]);
/varAとvarBの差を作図(UserTemp1[Dno]-UserTemp2[Dno])、
/また、この差のVarC期間の移動平均を作図
/Macd
UserTemp3[Dno]:=UserTemp1[Dno]-UserTemp2[Dno];
SisuColor1:=red;
UserSisu1[Dno]:=UserTemp3[Dno];
/varA-varBのvarC移動平均を作図
SisuColor2:=maroon;
UserSisu2[Dno]:=CalcAV('Usersisu1',Dno-varC);
end;
MM法
/----------------------------------------------------
/
/ MM法 増田正美著 <個人投資家の復権>参照
/ ISBN4-620-31638-5
/
/ ただし、同書のMACDの判定の内、MACDとシグナルの
/ 最大乖離はチェックしていません。
/
/ 各指数はユーザー関数ライブラリーを使用しています。
/
/ 売買モードの選択することが出来ます。
/ Mode を指定してください。
/ Mode=1 サインのみ表示
/ Mode=2
最初のサインで売買、次の反対サインでドテン処理、トレード処理と損益を計算
/
/----------------------------------------------------
SisuName:=MM法;
/sisupriod:=24month; //検索のときは2MonthでOK
/計算を画面左端からさらに100引いた点から計算を行う
SetStartDno:=120;
var fnIdo, fnHensa;
fnPDI,fnMDI, fnADX, fnADXR;
fnRSI;
fnMacd, fnSig, fnOsc;
Mode;
begin
{$definit}
CalcBollinger(20, fnIdo ,fnHensa);
CalcDMI(1, fnPDI , fnMDI, fnADX, fnADXR);
CalcRSI(13,fnRSI);
CalcMACD(12,26,9, fnMacd, fnSig, fnOsc);
/売買モードの指定
Mode:=1; //サインのみ表示
{$defend}
if (NowE(Dno)<(fnIdo[Dno]-fnHensa[Dno]*2))
and (fnRSI[Dno]<25)
and (fnADX[Dno]>75)
and checkMACDLOW(Dno,fnMacd[Dno]) then begin
case Mode of
1: buy;
2: buydoten;
end;
end;
if (NowE(Dno)>(fnIdo[Dno]+fnHensa[Dno]*2))
and (fnRSI[Dno]>75)
and (fnADX[Dno]>75)
and checkMACDHIGH(Dno,fnMacd[Dno]) then begin
case Mode of
1: sell;
2: selldoten;
end;
end;
end;
/ユーザー関数ライブラリー
/Bollingerの計算
function CalcBollinger(p; var fnIdo, fnHensa);
var Dn,stDno;
begin
if StartDno<=p then stDno:=p
else stDno:=StartDno;
for Dn:=StDno to EndDno do begin
/移動平均
fnIdo[Dn] :=CalcAV('close',Dn-p+1,Dn);
/標準偏差
fnHensa[Dn]:=HyojunHensa(Dn-p+1,Dn);
end;
end;
/DMIの計算
function CalcDMI(p; var fnPDI, fnMDI, fnADX, fnADXR);
var k,stDno,Dn,TR,
PDMsum,MDMsum,ADXsum,
PDM,MDM,uDX;
begin
if StartDno<=1 then stDno:=2
else stDno:=StartDno;
for Dn:=StDno to EndDno do begin
PDM[Dn]:=NowH(Dn)-NowH(Dn-1);
MDM[Dn]:=NowL(Dn-1)-NowL(Dn);
/はらみなどは方向性なしとする
if PDM[Dn]>MDM[Dn] then MDM[Dn]:=0
else if PDM[Dn]<MDM[Dn] then PDM[Dn]:=0
else if PDM[Dn]=MDM[Dn] then begin
PDM[Dn]:=0;
MDM[Dn]:=0;
end
else if (PDM[Dn]<0) and (MDM[Dn]<0) then begin
PDM[Dn]:=0;
MDM[Dn]:=0;
end;
if Dn>p then begin
PDMsum:=0;
MDMsum:=0;
for k:=Dn-p+1 to Dn do begin
PDMsum:=PDMsum+PDM[k];
MDMsum:=MDMsum+MDM[k];
end;
TR:=TrueRange(Dn-p+1,Dn);
fnPDI[Dn]:=(PDMsum/TR)*100;
fnMDI[Dn]:=(MDMsum/TR)*100;
uDX[Dn]
:=(abs(fnPDI[Dn]-fnMDI[Dn])/(fnPDI[Dn]+fnMDI[Dn]))*100;
end;
if Dn>(p*2) then begin
ADXsum:=0;
for k:=Dn-p+1 to Dn do
ADXsum := ADXsum + uDX[k];
fnADX[Dn] := ADXsum/p;
fnADXR[Dn]:=(fnADX[Dn] + fnADX[Dn-p])/2;
end;
end;
end;
/RSIの計算
function CalcRSI(p; var fnRSI);
var i,k,up,sumall;
begin
if p=0 then exit;
for i:=StartDno to EndDno do begin
up:=0;
sumall:=0;
if i>1 then
for k:=i-p+1 to i do begin
if NowE(k)>NowE(k-1) then
up:=up+NowE(k)-NowE(k-1);
sumall:=sumall+abs(NowE(k)-NowE(k-1));
end;
fnRSI[i]:=(up/sumall)*100;
end;
end;
/Macdの計算
function CalcMacd(p1,p2,p3;var fnMacd, fnSig, fnOsc);
var alpha1,alpha2,i,k,s;
EMA1=0;EMA2=0;
begin
if (p1=0) or (p2=0) or (p3=0) then exit;
/EMA1
alpha1:=2/(p1+1);
for i:=StartDno to EndDno do begin
if i>p1 then begin
if EMA1[i-1]=0 then begin
s:=0;
for k:=i-p1 to i-1 do
s:=s+NowE(k);
EMA1[i-1]:=s/p1;
end;
EMA1[i]:=EMA1[i-1]+alpha1*(NowE(i)-EMA1[i-1]);
end;
/EMA2
alpha2:=2/(p2+1);
if i>p2 then begin
if EMA2[i-1]=0 then begin
s:=0;
for k:=i-p2 to i-1 do
s:=s+NowE(k);
EMA2[i-1]:=s/p2;
end;
EMA2[i]:=EMA2[i-1]+alpha2*(NowE(i)-EMA2[i-1]);
end;
/fnMacd
if (i>p1) and (i>p2) then
fnMacd[i] := EMA1[i] - EMA2[i];
if (i>p2) and (i>p3) then begin
/fnSig
s:=0;
for k:=i-p3+1 to i do
s:=s+fnMacd[k];
fnSig[i] := s/p3;
/fnOsc
fnOsc[i] := fnMacd[i] - fnSig[i];
end;
end;
end;
/Macdが過去6ヶ月間の底に近いかチェック
function checkMACDLOW(Dno,MacdNow);
var i,L;
begin
result:=true;
i:=Dno;
L:=Maxint;
while (i>0) and (i>(Dno-120)) and (i>=OffsetStartDno) do begin
if fnMacd[i]<L then L:=fnMacd[i];
i:=i-1;
end;
if (L<>Maxint) and (MacdNow<(L*0.9)) then exit;
result:=false;
end;
/Macdが過去6ヶ月間の天井に近いかチェック
function checkMACDHIGH(Dno,MacdNow);
var i,H;
begin
result:=true;
i:=Dno;
H:=0;
while (i>0) and (i>(Dno-120)) and (i>=OffsetStartDno) do begin
if fnMacd[i]>H then H:=fnMacd[i];
i:=i-1;
end;
if (H>0) and (MacdNow>(H*0.9)) then exit;
result:=false;
end;
ランダムウォークによるバーチャル株価
/---------------------------------------
/ ランダムウォークによるバーチャル株価
/
/ ベルヌーイ試行を時刻t毎に実行
/
/---------------------------------------
OrgAllChart:=off;
UserCanvas:=On;
FullCanvas:=on;
SisuName:=ランダムウォークによるバーチャル株価;
Var cx,cy,dot,stepX,stepY,numX,Dnum,Data,dMax,dmin,s,i;
stepP,y,y1,befory,befory1,x,p;
begin
CanvasClear(black);
Randomize;
cx:=80;
cy:=ChartH-80;
dot:=AshiDot;
stepX:=Dot*10;
stepY:=round((ChartH-120) / 8);
numx :=round((ChartW-150)/stepX);
Dnum :=(ChartW-150)/dot;
Data[Dnum];
/株価を計算
dMax:=0;
dMin:=MaxInt;
/スタート時点の株価
s:=3000;
for i:=1 to Dnum do begin
if 0.5>random then
s:=s+random(50)
else
s:=s-random(50);
Data[i]:=s;
if Data[i]>dMax then dMax:=Data[i]
else if Data[i]<dMin then dMin:=Data[i];
/print(dmin,dmax,tostr(i)+'='+tostr(Data[i]));
end;
writecomment('ランダムウォークによるバーチャル株価(Dotボタンでランダム実行)',Red);
dMin:=round((dMin-100)/100)*100;
dMax:=round((dMax+50)/100)*100;
StepP:=(dMax-dMin)/8;
StepP:=round((StepP+50)/100)*100;
dMax:=dmin+StepP*8;
Axis(cx,cy,0,StepX*(numX),stepX,0,stepY*8,stepY);
AxisX(cx,cy,StepX,numX,0,StepX,'時間軸');
AxisY(cx,cy,StepY,8,dMin,StepP,'ランダム株価');
befory:=0;
befory1:=0;
x:=cx;
for i:=1 to Dnum do begin
y:=cy-(((Data[i]-dmin)/(dmax-dmin))*(StepY*8));
if befory>0 then begin
moveToD(x-Dot,befory);
lineToD(red,1,x,y);
end;
p:=CalcIdoHeikin(i,25);
if p>0 then begin
y1:=cy-(((p-dmin)/(dmax-dmin))*(StepY*8));
if befory1>0 then begin
moveToD(x-Dot,befory1);
lineToD(blue,1,x,y1);
end;
end;
x:=x+Dot;
befory:=y;
befory1:=y1;
end;
end;
/移動平均
function CalcIdoHeikin(d,dnum);
var a,i;
begin
a:=0;
if dnum<=0 then exit;
if (d-dnum)>0 then begin
for i:=d-dnum+1 to d do
a:=a+Data[i];
end;
result:=a/dnum;
end;
/------------------------------------------
/
/
取引に疲れたら ライフゲーム
/
/------------------------------------------
UserCanvas:=on;
OrgAllChart:=off;
FullCanvas:=on;
SisuName:=ライフゲーム;
Var Dno,size,cx,a,count,s,SelNo,Ok,
c[40][40],p[40][40];
begin
/初期化
size:=40;
cx:=Chartw/2-(size*16)/2;
init;
a:=round(size/2);
/初期パラーン(Rペントミノ)
SelNo:=1;
beep;
c[a-1][a] :=true;
c[a][a] :=true;
c[a][a+1] :=true;
c[a][a+2] :=true;
c[a+1][a+1]:=true;
CanvasClear;
writeData(red,13,10,30,'ライフゲーム(クリックで中止)');
/実行、無限ループになっています。
count:=0;
while (true) do begin
count:=count+1;
writeData(red,14,10,50,'No='+tostr(count));
show;
next;
sleep(0.2);
end;
exit;
end;
/------------ 以下、関数 --------------
/ 関数内定義されている変数はその関数内で
/ のみ有効なローカル変数です。
/--------------------------------------
function init;
var x,y;
begin
for y:=0 to size-1 do
for x:=0 to size-1 do begin
c[x][y]:=false;
p[x][y]:=false;
end;
end;
function show;
var x,y;
begin
for y:=0 to size-1 do
for x:=1 to size-1 do
if c[x][y] then
FillCircleD(blue,1,cx+x*13,y*13,6)
else
FillCircleD(bkchart,1,cx+x*13,y*13,6);
end;
function next;
var x,y;
begin
for y:=0 to size-1 do
for x:=0 to size-1 do begin
p[x][y]:=c[x][y];
c[x][y]:=false;
end;
for x:=1 to size-1 do begin
p[x][0] :=c[x][size-1];
p[x][size]:=c[x][1];
end;
for y:=1 to size-1 do begin
p[0][y] :=c[size-1][y];
p[size][y]:=c[1][y];
end;
p[0][0] :=c[size-1][size-1];
p[0][size] :=c[size-1][1];
p[size][0] :=c[1][size-1];
p[size][size]:=c[1][1];
for y:=1 to size-1 do
for x:=1 to size-1 do begin
s:=0;
if p[x-1][y-1] then s:=s+1;
if p[x-1][y ] then s:=s+1;
if p[x-1][y+1] then s:=s+1;
if p[x][ y-1] then s:=s+1;
if p[x][ y+1] then s:=s+1;
if p[x+1][y-1] then s:=s+1;
if p[x+1][y ] then s:=s+1;
if p[x+1][y+1] then s:=s+1;
if p[x][y] then begin
if (s=2) or (s=3) then c[x][y]:=true
else c[x][y]:=false;
end
else begin
if s=3 then c[x][y]:=true
else c[x][y]:=false;
end;
end;
end;
このページのトップにある図形を出力するマクロです。
式 = sqr(x)/25-sqr(y)/9 の場合
/-----------------------------------------
/
/
3次元曲面プロット
/ f = ( x
,y )
/
/ 任意の式で3次元空間内の2次元曲面を作図します。
/
/ ここでは、専用マクロの Plot3Dを使っています。
/
/ マクロの編集画面から、Execボタンで実行すると、
/ 各種関数式を選択することが出来ます。
/
/-----------------------------------------
SisuName:=3次元曲面プロット1;
Var Dno,x,y,CalcStr;
begin
OrgAllChart:=off;
UserCanvas:=On;
FullCanvas:=On;
canvasClear(black);
Canvaspen(blue,1);
CalcStr:='sqr(x)/25-sqr(y)/9,x=-2 2,y=-2 2';
/Calcstr:='(cos(sqrt(sqr(x)+sqr(y)))+cos(3*sqrt(sqr(x)+sqr(y))))/2,x=-3
3,y=-3 3';
writecomment('3次元曲面プロット(ドットボタンで再描画)'
+' 計算式='+CalcStr,red);
Plot3D(CalcStr);
Reg3DEquat('x^4+y^4,x=-2 2,y=-2 2,color=true',
'(1/(2*Pi))*Exp(-1/2*(x^2+y^2))*(x^2+y^2),x=-1.5 1.5,y=-1.5
1.5',
'x^4+y^4,x=-2 2,y=-2 2,color=false',
'x^3-3*x*(y^2),x=-2 2,y=-2 2',
'sin(sqrt(x^2+y^2))/sqrt(x^2+y^2),x=-3 3,y=-3 3',
'Sin(x)+Sin(y),x=-5 5,y=-5 5,Grid=50',
'Sin(x)*Sin(y),x=-5 5,y=-5 5,Grid=50,color=false',
'sqrt(sqr(x)+sqr(y))',
'exp(-(x^2+y^2))',
'Sin(x+y)',
'Sin(x + Sin(y))',
'Sin(x + Sin(y)),color=false',
'(2 + Sin(x))+(1 + Cos(2+y))',
'(1 - Sin(x))+(2 - Cos(2+y)),color=fasle',
'Sin(x)+ power(Sin(y),2)',
'sqr(x)/25-sqr(y)/9,x=-2 2,y=-2 2',
'sqr(x)/25-sqr(y)/9,x=-2 2,y=-2 2,color=false');
end;
/------------------------------------------------------
/ 財務データによる検索例
/ 下記のマクロをマクロ編集画面のRUNボタンで実行します。
/ 該当銘柄が注目銘柄のE、画面下部の両方に出力されます。
/------------------------------------------------------
SisuName:=財務データの検索;
/自動ループを中止し、下記のマクロを1回だけ実行
DnoLoop:=off;
var count, cd, s,temp;
begin
temp:='C';
if CheckChumoku(6701,temp,s) then
debugout(temp,' ',s);
exit;
/全銘柄の注目Eをクリア
ResetChumokuALL('E');
count:=0;
for cd:=1013 to 9999 do
if ExistCode(cd) then begin
/財務データを読み込み
ReadZaimuData(cd);
if (Sijo(cd)=0)
/PBR
and ((rnPBR(2006)>0) and (rnPBR(2006)<=1))
/PER
and ((rnPER(2006)>0) and (rnPER(2006)<=10))
/前期が赤字で今期が黒字予想か
/今期(予想)が前期(2006確定)より増益
and ((rnKeijoRiekiYoso>0) and (rnkeijoRieki(2006))
or (rnKeijoRiekiYoso>rnKeijoRieki(2006)))
then begin
/検出銘柄を注目銘柄Eへ設定
SetChumoku(cd,'E');
/下部のデバッグ窓へも表示
/デバッグ欄のデータはクリップボードへコピーも可能です。
Debugout(cd,' PBR=',rnPBR(2006),' PER=',rnPER(2006),' ',MeigaraName(cd));
count := count + 1;
end;
end;
Message(tostr(count)+'個の銘柄が検出されました', MT_INFORMATION);
end;
S.I.G(エスアイジー)
Copyright © 1989 [S.I.G]. All rights reserved.
Top
サポートは下記MLへ登録し読んでいる必要があります。
http://www.sankayo-jp.com/support.htm