■超直感!MT4プログラミング講座■ 第33回 発注スプリクトをサブルーチン化する(2)

スポンサーリンク

こんにちは。キリンです。
昨日、同い年の投資を始めている医大生とお会いしてきました。
すでに何度か事業にもチャレンジされて、撤退もした経験をお持ちです。
素晴らしい行動力だなぁと思いつつ、
僕も負けてられないという意識にさせてもらいました。
こういうつながりを広めていきたいものですね!
関西でお会いできる方、ご連絡いただければ飛んでいきますので(w
では、本日の講義です。


第33回 発注スプリクトをサブルーチン化する(2)

■発注サブルーチン
■サブルーチンの説明
■まとめ
■発注スプリクト
これからはかなり本格的な内容になってきます。
実際に使えるサブルーチンですので、
コピーしていただいても構いません。
※参考文献
FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ)/豊嶋久道

¥2,940
Amazon.co.jp
// 注文時の矢印の色

color ArrowColor[6] = {Blue, Red, Blue, Red, Blue, Red};
bool KirinOrderSend(int type, double lots, double price, int slippage, double slpips, double tppips, string comment, int magic)
{
int mult=1;
if(Digits == 3 || Digits == 5) mult=10;
slippage *= mult;
if(type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP) mult*=-1;
double sl=0, tp=0;
if(slpips > 0) sl = price – slpips * Point * mult;
if(tppips > 0) tp = price + tppips * Point * mult;
price = NormalizeDouble(price, Digits);
sl = NormalizeDouble(sl, Digits);
tp = NormalizeDouble(tp, Digits);
int starttime = GetTickCount();
while(true)
{
if(GetTickCount() – starttime > 10*1000)
{
Alert(“OrderSend timeout. Check the experts log.”);
return(false);
}
if(IsTradeAllowed() == true)
{
RefreshRates();
if(OrderSend(Symbol(), type, lots, price, slippage, sl, tp, comment, magic, 0, ArrowColor[type]) != -1) return(true);
int err = GetLastError();
Print(“[OrderSendError] : “, err, ” “, ErrorDescription(err));
if(err == ERR_INVALID_PRICE) break;
if(err == ERR_INVALID_STOPS) break;
}
Sleep(100);
}
return(false);
}

上記が僕が使っているスプリクトの一部です。
ブログ用に改変していますが、十分役に立つと思います。
■サブルーチンの説明
では、簡単に説明していきます。

int mult=1;
if(Digits == 3 || Digits == 5) mult=10;

上記は業者によるDigitsの差をなくすために、
桁数が多い5digitsの業者の場合、10倍するようにしています。
その準備ですね。

slippage *= mult;
if(type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP) mult*=-1;
double sl=0, tp=0;
if(slpips > 0) sl = price – slpips * Point * mult;
if(tppips > 0) tp = price + tppips * Point * mult;
price = NormalizeDouble(price, Digits);
sl = NormalizeDouble(sl, Digits);
tp = NormalizeDouble(tp, Digits);

上記はmultを使ってオーダーの種別により逆指値、指値を計算しています。
売りの場合は買いの場合と逆の計算をするので、
if文を使って符号を変えています。
▼doulbe NormalizeDouble(double num, int digit)
numの小数点以下の桁数をdigitに揃えます。
▼int Point
表示している通貨の1pipを返します
※重要
なぜ、priceにもNormalizeDoubleをしているかというと、
バックテストデータにはたまにゴミがあって、
4digitsの業者に5digitsのデータがあったりするんです。
その際、オーダーが通らずにエラーで返ってきてしまいます。
それを防ぐためにやってるんですね。
AskやBidも注文を通す際には必ずNormalizeDoubleをする必要があります。
ご注意ください。

int starttime = GetTickCount();

▼int GetTickCount()
start()が開始されてからの時間をミリ単位で返します

while(true)
{
if(GetTickCount() – starttime > 10*1000)
{
Alert(“OrderSend timeout. Check the experts log.”);
return(false);
}
if(IsTradeAllowed() == true)
{
RefreshRates();
if(OrderSend(Symbol(), type, lots, price, slippage, sl, tp, comment, magic, 0, ArrowColor[type]) != -1) return(true);
int err = GetLastError();
Print(“[OrderSendError] : “, err, ” “, ErrorDescription(err));
if(err == ERR_INVALID_PRICE) break;
if(err == ERR_INVALID_STOPS) break;
}
Sleep(100);
}
return(false);

whileで無限ループを発生させ、breakでループが崩されるまで動作し続けます。
そして、そのループが崩される条件のひとつが時間的制約です。
それが
if(GetTickCount() – starttime > 10*1000)
で表現されています。
▼void Alert(string txt)
ポップアップで警告を出します。
▼bool IsTradeAllowed()
トレードができる状態なのかを返します。
トレードできる状態ならtrue,
できなければfalseです。
▼RefreshRates()
AskとBidの値をチャートから再度取得します。
start()がはじまってからtick発生によるズレを回避します。
▼ArrowColor[]
あらかじめ冒頭で発注の種類による色の指定を行っておきました。
▼GetLastError()
プログラムで一番最後に発生したエラーを取得できます。
エラーの種類によって、リピートさせないかを判断しています。
今回のプログラムの場合、
リピートさせないエラーは、逆指値、指値注文が近すぎるときです。
▼Sleep(int time)
timeの時間の間、待機します。
■まとめ
簡単に要約しますと、10秒間の間に0.1秒に1回、注文が通るまで繰り返し注文をし続けるプログラムになります。
注文が通れば終了しますし、特定のエラーになれば終了します。
注文のタイプも自動で分けているため、成り行き、OCO等に万能に機能します。
これは使えると思いますよ^^
豊嶋先生に感謝です。
今日もお読みくださり、ありがとうございます!

コメント

  1. baron より:

    キリンさんお久しぶりです。
    GBPJPYの3桁でTICKMILLというブローカーでトレーリングストップを使用できていますが、
    XMというブローカーではトレーリングストップが出来ません。
    エラー130が表示されます。 ブローカーで使用出来るもの出来ないものがあるのでしょうか。
    トレーリングストップは1にしています。
    _point = Point;
    if (Digits % 2 == 1)
    {
    _point *= 10;
    Slippage *= 10;
    }

    maxlot = MarketInfo(Symbol(), MODE_MAXLOT);
    minlot = MarketInfo(Symbol(), MODE_MINLOT);

    double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP);
    if(NormalizeDouble(lotstep, 3) <= 0.001) lotdigit = 3;
    else if(NormalizeDouble(lotstep, 2) <= 0.01) lotdigit = 2;
    else if(NormalizeDouble(lotstep, 1) <= 0.1) lotdigit = 1;
    else lotdigit = 0;

    trade_mode = 0;

タイトルとURLをコピーしました