まず “何を条件(シグナル)にするか” をきっちり決めるのがコツです。移動平均だけでも、決め方は意外と多いです。
1) 移動平均だけで作れる代表的な売買条件パターン
A. ゴールデンクロス/デッドクロス(基本)
買い:短期MAが長期MAを下→上にクロス
売り:短期MAが長期MAを上→下にクロス
必要なパラメータMA期間(例:Fast=10 / Slow=50)
MA種類(SMA/EMAなど)
適用価格(Closeが一般的)
どの足で判定するか(新しいバー確定で判定推奨)
B. 1本MAの“傾き”でトレンド判定(MA slope)
買い:MAが上向き(MA[0] > MA[1])
売り:MAが下向き(MA[0] < MA[1])
※ノイズが多いので、MA[0] - MA[1] > 閾値 のような“最低傾き”を入れるのが定番です(これもMA値だけで作れます)。
C. 価格とMAの位置(乖離を含む)
買い:終値がMAより上で確定(Close[1] > MA[1])
売り:終値がMAより下で確定
さらに「MAからの距離(乖離)が一定以上のときだけ」なども可能(Close-MAだけで完結)。
D. 3本MA(順序)でフィルタ(いわゆる“パーフェクトオーダー”)
買い:短期 > 中期 > 長期
売り:短期 < 中期 < 長期
クロスよりダマしが減りやすい一方、入りが遅れやすいです。
2) “EAとして成立させるため”に最低限決めるべき条件(超重要)
移動平均シグナルだけ決めても、EAは事故ります。以下を先にルール化すると安定します。
エントリー関連
判定タイミング:ティックごとではなく「新しいバーが確定したときだけ」がおすすめ
(同じバーの中で何度もクロスした扱いになりやすい)同方向のポジション制限:すでに買いがあるなら追加しない、など
決済(出口)関連(ここが成績の大半を決めます)
移動平均だけでも出口は作れます:
反対クロスでドテン or 決済
MAを割ったら撤退(CloseがMAを反対側で確定したら)
固定SL/TP(これはMA以外ですがEAとしてはほぼ必須。最低でもSL推奨)
トレーリング(MAを追従線として使う:例「SlowMAの反対側に来たらクローズ」)
リスク管理(証拠金取引なので必須)
ロット計算(固定ロット or 口座残高%)
最大スプレッドで取引停止
取引時間帯フィルタ(スプレッドが広い時間を避ける)
3) まずはこれで動く:2本MAクロスEAの“条件例”
指標:EMA(Fast=10 / Slow=50)
エントリー:バー確定時のクロス
決済:反対クロスでクローズ(またはドテン)
フィルタ:スプレッドが一定以下のみ
4) MQL5の最小サンプル(2本MAクロス、バー確定で判定)
※そのまま貼って動く“骨格”です。細部(SL/TP/ロット)を足していく形が安全です。
//+------------------------------------------------------------------+
//| Simple MA Crossover EA (MT5 / MQL5) |
//+------------------------------------------------------------------+
#property strict
#include <Trade/Trade.mqh>
CTrade trade;
input int FastPeriod = 10;
input int SlowPeriod = 50;
input ENUM_MA_METHOD MaMethod = MODE_EMA;
input ENUM_APPLIED_PRICE PriceType = PRICE_CLOSE;
input double Lots = 0.10;
input int MaxSpreadPoints = 30; // 例: 30 points
int fastHandle, slowHandle;
datetime lastBarTime = 0;
bool IsNewBar()
{
datetime t = iTime(_Symbol, _Period, 0);
if(t != lastBarTime)
{
lastBarTime = t;
return true;
}
return false;
}
bool GetMA(int handle, double &ma0, double &ma1)
{
double buf[2];
if(CopyBuffer(handle, 0, 0, 2, buf) != 2) return false;
ma0 = buf[0]; // current bar (still forming)
ma1 = buf[1]; // previous closed bar
return true;
}
int OnInit()
{
fastHandle = iMA(_Symbol, _Period, FastPeriod, 0, MaMethod, PriceType);
slowHandle = iMA(_Symbol, _Period, SlowPeriod, 0, MaMethod, PriceType);
if(fastHandle == INVALID_HANDLE || slowHandle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(fastHandle != INVALID_HANDLE) IndicatorRelease(fastHandle);
if(slowHandle != INVALID_HANDLE) IndicatorRelease(slowHandle);
}
void OnTick()
{
// スプレッドフィルタ
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
if(spread > MaxSpreadPoints) return;
// バー確定ごとに判定(ダマしと多重発注を減らす)
if(!IsNewBar()) return;
double f0,f1,s0,s1;
if(!GetMA(fastHandle, f0, f1)) return;
if(!GetMA(slowHandle, s0, s1)) return;
// クロス判定は「確定足どうし」で見るのが基本 → f1/s1 と f2/s2 を見たいが
// 最低限、前足(1)とその一つ前(2)で判断するのが堅い。
// ここでは簡易に CopyBuffer の取り方を変えて2本見る例にする:
double f[3], s[3];
if(CopyBuffer(fastHandle, 0, 0, 3, f) != 3) return;
if(CopyBuffer(slowHandle, 0, 0, 3, s) != 3) return;
double f1c = f[1], f2c = f[2];
double s1c = s[1], s2c = s[2];
bool crossUp = (f2c <= s2c) && (f1c > s1c);
bool crossDown = (f2c >= s2c) && (f1c < s1c);
// いまのポジション状況
bool hasPos = PositionSelect(_Symbol);
long posType = hasPos ? (long)PositionGetInteger(POSITION_TYPE) : -1;
if(crossUp)
{
// 反対ポジがあればクローズ
if(hasPos && posType == POSITION_TYPE_SELL) trade.PositionClose(_Symbol);
// 買いがなければ新規
if(!PositionSelect(_Symbol)) trade.Buy(Lots, _Symbol);
}
else if(crossDown)
{
if(hasPos && posType == POSITION_TYPE_BUY) trade.PositionClose(_Symbol);
if(!PositionSelect(_Symbol)) trade.Sell(Lots, _Symbol);
}
}
5) 失敗しがちな点(MAだけEAで特に多い)
ティックごと判定で同バー内に連打してしまう → 新バー確定で判定
クロス判定に「確定足」を使っていない → [1]と[2]で判定が堅い
出口が弱い(エントリーより出口が重要)
スプレッド・約定拒否・ロット計算などの実運用要件が抜ける
0 件のコメント:
コメントを投稿