こんにちは。キリンです。
昨日、同い年の投資を始めている医大生とお会いしてきました。
すでに何度か事業にもチャレンジされて、撤退もした経験をお持ちです。
素晴らしい行動力だなぁと思いつつ、
僕も負けてられないという意識にさせてもらいました。
こういうつながりを広めていきたいものですね!
関西でお会いできる方、ご連絡いただければ飛んでいきますので(w
では、本日の講義です。
■発注サブルーチン
■サブルーチンの説明
■まとめ
■発注スプリクト
これからはかなり本格的な内容になってきます。
実際に使えるサブルーチンですので、
コピーしていただいても構いません。
※参考文献
FXメタトレーダー実践プログラミング (現代の錬金術師シリーズ)/豊嶋久道
¥2,940
Amazon.co.jp
// 注文時の矢印の色
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);
}
上記が僕が使っているスプリクトの一部です。
ブログ用に改変していますが、十分役に立つと思います。
■サブルーチンの説明
では、簡単に説明していきます。
if(Digits == 3 || Digits == 5) mult=10;
上記は業者によるDigitsの差をなくすために、
桁数が多い5digitsの業者の場合、10倍するようにしています。
その準備ですね。
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 GetTickCount()
start()が開始されてからの時間をミリ単位で返します
{
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等に万能に機能します。
これは使えると思いますよ^^
豊嶋先生に感謝です。
今日もお読みくださり、ありがとうございます!
コメント
キリンさんお久しぶりです。
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;