C#言語 for 株探検
〜〜カスタム式を使った高度なスクリーニングのために〜〜

カスタム式を使わなくても、いろいろなスクリーニングができますが、 カスタム式を使えばより高度なスクリーニング・売買検証が可能になります。

株探検のカスタム式はC#言語です。

プログラミングがはじめての方には、少々難しいかもしれません。
しかし、ある程度習得すればスクリーニングの範囲がとても広がりますので、ぜひ挑戦していたければ幸いです。

■簡単なカスタム式の例

if( (Close(0)-Close(-1))/Close(-1)*100 > 10 ) return true; return false;
これは終値上昇率が10%以上のものを抽出する例です。カスタム式なしでもできますが・・・

Close(0)は基準日の終値を表します。
括弧内の「0」が基準日です。-1なら基準日の前日です。

Close(〜)以外に、Open(〜)やHigh(〜)などが使えます。どんなものがあるのかはマニュアルをご覧ください。

Close(0)-Close(-1)は、今日の終値から昨日終値で引いているので上昇額になります。

(Close(0)-Close(-1))/Close(-1)は上昇率です。上昇額を昨日終値で割算しています。
(Close(0)-Close(-1))と括弧がついているのは、割算より先に引算をするためです。

(Close(0)-Close(-1))/Close(-1)*100で%の値になります。

次にif文です。
if文の詳細は、こちらをご覧ください。

if( A > B ) return true; と書くと、AのほうがBより大きいならtrueを返すという意味です。
trueは「真」という意味で、「抽出対象にする」という意味になります。
文がこれで一区切りなので、文の最後にはセミコロン「;」をつけます。

if( A > B ) return true; return false; A>Bだったらreturn true;、でなかったらreturn false;です。すなわち「偽」を返します。抽出対象でないということです。

次のように書くこともできます。

if( A > B ) { return true; } return false; 中括弧{}で囲まれた部分には、文をいくつでもかけます。

■中括弧を使ったすこし複雑な例。

if( (Close(0)-Close(-1))/Close(-1)*100 > 10 ) { if( Low(0)>High(-1) ) return true; } return false;
終値上昇率10%以上という条件は先ほどと同じで、さらに窓を開けて上昇しているという条件を増やしました。

中括弧{}で囲まれた部分は、上昇率が10%以上のときだけ実行されます。
Low(0)>High(-1)というのは、今日の安値が昨日の高値より高いという条件です。

なおif文は次のようにも記述できます。
if( (Close(0)-Close(-1))/Close(-1)*100 > 10 ) { if( Low(0)>High(-1) ) return true; } else { return false; }
これは次のような文法です。
if(条件) {  //条件にマッチしたときに実行される文。 } else {  //条件にマッチしなかったときに実行される文。 } ※「//」の後にコメントを書くことができます。

■変数を使った例

double c0 = Close(0); double c1 = Close(-1); double l0 = Low(0); double h1 = High(-1); double upRatio = (c0-c1)/c1*100; // 上昇率 if( upRatio > 10 ) { if( l0 > h1 ) // 窓を開けたか? return true; } return false;
これは上の例と同じことをしています。

double c0 = Close(0);は、c0が変数で、c0は終値の値を持つようになります。
doubleは実数(小数点以下の値も保持できる数)の変数ということを宣言しています。

■実は私はこう書きます・・・

double c0 = Close(0); double c1 = Close(-1); double l0 = Low(0); double h1 = High(-1); double upRatio = (c0-c1)/c1*100; // 上昇率 if( upRatio <= 10 ) return false; // 上昇率が10%以下なのでやめ。 if( l0 <= h1 ) return false; // 窓を開けてないのでやめ。 return true;
同じことをしているのですが、駄目なものはさっさと計算をやめています。

■実用的な書き方

いままでの例は少し問題があります。
取引がない日のことが考慮されていません。
実際は、以下のようにしないと余計なものまで抽出されてしまうことがあります。
double c0 = Close(0); if( Double.IsNaN(c0) ) // 今日取引がないときはやめ。 return false; double c1 = Close(-1); if( Double.IsNaN(c1) ) // 昨日取引がないときもやめ。 return false; double l0 = Low(0); double h1 = High(-1); double upRatio = (c0-c1)/c1*100; // 上昇率 if( upRatio <= 10 ) return false; // 上昇率が10%以下なのでやめ。 if( l0 <= h1 ) return false; // 窓を開けてないのでやめ。 return true;
Double.IsNaN(〜)は値が得られないことを意味します。
おまじないみたいなものだと思ってください。
「NaN」は「Not a Number」の意味です。
なお出来高を知るVolume(〜)は取引がないと0になります。

■if文の括弧内の詳細

if文の()内の文法を説明します。

A>B AがBより大きい。
A<B AがBより小さい。
A>=B AがBより大きいか等しい。
A<=B AがBより小さいか等しい。
A==B AとBが等しい。 「==」です。「=」は代入になってしまいます。
A!=B AとBが違う。
式1&&式2 式1でかつ式2 たとえば、if( A>B && C<B )
「AがBより大きく、かつ、CがBより小さい」という条件。
式1||式2 式1または式2 たとえば、if( A>B || C<B )
「AがBより大きい、または、CがBより小さい」という条件。
(式1||式2)&&式3 式1または式2、かつ、式3 たとえば、if( (A>B || C<B) && A<C )
いくらでも増やせる例です。
()をつけたほうが先に実行されます。
「if( A>B || C<B && A<C )」とは結果が違うので注意です。
!式 式のtrueとfalseを反転します。 たとえば、if( A<B )は、 if( !(A>=B) )と同じです。

■変数の種類(株探検でよく使うものだけ)

変数の型 宣言例 備考 
実数(小数点をもつ) double a;
double a=10;
終値などはdouble。
整数 int i;
int i=10;
ループなどのカウンタに使う。
論理値 bool flag;
bool flag=true;
たとえばこんなことは普通しませんが、意味はわかるかと思います。
bool flag = Low(0)>High(-1);
if( flag ) {

}
「Low(0)>High(-1)」はif文の中によくでてくる比較式です。


■変数の寿命とスコープ

間違いをしやすいところなので注意してください。
for(〜) { } や if(〜) { }
のように、{}で囲まれた部分をスコープといいます。
スコープと変数は深い関係があります。
以下が例です。
//------------------------------------------------------------------ int a = 10; // 変数aを宣言して、値を10にしています。 if(〜) { int a = 20; // 変数aの宣言です。このaはスコープの中でだけ有効です。 } int b = a; // bは10になります!! //-------------------------------------------------------------------
次は少し違うだけで大違いです。
//------------------------------------------------------------------ int a = 10; // 変数aを宣言して、値を10にしています。 if(〜) { a = 20; // 代入です。 } int b = a; // bは20になります!! //-------------------------------------------------------------------
なお{}だけでも使えます。意識的にスコープを使うことができます。
滅多に使いませんが、スコープの理解を深める意味で書きました。
//------------------------------------------------------------------ int a = 10; // 変数aを宣言して、値を10にしています。 { int a = 20; // 変数名はどうしてもaにしたい。 // でも他人には迷惑を掛けたくない。 } //-------------------------------------------------------------------

■数値計算式の計算順番

数値計算式には、足算、引算、割算、掛算などがありますが、同時に使用したときの優先度について説明します。

優先度は以下のようになります。同レベル(掛算と割算など)は先に記述されたものが先に計算されます。
1 括弧内の計算
2 掛算と割算
3 足算と引算
良くわからないときは括弧を付けてしまいましょう。

●例
double a = (Close(0)-Close(-1))/Close(0)*100;
1) 括弧内のClose(0)-Close(-1)が最初
2) /Close(0)
3) *100

これを以下のように書いてしまうと駄目です。
double a = Close(0)-Close(-1)/Close(0)*100
これは引算より割算、すなわち「Close(-1)/Close(0)」が先に計算されてしまいます。

■条件式の計算順番

条件計算式の優先順位は次のようになります。
1 括弧内の計算  
2 <、>、<=、>= 大小関係が合っているか合っていないかをtrue,falseとして求める。
3 && かつ
4 || または
良くわからないときは括弧を付けてしまいましょう。

●例
if( (a > b || c > b) && a < c ) {〜}
1) a > b
2) c < b
3) ||
4) a < c
5) &&

これを以下のように書いてしまうと駄目です。
if( a > b || c > b && a < c ) {〜}
&&のほうが、||より先に計算されてしまいます。


■ループを使った例

//-------------------------------------------------------------------------------------- double max = Double.NaN; // maxの値はNaN(値でない)にしておく。 for(int i = 1 ; i <= 26 ; i++) { double c = Close(-i); // i日前の終値を 変数c に代入。 if( Double.IsNaN(max) || c > max ) { // maxがまだ設定されていないか、c>maxならmaxを置き換える。 max = c; } } if( (Close(0)-max)/max)*100 < 10.0 ) return false; // 過去26日の高値から今日の終値の上昇率が10%以下ならやめ。 return true; // 条件にマッチしたので、trueを返す。 //--------------------------------------------------------------------------------------
過去26日の高値から今日の終値の上昇率が10%以上のものを抽出しています。
 ※過去N日の高値を簡単に計算する関数は用意されています。

for文は繰り返しのために使います。for文の書式は以下のようになります。

for( 最初に1度だけ実行される式 ; ループを続ける条件式 ; ループするたびに最後に実行する式 ) { ループのたびに実行される文 } ●for(int i = 1 ; i <= 26 ; i++) int i = 1;は、ループを開始する前に、変数iを1にしています。
  intは整数の変数を宣言します。
i<=26は、iが26を超えるまでループするという意味です。
i++は、iを1つ大きくしています。i = i+1と書いてもいいです。

●double c = Close(-i); 変数c にi日前の終値を代入しています
●if( Double.IsNaN(max) || c > max ) Double.IsNaN(max)は、maxが値かどうかを調べています。
最初の方で、max = Double.NaN; としていますから、1回目はtrueになりますね。
if文は、if文 を参照してください。
if( (Close(0)-max)/max)*100 < 10.0 ) これは、前回の終値上昇率と要領は同じなので説明を省略します。

■ループ例(取引がない日を考慮)
//-------------------------------------------------------------------------------------- double max = Double.NaN; // maxの値はNaN(値でない)にしておく。 for(int i = 1 ; i <= 26 ; i++) { double c = Close(-i); // i日前の終値を 変数c に代入。 if( Double.IsNaN(c) ) // ★ここが増えた。 continue; // 残りの文は実行せずにループを繰り返す。 if( Double.IsNaN(max) || c > max ) { // maxがまだ設定されていないか、c>maxならmaxを置き換える。 max = c; } } if( Double.IsNaN(max) ) // ★ここが増えた。 return false; // 26日間取引がまったくないとmaxに値が設定されないです。 if( (Close(0)-max)/max)*100 < 10.0 ) return false; // 過去26日の高値から今日の終値の上昇率が10%以下ならやめ。 return true; // 条件にマッチしたので、trueを返す。 //--------------------------------------------------------------------------------------
continue;は、ループ内の残りを飛ばしてループの先頭に戻ります。
ただし、i++は実行します。

■つづく・・・