mql5言語の特徴、微妙なニュアンスとテクニック - ページ 4 1234567891011...247 新しいコメント fxsaber 2017.02.25 15:12 #31 // Возвращает тип исполнения ордера, равный Type, если он доступен на символе Symb, иначе - корректный вариант.ENUM_ORDER_TYPE_FILLING GetFilling( const string Symb, const uint Type = ORDER_FILLING_FOK ){ const ENUM_SYMBOL_TRADE_EXECUTION ExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(Symb, SYMBOL_TRADE_EXEMODE); const int FillingMode = (int)::SymbolInfoInteger(Symb, SYMBOL_FILLING_MODE); return((FillingMode == 0 || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ? (((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ? ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) : (ENUM_ORDER_TYPE_FILLING)Type);} アプリケーションRequest.type_filling = GetFilling(Request.symbol); Features of the mql5 Unsupported filling mode What is fastest way fxsaber 2017.02.25 15:16 #32 // Возвращает тип истечения ордера, равный Expiration, если он доступен на символе Symb, иначе - корректный вариант.ENUM_ORDER_TYPE_TIME GetExpirationType( const string Symb, uint Expiration = ORDER_TIME_GTC ){ const int ExpirationMode = (int)::SymbolInfoInteger(Symb, SYMBOL_EXPIRATION_MODE); if ((Expiration > ORDER_TIME_SPECIFIED_DAY) || (((ExpirationMode >> Expiration) & 1) == 0)) { if ((Expiration < ORDER_TIME_SPECIFIED) || (ExpirationMode < SYMBOL_EXPIRATION_SPECIFIED)) Expiration = ORDER_TIME_GTC; else if (Expiration > ORDER_TIME_DAY) Expiration = ORDER_TIME_SPECIFIED; uint i = 1 << Expiration; while ((Expiration <= ORDER_TIME_SPECIFIED_DAY) && ((ExpirationMode & i) != i)) { i <<= 1; Expiration++; } } return((ENUM_ORDER_TYPE_TIME)Expiration);} アプリケーションRequest.type_time = GetExpirationType(Request.symbol, (uint)Expiration); // Expiration может быть datetime-временемif (Expiration > ORDER_TIME_DAY) Request.expiration = Expiration; Features of the mql5 Pending Order should cancel エラー、バグ、質問 fxsaber 2017.02.25 15:27 #33 MqlTrade構造体の文字列への変換#define TOSTRING(A) #A + " = " + (string)(A) + "\n"#define TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"string ToString( const MqlTradeTransaction &Trans ){ return(TOSTRING(Trans.deal) + TOSTRING(Trans.order) + TOSTRING(Trans.symbol) + TOSTRING2(Trans.type) + TOSTRING2(Trans.order_type) + TOSTRING2(Trans.order_state) + TOSTRING2(Trans.deal_type) + TOSTRING2(Trans.time_type) + TOSTRING(Trans.time_expiration) + TOSTRING(Trans.price) + TOSTRING(Trans.price_trigger) + TOSTRING(Trans.price_sl) + TOSTRING(Trans.price_tp) + TOSTRING(Trans.volume) + TOSTRING(Trans.position) + TOSTRING(Trans.position_by));}string ToString( const MqlTradeRequest &Request ){ return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) + TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) + TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) + TOSTRING(Request.tp) + TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) + TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) + TOSTRING(Request.position) + TOSTRING(Request.position_by));}string ToString( const MqlTradeResult &Result ){ return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) + TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) + TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) + TOSTRING(Result.retcode_external));}#undef TOSTRING#undef TOSTRING2 アプリケーションvoid OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result ){ Print(ToString(Trans) + ToString(Request) + ToString(Result));} 初心者の方からの質問 MQL5 MT5 MetaTrader MetaEditor build 1490 Features of the mql5 fxsaber 2017.02.25 15:30 #34 // Триггер срабатывания SL/TP - работает только на демо/реале (не в тестере).void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result ){ if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) && PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) && (PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE))) { const double Price = OrderGetDouble(ORDER_PRICE_OPEN); if (Price == PositionGetDouble(POSITION_TP)) Print("Position #" + (string)Trans.position + " - triggered TP."); else if (Price == PositionGetDouble(POSITION_SL)) Print("Position #" + (string)Trans.position + " - triggered SL."); }} MetaEditor build 1490 エラー、バグ、質問 Features of the mql5 fxsaber 2017.02.25 15:39 #35 ENUM_DAY_OF_WEEK GetDayOfWeek( const datetime time ){ MqlDateTime sTime = {0}; ::TimeToStruct(time, sTime); return((ENUM_DAY_OF_WEEK)sTime.day_of_week);}// true - находимся в торговой сессииbool SessionTrade( const string Symb ){ datetime TimeNow = ::TimeTradeServer(); const ENUM_DAY_OF_WEEK DayOfWeek = GetDayOfWeek(TimeNow); TimeNow %= 24 * 60 * 60; bool Res = false; datetime From, To; for (int i = 0; (!Res) && ::SymbolInfoSessionTrade(Symb, DayOfWeek, i, From, To); i++) Res = ((From <= TimeNow) && (TimeNow < To)); return(Res);}// Возвращает true, если символ торгуемый. Иначе - false.bool SymbolTrade( const string Symb ){ MqlTick Tick; return(::SymbolInfoTick(Symb, Tick) ? ((Tick.bid != 0) && (Tick.ask != 0) && SessionTrade(Symb) /* && ((ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(Symb, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL) */) : false);}アプリケーションif (OrderCheck(Request, CheckResult) && SymbolTrade(Request.symbol)) OrderSend(Request, Result); エラー、バグ、質問 Features of the mql5 Errors, bugs, questions Dmitry Fedoseev 2017.02.25 16:25 #36 物事はもっとシンプルでいいんです。注文を出す 前に履歴の長さを記憶し、出した後は履歴の長さが伸びるのを待つ。突然、永久に動かなくなることがないように、タイムアウトを入力する必要があります。 fxsaber 2017.02.25 16:29 #37 ドミトリー・フェドセーエフ: 物事はもっとシンプルでいいんです。注文を出す前に履歴の長さを記憶し、出した後は履歴の長さが伸びるのを待つ。突然、永久に動かなくなることがないように、タイムアウトを入力する必要があります。タイムアウトがある。あなたのバリアントでは、残念ながら、いくつかのOrderSendsが(異なるExpert Advisorから)一緒に動作する場合、問題が発生する可能性があります。また、履歴だけでなく、オープンポジション/注文の SL/TP等も同期されていません。市場の場合、最初は注文だけで履歴が増え、しばらくして取引で履歴が増えることがあります。それ以外の状況もあります。そのため、一見すると面倒くさそうに見えるのです。 Alexey Volchanskiy 2017.02.25 21:20 #38 ドミトリー・フェドセーエフメッセージのポイントは何ですか?OnTradeTransaction()で来るから何? イベントを待つしかないってことです。まだ待たなきゃいけないのか。fxsaberさんのメッセージの本質は、OrderSend()を実行した後、実行したアクションに関する情報がすぐにターミナルに表示されないということです。OnTradeTransaction()を待つのが好きな人もいれば、リストで注文や取引を確認するのが好きな人もいます。ここでは、例としてMT4との違いを紹介します。M4 では、OrderSend() の後、注文はすでに注文リストにあり、OrderClose() の後は、常に履歴に残ります。 また、なぜOnTradeTransaction() を待つのでしょうか?リクエストのキューを作り、答えがあれば、何かする...少なくともキューからリクエストを削除する。SBにはQueueがないのが残念ですが、シンプルなクラスです。 Dmitry Fedoseev 2017.02.26 06:18 #39 fxsaber: タイムアウトがある。あなたのバージョンでは、残念ながら、複数のOrderSendsが(異なるEAから)一緒に動作する場合、問題が発生する可能性があります。また、履歴だけでなく、オープンポジション/注文の SL/TP等も同期されていません。市場の場合、最初は注文だけで履歴が増え、しばらくして取引で履歴が増えることがあります。それ以外の状況もあります。そのため、一見すると面倒くさそうに見えるのです。はい、そうですね。でも、そんなEAは一度だけで、どちらかというと害はないでしょう。待機用の関数を別に書いて、標準の取引クラスも使えるようにした方が良いだろう。 Dmitry Fedoseev 2017.02.26 06:23 #40 アレクセイ・ヴォルチャンスキーなぜOnTradeTransaction() を待つのですか?リクエストのキューを作り、答えが来たら何かする...少なくともキューからリクエストを削除する。SBにQueueがないのは残念ですが、シンプルなクラスです。ポイントは、OrderSendの直後にOnTradeTransaction()が発動しないことです。要するに、ここでは議論の対象にならずに言い争うファンが群がっているだけなのです。OrderSend()の直後に何かをしなければならない場合、アルゴリズムには2つのバリエーションがあります。1.注文や案件のリストの更新を待つループを開始することができます。2.OnTick()を終了し、OnTradeTransaction()がトリガーするのを待ちます。3.新しい注文や案件がリストに表示されるかどうか、ティックで確認します。 1234567891011...247 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
ENUM_ORDER_TYPE_FILLING GetFilling( const string Symb, const uint Type = ORDER_FILLING_FOK )
{
const ENUM_SYMBOL_TRADE_EXECUTION ExeMode = (ENUM_SYMBOL_TRADE_EXECUTION)::SymbolInfoInteger(Symb, SYMBOL_TRADE_EXEMODE);
const int FillingMode = (int)::SymbolInfoInteger(Symb, SYMBOL_FILLING_MODE);
return((FillingMode == 0 || (Type >= ORDER_FILLING_RETURN) || ((FillingMode & (Type + 1)) != Type + 1)) ?
(((ExeMode == SYMBOL_TRADE_EXECUTION_EXCHANGE) || (ExeMode == SYMBOL_TRADE_EXECUTION_INSTANT)) ?
ORDER_FILLING_RETURN : ((FillingMode == SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) :
(ENUM_ORDER_TYPE_FILLING)Type);
}
ENUM_ORDER_TYPE_TIME GetExpirationType( const string Symb, uint Expiration = ORDER_TIME_GTC )
{
const int ExpirationMode = (int)::SymbolInfoInteger(Symb, SYMBOL_EXPIRATION_MODE);
if ((Expiration > ORDER_TIME_SPECIFIED_DAY) || (((ExpirationMode >> Expiration) & 1) == 0))
{
if ((Expiration < ORDER_TIME_SPECIFIED) || (ExpirationMode < SYMBOL_EXPIRATION_SPECIFIED))
Expiration = ORDER_TIME_GTC;
else if (Expiration > ORDER_TIME_DAY)
Expiration = ORDER_TIME_SPECIFIED;
uint i = 1 << Expiration;
while ((Expiration <= ORDER_TIME_SPECIFIED_DAY) && ((ExpirationMode & i) != i))
{
i <<= 1;
Expiration++;
}
}
return((ENUM_ORDER_TYPE_TIME)Expiration);
}
if (Expiration > ORDER_TIME_DAY)
Request.expiration = Expiration;
#define TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"
string ToString( const MqlTradeTransaction &Trans )
{
return(TOSTRING(Trans.deal) + TOSTRING(Trans.order) + TOSTRING(Trans.symbol) +
TOSTRING2(Trans.type) + TOSTRING2(Trans.order_type) + TOSTRING2(Trans.order_state) +
TOSTRING2(Trans.deal_type) + TOSTRING2(Trans.time_type) +
TOSTRING(Trans.time_expiration) + TOSTRING(Trans.price) + TOSTRING(Trans.price_trigger) +
TOSTRING(Trans.price_sl) + TOSTRING(Trans.price_tp) + TOSTRING(Trans.volume) +
TOSTRING(Trans.position) + TOSTRING(Trans.position_by));
}
string ToString( const MqlTradeRequest &Request )
{
return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) +
TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) +
TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) + TOSTRING(Request.tp) +
TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) +
TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) +
TOSTRING(Request.position) + TOSTRING(Request.position_by));
}
string ToString( const MqlTradeResult &Result )
{
return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) +
TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) +
TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) +
TOSTRING(Result.retcode_external));
}
#undef TOSTRING
#undef TOSTRING2
{
Print(ToString(Trans) + ToString(Request) + ToString(Result));
}
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
(PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
{
const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
if (Price == PositionGetDouble(POSITION_TP))
Print("Position #" + (string)Trans.position + " - triggered TP.");
else if (Price == PositionGetDouble(POSITION_SL))
Print("Position #" + (string)Trans.position + " - triggered SL.");
}
}
{
MqlDateTime sTime = {0};
::TimeToStruct(time, sTime);
return((ENUM_DAY_OF_WEEK)sTime.day_of_week);
}
// true - находимся в торговой сессии
bool SessionTrade( const string Symb )
{
datetime TimeNow = ::TimeTradeServer();
const ENUM_DAY_OF_WEEK DayOfWeek = GetDayOfWeek(TimeNow);
TimeNow %= 24 * 60 * 60;
bool Res = false;
datetime From, To;
for (int i = 0; (!Res) && ::SymbolInfoSessionTrade(Symb, DayOfWeek, i, From, To); i++)
Res = ((From <= TimeNow) && (TimeNow < To));
return(Res);
}
// Возвращает true, если символ торгуемый. Иначе - false.
bool SymbolTrade( const string Symb )
{
MqlTick Tick;
return(::SymbolInfoTick(Symb, Tick) ? ((Tick.bid != 0) && (Tick.ask != 0) && SessionTrade(Symb) /* &&
((ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(Symb, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL) */) : false);
}
アプリケーション
OrderSend(Request, Result);
物事はもっとシンプルでいいんです。注文を出す 前に履歴の長さを記憶し、出した後は履歴の長さが伸びるのを待つ。突然、永久に動かなくなることがないように、タイムアウトを入力する必要があります。
物事はもっとシンプルでいいんです。注文を出す前に履歴の長さを記憶し、出した後は履歴の長さが伸びるのを待つ。突然、永久に動かなくなることがないように、タイムアウトを入力する必要があります。
タイムアウトがある。あなたのバリアントでは、残念ながら、いくつかのOrderSendsが(異なるExpert Advisorから)一緒に動作する場合、問題が発生する可能性があります。
また、履歴だけでなく、オープンポジション/注文の SL/TP等も同期されていません。市場の場合、最初は注文だけで履歴が増え、しばらくして取引で履歴が増えることがあります。それ以外の状況もあります。そのため、一見すると面倒くさそうに見えるのです。
メッセージのポイントは何ですか?OnTradeTransaction()で来るから何? イベントを待つしかないってことです。まだ待たなきゃいけないのか。fxsaberさんのメッセージの本質は、OrderSend()を実行した後、実行したアクションに関する情報がすぐにターミナルに表示されないということです。OnTradeTransaction()を待つのが好きな人もいれば、リストで注文や取引を確認するのが好きな人もいます。ここでは、例としてMT4との違いを紹介します。M4 では、OrderSend() の後、注文はすでに注文リストにあり、OrderClose() の後は、常に履歴に残ります。
また、なぜOnTradeTransaction() を待つのでしょうか?リクエストのキューを作り、答えがあれば、何かする...少なくともキューからリクエストを削除する。SBにはQueueがないのが残念ですが、シンプルなクラスです。
タイムアウトがある。あなたのバージョンでは、残念ながら、複数のOrderSendsが(異なるEAから)一緒に動作する場合、問題が発生する可能性があります。
また、履歴だけでなく、オープンポジション/注文の SL/TP等も同期されていません。市場の場合、最初は注文だけで履歴が増え、しばらくして取引で履歴が増えることがあります。それ以外の状況もあります。そのため、一見すると面倒くさそうに見えるのです。
はい、そうですね。でも、そんなEAは一度だけで、どちらかというと害はないでしょう。
待機用の関数を別に書いて、標準の取引クラスも使えるようにした方が良いだろう。
なぜOnTradeTransaction() を待つのですか?リクエストのキューを作り、答えが来たら何かする...少なくともキューからリクエストを削除する。SBにQueueがないのは残念ですが、シンプルなクラスです。
ポイントは、OrderSendの直後にOnTradeTransaction()が発動しないことです。
要するに、ここでは議論の対象にならずに言い争うファンが群がっているだけなのです。
OrderSend()の直後に何かをしなければならない場合、アルゴリズムには2つのバリエーションがあります。
1.注文や案件のリストの更新を待つループを開始することができます。
2.OnTick()を終了し、OnTradeTransaction()がトリガーするのを待ちます。
3.新しい注文や案件がリストに表示されるかどうか、ティックで確認します。