E se non usi le classi, ti stanchi di scrivere costantemente qualcosa come SymbolInfoDouble(_Symbol,MODE_BID). Questo balla ogni volta - sia parentesi che underscore, e non sai se premere il capslock (e poi da qualche altra parte senza guardare, digitare un'intera stringa maiuscola e riscriverla) o tenere premuto lo shifter. Almeno è qui che l'OOP è utile. Se almeno fanno delle classi per tutte queste funzioni, allora sì - sono enormi. Se lo scrivi per te stesso, non è un problema. Per quanto riguarda il lavoro con gli ordini, non ci sono molte funzioni di uso frequente, possiamo semplicemente mettere alcune funzioni in una libreria. Ma in generale, un approccio ideale non è ancora stato trovato.
Ecco la mia visione della classe che può aprire/chiudere/impostare lo stop loss e poi visualizzarelo stato dell'ordine
class CConstVolume
{
protected:
staticconstdouble VolumeMAX;
staticconstdouble VolumeMIN;
staticconstdouble VolumeSTEP;
staticconstdouble ZerroPrice;
staticconstint VolumeDIGITS;
staticint GetDigitsInVolumeStep(); };
//___________________________________________________________________________staticint CConstVolume::GetDigitsInVolumeStep()
{ int result = 0;
long i = 10000000, k = long(::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP) / 0.0000001);
while(result < 7 && k % i > 0)
{ i /= 10;
result++; }
return(result); }
//____________________________________________________________________staticconstdouble CConstVolume::VolumeMAX = ::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
//____________________________________________________________________staticconstdouble CConstVolume::VolumeMIN = ::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
//____________________________________________________________________staticconstdouble CConstVolume::VolumeSTEP = ::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
staticconstdouble CConstVolume::ZerroPrice = ::NormalizeDouble(0.0, _Digits);
//____________________________________________________________________staticconstint CConstVolume::VolumeDIGITS = CConstVolume::GetDigitsInVolumeStep();
//____________________________________________________________________//+------------------------------------------------------------------+//| class COrder |//+------------------------------------------------------------------+class COrder : private CConstVolume
{
private:
SOrderInfo m_info; //структура для инициализации класса, и хранения информации о ордере, тип, цена отркытия, лот, и состояние ордера
CError error; //класс с описание ошибок на 2-х языкахint sl_error_count;//счетчик ошибок установки стоплосса/тейкаbool m_needstoploss;//флаг для установки стоплосса, сбросим когда все ОКbool CheckMarginRequirements();
bool ServerDisable();
intOrdersend();
int CheckOrderByMagicnumber(int magic_); //метод нужен для поиска открытого ордера по магику, использую в конструктореvoid SetStoploss();
void NULLOrder() { ZeroMemory(m_info); m_info.cmd = -1; m_info.status = ErrorOrder; m_needstoploss = false; }
void PrintError(string func) { Print(func); error.GetLastError(); }
public:
COrder():m_needstoploss(false) { NULLOrder(); }
COrder(SOrderInfo &ordersetting);
SOrderInfo GetOrderInfo();
bool Orderclose();};
//________________________________
e notare l'uso su un simbolo - specialmente una classe statica da usare
tutto sommato, tutto funziona come previsto.... ma non mi piace, come ho scritto sopra è ingombrante e superfluo
E se non usate le classi, vi stancherete di scrivere costantemente qualcosa come SymbolInfoDouble(_Symbol,SYMBOL_BID). Questo balla ogni volta ...
Si potrebbero fare wrapper più convenienti e concisi per queste funzioni, pur mantenendole in stile procedurale. Soprattutto tenendo conto del fatto che nelle ultime build hanno finalmente aggiunto il namespace, tutto è fantastico. Prima bisognava implementarle come metodi statici, ma ora è tutto molto più facile:
Si possono fare wrapper più convenienti e concisi per queste funzioni, pur rimanendo all'interno dello stile procedurale. Specialmente da quando hanno finalmente aggiunto lo spazio dei nomi nelle ultime build, è fantastico. Prima bisognava implementarli come metodi statici, ma ora tutto è diventato molto più semplice:
È davvero importante rimanere nei limiti? Se è importante rimanere nei limiti, si possono scrivere delle funzioni.
beh, non molto, direi un bel po' di azioni per impostare un ordine, ecco la mia visione per una classe che sa come aprire/chiudere/impostare lo stoploss/ed emettere ulteriormente lo stato dell'ordine
e notare l'uso su un simbolo - specialmente una classe statica da usare
tutto sommato, tutto funziona come previsto.... ma non mi piace, come ho scritto sopra è ingombrante e superfluo
Sì, ecco un'altra domanda che continua a sorgere e che non ha una risposta univoca. Quando hai bisogno di ereditare la tua classe - cosa è meglio fare, ereditarla o scrivere una nuova versione estesa della tua classe.
È possibile fare wrapper più convenienti e concisi per queste funzioni, pur rimanendo all'interno dello stile procedurale. Specialmente da quando hanno finalmente aggiunto il namespace nelle ultime build, è fantastico. Prima, dovevi implementarli come metodi statici, ora le cose sono molto più semplici:
Non hai una notazione sintetica, se non ci sono controlli, è più facile scrivere così com'è:
e notate che per essere usato su un singolo carattere - in particolare una classe statica usata
Cosa ti impedisce di passare il nome del simbolo al costruttore, rendendo la classe flessibile e versatile? Non consideri la possibilità del trading di portafoglio come una questione di principio?
La tua voce non è succinta, se non ci sono controlli, è più facile scrivere così com'è:
Ci sono molte funzioni come SymbolInfoDouble. È una seccatura trovare dei nomi brevi per tutti loro, ma assemblandoli in classi, non ci si deve preoccupare dell'unicità dei nomi.
Ho il seguente circuito dove non ho avuto problemi.
Scrivo TC solo per Tester. Nessun log, gestori di errori o altre stronzate. Il codice è molto conciso, comprensibile e suscettibile di revisioni, se fatto tramite OOP (ma non fondamentale). Ho già postato l'esempio in KB. Il bonus è l'ottimizzazione veloce.
La cosa principale è che dovrebbe essere disponibile per il tester e in blocchi indipendenti. La generazione di segnali di trading - un blocco. Trading di segnali - un altro blocco.
Il trasferimento al conto reale è sempre fatto in diverse mosse una e una sola. Il TS è inserito in un ambiente virtuale senza alcun cambiamento di codice. Diversi TS possono essere messi in un ambiente o ogni TS nel proprio ambiente, allora l'OOP diventa particolarmente conveniente. Poi prendiamo una fotocopiatrice (il mercato ne è pieno, quindi la gente è brava nella logica delle fotocopiatrici), che semplicemente copia le offerte/ordini dall'ambiente virtuale a quello reale.
Con questo schema, scrivere TS è facile e veloce. Il trasferimento al reale (che è raro in effetti) è sempre fatto in modo uniforme, rapido e chiaro.
non hai una voce concisa, se non ci sono controlli, è più facile scrivere così com'è:
Non è così che si fa. Hai bisogno almeno di chiamare sia Bid() che Ask(). La tua voce sembra solo una variabile, dando l'impressione che il suo valore sia invariato, quando in realtà non lo è.
Alexey Navoykov: Cosa vi impedisce di passare il nome del simbolo al costruttore, rendendo la classe flessibile e versatile? Fondamentalmente non considerate la possibilità del trading di portafoglio?
Ciò che ostacola questo è che la maggior parte degli EA di un solo carattere sono scritti, e passare un simbolo sarebbe un'azione non necessaria (ed estenuante)) nella maggior parte dei casi. Un'altra cosa è fare in modo che il simbolo del grafico sia selezionato automaticamente per impostazione predefinita, e se necessario, si può sovrascrivere il simbolo per un po'. Ma ancora una volta la domanda sorge, che cosa è meglio - usare un'istanza della classe e sovrascrivere il simbolo come necessario, o creare un'istanza separata per ogni simbolo.
E se non usi le classi, ti stanchi di scrivere costantemente qualcosa come SymbolInfoDouble(_Symbol,MODE_BID). Questo balla ogni volta - sia parentesi che underscore, e non sai se premere il capslock (e poi da qualche altra parte senza guardare, digitare un'intera stringa maiuscola e riscriverla) o tenere premuto lo shifter. Almeno è qui che l'OOP è utile. Se almeno fanno delle classi per tutte queste funzioni, allora sì - sono enormi. Se lo scrivi per te stesso, non è un problema. Per quanto riguarda il lavoro con gli ordini, non ci sono molte funzioni di uso frequente, possiamo semplicemente mettere alcune funzioni in una libreria. Ma in generale, un approccio ideale non è ancora stato trovato.
Ecco la mia visione della classe che può aprire/chiudere/impostare lo stop loss e poi visualizzarelo stato dell'ordine
e notare l'uso su un simbolo - specialmente una classe statica da usare
tutto sommato, tutto funziona come previsto.... ma non mi piace, come ho scritto sopra è ingombrante e superfluo
E se non usate le classi, vi stancherete di scrivere costantemente qualcosa come SymbolInfoDouble(_Symbol,SYMBOL_BID). Questo balla ogni volta ...
Si potrebbero fare wrapper più convenienti e concisi per queste funzioni, pur mantenendole in stile procedurale. Soprattutto tenendo conto del fatto che nelle ultime build hanno finalmente aggiunto il namespace, tutto è fantastico. Prima bisognava implementarle come metodi statici, ma ora è tutto molto più facile:
Si possono fare wrapper più convenienti e concisi per queste funzioni, pur rimanendo all'interno dello stile procedurale. Specialmente da quando hanno finalmente aggiunto lo spazio dei nomi nelle ultime build, è fantastico. Prima bisognava implementarli come metodi statici, ma ora tutto è diventato molto più semplice:
È davvero importante rimanere nei limiti? Se è importante rimanere nei limiti, si possono scrivere delle funzioni.
beh, non molto, direi un bel po' di azioni per impostare un ordine, ecco la mia visione per una classe che sa come aprire/chiudere/impostare lo stoploss/ed emettere ulteriormente lo stato dell'ordine
e notare l'uso su un simbolo - specialmente una classe statica da usare
tutto sommato, tutto funziona come previsto.... ma non mi piace, come ho scritto sopra è ingombrante e superfluo
Sì, ecco un'altra domanda che continua a sorgere e che non ha una risposta univoca. Quando hai bisogno di ereditare la tua classe - cosa è meglio fare, ereditarla o scrivere una nuova versione estesa della tua classe.
È possibile fare wrapper più convenienti e concisi per queste funzioni, pur rimanendo all'interno dello stile procedurale. Specialmente da quando hanno finalmente aggiunto il namespace nelle ultime build, è fantastico. Prima, dovevi implementarli come metodi statici, ora le cose sono molto più semplici:
Non hai una notazione sintetica, se non ci sono controlli, è più facile scrivere così com'è:
e notate che per essere usato su un singolo carattere - in particolare una classe statica usata
La tua voce non è succinta, se non ci sono controlli, è più facile scrivere così com'è:
Ci sono molte funzioni come SymbolInfoDouble. È una seccatura trovare dei nomi brevi per tutti loro, ma assemblandoli in classi, non ci si deve preoccupare dell'unicità dei nomi.
Ho il seguente circuito dove non ho avuto problemi.
non hai una voce concisa, se non ci sono controlli, è più facile scrivere così com'è:
Cosa vi impedisce di passare il nome del simbolo al costruttore, rendendo la classe flessibile e versatile? Fondamentalmente non considerate la possibilità del trading di portafoglio?
Ciò che ostacola questo è che la maggior parte degli EA di un solo carattere sono scritti, e passare un simbolo sarebbe un'azione non necessaria (ed estenuante)) nella maggior parte dei casi. Un'altra cosa è fare in modo che il simbolo del grafico sia selezionato automaticamente per impostazione predefinita, e se necessario, si può sovrascrivere il simbolo per un po'. Ma ancora una volta la domanda sorge, che cosa è meglio - usare un'istanza della classe e sovrascrivere il simbolo come necessario, o creare un'istanza separata per ogni simbolo.