Discusión sobre el artículo "Biblioteca para el desarrollo rápido y sencillo de programas para MetaTrader (Parte VIII): Eventos de modificación de órdenes y posiciones" - página 2
Artem, ¡gracias de nuevo! El método"void CEventsCollection::CreateNewEvent(COrderControl* order)" se utiliza para crear un evento comercial dependiendo del tipo de cambio de orden, es decir, crea un evento asociado a cualquier cambio de orden..... Y el motivo del cambio de orden que se envía al evento creado es el mismo: EVENT_REASON_STOPLIMIT_TRIGGERED.
//--- Crear un eventoif(event!=NULL)
{
event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time()); // Hora del eventoevent.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED); // Causa del evento (de la enumeración ENUM_EVENT_REASON)
Si estoy en lo correcto por favor corrijanlo, si no por favor expliquen que es lo que no vi.
Muchas gracias por la biblioteca que ha simplificado mi trabajo en varias ocasiones, especialmente cuando el trabajo principal no está relacionado con la programación.
Artem, ¡gracias de nuevo! El método"void CEventsCollection::CreateNewEvent(COrderControl* order)" se utiliza para crear un evento comercial en función del tipo de cambio de orden, es decir, crea un evento asociado a cualquier cambio de orden..... Y el motivo del cambio de orden que se envía al evento creado es el mismo: EVENT_REASON_STOPLIMIT_TRIGGERED.
Si estoy en lo cierto por favor corrijanlo, si no por favor expliquen lo que no vi.
Muchas gracias por la biblioteca que ha simplificado mi trabajo en varias ocasiones, especialmente cuando el trabajo principal no está relacionado con la programación.
Sin vincular a la ubicación exacta de las líneas citadas, no puedo entender lo que exactamente estás hablando - sólo por la búsqueda (Shift + Ctrl + F) no pude encontrar ese código en todos los archivos de la biblioteca ...
Aquí están las líneas de la descripción en la parte misma de este artículo y el código al final del artículo:
//+------------------------------------------------------------------+//|| Crea un evento de operación en función del tipo de cambio de orden |||//+------------------------------------------------------------------+void CEventsCollection::CreateNewEvent(COrderControl* order)
{
if(!::SymbolInfoTick(order.Symbol(),this.m_tick))
{
Print(DFUN,TextByLanguage("Fallo al recuperar los precios actuales por símbolo de evento ","Failed to get current prices by event symbol "),order.Symbol());
return;
}
CEvent* event=NULL;
//--- Orden StopLimit pendiente activadaif(order.GetChangeType()==CHANGE_TYPE_ORDER_TYPE)
{
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_PLASED;
event=new CEventOrderPlased(this.m_trade_event_code,order.Ticket());
}
//--- Modificaciónelse
{
//--- Precio de la orden pendiente modificadoif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE;
//--- Modificado el precio de la orden pendiente y su StopLosselseif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL;
//--- Precio de la orden pendiente modificado y su TakeProfitelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_TP;
//--- Modificado el precio de la orden pendiente, su StopLoss y TakeProfitelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
//--- StopLoss modificado de la orden pendienteelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL;
//--- TakeProfit modificado de la orden pendienteelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_TP;
//--- StopLoss y TakeProfit modificados de la orden pendienteelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
//--- Posición StopLoss modificadaelseif(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS)
this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL;
//--- Posición TakeProfit modificadaelseif(order.GetChangeType()==CHANGE_TYPE_POSITION_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_TP;
//--- StopLoss y TakeProfit modificados de la posiciónelseif(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
//--- Crear un evento de modificaciónevent=new CEventModify(this.m_trade_event_code,order.Ticket());
}
//--- Crear un eventoif(event!=NULL)
{
event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time()); // Hora del eventoevent.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED);// Causa del evento (de la enumeración ENUM_EVENT_REASON)event.SetProperty(EVENT_PROP_TYPE_DEAL_EVENT,PositionTypeByOrderType((ENUM_ORDER_TYPE)order.TypeOrderPrev())); // Tipo de orden cuya activación dio lugar al sucesoevent.SetProperty(EVENT_PROP_TICKET_DEAL_EVENT,order.Ticket()); // Ticket de la orden que desencadenó el eventoevent.SetProperty(EVENT_PROP_TYPE_ORDER_EVENT,order.TypeOrder()); // Tipo de orden de eventoevent.SetProperty(EVENT_PROP_TICKET_ORDER_EVENT,order.Ticket()); // Billete de pedido de eventoevent.SetProperty(EVENT_PROP_TYPE_ORDER_POSITION,order.TypeOrder()); // Tipo de la orden de primera posiciónevent.SetProperty(EVENT_PROP_TICKET_ORDER_POSITION,order.Ticket()); // Billete de la orden de primera posiciónevent.SetProperty(EVENT_PROP_POSITION_ID,order.PositionID()); // Identificador de posiciónevent.SetProperty(EVENT_PROP_POSITION_BY_ID,0); // Identificador de la posición del contadorevent.SetProperty(EVENT_PROP_MAGIC_BY_ID,0); // Número mágico de la posición del contadorevent.SetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE,order.TypeOrderPrev()); // Tipo de orden de posición antes del cambio de direcciónevent.SetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE,order.Ticket()); // Ticket de pedido de posición antes del cambio de direcciónevent.SetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT,order.TypeOrder()); // Tipo de orden de la posición actualevent.SetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT,order.Ticket()); // Ticket de la orden de la posición actualevent.SetProperty(EVENT_PROP_PRICE_OPEN_BEFORE,order.PricePrev()); // Orden de fijación del precio antes de la modificaciónevent.SetProperty(EVENT_PROP_PRICE_SL_BEFORE,order.StopLossPrev()); // Precio StopLoss antes de la modificaciónevent.SetProperty(EVENT_PROP_PRICE_TP_BEFORE,order.TakeProfitPrev()); // Precio TakeProfit antes de la modificaciónevent.SetProperty(EVENT_PROP_PRICE_EVENT_ASK,this.m_tick.ask); // Preguntar precio en el momento del eventoevent.SetProperty(EVENT_PROP_PRICE_EVENT_BID,this.m_tick.bid); // Precio de oferta en el momento del eventoevent.SetProperty(EVENT_PROP_MAGIC_ORDER,order.Magic()); // Número de pedido mágicoevent.SetProperty(EVENT_PROP_TIME_ORDER_POSITION,order.TimePrev()); // Hora de la primera orden de posiciónevent.SetProperty(EVENT_PROP_PRICE_EVENT,order.PricePrev()); // Precio al que se ha producido el eventoevent.SetProperty(EVENT_PROP_PRICE_OPEN,order.Price()); // Precio de fijación del pedidoevent.SetProperty(EVENT_PROP_PRICE_CLOSE,order.Price()); // Precio de cierre de la ordenevent.SetProperty(EVENT_PROP_PRICE_SL,order.StopLoss()); // Precio de la orden StopLossevent.SetProperty(EVENT_PROP_PRICE_TP,order.TakeProfit()); // Precio de la orden TakeProfitevent.SetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL,order.Volume()); // Volumen de pedido solicitadoevent.SetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED,0); // Volumen de la orden ejecutadaevent.SetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT,order.Volume()); // Volumen de órdenes restante (no ejecutado)event.SetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED,0); // Volumen de posición ejecutadoevent.SetProperty(EVENT_PROP_PROFIT,0); // Beneficioevent.SetProperty(EVENT_PROP_SYMBOL,order.Symbol()); // Símbolo de pedidoevent.SetProperty(EVENT_PROP_SYMBOL_BY_ID,order.Symbol()); // Símbolo de posición del contador//--- Establecer el identificador de programación del programa de control, descodificar el código de evento y establecer el tipo de eventoevent.SetChartID(this.m_chart_id);
event.SetTypeEvent();
//--- Si el objeto de evento no está en la lista - añádaloif(!this.IsPresentEventInList(event))
{
this.m_list_trade_events.InsertSort(event);
//--- Enviar un mensaje de evento y establecer el valor del último evento de comercioevent.SendEvent();
this.m_trade_event=event.TradeEvent();
}
//--- Si este evento ya está en la lista - borra el nuevo objeto evento y muestra un mensaje de depuraciónelse
{
::Print(DFUN_ERR_LINE,TextByLanguage("Tal acontecimiento ya está en la lista".,"This event is already in the list."));
delete event;
}
}
}
Sin enlazar a la ubicación exacta de las líneas citadas, no puedo entender de qué estás hablando exactamente - sólo buscando (Shift+Ctrl+F) no pude encontrar dicho código en todos los archivos de la biblioteca...
¿Dónde se encuentra?
¿Quizás ya lo has arreglado en los próximos capítulos de la descripción de la librería? Para mi tu libreria es muy adecuada para mi estrategia y la entiendo muy bien, ya que has hecho ademas de la libreria una metodologia para la correcta programacion.
BmC: Aquí están las líneas de la descripción en la misma parte de este artículo y el código al final del artículo: ¡subraye esta línea!
Por el momento - en la versión actual de la biblioteca, el método tiene este aspecto:
//+------------------------------------------------------------------+//|| Crea un evento de operación en función del tipo de cambio de orden |||//+------------------------------------------------------------------+void CEventsCollection::CreateNewEvent(COrderControl* order)
{
ENUM_EVENT_REASON reason=WRONG_VALUE;
if(!::SymbolInfoTick(order.Symbol(),this.m_tick))
{
::Print(DFUN,CMessage::Text(MSG_LIB_SYS_NOT_GET_CURR_PRICES),order.Symbol());
return;
}
CEvent* event=NULL;
//--- Orden StopLimit pendiente activadaif(order.GetChangeType()==CHANGE_TYPE_ORDER_TYPE)
{
reason=EVENT_REASON_STOPLIMIT_TRIGGERED;this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_PLASED;
event=new CEventOrderPlased(this.m_trade_event_code,order.Ticket());
}
//--- Modificaciónelse
{
//--- Precio de la orden pendiente modificadoif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE;
//--- Modificado el precio de la orden pendiente y su StopLosselseif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL;
//--- Precio de la orden pendiente modificado y su TakeProfitelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_TP;
//--- Modificado el precio de la orden pendiente, su StopLoss y TakeProfitelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_PRICE_STOP_LOSS_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_PRICE+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
//--- StopLoss modificado de la orden pendienteelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL;
//--- TakeProfit modificado de la orden pendienteelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_TP;
//--- StopLoss y TakeProfit modificados de la orden pendienteelseif(order.GetChangeType()==CHANGE_TYPE_ORDER_STOP_LOSS_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_ORDER_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
//--- Posición StopLoss modificadaelseif(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS)
this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL;
//--- Posición TakeProfit modificadaelseif(order.GetChangeType()==CHANGE_TYPE_POSITION_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_TP;
//--- StopLoss y TakeProfit modificados de la posiciónelseif(order.GetChangeType()==CHANGE_TYPE_POSITION_STOP_LOSS_TAKE_PROFIT)
this.m_trade_event_code=TRADE_EVENT_FLAG_POSITION_MODIFY+TRADE_EVENT_FLAG_SL+TRADE_EVENT_FLAG_TP;
//--- Crear un evento de modificaciónreason=EVENT_REASON_MODIFY;event=new CEventModify(this.m_trade_event_code,order.Ticket());
}
//--- Crear un eventoif(event!=NULL)
{
event.SetProperty(EVENT_PROP_TIME_EVENT,order.Time()); // Hora del eventoevent.SetProperty(EVENT_PROP_REASON_EVENT,reason); // Causa del evento (de la enumeración ENUM_EVENT_REASON)event.SetProperty(EVENT_PROP_TYPE_DEAL_EVENT,PositionTypeByOrderType((ENUM_ORDER_TYPE)order.TypeOrderPrev())); // Tipo de orden cuya activación dio lugar al sucesoevent.SetProperty(EVENT_PROP_TICKET_DEAL_EVENT,order.Ticket()); // Ticket de la orden que desencadenó el eventoevent.SetProperty(EVENT_PROP_TYPE_ORDER_EVENT,order.TypeOrder()); // Tipo de orden de eventoevent.SetProperty(EVENT_PROP_TICKET_ORDER_EVENT,order.Ticket()); // Billete de pedido de eventoevent.SetProperty(EVENT_PROP_TYPE_ORDER_POSITION,order.TypeOrder()); // Tipo de la orden de primera posiciónevent.SetProperty(EVENT_PROP_TICKET_ORDER_POSITION,order.Ticket()); // Billete de la orden de primera posiciónevent.SetProperty(EVENT_PROP_POSITION_ID,order.PositionID()); // Identificador de posiciónevent.SetProperty(EVENT_PROP_POSITION_BY_ID,0); // Identificador de la posición del contadorevent.SetProperty(EVENT_PROP_MAGIC_BY_ID,0); // Número mágico de la posición del contadorevent.SetProperty(EVENT_PROP_TYPE_ORD_POS_BEFORE,order.TypeOrderPrev()); // Tipo de orden de posición antes del cambio de direcciónevent.SetProperty(EVENT_PROP_TICKET_ORD_POS_BEFORE,order.Ticket()); // Ticket de pedido de posición antes del cambio de direcciónevent.SetProperty(EVENT_PROP_TYPE_ORD_POS_CURRENT,order.TypeOrder()); // Tipo de orden de la posición actualevent.SetProperty(EVENT_PROP_TICKET_ORD_POS_CURRENT,order.Ticket()); // Ticket de la orden de la posición actualevent.SetProperty(EVENT_PROP_PRICE_OPEN_BEFORE,order.PricePrev()); // Orden de fijación del precio antes de la modificaciónevent.SetProperty(EVENT_PROP_PRICE_SL_BEFORE,order.StopLossPrev()); // Precio StopLoss antes de la modificaciónevent.SetProperty(EVENT_PROP_PRICE_TP_BEFORE,order.TakeProfitPrev()); // Precio TakeProfit antes de la modificaciónevent.SetProperty(EVENT_PROP_PRICE_EVENT_ASK,this.m_tick.ask); // Preguntar precio en el momento del eventoevent.SetProperty(EVENT_PROP_PRICE_EVENT_BID,this.m_tick.bid); // Precio de oferta en el momento del eventoevent.SetProperty(EVENT_PROP_MAGIC_ORDER,order.Magic()); // Número de pedido mágicoevent.SetProperty(EVENT_PROP_TIME_ORDER_POSITION,order.TimePrev()); // Hora de la primera orden de posiciónevent.SetProperty(EVENT_PROP_PRICE_EVENT,order.PricePrev()); // Precio al que se ha producido el eventoevent.SetProperty(EVENT_PROP_PRICE_OPEN,order.Price()); // Precio de fijación del pedidoevent.SetProperty(EVENT_PROP_PRICE_CLOSE,order.Price()); // Precio de cierre de la ordenevent.SetProperty(EVENT_PROP_PRICE_SL,order.StopLoss()); // Precio de la orden StopLossevent.SetProperty(EVENT_PROP_PRICE_TP,order.TakeProfit()); // Precio de la orden TakeProfitevent.SetProperty(EVENT_PROP_VOLUME_ORDER_INITIAL,order.Volume()); // Volumen de pedido solicitadoevent.SetProperty(EVENT_PROP_VOLUME_ORDER_EXECUTED,0); // Volumen de la orden ejecutadaevent.SetProperty(EVENT_PROP_VOLUME_ORDER_CURRENT,order.Volume()); // Volumen de órdenes restante (no ejecutado)event.SetProperty(EVENT_PROP_VOLUME_POSITION_EXECUTED,0); // Volumen de posición ejecutadoevent.SetProperty(EVENT_PROP_PROFIT,0); // Beneficioevent.SetProperty(EVENT_PROP_SYMBOL,order.Symbol()); // Símbolo de pedidoevent.SetProperty(EVENT_PROP_SYMBOL_BY_ID,order.Symbol()); // Símbolo de posición del contador//--- Decodificar el código de evento y establecer el tipo de eventoevent.SetTypeEvent();
//--- Si el objeto de evento no está en la lista - añádaloif(!this.IsPresentEventInList(event))
{
this.m_list_trade_events.InsertSort(event);
//--- Enviar un mensaje de evento y establecer el valor del último evento de comerciothis.m_trade_event=event.TradeEvent();
this.m_is_event=true;
event.SendEvent();
CBaseObjExt::EventAdd(this.m_trade_event,order.Ticket(),order.Price(),order.Symbol());
}
//--- Si este evento ya está en la lista - borra el nuevo objeto evento y muestra un mensaje de depuraciónelse
{
::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_EVENT_ALREADY_IN_LIST));
delete event;
}
}
}
//+------------------------------------------------------------------+
Así que, o era un bug y se ha arreglado hace tiempo, o no es crítico en la versión discutida de la librería. No recuerdo exactamente cómo era....
Por el momento, en la versión actual de la biblioteca, el método tiene el siguiente aspecto:
Así que, o bien era un bug y se ha solucionado hace tiempo, o bien no es crítico en la versión discutida de la librería. No recuerdo exactamente cómo era...
Esto es muy importante, por parte del autor lo es aún más. Si no ha abandonado su idea original. Para ayudar a los programadores novatos como yo con mi trabajo. Cuando se es principiante (estudiante) y se está aprendiendo un lenguaje de programación, o programación en general, surgen muchas dudas y preguntas a la hora de estudiar tu trabajo (librería). En este caso no estuve seguro hasta el último momento si era un error o tu intención. Revisé tu código más de una vez. Y para mí es muy importante: "o no entendí el significado del autor, o es sólo un error tipográfico del autor en su gran proyecto" ¡¿Y cómo dices que no es crítico?! Esto es un error de tu parte, con lo cual tu y yo solo estamos confundiendo a los lectores. Que estudian o aprenden como yo, de su biblioteca.
Esto es muy importante, por parte del autor lo es aún más. Si usted no ha renunciado a su idea original. Para ayudar a los programadores novatos como yo con mi trabajo. Cuando eres principiante (estudiante) y estas aprendiendo un lenguaje de programación, o programación en general, surgen muchas dudas y preguntas a la hora de estudiar tu trabajo (librería). En este caso no estuve seguro hasta el último momento si era un error o tu intención. Revisé tu código más de una vez. Y para mí es muy importante: "o no entendí el significado del autor, o es sólo un error tipográfico del autor en su gran proyecto" ¡¿Y cómo dices que no es crítico?! Esto es un error de tu parte, con lo cual tu y yo solo estamos confundiendo a los lectores. Que estudian o aprenden como yo, de su biblioteca.
:)
Te mostré el código con las correcciones resaltadas en color. Ponlas en la versión de la biblioteca adjunta a este artículo.
Por supuesto, no recuerdo si fue un error mío o no es crítico en esta versión y por eso pasó por mis ojos durante la depuración. Después de todo, ya son cuarenta y tantos artículos, y de esto hace tanto tiempo. Lo más probable es que fuera un error, que se corrigió en los artículos posteriores - un montón de cosas en la biblioteca ya se crean sobre la marcha. Por supuesto que había, y más de una, versiones de prueba de la biblioteca. Pero desde el comienzo de la descripción de su creación mucho ha sido revisado y añadido. Es por eso que esta serie de artículos se posiciona como una descripción de la creación de la biblioteca. De esta forma intento involucrar al lector en el proceso de su creación. Con pruebas y errores, y con instrucciones sobre cómo solucionarlos - para hacer visible todo el proceso - para revelar, por así decirlo, "todos los dolores de la creación" :) :)
Así pues, pido disculpas por cualquier confusión en su comprensión de lo que está pasando..... Haz los cambios sugeridos más arriba. O déjelo para el artículo en el que se corregirá.
Andrii Miknevich: Quiero obtener el último símbolo de evento, ticket y tipo (apertura, cierre, modificación), ¿cómo hacerlo correctamente?
Veo que Artyom está tan ocupado que no aparece por el foro.)))))))) Tal vez pueda darte una pista, una vez que experimenté con su biblioteca. Hoy he revisado esos experimentos y he encontrado dicha función. El comentario dice que la función obtiene una lista de todas las posiciones abiertas.
void OrderActivated()
{
Print(__FUNCTION__, "***", ENUM_TRADE_EVENT(engine.LastTradeEvent()));
//--- Obtener la lista de todas las posiciones abiertas
CArrayObj* list = engine.GetListMarketPosition();
if(list == NULL || list.Total() == 0)
return;
int index = CSelect::FindOrderMax(list, ORDER_PROP_TIME_OPEN);
COrder *pos = list.At(index);
if(pos == NULL)
return;
pos.Print();
}/*******************************************************************/
Por desgracia, no puedo explicar para qué sirve, lo he olvidado todo, pero tal vez puedas averiguarlo....
Bueno... si no puedes, espera. Artem encontrará tiempo y responderá.
Cuando se recibe un tick, sobre el que se establece una orden pendiente y simultáneamente se activa (triggered) (he probado con Buy Stop), su motor no registra todos los eventos...
Se recibe el evento TRADE_EVENT_PENDING_ORDER_PLASED, pero no TRADE_EVENT_PENDING_ORDER_ACTIVATED.
Mi código es algo así
//+------------------------------------------------------------------+//| Procesar eventos comerciales|//+------------------------------------------------------------------+ void ProcessTradeEvents(void)
{
static ENUM_TRADE_EVENT last_event=WRONG_VALUE;
static CEvent *last_processed=NULL;
if(engine.LastTradeEvent()!=last_event)
{
if(last_event==TRADE_EVENT_NO_EVENT)
return;
CArrayObj *list=engine.GetListAllOrdersEvents();
if(list==NULL)
return;
list=CSelect::ByEventProperty(list,EVENT_PROP_SYMBOL,Symbol(),EQUAL);
if(list==NULL || list.Total()<=0)
return;
last_event=engine.LastTradeEvent();
//--- obtener índice de evento antiguoint index_of_old_event=0;
if(last_processed==NULL)
index_of_old_event=-1;
else
{
for(int i=list.Total()-1;i>=0;i--)
{
CEvent *event=list.At(i);
if(event==NULL)
return;
ENUM_TRADE_EVENT event_type=event.TypeEvent();
if(last_processed!=NULL && event.IsEqual(last_processed))
{
index_of_old_event=i;
break;
}
}
}
//--- comprobar todos los nuevos eventosfor(int i=index_of_old_event+1;i<list.Total();i++)
{
CEvent *event=list.At(i);
if(event==NULL)
break;
if(last_processed!=NULL && event.IsEqual(last_processed))
break;
Print(__FUNCTION__+": event : ",event.TypeEventDescription());
switch(event.TypeEvent())
{
case TRADE_EVENT_PENDING_ORDER_PLASED:
{
// algo de código
}
break;
case TRADE_EVENT_PENDING_ORDER_REMOVED:
{
// algo de código
}
break;
case TRADE_EVENT_PENDING_ORDER_ACTIVATED:
{
// algo de código
}
break;
case TRADE_EVENT_POSITION_CLOSED:
{
// algo de código
}
break;
case TRADE_EVENT_POSITION_CLOSED_BY_SL:
{
// algo de código
}
break;
case TRADE_EVENT_POSITION_CLOSED_BY_TP:
{
// algo de código
}
break;
case TRADE_EVENT_MODIFY_ORDER_PRICE:
{
// algo de código
}
break;
case TRADE_EVENT_MODIFY_POSITION_SL:
{
// algo de código
}
break;
case TRADE_EVENT_MODIFY_POSITION_TP:
{
// algo de código
}
break;
}
}
last_processed=list.At(list.Total()-1);
Comment("\nLast trade event: ",last_processed.TypeEventDescription());
}
}
Primero busco el índice del evento antiguo (procesado) en el bucle, y a partir de él, recorro todos los nuevos hasta el final. Así, en una situación en la que en un tick se establece una orden limitada y striggeren recibe un evento sobre el establecimiento... Por favor comenta.
Llamo a ProcessTradeEvents() en OnTick() siguiendo a engine.OnTick(rates_data).
Свойства ордеров - Торговые константы - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
Para iniciar sesión y usar el sitio web MQL5.com es necesario permitir el uso de Сookies.
Por favor, active este ajuste en su navegador, de lo contrario, no podrá iniciar sesión.
Ha iniciado sesión. La autenticación de dos factores se ha desactivado. Vuelva a configurarla y escanee un nuevo código QR, o continúe con la autenticación de dos factores desactivada.
Artem, ¡gracias de nuevo!
El método"void CEventsCollection::CreateNewEvent(COrderControl* order)" se utiliza para crear un evento comercial dependiendo del tipo de cambio de orden, es decir, crea un evento asociado a cualquier cambio de orden.....
Y el motivo del cambio de orden que se envía al evento creado es el mismo: EVENT_REASON_STOPLIMIT_TRIGGERED.
Si estoy en lo correcto por favor corrijanlo, si no por favor expliquen que es lo que no vi.
Muchas gracias por la biblioteca que ha simplificado mi trabajo en varias ocasiones,
especialmente cuando el trabajo principal no está relacionado con la programación.
Artem, ¡gracias de nuevo!
El método"void CEventsCollection::CreateNewEvent(COrderControl* order)" se utiliza para crear un evento comercial en función del tipo de cambio de orden, es decir, crea un evento asociado a cualquier cambio de orden.....
Y el motivo del cambio de orden que se envía al evento creado es el mismo: EVENT_REASON_STOPLIMIT_TRIGGERED.
Si estoy en lo cierto por favor corrijanlo, si no por favor expliquen lo que no vi.
Muchas gracias por la biblioteca que ha simplificado mi trabajo en varias ocasiones,
especialmente cuando el trabajo principal no está relacionado con la programación.
Sin vincular a la ubicación exacta de las líneas citadas, no puedo entender lo que exactamente estás hablando - sólo por la búsqueda (Shift + Ctrl + F) no pude encontrar ese código en todos los archivos de la biblioteca ...
event.SetProperty(EVENT_PROP_REASON_EVENT,EVENT_REASON_STOPLIMIT_TRIGGERED);¿Dónde se encuentra?
Sin enlazar a la ubicación exacta de las líneas citadas, no puedo entender de qué estás hablando exactamente - sólo buscando (Shift+Ctrl+F) no pude encontrar dicho código en todos los archivos de la biblioteca...
¿Dónde se encuentra?
Aquí están las líneas de la descripción en la misma parte de este artículo y el código al final del artículo: ¡subraye esta línea!
Por el momento - en la versión actual de la biblioteca, el método tiene este aspecto:
Así que, o era un bug y se ha arreglado hace tiempo, o no es crítico en la versión discutida de la librería. No recuerdo exactamente cómo era....
Por el momento, en la versión actual de la biblioteca, el método tiene el siguiente aspecto:
Así que, o bien era un bug y se ha solucionado hace tiempo, o bien no es crítico en la versión discutida de la librería. No recuerdo exactamente cómo era...
Esto es muy importante, por parte del autor lo es aún más. Si no ha abandonado su idea original. Para ayudar a los programadores novatos como yo con mi trabajo. Cuando se es principiante (estudiante) y se está aprendiendo un lenguaje de programación, o programación en general, surgen muchas dudas y preguntas a la hora de estudiar tu trabajo (librería). En este caso no estuve seguro hasta el último momento si era un error o tu intención. Revisé tu código más de una vez. Y para mí es muy importante: "o no entendí el significado del autor, o es sólo un error tipográfico del autor en su gran proyecto"
¡¿Y cómo dices que no es crítico?! Esto es un error de tu parte, con lo cual tu y yo solo estamos confundiendo a los lectores. Que estudian o aprenden como yo, de su biblioteca.
Esto es muy importante, por parte del autor lo es aún más. Si usted no ha renunciado a su idea original. Para ayudar a los programadores novatos como yo con mi trabajo. Cuando eres principiante (estudiante) y estas aprendiendo un lenguaje de programación, o programación en general, surgen muchas dudas y preguntas a la hora de estudiar tu trabajo (librería). En este caso no estuve seguro hasta el último momento si era un error o tu intención. Revisé tu código más de una vez. Y para mí es muy importante: "o no entendí el significado del autor, o es sólo un error tipográfico del autor en su gran proyecto"
¡¿Y cómo dices que no es crítico?! Esto es un error de tu parte, con lo cual tu y yo solo estamos confundiendo a los lectores. Que estudian o aprenden como yo, de su biblioteca.
:)
Te mostré el código con las correcciones resaltadas en color. Ponlas en la versión de la biblioteca adjunta a este artículo.
Por supuesto, no recuerdo si fue un error mío o no es crítico en esta versión y por eso pasó por mis ojos durante la depuración. Después de todo, ya son cuarenta y tantos artículos, y de esto hace tanto tiempo. Lo más probable es que fuera un error, que se corrigió en los artículos posteriores - un montón de cosas en la biblioteca ya se crean sobre la marcha. Por supuesto que había, y más de una, versiones de prueba de la biblioteca. Pero desde el comienzo de la descripción de su creación mucho ha sido revisado y añadido. Es por eso que esta serie de artículos se posiciona como una descripción de la creación de la biblioteca. De esta forma intento involucrar al lector en el proceso de su creación. Con pruebas y errores, y con instrucciones sobre cómo solucionarlos - para hacer visible todo el proceso - para revelar, por así decirlo, "todos los dolores de la creación" :) :)
Así pues, pido disculpas por cualquier confusión en su comprensión de lo que está pasando.....
Haz los cambios sugeridos más arriba. O déjelo para el artículo en el que se corregirá.
Quiero obtener el último símbolo de evento, ticket y tipo (apertura, cierre, modificación), ¿cómo hacerlo correctamente?
Veo que Artyom está tan ocupado que no aparece por el foro.)))))))) Tal vez pueda darte una pista, una vez que experimenté con su biblioteca. Hoy he revisado esos experimentos y he encontrado dicha función. El comentario dice que la función obtiene una lista de todas las posiciones abiertas.
Por desgracia, no puedo explicar para qué sirve, lo he olvidado todo, pero tal vez puedas averiguarlo....
Bueno... si no puedes, espera. Artem encontrará tiempo y responderá.
Cuando se recibe un tick, sobre el que se establece una orden pendiente y simultáneamente se activa (triggered) (he probado con Buy Stop), su motor no registra todos los eventos...
Se recibe el evento TRADE_EVENT_PENDING_ORDER_PLASED, pero no TRADE_EVENT_PENDING_ORDER_ACTIVATED.
Mi código es algo así
Primero busco el índice del evento antiguo (procesado) en el bucle, y a partir de él, recorro todos los nuevos hasta el final. Así, en una situación en la que en un tick se establece una orden limitada y striggeren recibe un evento sobre el establecimiento... Por favor comenta.
Llamo a ProcessTradeEvents() en OnTick() siguiendo a engine.OnTick(rates_data).