VBScript入門 for ITicker
■ 第2章 Function...End Function ステートメント
これまでに何回か「ITGetClose(i)」が登場していますが、これはカッコ内の引数「i」に値を渡すとそのインデックスの終値を返すという関数です。このよう「引数に値を渡してその処理を行った結果の値を返す」という関数はVBScriptやITickerから多く提供されていますが、更に、スクリプト内にFunction...End Function ステートメントを記述することによって、ユーザー独自の関数を作ることができます。
ここでは前章で扱ったスクリプトを例にして、Functionの説明を行います。

1 .Function...End Function ステートメント
  • 前章のN日移動平均スクリプトのメイン部です。
    IdouKikan = 5
    ave = 0
    If index-(IdouKikan-1) >= 0 Then
        sum = 0
        For j = 0 To IdouKikan-1
               sum = sum + ITGetClose(index-j)
        Next
        ave = sum / IdouKikan
    End If
  • この部分は、「IdouKikan」と「index」の2つの変数に値を与えてやると、移動平均の値「ave」が求まります。
  • つまり、関数名を「IdouHeikin」とすると 「ave = IdouHeikin(IdouKikan, index)」のように表すことが出来るということです。
  • そして、関数の具体的な中身は「Function 関数名(引数1, 引数2, 引数・・・・) 〜 End Function」で記述します。
  • この場合、具体的には下記リストの様になります。
Function IdouHeikin(IdouKikan, index)
    IdouHeikin = 0
    If index-(IdouKikan-1) >= 0 Then
        sum = 0
        For j = 0 To IdouKikan-1
               sum = sum + ITGetClose(index-j)
        Next
        IdouHeikin = sum / IdouKikan
    End If

End Function
  • これで、スクリプト中にIdouHeikin([計算期間を示す値], [インデックスを示す値])を記述するだけで移動平均の値を得ることが出来ます。
  • 前章の「4. 移動平均を複数描く」のスクリプトにこの関数を使って記述すると以下の様になります。
'ここから
Option Explicit
Dim pen1, pen2, pen3, index, sum, ave, j

Function IdouHeikin(IdouKikan, index)
    IdouHeikin = 0
    If index - (IdouKikan-1) >= 0 Then
        sum = 0
        For j = 0 To IdouKikan-1
               sum = sum + ITGetClose(index - j)
        Next
        IdouHeikin = sum / IdouKikan
    End If
End Function


ITCreateObjStdPen 3
Set pen1 = ITObjStdPen(0)
Set pen2 = ITObjStdPen(1)
Set pen3 = ITObjStdPen(2)
pen1.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen
pen2.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen
pen3.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen

For index = 0 To ITMaxCnt-1
    '5日移動平均
    ave = IdouHeikin( 5, index)
    pen1.SetData index, ave, 0, True, RGB(255,0,0)
    '20日移動平均
    ave = IdouHeikin(20, index)
    pen2.SetData index, ave, 0, True, RGB(0,255,0)
    '60日移動平均
    ave = IdouHeikin(60, index)
    pen3.SetData index, ave, 0, True, RGB(0,0,255)
Next
ITDraw
' ここまで
  • このように頻繁に出てくる処理を、旨くまとめて関数にすると、スクリプトがすっきりします。
  • ただ、上記スクリプトは動作上は問題ないのですが、スクリプトの保守や汎用性などの観点から少しまずい所があります。
  • それは、関数内で使用している変数を関数外で宣言していることです。「sum」や「j」などがそうです。
  • Function...End Function ステートメント内で使用する変数は、その関数内で完結するのが望ましいです。
  • そうすればFunction...End Functionをコピーして、他のスクリプトにもすぐ再利用できます。
2. ローカル変数
  • .Function...End Function 内でDimを使って宣言した変数は、そのFunction内のみで有効です。このような変数をローカル変数と呼びます。
  • 尚、引数の変数や戻り値の変数(関数名)は改めてDimで宣言する必要はありません。
'ここから
Option Explicit

Function IdouHeikin(kikan, index)
    Dim sum, j
    IdouHeikin = 0
    If index-(kikan-1) >= 0 Then
        sum = 0
        For j = 0 To kikan-1
               sum = sum + ITGetClose(index-j)
        Next
        IdouHeikin = sum / kikan
    End If
End Function

Dim i, pen1, pen2, pen3
ITCreateObjStdPen 3
Set pen1 = ITObjStdPen(0)
Set pen2 = ITObjStdPen(1)
Set pen3 = ITObjStdPen(2)
pen1.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen
pen2.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen
pen3.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen

For i = 0 To ITMaxCnt-1
    pen1.SetData i, IdouHeikin( 5, i), 0, True, RGB(255,0,0) '5日移動平均
    pen2.SetData i, IdouHeikin(20, i), 0, True, RGB(0,255,0) '20日移動平均
    pen3.SetData i, IdouHeikin(60, i), 0, True, RGB(0,0,255) '60日移動平均
Next
ITDraw
' ここまで
  • 上記の様に記述すると、IdouHeikin関数は引数と関数内でDimで宣言した変数だけで処理されており、Function IdouHeikin(kikan, index)〜End Functionをコピーするだけで他のスクリプトでもそのまま移動平均の関数を再利用することが出来ます。
3. サンプル
  • .複数の移動平均は既にやっているので、ここではボリンジャーバンドの様に移動平均の±5%を表示し、そして指標1の領域には移動平均に対する標準偏差を描くようなスクリプトを書いてみました。
  • といっても、IdouHeikin(kikan, index)は前述のコードを、また標準偏差を求める関数CalStd(term, index)は以前掲示板で出た話題にサンプルとして示したものを、それぞれそのままコピーして使い回しているので、スクリプト本体の作成所要時間は1,2分というところです。寧ろ、文章作成の方が何十倍もの時間を要しています。
'ここから
Option Explicit
'移動平均
Function IdouHeikin(kikan, index)
    Dim sum, j
    IdouHeikin = 0
    If index-(kikan-1)>= 0 Then
        sum = 0
        For j = 0 To kikan-1
               sum = sum + ITGetClose(index-j)
        Next
        IdouHeikin = sum / kikan
    End If
End Function
'標準偏差
Function CalStd(term, index)
    Dim j, stock, sum, sum2, ave
    CalStd = 0
    If index <= term Then Exit Function
    If term < 1 Then Exit Function
    sum = 0:sum2 = 0
    For j = 0 To term - 1
        sum = sum + ITGetClose(index - j)
        sum2 = sum2 + ITGetClose(index - j)*ITGetClose(index - j)
    Next
    ave = sum/term
    CalStd = (ITGetClose(index) - ave) / Sqr(sum2/term - ave*ave)
End Function
'main
Dim i, ave, pen1, pen2, pen3, pen4
ITCreateObjStdPen 4
Set pen1 = ITObjStdPen(0)
Set pen2 = ITObjStdPen(1)
Set pen3 = ITObjStdPen(2)
Set pen4 = ITObjStdPen(3)
pen1.SetCnd ITAreaStock, ITChartLine1, ITStyleSolid, 1, ITModeCopypen
pen2.SetCnd ITAreaStock, ITChartLine1, ITStyleDot, 1, ITModeCopypen
pen3.SetCnd ITAreaStock, ITChartLine1, ITStyleDot, 1, ITModeCopypen
pen4.SetCnd ITAreaOpt1, ITChartLine1, ITStyleSolid, 1, ITModeCopypen
ITSetYRange ITAreaOpt1, 3, -3, 1 'スケール設定

For i = 0 To ITMaxCnt-1
    ave = IdouHeikin(20, i) '20日移動平均
    pen1.SetData  i, ave, 0, True, RGB(0, 255, 0) '移動平均
    pen2.SetData  i, ave * 1.05, 0, True, RGB(255, 0, 0) '日移動平均+5%
    pen3.SetData  i, ave * 0.95, 0, True, RGB(255, 0, 0) '日移動平均-5%
    pen4.SetData  i, CalStd(20, i), 0, True, RGB(0, 0, 255) '20日移動平均に対する標準偏差
Next
ITDraw
' ここまで
  • 尚、「Exit Function」はその時点でその関数を終了させる命令、「Sqr」は平方根を求める関数です。

第1章へ← →

[トップページに戻る]