マクロ(独自トレード・システムの作成)

 逆ウオッチ曲線(住特金)


ユーザーが自由にトレードシステムを設計出来るよう、Fchartに高度なマクロを搭載しました。

Fchartの上に、新たなシステム記述用言語を搭載し、ユーザーは用意された関数や自由に
定義できる関数などを使用して、独自のトレードシステムを作成することが可能です。


マクロのマニュアルと全サンプル(Macro.chm)

マクロのサンプル   旧YahooのマクロMLの過去ログです(サンプル多数)。


詳しいことは、上記のマニュアルをご覧ください。


Fchartマクロで出来ること

1.ユーザー独自のチャート、指数、テクニカル売買のサインを自由に作成、表示することが可能です。
2.整数、浮動小数点、文字列に対応した、単純変数から2次元、3次元など高次の配列変数、自由な
  記述が可能です。
3.数百の組み込み関数に加えて、ユーザー独自の関数の作成が可能です(再帰可)。
4.多数のサンプルを用意しています。

下記はマクロの例です(この他多数のサンプルが上記マニュアルに記載されています)。

1.P&F(ポイント&フィギュアー)

2.逆ウオッチ曲線

3.ラリー・ウィリアムズのゼロバランス

4.HLバンドによる売買シミュレーション

5.3点チャージ

6.ベクトル

7.MACD

.MM法

9.ランダムウォークによるバーチャル株価による

10.ライフゲーム

11.3次元曲面プロット   

12.財務データによる銘柄検索


マクロ専用メルマガについて

下記はマクロ専用のメールマガジンです。
マクロについての質問やマクロ例などを整理して公開します。
マクロのユーザーはぜひご参加ください。 

参加、退会は下記へメールを送るだけです(件名、本文は不要です)。
投稿も可能です。 マクロの情報交換に使って下さい。

・参加(自動処理)
f-macro-subscribe@yahoogroups.jp
・退会(自動処理)
f-macro-unsubscribe@yahoogroups.jp
・グループページのURL
http://groups.yahoo.co.jp/group/f-macro

P&F(ポイント&フィギュアー)


/-----------------------------------------------
/
/            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バンドによる売買シミュレーション

/------------------------------------------------------
/
/ 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点チャージ

/------------------------------------------------
/
/  ユーザー関数ライブラリーを使った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

/--------------------------------------------
/      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;


3次元曲面プロット

このページのトップにある図形を出力するマクロです。
式 = 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