今回はMT4の自動売買用EAサンプルソース(FX用)を、プログラミング初心者の方向けに解説しています。
はじめに
今回はバー(ローソク足)に関わる関数や処理をご紹介します。
- 買いポジション又は売りポジションで、エントリーから何本のローソク足が経過したかを判定する関数
- 直近ローソク足で陽線の数をカウントする関数
- 直近ローソク足で陰線の数をカウントする関数
- エントリー後、バーが〇本を経過&損失中で決済する関数
- バーが新たに出来た時だけ処理を行いたい場合の処理
それでは、1つ見ていきましょう。
関数
買いポジション又は売りポジションで、エントリーから何本のローソク足が経過したかを判定する関数
int CountBarsSinceEntry(int positionType)
{
datetime entryTime = 0;
// 指定タイプのポジションを探す(現在のシンボル)
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderType() == positionType)
{
entryTime = OrderOpenTime();
break; // 最初に見つけたポジションだけ使う
}
}
}
if (entryTime == 0)
{
return -1;
}
int barCount = 1;
for (int i = 1; i < Bars; i++) // 確定済み足のみ
{
if (Time[i] <= entryTime)
break;
barCount++;
}
return barCount;
}
引数
OP_BUY[0] または OP_SELL[1]を渡しましょう。
戻り値
正常な場合、エントリーから何本のローソク足が経過したかを返します。
ポジションが見つからない等エラーの場合は、-1を返します。
使い方
簡単な使い方です。新規注文から一定期間(バー数)経過で決済をしています。
//新規注文(買い)から10バー経過でクローズ
if(CountBarsSinceEntry(OP_BUY) >= 10){
funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
}
//新規注文(売り)から30バー経過でクローズ
if(CountBarsSinceEntry(OP_SELL) >= 30){
funcOrder_Close(OP_SELL,0,MAGIC_NO,clrGray);
}
直近ローソク足で陽線の数をカウントする関数
// 直近countBars本のローソク足で陽線の数をカウントする関数
int CountYousen(int countBars)
{
int bearishCount = 0;
for (int i = 1; i <= countBars; i++) // i=1から。i=0は未確定足のため除外
{
if (Close[i] > Open[i]) {
bearishCount++;
}
}
return bearishCount;
}
引数
直近から何本分カウントするかを渡しましょう。
戻り値
陽線の本数を返します。
使い方
簡単な使い方です。陽線が5本連続したらクローズという使い方です。
if(CountYousen(5) >= 5){
Print("陽線が5本連続したためクローズします");
funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
}
直近ローソク足で陰線の数をカウントする関数
// 直近countBars本のローソク足で陰線の数をカウントする関数
int CountInsen(int countBars)
{
int bearishCount = 0;
for (int i = 1; i <= countBars; i++) // i=1から。i=0は未確定足のため除外
{
if (Close[i] < Open[i]) {
bearishCount++;
}
}
return bearishCount;
}
引数
直近から何本分カウントするかを渡しましょう。
戻り値
陰線の本数を返します。
使い方
簡単な使い方です。直近のローソク足20本中に陰線が10本確認されたらクローズという使い方です。
if(CountInsen(20) >= 10){
Print("陰線が複数確認されたので決済します");
funcOrder_Close(OP_BUY,0,MAGIC_NO,clrGray);
}
エントリー後、バーが〇本を経過&損失中で決済する関数
// エントリー後、バーが〇本を経過&損失中で決済する関数
void CountCloseChk(int countBars)
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
//オーダー後、バーが10本を超えた かつ 損失中の場合決済する
if(OrderOpenTime() < iTime(NULL, 0, countBars) && OrderProfit() < 0){
OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
}
}
}
引数
バー何本から決済チェックするかを渡しましょう。
戻り値
なし。
使い方
簡単な使い方です。基本呼び出すだけでOKです。
//エントリー後、バーが10本を経過&損失中で決済する
CountCloseChk(10);
バーが新たに出来た時だけ処理を行いたい場合の処理
datetime prevtime = 0;
void OnTick()
{
//新しい足ができた時だけ処理する
if(Time[0] != prevtime){
//時間を更新して処理を続行する
prevtime = Time[0];
}else{
//処理せずに終わる
return;
}
~~~~~~~~~~~~
解説
まず、Time[0]の値をセット(退避)するためにprevtimeというグローバル変数を設けます。
Time[0]は新しい足ができた時の時間がセットされているので、簡単に15分足とかでイメージしてもらうと 2021/04/01 18:15:00.000のような感じの値がセットされています。(実際は秒数)
このTime[0]は2021/04/01 18:30:00.000になるまで変わりません。
よって、2021/04/01 18:18:40.000とかの場合は、
Time[0]=2021/04/01/ 18:15:00.000
prevtime=2021/04/01/ 18:15:00.000
で同じ値となるためreturn;が実行されるので、以降処理はしない作りになっています。よって、エントリーもしないしエントリーするかどうかの判断もなくなります。
時間が進み2021/04/01 18:30:00.000になったジャストタイミングで、
Time[0]=2021/04/01/ 18:30:00.000
prevtime=2021/04/01/ 18:15:00.000
という状況になります。この場合は値が違うので、prevtimeに2021/04/01/ 18:30:00.000をセットし、
エントリーするかどうかの判断をしたりエントリーする場合はエントリーするといった形になります。
※if文の条件からreturn;は実行されません
こうすることで、『バーが新たに出来た時だけ処理を行う』という事ができるわけです。
※私が作っているサンプルソースは基本殆どがこの形です
さいごに
以上、『バー(ローソク足)に関わる関数』でした。
※ EAのサンプルソース一覧表へ
コメント