Regole della struttura. Imparare a strutturare i programmi, esplorare le possibilità, gli errori, le soluzioni, ecc. - pagina 7

 
Urain:

Suggerisco di stabilire i modelli di design di base:

1. Funzionale

2. modello di oggetto

3. Guidato dagli eventi.

...

tipo in

4. Componente

--

In generale, qualsiasi programma (compreso quello che intendete) può essere visto da diverse angolazioni. // è comprensibile.

Durante l'analisi iniziale di un progetto, cerco di considerare almeno 4 aspetti:

1. Strutturale: organizzazione fisica e logica del codice e dei componenti del programma.

2. Funzionale (da non confondere con l'approccio funzionale nello sviluppo): quali compiti risolve il programma (quale prodotto produce), qual è il suo uso, quali output dovrebbe produrre, ecc.

3. Comunicativo: che tipo di interfaccia utente deve avere il programma, con quali programmi comunica e come, protocolli di comunicazione, ecc.

4. Manageriale: come viene gestito il software, quali impostazioni devono essere fatte, gradi di libertà, ecc.

Tutti gli aspetti sono inestricabilmente legati, ma guardare da queste diverse angolazioni (+ alcune altre) permette di non perdere sottigliezze importanti, e nelle prime fasi solo di non sbadigliare qualcosa di importante con conseguenze di vasta portata... )

 
MetaDriver:

...In generale, qualsiasi programma (compreso un programma concepito) può essere guardato da diverse angolazioni. // questo è comprensibile...

Sono assolutamente d'accordo. È un principio filosofico generale - studiare un fenomeno da diversi punti di vista...

E sto cercando di rispondere alla domanda "Cosa dovrebbe fare e cosa non dovrebbe fare un programma?" all'inizio dello sviluppo. La prima parte della domanda rientra nel sistema (qui MTS), la seconda parte no, è fuori.

Imho, è molto importante, indipendentemente dal modello di progettazione, avere una gerarchia di elementi del modello. Il metodo deduttivo - "dal generale al particolare" - funziona allora bene, scomponendo il modello nei suoi blocchi principali e costitutivi.

 
MetaDriver:

Per scambiare idee / imparare gli uni dagli altri, suggerisco di prendere un problema più o meno pratico e ristrutturarlo insieme.

Per esempio, almeno delineare la struttura di base (o più precisamente, le varianti di tali strutture) per un tale problema:

C'è un Expert Advisor scritto in questo modo (per esempio, per testare un'idea di trading). Supponiamo che l'idea nello Strategy Tester (presso il cliente) mostri risultati promettenti. Ora dobbiamo riscrivere l'Expert Advisor per renderlo più adatto allo sviluppo. E in particolare, dotarlo di un pannello di controllo grafico per l'utente.

È auspicabile o rendere il pannello commutabile (per l'ottimizzazione nel tester), o spostare l'intera realizzazione "non grafica" dell'EA in un file collegabile (.mqh), che può poi essere collegato all'interfaccia grafica senza modifiche (per escludere) le differenze nel funzionamento delle versioni "tester" e "grafica".

Mi piacerebbe sentire-leggere le considerazioni sulla strutturazione di un tale progetto. In particolare, sull'implementazione del modello di controllo event-driven in un tale progetto. Supponiamo che la doppia implementazione (tester + pannello) sia un requisito rigoroso del cliente (cioè il progetto deve essere fatto in qualsiasi modo, si può solo scegliere il metodo di implementazione).

Vogliamo provare il compito?

Penso che sia ovvio che il pannello di controllo Expert Advisor e l'Expert Advisor sono due moduli completamente diversi in un programma. Pertanto, richiedono di essere separati in modo tale che ogni parte sia indipendente dall'altra. Ciò significa che se si cambia una parte di un Expert Advisor (per esempio, cambiare la logica di immissione degli ordini), non è necessario cambiare la logica del pannello e viceversa (cambiare l'interfaccia del pannello - non è necessario cambiare la logica dell'Expert Advisor). La prima cosa che viene in mente è la creazione di un'interfaccia unificata attraverso la quale il pannello e l'Expert Advisor possano comunicare. Ma purtroppo, i creatori di MQL5 non hanno considerato la possibilità di creare collegamenti orizzontali, e quindi, descrivere l'interfaccia tra loro per mezzo di MQL5 non funzionerà. Allora rimane la via dell'integrazione verticale. Un Expert Advisor deve essere ereditato da una classe base, che a sua volta contiene metodi e dati sufficienti per l'interazione con il pannello. Questo significa che qualsiasi EA ereditato dalla classe base sarà anche in grado di visualizzare e interagire con il pannello. L'implementazione dei metodi, responsabili dell'interazione con il pannello, non deve essere delegata ai discendenti, ma deve essere fatta dietro le quinte della classe base, cioè il messaggio "Descendant! Se volete interagire con il pannello, dovete chiamare tale-e-quello dei miei metodi con tale-e-quello dei parametri" non funziona affatto. Idealmente, qualsiasi Expert Advisor derivato che eredita dalla classe base dovrebbe semplicemente fare trading in modo conveniente e le sue azioni saranno automaticamente visualizzate su questo pannello.

Come organizzare una classe base universale è un argomento interessante a parte. Diversi anni di pratica in questa materia mi hanno finalmente portato al mio schema universale. Si è rivelato trasparente e universale. Se siete interessati, posso fornirvi il suo diagramma di flusso di base (ha ha, disegnare diagrammi di flusso è un'attività molto utile dopo tutto). Ma in ogni caso, ognuno ha il suo modo, e una buona soluzione per uno non sarà una buona soluzione per un altro.

 
C-4:

Se siete interessati, posso darvi un diagramma schematico (ha-ha, disegnare schemi a blocchi è un'attività utile, dopo tutto).

 
sergeev:
Finalmente qualcosa si è chiarito.... )
 
C-4:

La prima cosa che viene in mente è la creazione di un'interfaccia unificata attraverso la quale il pannello e l'EA possono scambiare dati. 2.

Sfortunatamente, i creatori di MQL5 non hanno fornito la possibilità di creare collegamenti orizzontali, e quindi, descrivere l'interfaccia tra loro usando gli strumenti MQL5 è impossibile.

1. senza ambiguità.

2. E gli eventi personalizzati? È abbastanza orizzontale e universale.

3. allora rimane la via dell'integrazione verticale. Un Expert Advisor deve essere ereditato da una classe base, che a sua volta contiene metodi e dati sufficienti per interagire con il pannello. Questo significa che qualsiasi Expert Advisor ereditato dalla classe base ottiene anche la capacità di visualizzare e interagire con il pannello. L'implementazione dei metodi, responsabili dell'interazione con il pannello, non deve essere delegata ai discendenti, ma deve essere fatta dietro le quinte della classe base, cioè il messaggio "Descendant! Se volete interagire con il pannello, dovete chiamare tale-e-quello dei miei metodi con tale-e-quello dei parametri" non funziona affatto. Idealmente, qualsiasi Expert Advisor derivato ereditato da una classe base dovrebbe semplicemente commerciare in un modo conveniente, mentre le sue azioni sarebbero automaticamente visualizzate su quel pannello.

Dato che non sono d'accordo con il punto 2, non mi piace ancora questa variante.

--

Ho un'alternativa, che trovo molto interessante (variante con pannello "scollegabile"). Fai il pannello sotto forma di indicatore. Se il tuo Expert Advisor è nello Strategy Tester, semplicemente non carica il pannello. Il bonus aggiuntivo è che il pannello viene eseguito in un thread diverso lasciando più risorse per l'Expert Advisor.

Per quanto riguarda la versatilità del pannello, non vedo grandi ostacoli al fatto che il pannello sia completamente configurabile attraverso un file ini. In altre parole, è possibile prescrivere lì assolutamente tutti i dati necessari per creare qualsiasi pannello da un insieme limitato di componenti visuali + codici di eventi che dovrebbero generare quando interagiscono con un utente.

Come organizzare una classe commerciale di base universale è un argomento interessante a parte. Diversi anni di pratica su questo argomento mi hanno finalmente portato al mio schema universale. Si è rivelato trasparente e universale. Se siete interessati, posso mostrarvi il suo schema a blocchi di base.....

Dai, sono anche molto interessato, e praticamente può essere utile.
 
MetaDriver:

1. senza ambiguità.

Nahr Perché? L'eccessiva universalizzazione è un male come l'ottimizzazione prematura.

E legare i blocchi di un modulo tramite eventi... ...è lento e scomodo.

 
MetaDriver:

Dai, in realtà sono abbastanza interessato, e potrebbe essere utile nella pratica.

La cornice blu è l'entità della classe base. La cornice rossa è l'entità della classe derivata. Potete vedere che la classe base impone la definizione della sua logica al discendente in quattro metodi. Questo è il modo in cui riduce la descrizione di qualsiasi strategia alla descrizione di solo quattro situazioni:

1. Se tutte le regole per l'apertura di una posizione lunga sono state rispettate, la posizione lunga viene aperta nel metodo InitBuy()

2. Se tutte le regole per la chiusura della posizione lunga sono soddisfatte - la posizione lunga viene chiusa usando il metodo SupportBuy()

3. Se tutte le regole per l'apertura di una posizione corta sono soddisfatte - allora la posizione corta viene aperta utilizzando il metodo InitSell()

4. Se tutte le regole per la chiusura della posizione corta sono soddisfatte - allora la posizione corta viene chiusa nel metodo SupportSell()

Secondo questa logica, l'inversione della strategia non è descritta in un metodo (per esempio, close long open short), ma in due metodi che non dipendono l'uno dall'altro. Si scopre che questo approccio è molto conveniente perché ci permette, per esempio, di vietare la vendita o di chiudere forzatamente le posizioni con un clic dopo che alcune condizioni generali che possono essere descritte in una classe base sono soddisfatte.

In alcuni casi, una strategia ha dati generali sia per le vendite che per gli acquisti che dovrebbero essere ricalcolati al verificarsi di qualche evento, per esempio l'arrivo di una nuova barra. In questi casi, è possibile per una strategia sottoscrivere i propri metodi di elaborazione agli eventi. Non è possibile aprire posizioni in questi metodi, ma è possibile fare vari calcoli.

Un altro punto interessante è come gestire le posizioni aperte. La classe base memorizza una lista separata di posizioni lunghe e corte. Quando si verifica un nuovo evento (per esempio, OnTick), la classe inizia a elencare tutte le posizioni aperte e offre di elaborare ciascuna di queste posizioni una per una utilizzando i metodi SupportBuy SupportSell. Questi metodi possono chiudere solo la posizione che viene loro offerta dalla classe base al momento. Tutte le altre posizioni sono di sola lettura. Così, la classe base impone l'idea ai suoi discendenti che al momento devono concentrarsi su una sola posizione. Quando ho testato questa idea, si è scoperto che la logica anche del più complesso Expert Advisor è molto più semplice. Inoltre, dà supporto automatico alla nozione di copertura, perché l'Expert Advisor mantiene informazioni sulle sue posizioni lunghe e corte.
 
TheXpert: ... L'implementazione della parte di trading dipende dalla strategia, quindi non c'è niente da discutere nel quadro di una strategia ipotetica. L'attuazione della strategia stranamente dipende anche dalla strategia :)
MetaDriver: ... L'intera parte di trading è scritta sotto forma di una classe (CMarketDriver) che implementa completamente il posizionamento degli ordini, il monitoraggio delle posizioni, le requote e altre cose relative al trading. Per tutti i simboli in una volta sola. La parte della strategia inserisce solo le posizioni di mercato raccomandate per i simboli, cioè riempie un array di strutture in formato {string Instrument; double Position} e richiede la sincronizzazione con il server: MD.Synchronize(PositionArray). Questo è tutto. Per ora commercia solo con ordini di mercato , ma una versione che commercia con limiti impostati all'interno dello spread (per ridurre i costi di scambio) è in arrivo. Per il trading i takeprofits/stop non sono usati, ma MarketDriver può mettere degli stop protettivi in caso di una lunga perdita di connessione al server (i parametri di stop sono specificati una volta nelle impostazioni del driver). A proposito, una soluzione strutturale di grande successo, quasi senza problemi. Per testare idee strategiche nel tester - nessun problema con il trading, tutta l'attenzione può essere dedicata alla strategia - tutto il trading è stato a lungo debuggato e incapsulato nel driver di trading.

Non appena si inizia a tradurre l'esecuzione di una strategia in ordini limite, si ricevono molte domande, in qualche modo:

  • l'effetto dei tuoi limitatori sul prezzo che colpisce la tua parte di strategia (analizzatore/prognosticatore/cervello).
  • sincronizzazione per una strategia multi-valuta
  • Assenza persistente di esecuzione in un commercio di tendenza (trawl? se sì, come, o sputare e seguire il mercato)
  • Esecuzione parziale
  • ...

Allora un feedback tra l'"esecutore" e l'"analizzatore" dovrà essere implementato, e inoltre i parametri di questo movimento non ideale dovrebbero essere in qualche modo incorporati nel modello matematico dell'analizzatore

MetaDriver: ... Per controllare le idee strategiche nel tester, una canzone - nessun problema con il trading ...

Sì, per i limitatori è davvero una canzone.
 
GaryKa:

Quando si comincia a convertire completamente l'esecuzione nella strategia in ordini limite

Questo è solo un esempio di ciò di cui stavo parlando - la parte di trading dipende dalla strategia.
Motivazione: