[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
これくらいのことで徹夜しました。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ボックスの高値と安値です。
高値と安値を超えたら白い文字が表示されます。
動画もアップしてみました。
『NYボックス』という手法があります。
日本時間にNY時間の高値と安値をブレイクしたらその方向にXXpip以上動くことが
多いことを利用する手法です。
ブレイクしてもXXpip動かなかったら反対の方向に動くことが多いことも利用します。
それを検証するためにインディケーターを探していたら
Meta Trader4用のが2つ見つかりました。
Sessions.mq4
BreakOut-EAGLE__ut2DaMax.mq4
BreakOut-EAGLE__ut2DaMax.mq4
のほうがわかりやすいので移植に挑戦してみたいと思います。
動作確認しようとしたら変なエラーが表示されて実行不可能でした。
エラー内容
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)のシグナルとほぼ同じです。
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期間の平均です。
計算部分だけのコードです。
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の移動平均線にしました。終値を使用しました。
パラメータを変更できるようにはしていません。
パラメータ変更する時は再コンパイルする自分仕様です。
ひまわり証券の自動売買システム「エコトレ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 で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関数の第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 では表示できました。
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 |
自分で売買ルールを作成してテストして自信をもってリアルトレードしたいです。