MQL4MQL5 スクリプト 注文・決済
損切り・利確を pips で指定して注文したい
結論:1pips の大きさ(5桁・3桁口座は _Point × 10)を求め、損切り・利確の価格を計算して NormalizeDouble() で丸めます。
考え方
注文に付ける損切り・利確は「価格」で指定します。pips で決めたい場合は、1pips が何円(何ドル)かを求めて価格に換算します。5桁(ドルストレート)・3桁(クロス円)の口座では 1pips = 10 ポイントです。また、損切り・利確は現在値からストップレベル以上離す必要があり、近すぎると MT4 はエラー130、MT5 はリターンコード 10016 になります。
- 1pips の大きさを求める(_Digits が 3 か 5 なら _Point × 10)
- 買いなら 損切り=Bid − 幅、利確=Bid + 幅。売りなら 損切り=Ask + 幅、利確=Ask − 幅
- ストップレベルより近ければ広げ、NormalizeDouble(価格, _Digits) で丸める
- 計算した損切り・利確を付けて注文する
そのまま使えるコード
MetaEditor の「新規作成」で「スクリプト」を選び、できたファイルの中身をすべてこのコードに置き換えてコンパイル(F7)します。ファイルは Scripts フォルダに保存され、ナビゲーターからチャートにドラッグして使います。
MQL4(MT4)
#property strict
#property script_show_inputs
// 損切り・利確を pips で指定して成行注文するスクリプト(MT4)
input bool InpBuy = true; // true=買い、false=売り
input double InpLots = 0.1; // ロット
input double InpSL = 20; // 損切り(pips)
input double InpTP = 40; // 利確(pips)
double PipSize()
{
return (_Digits == 3 || _Digits == 5) ? _Point * 10 : _Point;
}
void OnStart()
{
RefreshRates();
double pip = PipSize();
double stop = MarketInfo(_Symbol, MODE_STOPLEVEL) * _Point; // 最小距離
double slW = MathMax(InpSL * pip, stop + _Point);
double tpW = MathMax(InpTP * pip, stop + _Point);
double sl, tp, price;
int type;
if(InpBuy) { type = OP_BUY; price = Ask; sl = Bid - slW; tp = Bid + tpW; }
else { type = OP_SELL; price = Bid; sl = Ask + slW; tp = Ask - tpW; }
sl = NormalizeDouble(sl, _Digits);
tp = NormalizeDouble(tp, _Digits);
int ticket = OrderSend(_Symbol, type, InpLots, price, 30, sl, tp);
if(ticket < 0)
Print("注文失敗 error=", GetLastError(), " sl=", sl, " tp=", tp);
else
Print("注文成功 ticket=", ticket, " sl=", sl, " tp=", tp);
}MQL5(MT5)
#property script_show_inputs
// 損切り・利確を pips で指定して成行注文するスクリプト(MT5)
#include <Trade\Trade.mqh>
input bool InpBuy = true; // true=買い、false=売り
input double InpLots = 0.1; // ロット
input double InpSL = 20; // 損切り(pips)
input double InpTP = 40; // 利確(pips)
double PipSize()
{
return (_Digits == 3 || _Digits == 5) ? _Point * 10 : _Point;
}
void OnStart()
{
double pip = PipSize();
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double stop = (double)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * _Point; // 最小距離
double slW = MathMax(InpSL * pip, stop + _Point);
double tpW = MathMax(InpTP * pip, stop + _Point);
CTrade trade;
bool sent;
if(InpBuy)
sent = trade.Buy(InpLots, _Symbol, 0, NormalizeDouble(bid - slW, _Digits), NormalizeDouble(bid + tpW, _Digits));
else
sent = trade.Sell(InpLots, _Symbol, 0, NormalizeDouble(ask + slW, _Digits), NormalizeDouble(ask - tpW, _Digits));
if(!sent || trade.ResultRetcode() != TRADE_RETCODE_DONE)
Print("注文失敗 ", trade.ResultRetcode(), " ", trade.ResultRetcodeDescription());
else
Print("注文成功 deal=", trade.ResultDeal());
}MT4 版・MT5 版とも MetaEditor でコンパイル(エラー・警告なし)を確認済みです。実際の口座で使う前に、デモ口座やストラテジーテスターで動作を確かめてください。
カスタマイズのポイント
- 損切りを付けないときは 0 を渡します(利確も同じ)。
- 口座によっては成行注文と同時に損切り・利確を付けられない(Market 執行)ことがあります。その場合は注文のあとに OrderModify()・PositionModify() で付けます。
注意点
- 売りの損切りは現在値より上、利確は下です。向きを間違えるとエラーになります。
このコードで使っている関数
うまく動かないときに出やすいエラー
あわせて読みたいレシピ
- 成行で買い・売りの注文を出したいMQL4 は OrderSend(銘柄, OP_BUY, ロット, Ask, …)、MQL5 は CTrade の trade.Buy(ロット) を使います。
- pips とポイントを正しく換算したい(3桁・5桁対応)_Digits が 3 か 5 の口座では 1pips = 10 ポイント(_Point × 10)、2 か 4 の口座では 1pips = 1 ポイントです。
- トレーリングストップを入れたい現在値から一定の幅をとった位置に損切りを計算し、今の損切りより有利なときだけ OrderModify()・PositionModify() で動かします。
- 含み益が出たら損切りを建値に移動したい含み益が一定に達したら、損切りを建値(+少しの利益)に変更します。変更は1回だけになるよう、今の損切りと比べます。












