class vr_trade
{
private:
int openorders(string sy,int typ,double lot,double price);
string tip(int typ);
int m_magic;
int m_slip;
public:
int Buy(string sy,double lot);
int Sel(string sy,double lot);
int BuyLimit(string sy,double lot,double price);
int SelLimit(string sy,double lot,double price);
int BuyStop(string sy,double lot,double price);
int SelStop(string sy,double lot,double price);
void MagSlip(int mag=-1,int slip=0);
vr_MarketInfo *Log;
vr_trade();
~vr_trade();
};
MqlTick st;
//+------------------------------------------------------------------+
vr_trade:: vr_trade()
{
Log=new vr_MarketInfo;
MagSlip(-1,0);
}
Y añadió la herencia ... ( sospecho que puedo estar equivocado ) de la clase vr_MarketInfo
La clase vr_MarketInfo devuelve información sobre el punto, los dígitos del símbolo y comprueba el lote en busca de errores, y muchas otras cosas que necesito para el trabajo, incluyendo el mantenimiento de un registro en Excel y en un gráfico
Cuando se utiliza un método como el anterior se da una lista cuando se trabaja en Primer.Primer.Primer()
Me gustaría hacer algo más abreviado...
¿Dónde está la herencia? ¿Para qué sirve el puntero?
De hecho, el libro de texto y la documentación no son muy específicos sobre el uso de punteros o del nuevo operador. Podemos adivinar o esperar a que pase el tiempo. O cuando alguien dice algo accidentalmente en algún lugar. Me sorprende cómo funcionan las cosas. También es interesante que salvo yo y el tópico VLadimir nadie parece necesitar nada. Aunque sigo creyendo que mucha gente no entiende este tema. Y por eso no se meten en esas cuestiones...
hoz: De hecho, ni el manual ni la documentación ofrecen detalles sobre cómo utilizar los punteros o el nuevo operador. Podemos adivinar o esperar a que pase el tiempo. O cuando alguien dice algo accidentalmente en algún lugar. Estoy sorprendido de cómo funcionan las cosas. También es interesante que salvo yo y el tópico VLadimir nadie parece necesitar nada. Aunque sigo creyendo que mucha gente no entiende este tema. Y por eso no se meten en esas cuestiones...
¿Qué tipo de detalles necesita? Hay un principio que se aplica en todas partes: mantener las cosas lo más sencillas posible. No te metas en el meollo de la cuestión sólo por estar en el meollo de la cuestión. Si un problema puede resolverse de forma sencilla, debe resolverse de forma sencilla.
Los punteros dinámicos son necesarios si su programa necesita trabajar dinámicamente con objetos: crear, eliminar durante la ejecución del programa. Si sabes de antemano cuáles y cuántos objetos se necesitan en el programa, no necesitas punteros dinámicos. Pero a menos que tengas muchos objetos, puedes simplemente crearlos en un bucle con new.
VOLDEMAR: A mí por ejemplo me cuesta aprender la teoría, muéstrame un ejemplo y describe cómo las funciones definen el círculo, el cuadrado, el trapecio o el triángulo.
Uno de los artículos enlazados en el primer post tiene este ejemplo.
Una clase base con un método virtual. El descendiente tiene un método con el mismo nombre, en el que se realizan los cálculos.
VOLDEMAR: A mí me cuesta aprender la teoría, muéstrame un ejemplo y describe cómo las funciones definen un círculo, un cuadrado, un trapecio o un triángulo...
Dejo el trapecio y el triángulo para mi propio trabajo:
Los punteros dinámicos son necesarios si el programa necesita trabajar dinámicamente con objetos: crearlos, borrarlos durante el funcionamiento del programa. Si se sabe de antemano cuáles y cuántos objetos se van a necesitar en el programa, no se necesitan punteros dinámicos. Pero a menos que tengas muchos objetos, es más fácil crearlos en un bucle con new.
¡Exactamente! E incluso en ese caso se puede prescindir de los punteros.
#property strictinputint Slip=30;
inputint Magic=0;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+class vr_trade
{
private:
int openorders(string sy,int typ,double lot,double price);string tip(int typ);
public:
int Buy(string sy,double lot);int Sel(string sy,double lot);int BuyLimit(string sy,double lot, double price);int SelLimit(string sy,double lot, double price);int BuyStop(string sy,double lot, double price);int SelStop(string sy,double lot, double price); vr_trade(){}
~vr_trade(){}
};
MqlTick st;
vr_trade trade;
//+------------------------------------------------------------------+voidOnTick()
{
trade.Buy("EURUSD",0.01); // Пример открытия позиции возвращающей тиккет ордера.
}
//+------------------------------------------------------------------+ int vr_trade :: Buy(string sy,double lot)
{
return openorders(sy,0,lot);
}
//+------------------------------------------------------------------+ int vr_trade :: Sel(string sy,double lot)
{
return openorders(sy,1,lot);
}
//+------------------------------------------------------------------+ int vr_trade :: BuyLimit(string sy,double lot, double price)
{
return openorders(sy,2,lot,price);
}
//+------------------------------------------------------------------+ int vr_trade :: SelLimit(string sy,double lot, double price)
{
return openorders(sy,3,lot,price);
}
//+------------------------------------------------------------------+ int vr_trade :: BuyStop(string sy,double lot, double price)
{
return openorders(sy,4,lot,price);
}
//+------------------------------------------------------------------+ int vr_trade :: SelStop(string sy,double lot, double price)
{
return openorders(sy,5,lot,price);
}
//+------------------------------------------------------------------+int vr_trade :: openorders(string sy="",int typ=0,double lot=0,double price=0)
{
int tik=-2;
double di=NormalizeDouble(500*_Point,_Digits);
if(sy==""){sy=_Symbol;Print("Установлен символ текущего графика ",sy);}
if(lot<MarketInfo(sy,MODE_MINLOT)){lot=MarketInfo(sy,MODE_MINLOT); Print("Советник скорректировал лот ",lot);}
if(!SymbolInfoTick(sy,st))Print("Не удалось прогрузить цены для символа ",sy);
if(price==0)//Даблы так лучше не сравнивать.
{
if(typ==0)price=st.ask;
if(typ==1)price=st.bid;
if(typ==2)price=st.ask-di;
if(typ==3)price=st.bid+di;
if(typ==4)price=st.ask+di;
if(typ==5)price=st.bid-di;
}
if(IsTradeAllowed()==true)
{
RefreshRates();
tik=OrderSend(sy,typ,lot,price,Slip,0,0,"",Magic,0,clrRed);
if(tik>0)Print("Успешно открыт ордер Ticket ",tik," Typ ",tip(typ)," Symbol ",sy," Lot ",lot," Price ",price);
elsePrint("Ошибка открытия ордера N",GetLastError());
}
elsePrint("Торговый поток занят");
return tik;
}
//+------------------------------------------------------------------+string vr_trade :: tip(int typ ENUM_ORDER_TYPE type)
{
string txt="";
switch(typ)
{
case0: txt="BUY"; break;
case1: txt="SELL"; break;
case2: txt="BUY LIMIT"; break;
case3: txt="SELL LIMIT"; break;
case4: txt="BUY STOP"; break;
case5: txt="SELL STOP"; break;
default : txt="Ошибка типа ордера";
}
return txt;
}
//+------------------------------------------------------------------+
Su clase es redundante en un 90%. Sólo dos funciones realizan el trabajo principal, éstas son openorders y consejo ¿Por qué se utiliza Sel, Buy SelStop, etc., cuando en realidad todas ellas sólo llaman a Openorders? Además, el tipo de orden se pasa como int, por lo que no está protegido. En lugar de int, es mejor utilizar su propia enumeración o el estándar ENUM_ORDER_TYPE. Y, en general, es mejor no utilizar nunca los números mágicos "1", "2", etc., sólo las enumeraciones. Esto evitará que envíe el valor de la orden izquierda a la función. La propia función de Openorders es demasiado grande. Obviamente, consta de dos bloques, el bloque de hacer un trato y el bloque de comprobar las condiciones. Cada uno de ellos debe ser como una función privada separada.
Es un buen comienzo, pero todavía hay mucho que aprender. La función de la punta se reescribiría mejor de la siguiente manera:
¿Qué detalles se necesitan? El mismo principio se aplica en todas partes: todo debe hacerse de la forma más sencilla posible. No hay que ir al desierto sólo para estar en el desierto. Si un problema puede resolverse de forma sencilla, debe resolverse de forma sencilla.
Los punteros dinámicos son necesarios si el programa necesita trabajar dinámicamente con los objetos: crear, borrar durante el funcionamiento del programa. Si se sabe de antemano cuáles y cuántos objetos se van a necesitar en el programa, no se necesitan punteros dinámicos. Pero excepto cuando hay tantos objetos, es más fácil crearlos en un bucle mediante new.
Los punteros son indispensables para las conversiones complejas de objetos en las que se requiere una identificación dinámica del tipo.
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.
Ahora he rediseñado mi clase
Y añadió la herencia ... ( sospecho que puedo estar equivocado ) de la clase vr_MarketInfoLa clase vr_MarketInfo devuelve información sobre el punto, los dígitos del símbolo y comprueba el lote en busca de errores, y muchas otras cosas que necesito para el trabajo, incluyendo el mantenimiento de un registro en Excel y en un gráfico
Cuando se utiliza un método como el anterior se da una lista cuando se trabaja en Primer.Primer.Primer()
Me gustaría hacer algo más abreviado...
¿Dónde está la herencia? ¿Para qué sirve el puntero?
¿Dónde está la herencia? ¿Para qué sirve el puntero?
Escriba un libro de texto sobre MQL4+. Cooperen, conocedores, y escríbanlo. 50 dólares :)
Escriba un libro de texto sobre MQL4+. Cooperen, conocedores, y escríbanlo. 50 dólares :)
Todo fue escrito hace mucho tiempo.
MQL4 == C++ con ligeras limitaciones.
De hecho, ni el manual ni la documentación ofrecen detalles sobre cómo utilizar los punteros o el nuevo operador. Podemos adivinar o esperar a que pase el tiempo. O cuando alguien dice algo accidentalmente en algún lugar. Estoy sorprendido de cómo funcionan las cosas. También es interesante que salvo yo y el tópico VLadimir nadie parece necesitar nada. Aunque sigo creyendo que mucha gente no entiende este tema. Y por eso no se meten en esas cuestiones...
¿Qué tipo de detalles necesita? Hay un principio que se aplica en todas partes: mantener las cosas lo más sencillas posible. No te metas en el meollo de la cuestión sólo por estar en el meollo de la cuestión. Si un problema puede resolverse de forma sencilla, debe resolverse de forma sencilla.
Los punteros dinámicos son necesarios si su programa necesita trabajar dinámicamente con objetos: crear, eliminar durante la ejecución del programa. Si sabes de antemano cuáles y cuántos objetos se necesitan en el programa, no necesitas punteros dinámicos. Pero a menos que tengas muchos objetos, puedes simplemente crearlos en un bucle con new.
A mí por ejemplo me cuesta aprender la teoría, muéstrame un ejemplo y describe cómo las funciones definen el círculo, el cuadrado, el trapecio o el triángulo.
Uno de los artículos enlazados en el primer post tiene este ejemplo.
Una clase base con un método virtual. El descendiente tiene un método con el mismo nombre, en el que se realizan los cálculos.
A mí me cuesta aprender la teoría, muéstrame un ejemplo y describe cómo las funciones definen un círculo, un cuadrado, un trapecio o un triángulo...
Dejo el trapecio y el triángulo para mi propio trabajo:
Los punteros dinámicos son necesarios si el programa necesita trabajar dinámicamente con objetos: crearlos, borrarlos durante el funcionamiento del programa. Si se sabe de antemano cuáles y cuántos objetos se van a necesitar en el programa, no se necesitan punteros dinámicos. Pero a menos que tengas muchos objetos, es más fácil crearlos en un bucle con new.
Su clase es redundante en un 90%. Sólo dos funciones realizan el trabajo principal, éstas son openorders y consejo ¿Por qué se utiliza Sel, Buy SelStop, etc., cuando en realidad todas ellas sólo llaman a Openorders? Además, el tipo de orden se pasa como int, por lo que no está protegido. En lugar de int, es mejor utilizar su propia enumeración o el estándar ENUM_ORDER_TYPE. Y, en general, es mejor no utilizar nunca los números mágicos "1", "2", etc., sólo las enumeraciones. Esto evitará que envíe el valor de la orden izquierda a la función. La propia función de Openorders es demasiado grande. Obviamente, consta de dos bloques, el bloque de hacer un trato y el bloque de comprobar las condiciones. Cada uno de ellos debe ser como una función privada separada.
Es un buen comienzo, pero todavía hay mucho que aprender. La función de la punta se reescribiría mejor de la siguiente manera:
¿Qué detalles se necesitan? El mismo principio se aplica en todas partes: todo debe hacerse de la forma más sencilla posible. No hay que ir al desierto sólo para estar en el desierto. Si un problema puede resolverse de forma sencilla, debe resolverse de forma sencilla.
Los punteros dinámicos son necesarios si el programa necesita trabajar dinámicamente con los objetos: crear, borrar durante el funcionamiento del programa. Si se sabe de antemano cuáles y cuántos objetos se van a necesitar en el programa, no se necesitan punteros dinámicos. Pero excepto cuando hay tantos objetos, es más fácil crearlos en un bucle mediante new.