忍者ブログ

forex tester2のインディケーターを自作

fx(外国為替証拠金取引)のトレードの練習やルールの検証をForex Tester 2というソフトでしてみます。 Meta Trader4(MT4)のインディケーター(indicator)をForex Tester2用に移植できたらしてみます。

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


BreakOut-EAGLE__ut2DaMax.mq4 みたいなの移植成功

BreakOut-EAGLE__ut2DaMax.mq4 に似たのが完成しました。
これくらいのことで徹夜しました。4流プログラマー以下です。

Forex Tester2には矩形(OBJ_RECTANGLE)のオブジェクトが無いようなので
4本の線で代用しました。

下手なコードですがCalculateだけ晒します。

procedure Calculate(index: integer); stdcall; var timestr, objnumstr: String; timeindex: TDateTime; begin if (index <> 0) then exit; if oldBars > Bars then exit; timeindex := Time(index); timestr := TimeToStr(timeindex); objnumstr := IntToStr(objnum); if (mode = 0) then begin if StrLComp(PChar(timestr),PChar('21:00:00'),4) = 0 then begin highp := High(index); lowp := Low(index); if ObjectExists(objnumstr+'l') then begin ObjectDelete(objnumstr+'l'); ObjectDelete(objnumstr+'u'); ObjectDelete(objnumstr+'d'); ObjectDelete(objnumstr+'r'); end; ObjectCreate(objnumstr+'l', obj_TrendLine, 0,timeindex, highp,timeindex, lowp); ObjectCreate(objnumstr+'u', obj_TrendLine, 0,timeindex, highp,timeindex, highp); ObjectCreate(objnumstr+'d', obj_TrendLine, 0,timeindex, lowp, timeindex, lowp); // create text if ObjectExists(objnumstr+'t1') then begin ObjectDelete(objnumstr+'t1'); ObjectDelete(objnumstr+'t2'); end; ObjectCreate(objnumstr+'t1', obj_Text, 0, timeindex, highp); ObjectSetText(objnumstr+'t1', FloatToStr(highp), 12, 'Arial', clYellow); ObjectSet(objnumstr+'t1', OBJPROP_VALIGNMENT, tlBottom); ObjectSet(objnumstr+'t1', OBJPROP_HALIGNMENT, taLeftJustify); ObjectCreate(objnumstr+'t2', obj_Text, 0, timeindex, lowp); ObjectSetText(objnumstr+'t2', FloatToStr(lowp), 12, 'Arial', clYellow); ObjectSet(objnumstr+'t2', OBJPROP_VALIGNMENT, tlTop); ObjectSet(objnumstr+'t2', OBJPROP_HALIGNMENT, taLeftJustify); mode := 1; end; end else if (mode = 1) then begin if (highp < high(index)) then highp := high(index); if (lowp > low(index)) then lowp := low(index); ObjectSet(objnumstr+'l', OBJPROP_PRICE1, highp); ObjectSet(objnumstr+'l', OBJPROP_PRICE2, lowp); ObjectSet(objnumstr+'u', OBJPROP_PRICE1, highp); ObjectSet(objnumstr+'u', OBJPROP_PRICE2, highp); ObjectSet(objnumstr+'u', OBJPROP_TIME2, timeindex); ObjectSet(objnumstr+'d', OBJPROP_PRICE1, lowp); ObjectSet(objnumstr+'d', OBJPROP_PRICE2, lowp); ObjectSet(objnumstr+'d', OBJPROP_TIME2, timeindex); // set text props ObjectSet(objnumstr+'t1', OBJPROP_TIME1, timeindex); ObjectSet(objnumstr+'t1', OBJPROP_PRICE1, highp); ObjectSet(objnumstr+'t2', OBJPROP_TIME1, timeindex); ObjectSet(objnumstr+'t2', OBJPROP_PRICE1, lowp); ObjectSetText(objnumstr+'t1', FloatToStr(highp), 12, 'Arial', clYellow); ObjectSetText(objnumstr+'t2', FloatToStr(lowp), 12, 'Arial', clYellow); if StrLComp(PChar(timestr),PChar('5:00:00'), 3) = 0 then begin mode := 2; if not(ObjectExists(objnumstr+'r')) then ObjectCreate(objnumstr+'r', obj_TrendLine, 0, timeindex, highp, timeindex, lowp); highp2 := highp; lowp2 := lowp; mode2 := 0; end; end else if (mode = 2) then begin ObjectSet(objnumstr+'u', OBJPROP_TIME2, timeindex); ObjectSet(objnumstr+'d', OBJPROP_TIME2, timeindex); if ((mode2 = 0) and (highp2 < Close(index))) or ((mode2 = 1) and (highp2 <= high(index))) then begin highp2 := high(index); if ObjectExists(objnumstr+'t3') then ObjectDelete(objnumstr+'t3'); ObjectCreate(objnumstr+'t3', obj_Text, 0, timeindex, highp2); ObjectSetText(objnumstr+'t3', FloatToStr(highp2), 12, 'Arial', clWhite); ObjectSet(objnumstr+'t3', OBJPROP_VALIGNMENT, tlBottom); ObjectSet(objnumstr+'t3', OBJPROP_HALIGNMENT, taLeftJustify); if mode2 = 0 then begin lowp2 := low(index); mode2 := 1; end; end; if ((mode2 = 0) and (lowp2 > Close(index))) or ((mode2 = 1) and (lowp2 >= low(index))) then begin lowp2 := low(index); if ObjectExists(objnumstr+'t4') then ObjectDelete(objnumstr+'t4'); ObjectCreate(objnumstr+'t4', obj_Text, 0, timeindex, lowp2); ObjectSetText(objnumstr+'t4', FloatToStr(lowp2), 12, 'Arial', clWhite); ObjectSet(objnumstr+'t4', OBJPROP_VALIGNMENT, tlTop); ObjectSet(objnumstr+'t4', OBJPROP_HALIGNMENT, taLeftJustify); if mode2 = 0 then begin highp2 := high(index); mode2 := 1; end; end; if StrLComp(PChar(timestr),PChar('20:00:00'), 4) = 0 then begin objnum := objnum+1; if objnum > 10 then begin objnum := 0; end; mode := 0; end; end; oldbars := Bars; end;

赤い枠がNYボックスです。まだ時間は合わせていません。
黄色い文字がNYボックスの高値と安値です。
高値と安値を超えたら白い文字が表示されます。



動画もアップしてみました。

PR

『NYボックス』の検証

『NYボックス』という手法があります。
日本時間にNY時間の高値と安値をブレイクしたらその方向にXXpip以上動くことが
多いことを利用する手法です。
ブレイクしてもXXpip動かなかったら反対の方向に動くことが多いことも利用します。

それを検証するためにインディケーターを探していたら
Meta Trader4用のが2つ見つかりました。

Sessions.mq4
 

BreakOut-EAGLE__ut2DaMax.mq4
 

BreakOut-EAGLE__ut2DaMax.mq4  
のほうがわかりやすいので移植に挑戦してみたいと思います。
 




Access violation

Forex Tester2 のインディケーターを作成したのですが
動作確認しようとしたら変なエラーが表示されて実行不可能でした。




エラー内容
exception number    : 1
exception class     : EAccessViolation
exception message   : Access violation at address 00602E5E in module 'ForexTester.exe'. Read of address 00000008.



いろいろやってみましたが原因は

IndicatorBuffers(0);

を実行していなかったためでした。


バッファを使用しない場合でも引数を0で実行しておかないと駄目みたいです。










シグナルの表示

乖離の平均が反転する時にシグナルを表示してみます。
反転が確定した次の足にシグナルを表示しました。

procedure Calculate(index: integer); stdcall; var i:integer; sum:double; begin if Bars < index + 21 then exit; MA1[index] := GetMA(index, 0, 5, ma_SMA, pt_Close) -
GetMA(index, 0, 20, ma_SMA, pt_Close); if Bars < index + 41 then exit; sum := 0; for i:=index to index + 20 - 1 do sum := sum + MA1[i]; MA2[index] := sum / 20; if (MA2[index + 3] >= MA2[index + 2]) and (MA2[index + 2] < MA2[index + 1]) then SGB[index] := MA2[index]; if (MA2[index + 3] <= MA2[index + 2]) and (MA2[index + 2] > MA2[index + 1]) then SGS[index] := MA2[index]; end;


MA1は見にくくなるのでds_Noneにして消しています。

 


決済をトレールにして損切りを小さくすれば面白そうです。


わかっていたことですがMACD(5,20,20)のシグナルとほぼ同じです。

乖離と乖離の平均を表示

5本と20本の平均線の乖離と乖離の20本の平均を表示してみます。


procedure Calculate(index: integer); stdcall; var i:integer; sum:double; begin if Bars < index + 21 then exit; MA1[index] := GetMA(index, 0, 5, ma_SMA, pt_Close) - GetMA(index, 0, 20, ma_SMA, pt_Close); if Bars < index + 41 then exit; sum := 0; for i:=index to index + 20 - 1 do sum := sum + MA1[i]; MA2[index] := sum / 20; end;


赤が乖離で黄色が乖離の20期間の平均です。



移動平均を2本表示

最初に移動平均線を2本表示してみます。

計算部分だけのコードです。
procedure Calculate(index: integer); stdcall; begin if Bars < index + 20 then exit; MA1[index] := GetMA(index, 0, 5, ma_SMA, pt_Close); MA2[index] := GetMA(index, 0, 20, ma_SMA, pt_Close); end;

5と20の移動平均線にしました。終値を使用しました。
パラメータを変更できるようにはしていません。
パラメータ変更する時は再コンパイルする自分仕様です。





MAマスター のルール

ひまわり証券の自動売買システム「エコトレFX」で人気のシステム
「MAマスター」をForexTester2でバックテストしてみようと思います。


「MAマスター」売買ルール
Ⅰ.買いルール

1.前提条件:下記条件を満たした場合のみ、仕掛けルールを適用する
 ・2本の単純移動平均線(x期間・y期間)の乖離幅(z期間の平均値)が、
 「縮小」から「拡大」に転じる

2.仕掛けルール:買いポジションを作るときのルール
 ・上記の前提条件を満たした期間(以下、期間〔t〕)の直後の期間
 (以下、期間〔t+1〕)の始値で買い

3.手仕舞いルール:買いポジションを手仕舞うときのルール
 ①過去a期間の最安値で転売 または、
 ②前提条件である乖離幅が「拡大」から「縮小」に転じたら、途転売り
  ※途転とは、ポジションを決済する(手仕舞う)と同時に、決済前とは
    逆のポジションを新規に建てること。

Ⅱ.売りルール

1.前提条件:下記条件を満たした場合のみ、仕掛けルールを適用する
 ・2本の単純移動平均線(x期間・y期間)の乖離幅(z期間の平均値)が、
 「拡大」から「縮小」に転じる

2.仕掛けルール:売りポジションを作るときのルール
 ・上記の前提条件を満たした期間(以下、期間〔t〕)の直後の期間
 (以下、期間〔t+1〕)の始値で売り

3.手仕舞いルール:売りポジションを手仕舞うときのルール
 ①過去a期間の最高値で買戻し または、
 ②前提条件である乖離幅が「縮小」から「拡大」に転じたら、途転買い
  ※途転とは、ポジションを決済する(手仕舞う)と同時に、決済前とは
    逆のポジションを新規に建てること。

 

 最初はForexTester2に売買タイミングを表示させてみようと思います。
可能なら自動で売買させてみたいです。無理かもしれないですけど。
 


ds_ColoredCandles を試してみた

SetIndexStyle関数の引数で指定できる ds_ColoredCandles を使用してみました。
ds_ColoredCandles で4つのバッファを使用してロウソク足を表示できます。

例としてサブウインドウにUSDJPYのロウソク足を表示するインディケーターを作ってみました。
以下はプログラムコードです。
library RousokuTest; uses SysUtils, Interfaces, DateUtils, graphics, IndicatorInterfaceUnit, TechnicalFunctions; var HIGH,LOW,OPEN,CLOSE: TIndexBuffer; procedure Init; stdcall; begin IndicatorShortName('Rousoku Test'); SetOutputWindow(ow_SeparateWindow); HIGH := CreateIndexBuffer; LOW := CreateIndexBuffer; OPEN := CreateIndexBuffer; CLOSE := CreateIndexBuffer; IndicatorBuffers(4); SetIndexBuffer(0, OPEN); SetIndexStyle(0, ds_None, psSolid, 1, clLime); SetIndexLabel(0, 'Up bar color'); SetIndexBuffer(1, HIGH); SetIndexStyle(1, ds_None, psSolid, 1, clBlack); SetIndexLabel(1, 'Up bar fill color'); SetIndexBuffer(2, LOW); SetIndexStyle(2, ds_None, psSolid, 1, clLime); SetIndexLabel(2, 'Down bar color'); SetIndexBuffer(3, CLOSE); SetIndexStyle(3, ds_ColoredCandles, psSolid, 1, clWhite); SetIndexLabel(3, 'Down bar fill color'); end; procedure Calculate(index: integer); stdcall; begin OPEN[index] := iOpen('USDJPY',TimeFrame,index); HIGH[index] := iHigh('USDJPY',TimeFrame,index); LOW[index] := iLow('USDJPY',TimeFrame,index); CLOSE[index] := iClose('USDJPY',TimeFrame,index); end; exports Init, Calculate; end.

4つ目のバッファだけに ds_ColoredCandles を指定したら表示できました。
最初の3つのバッファは色の指定だけが影響を与えると思われます。
USDJPY の始値、高値、安値、終値をバッファに設定していますが別の通貨の組み合わせを設定しても面白いかもしれません。
4つ目のバッファのプロパティを変更することで実線を点線にしたり線の太さを変更したりできます。
 
以下はUSDJPYのチャートのサブウィンドウに表示した例です。

Forex Tester 2の購入はこちらから。


SetIndexStyle関数の調査


SetIndexStyle関数の第2引数でds_Fillとds_HistogramFillの使用方法が
わからなかったのでいろいろ試してみました。

両方とも2つのバッファを使用します。
バッファが1つだけのとき指定してもds_Lineと同じか何も表示されないです。

以下は2つのバッファにいろいろスタイルを組み合わせた例です。

1つ目のバッファに ds_Fill を指定しても意味が無いようです。



2つ目にds_Fillを設定した場合は1つ目がds_Fillでもds_Lineでもds_Sectionでも同じようです。
でもds_Sectionが歯抜けの場合はどうなるか面倒なので試していません。







2つ目にds_Fillを設定した場合は1つ目がds_Noneでもds_HistogramFillでも同じようです。





ds_Histogramとds_Fillの組み合わせでも表示できました。使用することは無いでしょう。



ds_Symbolとds_Fillの組み合わせでも表示できました。歯抜けの場合どうなるかわかりません。



2つ目にds_HistogramFillを設定した場合は1つ目がds_Fillでもds_Lineでもds_Sectionでも同じようです。







ds_HistogramFillとds_Histogramの組み合わせも可能でした。



ds_HistogramFillとds_Symbolの組み合わせも可能でした。


2つ目にds_HistogramFillを設定した場合は1つ目がds_Noneでもds_HistogramFillでも同じようです。






歯抜けのバッファの場合も試してみたら
両方のバッファに値の存在する時間だけ縦線が表示されました。

ds_Fillはds_HistogramFillとds_Lineのセットみたいな感じですね。

 

以上暇なことをしてみました。


Forex Tester 2の購入はこちらから。

売買シグナルを表示

オシレーターウィンドウに売買シグナルを表示してみます。

単純に1時と13時に買いシグナル、7時と19時に売りシグナルを表示してみます。

コードは以下です。
library SymbolTest; uses SysUtils, Interfaces, DateUtils, graphics, IndicatorInterfaceUnit, TechnicalFunctions; var BUY: TIndexBuffer; SELL: TIndexBuffer; procedure Init; stdcall; begin IndicatorShortName('Symbol Test'); SetOutputWindow(ow_SeparateWindow); SetFixedMinMaxValues(-1, 24); SetEmptyValue(100); BUY := CreateIndexBuffer; SELL := CreateIndexBuffer; IndicatorBuffers(2); SetIndexBuffer(0, BUY); SetIndexStyle(0, ds_Symbol, psSolid, 1, clRed); SetIndexSymbol(0, 241, 0, 0); SetIndexBuffer(1, SELL); SetIndexStyle(1, ds_Symbol, psSolid, 1, clBlue); SetIndexSymbol(1, 242, 0, 0); end; procedure Calculate(index: integer); stdcall; begin if (BUY[index] < 24) or (SELL[index] < 24) then exit; if HourOf(Time(index)) = 1 then BUY[index] := 1; if HourOf(Time(index)) = 13 then BUY[index] := 13; if HourOf(Time(index)) = 7 then SELL[index] := 7; if HourOf(Time(index)) = 19 then SELL[index] := 19; end; exports Init, Calculate; end.


SetIndexStyle関数でds_Symbolを指定して
SetIndexSymbol関数で文字を指定します。
シンボルを表示したい時だけバッファに値を設定します。
指定した値の位置にシンボルが表示されます。

実行結果です。

週の始めは7時のデータが無いので空白になっています。

SetIndexSymbol関数の第2引数ではWingdings の文字が指定可能です。

Wingdings  シンボル一覧
  32 ! 33 " 34 # 35 $ 36 % 37 & 38 ' 39
( 40 ) 41 * 42 + 43 , 44 - 45 . 46 / 47
0 48 1 49 2 50 3 51 4 52 5 53 6 54 7 55
8 56 9 57 : 58 ; 59 < 60 = 61 > 62 ? 63
@ 64 A 65 B 66 C 67 D 68 E 69 F 70 G 71
H 72 I 73 J 74 K 75 L 76 M 77 N 78 O 79
P 80 Q 81 R 82 S 83 T 84 U 85 V 86 W 87
X 88 Y 89 Z 90 [ 91 \ 92 ] 93 ^ 94 _ 95
` 96 a 97 b 98 c 99 d 100 e 101 f 102 g 103
h 104 i 105 j 106 k 107 l 108 m 109 n 110 o 111
p 112 q 113 r 114 s 115 t 116 u 117 v 118 w 119
x 120 y 121 z 122 { 123 | 124 } 125 ~ 126  127
128  129 130 ƒ 131 132 133 134 135
ˆ 136 137 Š 138 139 Œ 140  141 Ž 142  143
 144 145 146 147 148 149 150 151
˜ 152 153 š 154 155 œ 156  157 ž 158 Ÿ 159
  160 ¡ 161 ¢ 162 £ 163 ¤ 164 ¥ 165 ¦ 166 § 167
¨ 168 © 169 ª 170 « 171 ¬ 172 ­ 173 ® 174 ¯ 175
° 176 ± 177 ² 178 ³ 179 ´ 180 µ 181 182 · 183
¸ 184 ¹ 185 º 186 » 187 ¼ 188 ½ 189 ¾ 190 ¿ 191
À 192 Á 193 Â 194 Ã 195 Ä 196 Å 197 Æ 198 Ç 199
È 200 É 201 Ê 202 Ë 203 Ì 204 Í 205 Î 206 Ï 207
Ð 208 Ñ 209 Ò 210 Ó 211 Ô 212 Õ 213 Ö 214 × 215
Ø 216 Ù 217 Ú 218 Û 219 Ü 220 Ý 221 Þ 222 ß 223
à 224 á 225 â 226 ã 227 ä 228 å 229 æ 230 ç 231
è 232 é 233 ê 234 ë 235 ì 236 í 237 î 238 ï 239
ð 240 ñ 241 ò 242 ó 243 ô 244 õ 245 ö 246 ÷ 247
ø 248 ù 249 ú 250 û 251 ü 252 ý 253 þ 254 ÿ 255


SetIndexStyle関数で指定できるds_Sectionとds_Lineの違いを調べてみました。
先ほどのプログラムのds_Symbolをds_Sectionとds_Lineに変更してみました。
ds_Lineでは何も表示されませんでした。隣のバッファが空の時は線を引かないようです。


ds_Histogram では表示できました。


forex tester2 販売
Forex Tester 2の購入はこちらから。
カレンダー
03 2025/04 05
S M T W T F S
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
カテゴリー
フリーエリア



最新記事
最新CM
最新TB
RSS
ブログ内検索
アーカイブ
最古記事
プロフィール
HN:
fx練習生
年齢:
50
性別:
男性
誕生日:
1975/04/03
職業:
夢は専業トレーダー
趣味:
fx
自己紹介:
fxの専業トレーダーになって経済的自由と時間的自由を手に入れたいです。
自分で売買ルールを作成してテストして自信をもってリアルトレードしたいです。
P R