Amigos, por favor, acerquémonos al tema: me gustaría ver ejemplos de aplicación de tal o cual afirmación. No necesariamente el código, si hay mucho, se puede describir la lógica, por ejemplo, enviar la solicitud para asegurarse de que se envía, mirar allí, si se obtiene tal y tal código de retorno, hacer tal y tal. Es decir, ejemplos de la forma más fiable de obtener datos.
De lo contrario, si discutimos, pasaremos de un tema útil a varias páginas de discusiones. Luego hay que limpiarlo todo para dejar la esencia... Exactamente me gustaría la esencia de tal o cual proceso. Que haya varias versiones de alguna implementación de algo. Se podrán discutir las ventajas y desventajas de cada método.
Luego, cuando se acumula suficiente información útil diferente, se piensa en acumularla toda en una tabla. Y reponerla constantemente cuando se acumulen las próximas fichas útiles. Creo que esto será útil para todos.
Mueve la discusión de los compañeros fxsaber y prostotrader a un hilo aparte, si hay discusiones aquí, el hilo perderá su relevancia práctica. Cuando den con una solución real, la publicarán aquí. Y en mi opinión, esto no debería ser una rama de dudas o de investigación. Debe ser una rama de soluciones prácticas. Y si algunas personas tienen visiones diferentes del tema, que lo discutan en otro lugar.
<puesto a eliminar
Dejemos que se encuentre la verdad. Tuve tiempo de pensarlo y decidí publicarlo, y Vitya (Vinin) a quien pregunté y pedí que disipara mis dudas, también sugirió publicar una discusión (confirmando mis dudas sobre la eliminación) - que se encuentre la verdad. Creo que eso sería lo correcto. De todos modos, voy a empezar a tabularlo más tarde, así que puedo publicarlo aquí a medida que se vaya llenando.
¿Cuál es el objetivo de su mensaje? Llegará en OnTradeTransaction(), y qué, significa que tenemos que esperar el evento. Esperamos de todos modos. El significado del mensaje de fxsaber es que después de ejecutar OrderSend(), la información sobre la acción ejecutada no aparece inmediatamente en el terminal. A algunos les gusta esperar a OnTradeTransaction(), mientras que a otros les gusta ver una orden o una transacción en la lista. Esta es la diferencia con respecto a MT4, como ejemplo. En M4, después de OrderSend(), la orden ya está en la lista de órdenes, y después de OrderClose(), la orden siempre está en el historial.
Artyom Trishkin: Dejemos que se encuentre la verdad. Tuve tiempo de pensarlo y decidí dejarlo, y Vitya (Vinin), a quien pedí y pedí que disipara mis dudas, también sugirió dejar la discusión (confirmando mis dudas sobre el borrado) - que nazca la verdad. Creo que eso sería lo correcto. De todos modos, voy a empezar a tabularlo más tarde, para publicarlo aquí a medida que se vaya llenando.
En las discusiones con prostotrader puede que no surja la verdad, no es por eso que las inicia. Como siempre, no sabe ni de qué habla.
¿Qué tipo de argumento hay de todas formas? En este caso no hay disputa. fxsaber nos ha recordado una característica del terminal que está realmente indocumentada y que todo el mundo necesita conocer, ya que de lo contrario habrá problemas a la hora de desarrollar EAs, que tendrás que encontrar y limpiar después.
Artyom Trishkin: Dejemos que se encuentre la verdad...
¡Artyom!
Es usted un hombre razonable y políticamente correcto.
¿Qué verdad? Sabes exactamente de qué estamos hablando.
fxsaber escribió un guión (no está mal), pero nadie lo alabó, así que
intenta recordarlo en cada hilo.
¡Bien hecho!
Pero aquí está el problema, no se puede utilizar OnTradeTransaction en este script, por lo que tiene que "rodar bolas" (como Sleep u otro temporizador) de "Sr. OnTradeTransaction".
¡Y por supuesto, "preocuparse" por otros usuarios que aún no saben que SCRIPT es mejor que COUNTER!
YDmitry Fedoseev siempre está en contra de lo que digo, sin importar si tengo razón o no.
La verdad no se puede encontrar aquí porque no es una causa, sino una causa personal la que sale a relucir.
#define WHILE(A) while ((!(Res = (A))) && ORDERSEND::Waiting())
public: staticuint OrderSend_MaxPause; // максимальное время на синхронизацию в мкс.
// Полностью синхронизированный с торговым окружением OrderSend. // По окончании работы ГАРАНТИРОВАННО и за МИНИМАЛЬНОЕ время доступно корректное торговое окружение. // По скорости ничем не уступает связке OrderSendAsync + OnTradeTransaction. // Учтены MT5-нюансы: Result.deal == 0, STATE_STARTED и STATE_MODIFY pending. // В тестере/оптимизаторе производительность равна штатной OrderSend. staticbool OrderSendSync( constMqlTradeRequest &Request, MqlTradeResult &Result ) { constulong StartTime1 = ::GetMicrosecondCount();
staticuint ORDERSEND::OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.
// Эта строчка позволяет сделать все OrderSend корректными. #define OrderSend ORDERSEND::OrderSendSync
Todo se envuelve deliberadamente en el aula para reducir el número de problemas potenciales.
Utilizando
OrderSend(Request, Result); // Все так же, как со штатной OrderSend
Es decir, para que todos los OrderSend estén sincronizados con el entorno comercial y evitar las trampas, basta con escribir este código fuente como un archivo mqh y utilizar el correspondiente #include en sus programas.
De lo contrario, si discutimos, pasaremos de un tema útil a varias páginas de discusiones. Luego hay que limpiarlo todo para dejar la esencia... Exactamente me gustaría la esencia de tal o cual proceso. Que haya varias versiones de alguna implementación de algo. Se podrán discutir las ventajas y desventajas de cada método.
Luego, cuando se acumula suficiente información útil diferente, se piensa en acumularla toda en una tabla. Y reponerla constantemente cuando se acumulen las próximas fichas útiles.
Creo que esto será útil para todos.
Respuestas:
1.
Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio
8 y 16 ricas
Taras Slobodyanik, 2017.02.24 22:16
{
string s = "", c;
while(n != 0)
{
if(n%16<10)
c=CharToStr(n%16+'0');
else
c=CharToStr(n%16+'A'-10);
s = c + s;
n = n / 16;
}
return(s);
}
Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio
8 y 16 ricas
Maxim Kuznetsov, 2017.02.24 22:20
De repente, StringFormat, PrintFormat :-)PrintFormat("Hex %x y octal %o",1122,1122);
Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio
8 y 16 ricas
fxsaber, 2017.02.24 22:21
{
static const string digits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "V", "X", "Y", "Z"};
string Str = (Num == 0) ? "0" : "";
while (Num > 0)
{
Str = digits[Num % Scale] + Str;
Num /= Scale;
}
return(Str);
}
void OnStart()
{
Print(NumToString(123, 8));
Print(NumToString(123, 16));
}
¿De verdad cree que se puede escribir un robot de trading completo en un script?
Mueve la discusión de los compañeros fxsaber y prostotrader a un hilo aparte, si hay discusiones aquí, el hilo perderá su relevancia práctica. Cuando den con una solución real, la publicarán aquí. Y en mi opinión, esto no debería ser una rama de dudas o de investigación. Debe ser una rama de soluciones prácticas. Y si algunas personas tienen visiones diferentes del tema, que lo discutan en otro lugar.
<puesto a eliminar
No hay que esperar unos milisegundos.
El mensaje llegará en OnTradeTransaction
ver código
¿Cuál es el objetivo de su mensaje? Llegará en OnTradeTransaction(), y qué, significa que tenemos que esperar el evento. Esperamos de todos modos. El significado del mensaje de fxsaber es que después de ejecutar OrderSend(), la información sobre la acción ejecutada no aparece inmediatamente en el terminal. A algunos les gusta esperar a OnTradeTransaction(), mientras que a otros les gusta ver una orden o una transacción en la lista. Esta es la diferencia con respecto a MT4, como ejemplo. En M4, después de OrderSend(), la orden ya está en la lista de órdenes, y después de OrderClose(), la orden siempre está en el historial.
Dejemos que se encuentre la verdad. Tuve tiempo de pensarlo y decidí dejarlo, y Vitya (Vinin), a quien pedí y pedí que disipara mis dudas, también sugirió dejar la discusión (confirmando mis dudas sobre el borrado) - que nazca la verdad. Creo que eso sería lo correcto. De todos modos, voy a empezar a tabularlo más tarde, para publicarlo aquí a medida que se vaya llenando.
Dejemos que se encuentre la verdad...
¡Artyom!
Es usted un hombre razonable y políticamente correcto.
¿Qué verdad? Sabes exactamente de qué estamos hablando.
fxsaber escribió un guión (no está mal), pero nadie lo alabó, así que
intenta recordarlo en cada hilo.
¡Bien hecho!
Pero aquí está el problema, no se puede utilizar OnTradeTransaction en este script, por lo que tiene que "rodar bolas" (como Sleep u otro temporizador) de "Sr. OnTradeTransaction".
¡Y por supuesto, "preocuparse" por otros usuarios que aún no saben que SCRIPT es mejor que COUNTER!
YDmitry Fedoseev siempre está en contra de lo que digo, sin importar si tengo razón o no.
La verdad no se puede encontrar aquí porque no es una causa, sino una causa personal la que sale a relucir.
{
private:
static const bool IsTester;
static bool Waiting( const bool FlagInit = false )
{
static ulong StartTime = 0;
const bool Res = FlagInit ? false : (::GetMicrosecondCount() - StartTime < ORDERSEND::OrderSend_MaxPause);
if (FlagInit)
StartTime = ::GetMicrosecondCount();
else if (Res)
::Sleep(0);
return(Res);
}
static bool EqualPrices( const double Price1, const double Price2, const int digits)
{
return(::NormalizeDouble(Price1 - Price2, digits) == 0);
}
static bool HistoryDealSelect( MqlTradeResult &Result )
{
if ((Result.deal == 0) && (Result.order != 0))
{
if (::HistorySelectByPosition(::HistoryOrderGetInteger(Result.order, ORDER_POSITION_ID)))
for (int i = ::HistoryDealsTotal() - 1; i >= 0; i--)
{
const ulong DealTicket = ::HistoryDealGetTicket(i);
if (Result.order == ::HistoryDealGetInteger(DealTicket, DEAL_ORDER))
{
Result.deal = DealTicket;
break;
}
}
}
return(::HistoryDealSelect(Result.deal));
}
#define TMP_ORDERSEND_BENCHMARK(A) \
static ulong Max##A = 0; \
\
if (Interval##A > Max##A) \
{ \
ORDERSEND_BENCHMARK \
\
Max##A = Interval##A; \
}
static void OrderSend_Benchmark( const ulong Interval1, const ulong Interval2 = 0 )
{
#ifdef ORDERSEND_BENCHMARK
TMP_ORDERSEND_BENCHMARK(1)
TMP_ORDERSEND_BENCHMARK(2)
#endif // ORDERSEND_BENCHMARK
return;
}
#undef TMP_ORDERSEND_BENCHMARK
#define WHILE(A) while ((!(Res = (A))) && ORDERSEND::Waiting())
public:
static uint OrderSend_MaxPause; // максимальное время на синхронизацию в мкс.
// Полностью синхронизированный с торговым окружением OrderSend.
// По окончании работы ГАРАНТИРОВАННО и за МИНИМАЛЬНОЕ время доступно корректное торговое окружение.
// По скорости ничем не уступает связке OrderSendAsync + OnTradeTransaction.
// Учтены MT5-нюансы: Result.deal == 0, STATE_STARTED и STATE_MODIFY pending.
// В тестере/оптимизаторе производительность равна штатной OrderSend.
static bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
const ulong StartTime1 = ::GetMicrosecondCount();
bool Res = ::OrderSend(Request, Result);
const ulong Interval1 = ::GetMicrosecondCount() - StartTime1;
const ulong StartTime2 = ::GetMicrosecondCount();
if (Res && !ORDERSEND::IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (ORDERSEND::OrderSend_MaxPause > 0))
{
Res = (Result.retcode == TRADE_RETCODE_DONE);
ORDERSEND::Waiting(true);
if (Request.action == TRADE_ACTION_DEAL)
{
WHILE(::HistoryOrderSelect(Result.order))
;
Res = Res && (((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_FILLED) ||
((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_PARTIAL));
if (Res)
WHILE(ORDERSEND::HistoryDealSelect(Result))
;
}
else if (Request.action == TRADE_ACTION_PENDING)
{
if (Res)
WHILE(::OrderSelect(Result.order) && ((ENUM_ORDER_STATE)::OrderGetInteger(ORDER_STATE) == ORDER_STATE_PLACED))
;
else
{
WHILE(::HistoryOrderSelect(Result.order))
;
Res = false;
}
}
else if (Request.action == TRADE_ACTION_SLTP)
{
if (Res)
{
bool EqualSL = false;
bool EqualTP = false;
const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);
if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
{
EqualSL = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
EqualTP = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
}
WHILE((EqualSL && EqualTP))
if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
{
EqualSL = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
EqualTP = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
}
}
}
else if (Request.action == TRADE_ACTION_MODIFY)
{
if (Res)
{
bool EqualSL = false;
bool EqualTP = false;
bool EqualPrice = false;
const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);
if (::OrderSelect(Result.order))
{
EqualSL = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
EqualTP = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
EqualPrice = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_PRICE_OPEN), Request.price, digits);
}
WHILE((EqualSL && EqualTP && EqualPrice))
if (::OrderSelect(Result.order) && ((ENUM_ORDER_STATE)::OrderGetInteger(ORDER_STATE) != ORDER_STATE_REQUEST_MODIFY))
{
EqualSL = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
EqualTP = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
EqualPrice = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_PRICE_OPEN), Request.price, digits);
}
}
}
else if (Request.action == TRADE_ACTION_REMOVE)
if (Res)
WHILE(::HistoryOrderSelect(Result.order))
;
}
const ulong Interval2 = ::GetMicrosecondCount() - StartTime2;
Result.comment += " " + ::DoubleToString(Interval1 / 1000.0, 3) + " + " + ::DoubleToString(Interval2 / 1000.0, 3) + " ms";
ORDERSEND::OrderSend_Benchmark(Interval1, Interval2);
return(Res);
}
#undef WHILE
};
static const bool ORDERSEND::IsTester = (::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_OPTIMIZATION) ||
::MQLInfoInteger(MQL_VISUAL_MODE) || ::MQLInfoInteger(MQL_FRAME_MODE));
static uint ORDERSEND::OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.
// Эта строчка позволяет сделать все OrderSend корректными.
#define OrderSend ORDERSEND::OrderSendSync
Todo se envuelve deliberadamente en el aula para reducir el número de problemas potenciales.
Utilizando
Es decir, para que todos los OrderSend estén sincronizados con el entorno comercial y evitar las trampas, basta con escribir este código fuente como un archivo mqh y utilizar el correspondiente #include en sus programas.