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);
}
E ha aggiunto l'eredità ... (sospetto di essermi sbagliato) dalla classe vr_MarketInfo
La classe vr_MarketInfo restituisce informazioni su Point, Digits per il simbolo e controlla il lotto per gli errori, e molte altre cose di cui ho bisogno per il lavoro tra cui tenere un registro in Excel e su un grafico
Quando si usa un metodo come sopra, quando si lavora in Primer.Primer.Primer() viene dato un elenco
In effetti, il libro di testo e la documentazione non sono molto specifici sull'uso dei puntatori o delnuovo operatore. Possiamo indovinare o aspettare che il tempo passi. O quando qualcuno dice accidentalmente qualcosa da qualche parte. Sono scioccato da come funzionano le cose. È anche interessante che a parte me e il topicstarter VLadimir nessuno sembra aver bisogno di qualcosa. Anche se continuo a credere che molte persone non capiscono questo argomento. Ed è per questo che non si fanno queste domande...
hoz: Di fatto, né il manuale, né la documentazione offrono alcuno specifico su come usare i puntatori, o il nuovo operatore. Possiamo indovinare o aspettare che il tempo passi. O quando qualcuno dice accidentalmente qualcosa da qualche parte. Sono scioccato da come succede. È anche interessante che a parte me e il topicstarter VLadimir nessuno sembra aver bisogno di qualcosa. Anche se continuo a credere che molte persone non capiscono questo argomento. Ed è per questo che non indagano su tali questioni...
Di che tipo di specifiche avete bisogno? Un principio si applica ovunque: mantenere le cose il più semplice possibile. Non entrare nel vivo delle cose solo per essere nel vivo delle cose. Se un problema può essere risolto semplicemente, deve essere risolto semplicemente.
I puntatori dinamici sono necessari se il vostro programma ha bisogno di lavorare dinamicamente con gli oggetti: creare, cancellare durante l'esecuzione del programma. Se sapete in anticipo quali e quanti oggetti sono necessari nel programma, non avete bisogno di puntatori dinamici. Ma a meno che non abbiate molti oggetti, potete semplicemente crearli in un ciclo con new.
VOLDEMAR: Io per esempio trovo difficile imparare la teoria, mostratemi un esempio e descrivete come le funzioni definiscono cerchio, quadrato, trapezio o triangolo.
Uno degli articoli linkati nel primo post ha questo esempio.
Una classe base con un metodo virtuale. Il discendente ha un metodo con lo stesso nome, in cui vengono fatti i calcoli.
VOLDEMAR: Per me è difficile imparare la teoria, mostratemi un esempio e descrivete come le funzioni definiscono un cerchio, un quadrato, un trapezio o un triangolo.
I puntatori dinamici sono necessari se il programma ha bisogno di lavorare dinamicamente con gli oggetti: crearli, cancellarli nel processo di funzionamento del programma. Se sapete in anticipo quali e quanti oggetti saranno necessari nel programma, non avete bisogno di puntatori dinamici. Ma a meno che non abbiate molti oggetti, è più facile crearli in un ciclo con new.
Esattamente! E anche in questo caso si può fare a meno dei puntatori.
#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;
}
//+------------------------------------------------------------------+
La vostra classe è ridondante al 90%. Solo due funzioni eseguono il lavoro principale, queste sono openorders e tip Perché usate Sel, Buy SelStop, etc., quando in realtà tutte chiamano semplicemente Openorders? Inoltre, il tipo di ordine è passato come int, quindi non è protetto. Invece di int è meglio che usiate la vostra enumerazione o lo standard ENUM_ORDER_TYPE. E in generale, è meglio non usare mai i numeri magici "1", "2" ecc. Questo vi impedirà di inviare il valore dell'ordine sinistro alla funzione. La stessa funzione Openorders è troppo grande. Ovviamente, consiste di due blocchi, il blocco di fare un accordo e il blocco di verificare le condizioni. Ognuno di loro dovrebbe essere come una funzione privata separata.
È un buon inizio, ma c'è ancora molto da imparare. La funzione di punta sarebbe meglio riscritta come segue:
Quali specifiche sono necessarie? Lo stesso principio si applica ovunque: tutto deve essere fatto nel modo più semplice possibile. Non c'è bisogno di andare nel deserto solo per essere nel deserto. Se un problema può essere risolto semplicemente, dovrebbe essere risolto semplicemente.
I puntatori dinamici sono necessari se il programma ha bisogno di lavorare dinamicamente con gli oggetti: creazione, cancellazione durante il funzionamento del programma. Se sapete in anticipo quali e quanti oggetti saranno necessari nel programma, non avete bisogno di puntatori dinamici. Ma a parte quando ci sono tanti oggetti, è più facile crearli in un ciclo tramite new.
I puntatori sono indispensabili per le conversioni di oggetti complessi in cui è richiesta l'identificazione dinamica del tipo.
Ora ho riprogettato la mia classe
E ha aggiunto l'eredità ... (sospetto di essermi sbagliato) dalla classe vr_MarketInfoLa classe vr_MarketInfo restituisce informazioni su Point, Digits per il simbolo e controlla il lotto per gli errori, e molte altre cose di cui ho bisogno per il lavoro tra cui tenere un registro in Excel e su un grafico
Quando si usa un metodo come sopra, quando si lavora in Primer.Primer.Primer() viene dato un elenco
Vorrei fare qualcosa di più abbreviato...
Dov'è l'eredità? Qual è lo scopo del puntatore?
Dov'è l'eredità? Qual è lo scopo del puntatore?
Scrivere un libro di testo su MQL4+. Cooperate, intenditori, e scrivetelo. 50 dollari :)
Scrivere un libro di testo su MQL4+. Cooperate, intenditori, e scrivetelo. 50 dollari :)
Tutto è stato scritto molto tempo fa.
MQL4 == C++ con leggere limitazioni.
Di fatto, né il manuale, né la documentazione offrono alcuno specifico su come usare i puntatori, o il nuovo operatore. Possiamo indovinare o aspettare che il tempo passi. O quando qualcuno dice accidentalmente qualcosa da qualche parte. Sono scioccato da come succede. È anche interessante che a parte me e il topicstarter VLadimir nessuno sembra aver bisogno di qualcosa. Anche se continuo a credere che molte persone non capiscono questo argomento. Ed è per questo che non indagano su tali questioni...
Di che tipo di specifiche avete bisogno? Un principio si applica ovunque: mantenere le cose il più semplice possibile. Non entrare nel vivo delle cose solo per essere nel vivo delle cose. Se un problema può essere risolto semplicemente, deve essere risolto semplicemente.
I puntatori dinamici sono necessari se il vostro programma ha bisogno di lavorare dinamicamente con gli oggetti: creare, cancellare durante l'esecuzione del programma. Se sapete in anticipo quali e quanti oggetti sono necessari nel programma, non avete bisogno di puntatori dinamici. Ma a meno che non abbiate molti oggetti, potete semplicemente crearli in un ciclo con new.
Io per esempio trovo difficile imparare la teoria, mostratemi un esempio e descrivete come le funzioni definiscono cerchio, quadrato, trapezio o triangolo.
Uno degli articoli linkati nel primo post ha questo esempio.
Una classe base con un metodo virtuale. Il discendente ha un metodo con lo stesso nome, in cui vengono fatti i calcoli.
Per me è difficile imparare la teoria, mostratemi un esempio e descrivete come le funzioni definiscono un cerchio, un quadrato, un trapezio o un triangolo.
Lascio il trapezio e il triangolo al mio lavoro:
I puntatori dinamici sono necessari se il programma ha bisogno di lavorare dinamicamente con gli oggetti: crearli, cancellarli nel processo di funzionamento del programma. Se sapete in anticipo quali e quanti oggetti saranno necessari nel programma, non avete bisogno di puntatori dinamici. Ma a meno che non abbiate molti oggetti, è più facile crearli in un ciclo con new.
La vostra classe è ridondante al 90%. Solo due funzioni eseguono il lavoro principale, queste sono openorders e tip Perché usate Sel, Buy SelStop, etc., quando in realtà tutte chiamano semplicemente Openorders? Inoltre, il tipo di ordine è passato come int, quindi non è protetto. Invece di int è meglio che usiate la vostra enumerazione o lo standard ENUM_ORDER_TYPE. E in generale, è meglio non usare mai i numeri magici "1", "2" ecc. Questo vi impedirà di inviare il valore dell'ordine sinistro alla funzione. La stessa funzione Openorders è troppo grande. Ovviamente, consiste di due blocchi, il blocco di fare un accordo e il blocco di verificare le condizioni. Ognuno di loro dovrebbe essere come una funzione privata separata.
È un buon inizio, ma c'è ancora molto da imparare. La funzione di punta sarebbe meglio riscritta come segue:
Quali specifiche sono necessarie? Lo stesso principio si applica ovunque: tutto deve essere fatto nel modo più semplice possibile. Non c'è bisogno di andare nel deserto solo per essere nel deserto. Se un problema può essere risolto semplicemente, dovrebbe essere risolto semplicemente.
I puntatori dinamici sono necessari se il programma ha bisogno di lavorare dinamicamente con gli oggetti: creazione, cancellazione durante il funzionamento del programma. Se sapete in anticipo quali e quanti oggetti saranno necessari nel programma, non avete bisogno di puntatori dinamici. Ma a parte quando ci sono tanti oggetti, è più facile crearli in un ciclo tramite new.