ストキャスティクスの%Kと%Dが交差した瞬間を、
矢印で知らせるだけでなく、実際に発注まで行いたい。
この記事では既刊の矢印表示インジケーターを土台に、
買われすぎ・売られすぎ領域だけに絞るフィルターと、
損切り必須・ポジション重複防止を備えたEAを作ります。
・iStochastic関数のmode引数(%K/%D)を使ったクロス判定
・買われすぎ・売られすぎ領域だけに絞るフィルター設計
・損切り必須・ポジション重複防止という資金管理の基本
・実際に動くEAのコード全体
ストキャスティクスクロスEAの全体像
まず、このEAがどういう流れで動くのかを確認します。
既刊インジケーターとの役割分担
・既刊の矢印インジケーター記事は矢印のみ
・本記事は同じ判定ロジックで発注まで行うEAに発展
・買われすぎ・売られすぎ領域に絞る考え方も、そのまま引き継ぐ
このEAが対応するポジションの数
シンプルさを優先し、
この記事のEAは同時に1ポジションまでしか持たない設計にしています。
状態ではなく変化を検知する
「%Kが%Dより上にある」という状態のまま条件にすると、
その状態が続く間ずっとエントリーしようとしてしまいます。
このEAも既刊インジケーターと同じく、
「いま交差したか」という変化だけを発注条件にします。
iStochastic関数の引数とクロス判定
発注条件の土台になる、iStochastic関数の使い方を確認します。
iStochasticのシグネチャ
double iStochastic( string symbol, int timeframe, int Kperiod, int Dperiod, int slowing, int method, int price_field, int mode, int shift );
`mode`に`MODE_MAIN`(0)を指定すると%Kの値、
`MODE_SIGNAL`(1)を指定すると%Dの値が、
それぞれ取得できます。
1本前との比較でクロスを検知する
//今の確定足と1本前の確定足を比較 currentK > currentD && previousK <= previousD //ゴールデンクロス currentK < currentD && previousK >= previousD //デッドクロス
1本前の関係と今の関係を比較することで、
クロスが発生した瞬間だけを取り出せます。
確定足だけを判定に使う理由
形成中の0番目の足は値が変化し続けて確定していないため、
このEAはshift=1(直近の確定足)とshift=2(その1本前)を基準に判定します。
買われすぎ・売られすぎ領域だけに絞るフィルター
クロスの発生場所を絞り込み、エントリー精度を上げます。
既刊インジケーターのFilterByZoneという考え方
既刊stochastic-cross-arrow-indicator-mt4.mdでは、
買われすぎ・売られすぎ領域だけに絞るオプションを用意していました。
本記事では、このフィルターを発注条件に組み込みます。
20以下・80以上に限定する条件
bool buySignal = (currentK > currentD && previousK <= previousD && previousK <= InpOversold); bool sellSignal = (currentK < currentD && previousK >= previousD && previousK >= InpOverbought);
クロスの直前の%Kが、
売られすぎ(20以下)・買われすぎ(80以上)の領域にあったときだけ、
シグナルをtrueにします。
フィルターを外すとどうなるか
・フィルターを外すとクロスのたびにエントリーしてしまう
・トレンドの強い相場では中央付近のクロスが連発し、ダマシが増える
・買われすぎ・売られすぎ領域への絞り込みは、逆張りの精度を上げる基本的な工夫
損切り・ポジション重複防止という資金管理の基本
発注する前に、必ず組み込むべき安全策を確認します。
損切り(StopLoss)は必ず設定する
・損切りを設定しないEAは、1回の逆行で大きな損失につながる
・この記事のEAはInpStopLossPipsで必ず損切り値を指定する設計にする
・0を指定しても動くコードにはしない(人為的に無効化できないようにする)
マジックナンバーで自分の注文だけを数える
int CountMyOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == InpMagicNumber && OrderSymbol() == _Symbol)
count++;
}
}
return(count);
}
他のEAや手動注文を数に含めないよう、
マジックナンバーと通貨ペアで絞り込みます。
ポジション重複エントリーを防ぐ
`CountMyOrders() == 0`を新規エントリーの条件に加えることで、
すでに1ポジション持っている状態での二重発注を防ぎます。
実際に動くEAのコード全体
ここまでの要素をまとめたEAの全体です。
//+------------------------------------------------------------------+
//| StochasticCrossEA.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property strict
input int InpKperiod = 5; //%K計算期間
input int InpDperiod = 3; //%D計算期間
input int InpSlowing = 3; //スローイング
input double InpOversold = 20.0; //売られすぎ閾値
input double InpOverbought = 80.0; //買われすぎ閾値
input double InpLots = 0.1; //発注ロット数
input int InpStopLossPips = 20; //損切り(pips)
input int InpSlippage = 3; //許容スリッページ
input int InpMagicNumber = 20261015;//マジックナンバー
int CountMyOrders()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == InpMagicNumber && OrderSymbol() == _Symbol)
count++;
}
}
return(count);
}
int OnInit()
{
if(InpStopLossPips <= 0)
{
Alert("InpStopLossPipsは1以上を指定してください(損切り必須設計)");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
void OnTick()
{
if(Bars < (InpKperiod + InpDperiod + InpSlowing + 3))
return;
double currentK = iStochastic(NULL, 0, InpKperiod, InpDperiod, InpSlowing, MODE_SMA, 0, MODE_MAIN, 1);
double currentD = iStochastic(NULL, 0, InpKperiod, InpDperiod, InpSlowing, MODE_SMA, 0, MODE_SIGNAL, 1);
double previousK = iStochastic(NULL, 0, InpKperiod, InpDperiod, InpSlowing, MODE_SMA, 0, MODE_MAIN, 2);
double previousD = iStochastic(NULL, 0, InpKperiod, InpDperiod, InpSlowing, MODE_SMA, 0, MODE_SIGNAL, 2);
bool buySignal = (currentK > currentD && previousK <= previousD && previousK <= InpOversold);
bool sellSignal = (currentK < currentD && previousK >= previousD && previousK >= InpOverbought);
if(CountMyOrders() > 0)
return;
double pip = (Digits == 3 || Digits == 5) ? Point * 10 : Point;
if(buySignal)
{
double sl = Bid - InpStopLossPips * pip;
OrderSend(_Symbol, OP_BUY, InpLots, Ask, InpSlippage, sl, 0,
"StochasticCrossEA", InpMagicNumber, 0, clrBlue);
}
else if(sellSignal)
{
double sl = Ask + InpStopLossPips * pip;
OrderSend(_Symbol, OP_SELL, InpLots, Bid, InpSlippage, sl, 0,
"StochasticCrossEA", InpMagicNumber, 0, clrRed);
}
}
`price_field`を0に固定しているのは、
既刊インジケーター記事と同じ、安値・高値を基準にした標準的な計算方法です。
MetaEditorでのコンパイル・バックテスト手順
実際に動かすまでの手順です。
- MetaEditorで新規EA「StochasticCrossEA」を作成し、上のコードを貼り付けてコンパイルする
- 「0 error(s), 0 warning(s)」になることを確認する
- ストラテジーテスターで任意の通貨ペア・期間を指定し、「全ティック」モードでバックテストする
- InpOversold・InpOverboughtの値を変えて、エントリー回数の変化を確認する
よくあるエラーと注意点
実装・運用でつまずきやすいポイントをまとめます。
OrderSendが失敗してもエラー処理がない
・このコードは解説用にOrderSendの戻り値チェックを省略している
・実運用では戻り値が-1の場合にGetLastError()で原因を調べる処理を追加する
・既刊get-last-error.mdのエラーコード確認方法が参考になる
フィルターが厳しすぎてエントリーが来ない
InpOversold・InpOverboughtを20・80のままにすると、
強いトレンド中はシグナルがほとんど出ないことがあります。
値を25・75のように緩めると、エントリー頻度を調整できます。
損切り幅を狭くしすぎるとすぐ決済される
InpStopLossPipsを極端に小さくすると、
通常のスプレッドの範囲内で損切りに達してしまうことがあります。
よくある質問
ストキャスティクスクロスEAについて、よく検索される疑問に回答します。
既刊の矢印インジケーターとの違いは何ですか?
既刊stochastic-cross-arrow-indicator-mt4.mdは、
画面に矢印を表示するだけです。
本記事はまったく同じクロス判定・フィルターの考え方を使いながら、
実際にOrderSendで発注するところまで実装している点が違いです。
MACDクロスと組み合わせられますか?
できます。
既刊macd-cross-ea-mt4.mdのゴールデンクロス判定をif文に追加すれば、
ストキャスティクス+MACDの2条件フィルターにできます。
このEAは必ず勝てますか?
断定はできません。
ストキャスティクスは買われすぎ・売られすぎを示す指標であり、
強いトレンド中は閾値に張り付いたままダマシが増えることがあります。
損切り設定は外さずに運用することをおすすめします。
【MQL4】ストキャスティクスの%Kと%DのクロスでエントリーするEAの作り方(買われすぎ・売られすぎ絞り込み設計):まとめ
既刊の矢印表示インジケーターで使ったiStochasticのクロス判定ロジックは、
買われすぎ・売られすぎ領域への絞り込みとあわせて、
そのままOrderSendの発注条件に転用できます。
「またいだ瞬間」だけ反応する判定と、
損切り必須・ポジション重複防止という資金管理の基本を、
組み合わせることが、実運用に耐える設計の最低条件です。
コメント