English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Come sviluppare un Expert Advisor utilizzando gli strumenti UML

Come sviluppare un Expert Advisor utilizzando gli strumenti UML

MetaTrader 5Integrazione | 11 gennaio 2022, 15:12
195 0
Denis Kirichenko
Denis Kirichenko

Gli scienziati indagano su ciò che già esiste; gli ingegneri creano ciò che non c’è mai stato.

Albert Einstein

Introduzione

Nel mio articolo Simulink: a Guide for the Developers of Expert Advisors ho suggerito di modellare un Expert Advisor utilizzando sistemi dinamici. Tuttavia, questo approccio rappresenta solo un aspetto del design di sistemi di trading, il comportamento dinamico del sistema. I professionisti hanno uno strumento specifico che amplia la metodologia di uno sviluppatore di sistemi di trading. In questo articolo discuteremo come sviluppare un Expert Advisor utilizzando uno strumento universale - il linguaggio grafico UML.

In generale, essendo un linguaggio grafico, UML viene utilizzato per la modellazione visiva di sistemi software orientati agli oggetti. Ma, per come la vedo io, possiamo usare i suoi strumenti per sviluppare un sistema di trading. Inoltre, MQL5 appartiene alla famiglia dei linguaggi orientati agli oggetti e questo ci facilita il compito.

Ai fini della modellazione, ho scelto gratuitamente il software non commerciale Ideas Modeler.


1. Nozioni di base su UML

In che modo UML può aiutare a creare un Expert Advisor? Innanzitutto, la grafica: il problema della modellazione multi-aspetto può essere risolto utilizzando le immagini grafiche disponibili nel linguaggio. In secondo luogo, la leggibilità. Anche se un Expert Advisor è ampio e complesso, l'universalità di UML consente di presentare il suo modello utilizzando diagrammi.

Come dicono gli sviluppatori di UML, la caratteristica specifica della percezione umana sta nel fatto che un testo con immagini è più facilmente percepito rispetto a un testo spoglio.

Discutiamo brevemente le basi di UML. Se sei interessato all'argomento, puoi imparare a usare gli strumenti UML tramite le numerose pubblicazioni disponibili gratuitamente sul web.

La struttura UML può essere visualizzata in uno schema (Fig.1).

Fig.1. La struttura di UML

Fig.1. La struttura UML

Gli elementi costitutivi includono quanto segue: entità (gli elementi del modello), le relazioni (che legano le cose) e i diagrammi (che rappresentano i modelli UML).

I diagrammi UML consentono di visualizzare la rappresentazione del sistema progettato da diversi punti di vista.

I meccanismi comuni includono: le specifiche (descrizione della semantica), gli ornamenti (che contrassegnano le caratteristiche importanti del modello), divisioni comuni (astrazione e sue istanze, interfacce e implementazione), meccanismi di estensibilità (vincoli, stereotipi e valori etichettati).

L'architettura è responsabile della presentazione di alto livello del sistema nel suo ambiente. L'architettura UML può essere meglio descritta dalla "visualizzazione dell'architettura 4+1" (Fig.2):

  • Vista logica
  • Vista processo
  • Vista sviluppo
  • Vista fisica
  • Scenari

Fig.2. Vista architettura 4+1

Fig.2. Vista Architettura 4+1


Va anche notato che l'UML ha una propria gerarchia di diagrammi canonici (Fig.3). La versione 2.2 del linguaggio utilizza 14 tipi di diagrammi UML.

Fig.3. Diagrammi UML canonici


Fig.3. Diagrammi UML canonici

Propongo inoltre di considerare alcuni casi speciali di utilizzo dei diagrammi UML. Pertanto, possiamo passare da un'astrazione a una variante specifica dell'utilizzo di uno qualsiasi dei diagrammi per scopi di sviluppo di EA. Ancora una volta, il principio della progettazione multi-aspetti dei sistemi di trading, fornito dalla gerarchia dei diagrammi UML, contribuisce alla soluzione sistematica e completa del compito di creazione del TS.


2. Diagrammi UML


2.1 Diagrammi dei casi d'uso

Come si suol dire, chi ben comincia è a metà dell’opera. Di solito, anche se non necessariamente, il lavoro analitico inizia con l’uso di diagrammi di casi. Descrive il sistema dal punto di vista degli utenti.

Quando lo creiamo, possiamo:

  • specificare le varianti di utilizzo TS
  • specificare i confini del TS
  • determinare gli attori del TS
  • definire la relazione tra gli attori e le versioni TS.

Il caso d’uso è un elenco di passaggi che in genere definiscono le interazioni tra un ruolo (noto in UML come "attore") e un sistema per raggiungere un obiettivo.

Un attore "specifica un ruolo svolto da un utente o da qualsiasi altro sistema che interagisce con il soggetto. Gli attori possono rappresentare ruoli interpretati da utenti umani, hardware esterno o altri soggetti.

La relazione è una connessione semantica tra i singoli elementi di un modello.

Potresti notare che questo tipo di schema è abbastanza generale e riflette la natura concettuale del TS, piuttosto che la sua implementazione. Ma questo è il punto: passare dal generale allo specifico, dall'astratto al concreto. Chi ha detto che non siamo artisti? Disegniamo un'immagine, partendo da idee generali e schizzi. Per prima cosa disegniamo dei tratti in una tela. Quindi aggiungiamo i colori. Disegniamo i dettagli...

Quindi, proviamo a creare uno schema dei casi d'uso per un sistema di trading.

Come attori in ingresso, ho scelto i seguenti ruoli: Sviluppatore, analista di sistema, Risk manager e amministratore. Va notato che questi ruoli possono essere interpretati da una o più persone. Quali azioni intraprende il nostro sistema di trading e quali azioni vengono intraprese in relazione ad esso?

Pertanto, lo sviluppatore può creare e implementare un TS. Inoltre, può partecipare all'ottimizzazione del TS. L'analista di sistema ottimizza il TS. Il Risk manager è responsabile della gestione del rischio. L'amministratore controlla il lavoro complessivo del TS. Dal lato dell'output, vediamo che l'utente realizza un profitto come risultato del funzionamento del TS. Questo ruolo è una somma di ruoli come il trader e l'investitore. E il gestore, così come l'amministratore, sovrintende al lavoro del TS.

Lo schema contiene il blocco "Trading System". Esprime il confine del TS e lo separa dal mondo esterno.

Ora, qualche parola sulla relazione tra gli attori e i casi d'uso, nonché tra gli attori e gli altri attori e i casi d'uso e altri casi d'uso. La maggior parte delle relazioni è rappresentata da associazioni contrassegnate da una linea continua. Ciò significa che un determinato attore avvia un caso d'uso. Pertanto, il Risk manager avvia il processo di gestione del rischio, ecc. Gli attori che avviano i casi d'uso sono principali e quelli che utilizzano i risultati delle azioni commesse sono secondari. Ad esempio, un attore secondario è il Manager sul lato di output. 

L'associazione può indicare che l'attore avvii il caso d'uso appropriato.

La generalizzazione simula l'appropriata generalità dei ruoli.

L'estensione è un tipo di relazione di dipendenza tra il caso d'uso di base e il suo caso speciale.

Includere definisce la relazione del caso d'uso di base con un altro caso d'uso il cui comportamento funzionale non viene sempre utilizzato dal caso di base, ma solo in condizioni aggiuntive.

Tuttavia, tieni presente che un ruolo secondario rispetto al caso d'uso non significa che questo ruolo sia di importanza secondaria. Inoltre, nello schema vediamo che il ruolo dell'utente TS è costituito dai ruoli del trader e dell'investitore attraverso le relazioni di generalizzazione, mostrate come una linea con la punta di freccia triangolare "non dipinta".

Fig.4. Schema dei casi d'uso del TS

Fig.4. Schema dei casi d'uso del TS

Casi d'uso "Open position" e "Close position", a loro volta, sono collegati da una generalizzazione con il "Trading". Quest'ultimo caso è quello base per gli altri due. Pertanto, include il caso d'uso "Manage risk". E il suo comportamento è complementare al caso dipendente "Profit".

Poiché il profitto TS si forma a condizione che il prezzo di vendita di un bene sia maggiore del suo prezzo di acquisto, per questi casi ho utilizzato la relazione di estensione. Lo schema mostra anche il punto di estensione, cioè una condizione specifica in base alla quale viene utilizzato il caso "To profit". Le relazioni di dipendenza sono visualizzate dalla linea tratteggiata con una freccia con i corrispondenti stereotipi "include" ed "extend".

Per ogni caso d'uso è necessario creare uno scenario, ovvero descrivere una sequenza di passaggi che porti al target previsto. Il caso d'uso può essere descritto in diverse forme. Le forme comunemente accettate includono: descrizioni testuali, pseudo codice, schema di attività, schema di interazione.

Va notato che un trader è interessato a un TS in senso stretto, piuttosto che a quello mostrato in Fig.4. Pertanto, suggerisco ulteriormente di concentrarci sul caso d'uso "Trading" con l'estensione "To profit".


2.2 Schema di classe

Utilizzando lo schema classe descriveremo la struttura del TS. Vale a dire che presenteremo un modello di una struttura statica del sistema di trading in termini di classi di programmazione orientata agli oggetti. Quindi, rifletteremo la logica di programmazione del TS.

In UML uno schema di classe è un tipo di schema di struttura statica. Descrive la struttura del sistema mostrando le sue classi, i loro attributi e operatori, nonché la relazione tra le classi.

Quali sono i vantaggi di questo tipo di schema? Coloro che hanno un po' di familiarità con i linguaggi di programmazione orientati agli oggetti noteranno immediatamente la nozione familiare di "classe". La classe agisce nello schema delle classi UML come elemento costitutivo di base. Ad esempio, quando si genera un codice C++, il blocco di classe UML viene creato automaticamente sotto forma di modello di classe. Dovrai solo completare l'implementazione di ogni metodo e proprietà.

Ora proviamo a progettare qualcosa come esempio. Ma prima vorrei attirare la vostra attenzione sull'articolo "Prototype of a Trading Robot", in cui l'autore descrive i vantaggi dell'utilizzo di una logica lineare. A mio parere, molto efficace e produttivo è il principio del nesting - "macro-funzioni-dei moduli di trading".

Ad esempio, abbiamo bisogno di un Expert Advisor che utilizzi la possibilità di scambiare classi della libreria standard.

Utilizzando il blocco Class, si crea un modello di classe nello schema delle classi. L'ho chiamato CTradeExpert. Aggiungiamo alcuni attributi (in MQL5 sono dati membri della classe) per la nuova classe. Essi sono: Magic_No, e_trade, e_account, e_deal, e_symbol, e_pnt. Inseriamo anche un metodo costruttore di classe CTradeExpert. Graficamente, l'operazione sarà come mostrato in Fig.5.

Fig.5. Modello UML della classe CTradeExpert

Fig.5. Modello UML della classe CTradeExpert

Il carattere "-" davanti a un attributo indica che l'attributo ha il diritto di accesso nella modalità «privato», «#» - «protetto», «+» - «pubblico». Pertanto, per l'attributo Magic_No l'identificatore di accesso è impostato su privato, per e_pnt su pubblico e per gli altri su protetto. I due punti che seguono il nome dell'attributo indicano un tipo di dati per gli attributi e il tipo di dati restituiti per i metodi. Ad esempio, l'attributo Magic_No è di tipo int, e_trade - CTrade, ecc.

Non stiamo aggiungendo alcun metodo e attributo ora, mostriamo semplicemente come la nostra classe CTradeExpert sia connessa con le classi della libreria standard. Per fare ciò, aggiungi 6 blocchi di classi allo schema e chiamali come mostrato di seguito: CTrade, CAccountInfo, CDealInfo, CSymbolInfo, CObject. Ora associamo il modello della classe CTradeExpert a 4 blocchi di classi di trading tramite relazioni di dipendenza con lo stereotipo "use" (la linea tratteggiata con una freccia). 

La dipendenza è una relazione semantica tra due entità in cui un cambiamento nell'una indipendente può influenzare la semantica dell'altra dipendente.

Lo stereotipo in UML è una descrizione del comportamento dell'oggetto.

Quindi, colleghiamo questi blocchi con il blocco CObject mediante la relazione di generalizzazione, utilizzando una linea con una punta di freccia triangolare "non dipinta". Aggiungi i commenti alle classi della libreria standard. Ora, il nostro schema UML appare come mostrato nella Figura 6.

Fig.6. Schema delle classi UML

Fig.6. Schema delle classi UML

Ora dobbiamo solo generare il codice utilizzando la funzione "Generate" della scheda "Generate" nella barra laterale (Fig.7).

Fig.7. Codice generato

Fig.7. Codice generato

Il più adatto è il linguaggio С++. Useremo C++ per generare il codice della classe Expert Advisor e poi lo tradurremo facilmente in MQL5.

Per questo schema il codice generato è il seguente:

//
class CTradeExpert
{

private:
        int Magic_No;

protected:
        CTrade e_trade;

protected:
        CAccountInfo e_account;

protected:
        CDealInfo e_deal;

protected:
        CSymbolInfo e_symbol;

public:
        double e_pnt;

public:
        void CTradeExpert () 
    {

    }

};


//
class CObject
{
};

//
class CTrade : public CObject
{
};

//
class CDealInfo : public CObject
{
};

//
class CSymbolInfo : public CObject
{
};

//
class CAccountInfo : public CObject
{
};

Una sintassi davvero familiare, non è vero? Dobbiamo solo adattarci al corpo della classe. A questo scopo su MetaEditor creiamo un file per la nuova classe TradeExpert.mqh. Copia il codice generato in precedenza su di esso. Per leggibilità eliminiamo l'identificatore di accesso ripetuto protetto per i membri della classe CTradeExpert.

Elimina le righe collegate alla dichiarazione delle classi della libreria standard. Successivamente, aggiungi il file che include l'istruzione # Include per ogni classe utilizzata della libreria standard, poiché queste classi sono già definite dallo sviluppatore. E aggiungi i nostri commenti. Di conseguenza, otteniamo il codice in questo modo:

//includes
#include <Trade\Trade.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\SymbolInfo.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CTradeExpert
  {
private:
   int               Magic_No;   // Expert Advisor magic

protected:
   CTrade            e_trade;    // An object for executing trade orders
   CAccountInfo      e_account;  // An object for receiving account properties
   CDealInfo         e_deal;     // An object for receiving deal properties
   CSymbolInfo       e_symbol;   // An object for receiving symbol properties

public:
   double            e_pnt;      // Value in points

public:
                     CTradeExpert()
     {
     }
  };
//+------------------------------------------------------------------+

ora aggiungiamo altri moduli di funzioni di trading alla nostra classe Expert Advisor.

Questi possono essere: CheckSignal, OpenPosition, CheckPosition, ClosePosition etc. Spero che tu conosca già il principio della "condizione al servizio". In questo caso, la nostra classe di test CTradeExpert non ti sembrerà difficile. Mi sono concentrato in particolare su alcuni esempi già familiari di Expert Advisor per rendere più facile la comprensione dei meccanismi di UML.

Quindi, ora il modello della classe appare come mostrato in Fig.8.

Fig.8. Modello UML della classe CTradeExpert

Fig.8. Modello UML della classe CTradeExpert

Per il modello aggiornato della classe possiamo anche generare un codice utilizzando il metodo già descritto.


2.3 Schema di attività

Utilizzando questo tipo di diagrammi UML possiamo studiare il comportamento del sistema utilizzando i modelli di flusso di dati e flusso di controllo. I diagrammi di attività sono rappresentazioni grafiche dei flussi di lavoro di attività e azioni graduali.

Lo schema di attività differisce dallo schema di flusso, il quale descrive solo i passaggi dell'algoritmo. La notazione dello schema di attività è più ampia. Ad esempio, è possibile specificare lo stato degli oggetti al suo interno.

I diagrammi di attività vengono utilizzati dagli sviluppatori per descrivere:

  • regole di business
  • casi monouso
  • serie complesse di casi d'uso multipli
  • processi con soluzioni e flussi alternativi
  • operazioni parallele
  • flussi di programma e strutture logiche di controllo

Supponi che la classe di expert creata CTradeExpert venga utilizzata nel file dell'Expert Advisor Test_TradeExpert.mq5. Come ricordiamo, il modello predefinito durante la creazione di un EA su MetaEditor 5 fornisce tre funzioni di gestione eventi predefinite: OnInit, OnDeinit e OnTick. Soffermiamoci su di essi.

Proviamo a visualizzare uno schema con la nostra operazione EA che tiene conto del file Test_TradeExpert.mq5. Qui va notato che l'Expert Advisor, o meglio la sua struttura, è piuttosto primitiva. Ci stiamo solo allenando per ora. Una semplice struttura EA va bene per questo scopo.

Progettiamo uno schema per l'utilizzo del nostro Expert Advisor, il cui algoritmo è rappresentato nel file Test_TradeExpert.mq5.

Quindi, tutto inizia con il nodo iniziale (Fig.9). Da questo nodo, un token di controllo si sposta sul nodo che chiama l'azione "Create an Expert Advisor instance". Questa azione avvia il flusso dell'oggetto (freccia blu) che modifica lo stato del nodo dell'oggetto (myTE=creato) e controlla il flusso in un nodo che chiama "Initialize the Expert Advisor". 

Un flusso di controllo è rappresentato sotto forma di un edge di attività che collega i due nodi di attività e su cui vengono passati solo i token di controllo. 

Un flusso di oggetto è rappresentato come un'attività edge a cui vengono passati solo oggetti o token di dati.

Un nodo di attività è una classe astratta per singoli punti nel flusso di attività connesse da bordi.

Un nodo di decisione è un nodo di controllo che sceglie tra i flussi in uscita.

Un nodo oggetto rappresenta gli oggetti utilizzati nell'attività.

Un edge di attività è una classe astratta per connessioni dirette tra due nodi di attività.

Il nodo iniziale mostra dove inizia l'attività.

Il nodo finale di un'attività completa tutti i flussi di attività.

Esso, a sua volta, cambia lo stato dell'oggetto myTE (myTE=initialized) e passa il token di controllo al nodo decisionale. Se l'Expert Advisor viene inizializzato con successo, il flusso di controllo va al nodo "Process the trade event NewTick". Se l'inizializzazione fallisce, il token di controllo entra prima nel nodo di generalizzazione, quindi nel nodo di azione "Deinitialize Expert Advisor".

I token sono costruzioni astratte introdotte per comodità nel descrivere il processo dinamico di esecuzione di un grafico di attività definito statisticamente. Il token non può contenere alcuna informazione aggiuntiva (un token vuoto); in questo caso viene chiamato token di flusso di controllo, oppure può contenere un riferimento a un oggetto o a una struttura dati e, in questo caso, viene chiamato token di flusso di dati.

Diamo un'occhiata al primo flusso di controllo che proviene dal nodo decisionale. È diretto verso un'area con un'azione interrotta, come indicato da un rettangolo con gli angoli arrotondati disegnato dalla linea tratteggiata rossa e dallo stereotipo di "interruptible". Quando il flusso di controllo si trova in quest'area potrebbe interrompersi inaspettatamente. Se attivi il nodo azione (flag arancione) che riceve l'evento "Unload Expert Advisor", interromperà tutti i flussi. Il token di controllo si sposta sul bordo dell'interruzione (freccia a zigzag arancione) e quindi sul nodo di connessione. Dopodiché l'EA viene deinizializzato. Quindi, il token di controllo va al nodo "Delete global variables", quindi il flusso verrà completato nel nodo di attività finale.

Il nodo di azione "Deinitalize Expert Advisor" cambia anche lo stato dell'oggetto myTE (myTE=deinitsialized) da un flusso di oggetti. Il nodo "Delete global variables", a sua volta, rimuove l'oggetto myTE (myTE=deleted).

Fig.9. Schema di attività per Test_TradeExpert.mq5

Fig.9. Schema di attività per Test_TradeExpert.mq5

Supponiamo che il flusso di controllo sia stabile: l'EA non è scaricato. Dal nodo "Process the trade event NewTick" il flusso si sposta su un altro blocco, un’area di espansione il cui stereotipo è definito "iterativo" (rettangolo verde con linee tratteggiate).

Chiamo quest'area "Blocco di trading" per riflettere le caratteristiche di trading di base e migliorare la percezione dello schema. Una caratteristica del blocco è l'esecuzione ciclica di operazioni per oggetti in entrata. Abbiamo bisogno solo di 2 cicli: gestisci le direzioni lunga e corta. All'ingresso del blocco e all'uscita dal blocco ci sono nodi di espansione che includono oggetti di direzione di trading (lungo o corto). 

Un nodo di espansione è una raccolta di oggetti che entra o esce dall'area di espansione eseguita una volta per ogni oggetto.

Il nodo azione che invia un segnale (invia segnale di azione) rappresenta l'invio del segnale.

Il nodo di azione che accetta un evento (accetta evento di azione) attende la ricezione di un evento del tipo appropriato.

Pertanto, ogni direzione è gestita da nodi come: "Check signal" (nodo di invio del segnale), "Receive signal" (nodo di ricezione del segnale), "Open position" (nodo di invio del segnale), "Check position" (nodo di invio del segnale), "Close position" (nodo di invio del segnale). Va notato che l'oggetto direzione (dir) può essere passato nel flusso dell'oggetto tra i nodi di azione, come indicato dalle frecce viola. Le operazioni in un blocco continueranno finché l'Expert Adviser sarà scarico.


2.4 Lo schema di sequenza

Usiamo lo schema di sequenza per descrivere la sequenza di interazione dell'oggetto. Un aspetto molto importante di questo tipo di schema è il tempo.

Quindi, lo schema ha due scale in forma implicita. Quello orizzontale è responsabile della sequenza delle interazioni degli oggetti. Quello verticale è un asse temporale. L'inizio dell'intervallo di tempo è la parte superiore dello schema.

La parte superiore dello schema contiene oggetti schema che interagiscono. Un oggetto possiede la propria lifeline come una linea tratteggiata verticale. Gli oggetti si scambiano messaggi. Sono rappresentati da frecce. Quando un oggetto è attivo, riceve il focus di controllo. Graficamente, questo focus è espresso come un rettangolo stretto sulla linea di vita.

Un oggetto è un rettangolo che contiene un nome di oggetto sottolineato e un nome di classe (facoltativo) separato da due punti.

Una lifeline dell'oggetto è una linea che mostra l'esistenza di un oggetto per un certo periodo di tempo; più lunga è la linea, più lungo è l'oggetto.

Il focus di controllo è disegnato come un rettangolo stretto il cui lato superiore indica l'inizio della ricezione del focus di controllo da parte dell'oggetto ( inizio dell'attività) e il suo lato negativo: la fine del focus di controllo (fine dell'attività).

In UML, ogni interazione è descritta da un insieme di messaggi che gli oggetti che vi partecipano si scambiano.

Facciamo un po' di pratica.

Il terminale è un attore. Avvia il funzionamento dell'Expert Advisor. Altri oggetti contrassegnati con lo stereotipo "evento" sono gli eventi del client terminal: Init, Deinit, NewTick. Naturalmente, se lo desideri, puoi ampliare la gamma di eventi. Quando si avvia un Expert Advisor, l'oggetto myTE viene creato a livello globale. È un'istanza della classe CTradeExpert. L'oggetto classe è leggermente inferiore rispetto ad altri oggetti nello schema, il che indica che è stato creato dopo la funzione di costruzione.

Un comando di creazione è contrassegnato da una linea tratteggiata, una freccia aperta e un messaggio 1.1 CTradeExpert(). La linea tratteggiata con una freccia indica il tipo "create" del costruttore predefinito CTradeExpert(). Dopo aver creato un'istanza di CTradeExpert, viene attivato il passaggio 1.2: il focus di controllo viene restituito al terminale. Per leggibilità, indico i messaggi sincroni nel formato #.# come 1.1 e gli asincroni come - #. Quindi, il terminale gestisce l'evento Init utilizzando la funzione OnInit() nel passaggio 2.1, lo stato attivo viene restituito al passaggio 2.2. I messaggi di tipo "Call" vengono visualizzati come linee con una freccia triangolare "dipinta" alla fine.

Se l'evento Init restituisce al terminale un valore diverso da zero, significa che l'inizializzazione non è riuscita: viene utilizzato il passo 3.1 che porta alla generazione e gestione dell'evento Deinit. Nel passaggio 3.2 il focus di controllo viene restituito al terminale. Quindi l'oggetto della classe CTradeExpert viene eliminato (passaggio 4.1). A proposito, durante la creazione di uno schema di classe, non ho incluso la funzione distruttore CTradeExpert nella classe. Ciò può essere fatto in seguito. Questo è uno dei vantaggi della costruzione di diagrammi: il processo di costruzione di più diagrammi è iterativo. Ciò che è stato fatto prima per uno schema, può essere fatto poi per un altro e, successivamente, è possibile modificare il primo.

Va notato che il codice MQL5 di un modello EA standard non contiene un blocco che gestisce l'inizializzazione non riuscita. L'ho specificato per salvare la logica della sequenza. Lo schema di sequenza UML usa il blocco opt con una condizione di guardia OnInit()!=0, la quale è equivalente alla costruzione MQL5 if(OnInit()!= 0) {}.

Nel passaggio 4.2, il controllo viene trasferito al terminale.

Ora il terminale è pronto per gestire l'evento NewTick.

L'elaborazione di questo evento avviene nel loop del blocco che significa un loop infinito. Cioè, l'EA gestirà questo evento fino a quando non lo disabilitiamo. Il terminale elabora l'evento NewTick utilizzando la funzione OnTick (passaggio 5). Nella fase 6, il focus di controllo viene trasferito all'Expert Advisor myTE. Utilizzando 4 messaggi riflessivi, implementa le seguenti funzioni: CheckSignal, OpenPosition, CheckPosition, ClosePosition. La riflessività è dovuta al fatto che l'oggetto Expert Advisor invia messaggi a se stesso.

Inoltre, queste funzioni della classe CTradeExpert sono racchiuse nel blocco loop(2). Il due indica che il ciclo consiste di due passaggi. Perché due? Perché gestisce due direzioni di scambio: lunga e corta (dal passaggio 7 al 10). Nell'undicesimo passaggio, il focus viene passato al terminale.

I passaggi 12 e 13 sono responsabili rispettivamente della deinizializzazione e dell'eliminazione dell'oggetto Expert Advisor.

Fig.10. Schema SD per Test_TradeExpert.mq5

Fig.10. Schema SD per Test_TradeExpert.mq5

Pertanto, abbiamo le principali capacità di design. Con l'aiuto dei diagrammi creati, il lavoro dello sviluppatore è ottimizzato. Ora possiamo iniziare a scrivere un codice per il file Test_TradeExpert.mq5. Certo, puoi fare a meno dei diagrammi. Ma quando hai un Expert Advisor complesso, l'uso dei diagrammi riduce la probabilità di errori e ti consente di gestire in modo efficiente lo sviluppo del tuo TS.

Utilizzando il modello Expert Advisor, ora creiamo Test_TradeExpert.mq5.

Creiamo un'istanza della classe CTradeExpert myTE a livello globale.

Ora riempiamo il corpo della funzione OnTick().

Scriviamo le funzioni della classe come segue:

for(long dir=0;dir<2;dir++)

     {

      myTE.CheckSignal(dir);

      myTE.OpenPosition(dir);

      myTE.CheckPosition (dir);

      myTE.ClosePosition(dir);

     }

Qualcosa di simile sarà la gestione dell'evento NewTick. Ovviamente, dobbiamo ancora specificare ciascuna delle funzioni che verranno utilizzate dai membri dei dati della classe, tra le altre. Ma lasciamo questo lavoro per il futuro. Ora il nostro obiettivo è trasferire la logica dei diagrammi UML nel codice MQL5.


3. Sviluppo e presentazione di un Expert Advisor basato sui diagrammi UML

Ad esempio, creiamo diagrammi per un Expert Advisor complesso. Definiamo le sue caratteristiche nel contesto di una determinata strategia implementata in MQL5. In generale, il nostro Expert Advisor eseguirà operazioni di trading; in particolare, genererà segnali di trading, manterrà posizioni aperte e gestirà il denaro. È piuttosto una strategia di trading modello. Tuttavia, per scopi di allenamento cercheremo di lavorare con questo.

Innanzitutto, creiamo uno schema dei casi d'uso per il nostro EA. Solo in una certa misura sarà diverso da quello discusso in precedenza. Ho prestato attenzione all'ambiente interno del TS, ignorando l'esterno (Fig.11), poiché nel codice implementeremo solo le attività di trading.

Fig.11. Schema dei casi d'uso del TS

Fig.11. Schema dei casi d'uso del TS

Definiamo ora la struttura dell'Expert Advisor. Supponiamo di utilizzare gli sviluppi della libreria standard perché è coerente con gli obiettivi dichiarati del TS. Recentemente, è stato notevolmente ampliato. E soprattutto riguarda le classi di strategie di trading. Quindi, il nostro obiettivo è creare uno schema di classe. Non sarà semplice, quindi ci vuole pazienza.

Qui vorrei sottolineare che consideriamo la libreria standard per alcuni motivi. Innanzitutto, sulla sua base proviamo a creare un robot di trading. E, secondo, ugualmente importante, facciamo un po' di pratica lavorando con i diagrammi UML. Terzo, forse la biblioteca stessa è molto preziosa. Così possiamo imparare molte cose utili dalla libreria e, allo stesso tempo, cercare di capire la sua struttura non proprio semplice.

La conversione di un codice nella struttura di uno schema UML si chiama ingegneria inversa. In realtà, lo stiamo facendo manualmente. Esistono dei software professionale che ti consente di farlo automaticamente (IBM Rational Rose, Visual Paradigm per UML, ecc.). Ma per scopi pratici, penso che dobbiamo lavorare "manualmente".

Creiamo un modello della classe base per implementare strategie di trading CExpert utilizzando il blocco "Classe". Vediamo quali altre classi e costruzioni vengono utilizzate nel corpo della classe CExpert. Innanzitutto, va notato che la classe CExpert è derivata dalla classe base CExpertBase, che a sua volta è derivata dalla classe base CObject.

Nello schema creiamo i blocchi per queste classi e definiamo la relazione tra le classi utilizzando una linea con una freccia triangolare "non dipinta" (generalizzazione). Aggiungi un commento al modello della classe CExpert (un rettangolo giallo con un angolo piegato). La struttura della classe intermedia ora si presenta così: Fig.12. Chiamiamo lo schema Expert.

Fig.12. Lo schema Expert, la vista iniziale

Fig.12. Lo schema Expert, la vista iniziale

Osserviamo il codice nel file Expert.mqh. La classe CExpert, tra l'altro, coinvolge le enumerazioni ENUM_TRADE_EVENTS e ENUM_TIMEFRAMES, una delle 8 strutture predefinite MqlDateTime. La classe usa anche altre istanze di classe, come: CExpertTrade, CExpertSignal, CExpertMoney, CExpertTrailing, CIndicators, CPositiontInfo, COrderInfo.

Ora dobbiamo apportare alcune modifiche allo schema. Innanzitutto, specifichiamo che le classi CExpertSignal, CExpertMoney, CExpertTrailing sono derivate da una classe base CExpertBase e le classi CPositiontInfo, COrderInfo sono derivate da CObject (ho impostato per lui lo stereotipo "metaclasse").

Segnaliamo le relazioni di dipendenza con lo stereotipo "use" tra il blocco della classe CExpert e le altre classi, non dimenticare la struttura e le enumerazioni MqlDateTime. Modifichiamo lo stile di colore dei blocchi e otteniamo la seguente struttura: Fig.13.

Fig.13. Lo schema Expert, la vista iniziale

Fig.13. Lo schema Expert, la vista iniziale


Tuttavia, questa struttura non riflette il quadro completo perché ci sono un certo numero di classi che vengono utilizzate indirettamente dalle classi già menzionate. Che tipo di classi sono? Innanzitutto, la classe CExpertTrade è derivata da CTrade. Quest'ultima è una sottoclasse di CObject.

La classe CExpertTrade utilizza l'enumerazione ENUM_ORDER_TYPE_TIME, le classi CSymbolInfo e CAccountInfo sono anch'esse figlie di CObject. La classe CTrade utilizza anche istanze delle classi CSymbolInfo. Apportiamo modifiche allo schema. Ora il nostro schema ha la seguente forma: Fig.14.

Fig.14. Lo schema Expert, la vista iniziale

Fig.14. Lo schema Expert, la vista iniziale

Ancora una volta, lo schema non è completo. Ad esempio, se guardi nel file della libreria standard Trade.mqh, vedrai che CTrade utilizza diverse strutture, enumerazioni e la classe CSymbolInfo. Se sono tutti visualizzati su uno schema, sarà troppo carico. E questo renderà difficile capire.

Per far fronte a questa difficoltà, ho utilizzato un pacchetto per lo schema. Incapsula classi correlate, enumerazioni, altri pacchetti, ecc. Ho collegato il pacchetto con gli elementi dello schema tramite l'interfaccia. Ad esempio, lo schema per il pacchetto CTrade può essere rappresentato come segue: Fig.15.

Fig.15. Lo schema delle classi per il pacchetto CTrade

Fig.15. Lo schema di classe per il pacchetto CTrade

Lo schema del pacchetto CTrade mostra le relazioni di dipendenza della classe CTrade con le enumerazioni e la struttura.

Le relazioni con la classe base CObject e la classe CSymbolInfo utilizzata vengono implementate tramite un'interfaccia.

In prossimità delle interfacce è presente un'icona di relazione con lo schema di classe che contiene il pacchetto CTrade come singolo elemento. Cliccando su una qualsiasi delle interfacce, queste portano automaticamente allo schema originale (Fig.16).

Fig.16. Lo schema Expert con interfacce

Fig. 16. Lo schema Expert con interfacce

Le relazioni di interfaccia sono arancioni. L'icona dello schema di classe accanto al pacchetto CTrade indica la possibilità di passare a questo schema. Quindi, usando l'incapsulamento, possiamo migliorare significativamente la leggibilità dello schema delle classi.

Quindi, andiamo avanti. La classe CObject usa puntatori a istanze della stessa classe nel suo corpo. Pertanto, possiamo impostare la relazione di dipendenza per il blocco CObject con lo stereotipo "use" relativo a se stesso.

Diamo un'occhiata al blocco del modello di classe CExpertBase. Sulla base delle prime righe del file di intestazione ExpertBase.mqh possiamo dire che questa classe utilizza più istanze di varie classi ed enumerazioni. Pertanto, per il modello di classe e le sue relazioni è ragionevole creare il pacchetto CExpertBase.

Quindi, prima definiamo il modello di classe CExpertBase nello schema del pacchetto. Attraverso l'interfaccia mostriamo la relazione con la classe base CObject e la relazione d'uso con le classi CSymbolInfo e CAccountInfo. Quindi, utilizzando blocchi di classi e relazioni di dipendenza, specifichiamo che la classe CExpertBase utilizza le seguenti classi: CiOpen, CiHigh, CiLow, CiSpread, CiTime, CiTickVolume, CiRealVolume.

Le prime quattro classi sono derivate da CPreseSeries e le ultime quattro da CSeries. Inoltre, la classe CSeries ha un figlio CPreseSeries il quale è, a sua volta, figlio di CARrayObj. Le relazioni ereditarie sono state usate in precedenza, come ricordiamo. Denotali come una relazione di generalizzazione nello schema.

Non dimenticare che la classe CExpertBase utilizza nel suo corpo enumerazioni come: ENUM_TYPE_TREND, ENUM_USED_SERIES, ENUM_INIT_PHASE, ENUM_TIMEFRAMES. L'ultima enumerazione viene utilizzata anche dai figli della classe CPreseSeries e della classe CSeries. Per non perdere le relazioni e per rendere chiaro lo schema, regoliamo lo stile per ciascuno degli elementi dello schema. Di conseguenza, otteniamo il seguente schema (Fig.17).

Fig.17. Lo schema delle classi per il pacchetto CExpertBase

Fig. 17. Lo schema delle classi per il pacchetto CExpertBase

Non è ancora completo e dovremo lavorarci ancora. Si scopre che le quattro classi, che ereditano la classe CPreseSeries usano anche la classe CDoubleBuffer. Inoltre, ciascuna delle quattro classi utilizza la propria classe buffer che deriva da CDoubleBuffer. Pertanto, COpen utilizza COpenBuffer ecc. CDoubleBuffer ha una classe base (CArrayDouble) e usa ENUM_TIMEFRAMES.

CArrayDouble eredita CArray, usa i puntatori alle istanze della sua stessa classe e l'enumerazione ENUM_DATATYPE. La classe COpenBuffer e altre classi buffer della serie di prezzi (CHighBuffer, CLowBuffer, CCloseBuffer) utilizzano l'enumerazione ENUM_TIMEFRAMES.

Le quattro classi che ereditano la classe CSeries utilizzano solo le proprie classi buffer (CSpreadBuffer, CTimeBuffer, CTickVolumeBuffer, CRealVolumeBuffer). Il primo dei buffer di classe CSpreadBuffer eredita CArrayInt, gli altri CArrayLong. Le ultime due classi utilizzano i puntatori alle istanze della propria classe e l'enumerazione ENUM_DATATYPE e sono derivate da CArray che, a sua volta, è figlio della classe CObject.

La classe CpriceSeries ei relativi elementi figlio utilizzano la classe CDoubleBuffer e l'enumerazione ENUM_TIMEFRAMES.

CSeries utilizza le enumerazioni ENUM_SERIES_INFO_INTEGER, ENUM_TIMEFRAMES. Eredita CARrayObj. Quest'ultimo eredita CArray, usa ENUM_POINTER_TYPE, i puntatori alle istanze della propria classe e la classe CObject. Di conseguenza, otteniamo lo schema mostrato in figura 18.

Fig.18. Schema delle classi esteso per il pacchetto CExpertBase

Fig.18. Schema di classe esteso per il pacchetto CExpertBase

E lo schema originale Expert per le classi e pacchetti CExpert, CExpertBase, CSymbolInfo, CAccountInfo e CObject con interfacce appare come segue (Fig.19).

Fig.19. Lo schema Expert con interfacce

Fig.19. Lo schema Expert con interfacce

Ho anche aggiunto l'enumerazione ENUM_ORDER_TYPE utilizzata da CExpertTrade. Per leggibilità, ho contrassegnato il gruppo di relazioni con colori diversi.

Continuiamo il nostro lavoro. Spero che tu capisca la logica. Il modello di una classe sullo schema può avere molte relazioni con altre classi e altre entità. Quindi sostituisco solo alcuni set con un pacchetto nello schema di base.

Quindi, studiamo CSymbolInfo. Se osservi il codice di SymbolInfo.mqh, vedrai che la classe base CSymbolInfo utilizza alcune enumerazioni e strutture MQL5. È bene usare un pacchetto per esso e le sue relazioni (Fig.20).

Fig.20. Schema del pacchetto CSymbolInfo

Fig.20. Schema del pacchetto CSymbolInfo

Un po' di spazio libero nello schema può essere utilizzato per i commenti. Inoltre, ho contrassegnato l'interfaccia di relazione con la classe genitoreCObject. Lo schema Expert originale di pacchetti e classi sarà leggermente modificato. Darò la sua versione aggiornata in seguito, quando tutte le classi e i pacchetti si rifletteranno nello schema.

Quindi, andiamo avanti. Diamo un'occhiata al codice MQL5 in AccountInfo.mqh. A quanto pare, CAccountInfo utilizza anche alcune enumerazioni. Li riflettiamo sullo schema del pacchetto che creerà per questa classe e le sue relazioni con altre entità (Fig.21).

Fig.21. Schema pacchetto CAAccountlInfo

Fig.21. Schema del pacchetto CAAccountlInfo

Ora ci occupiamo della classe CExpert. Per questa classe creiamo anche un pacchetto CExpert che apparirà come mostrato in Fig.22. Continuiamo a migliorare la leggibilità del nostro schema principale. La classe CExpert è collegata a diverse altre classi, come indicato dalle linee di interfaccia arancioni con una freccia.

Fig.22. Schema pacchetto CExpert

Fig.22. Schema del pacchetto Expert


Esploriamo altre classi rimanenti. Creeremo più pacchetti per loro.

CExpertSignal deriva da CExpertBase. Questa relazione è già stata mostrata nello schema originale Expert. Inoltre, la classe CExpertSignal utilizza CArrayObj, COrderInfo, CIndicators e istanze della propria classe (Fig .23). In particolare, l'interfaccia di relazione con la classe CArrayObj ci porterà allo schema del pacchetto CExpertBase, il quale mostra la relazione della classe CArrayObj con altre entità.

Fig.23. Schema del pacchetto CExpertSignal

Fig.23. Schema del pacchetto ExpertSignal

Non sto mostrando tutti i diagrammi adesso: sono tutti disponibili nel file allegato Expert.simp. Ora diamo un'occhiata al nostro schema aggiornato di pacchetti e classi Expert (Fig.24).

Come puoi vedere, quasi tutte le classi chiave nello schema sono state incapsulate in pacchetti per rendere lo schema più facile da capire. Ho cambiato il colore della linea di generalizzazione in marrone per distinguerlo dalla linea della relazione di dipendenza.

Fig.24. Lo schema dei pacchetti e delle classi Expert

Fig.24. Lo schema dei pacchetti e delle classi Expert

Quindi, abbiamo riflettuto tutto ciò che può essere preso dal codice disponibile nella libreria standard per la creazione di schemi. Abbiamo solo bisogno di aggiungere alcuni blocchi in più che specificano le operazioni di trading dell'Expert Advisor.

Il primo blocco è il blocco di CmyExpert che eredita le "abilità" di trading dalla classe CExpert. Questo è il blocco per il quale siamo stati così a lungo impegnati nell’ingegneria inversa. Attuerà una strategia di trading specifica. Dobbiamo anche specificare le funzioni virtuali delle classi base dell'EA.

A questo scopo creiamo un blocco di classi CmyExpertSignal, CmyExpertMoney, CmyExpertTrailing e indichiamo che sono derivate da quelle opportune (Fig.25).

Fig.25. Schema esteso di pacchetti e classi Expert

Fig.25. Schema esteso di pacchetti e classi Expert


Quali funzioni e dati dovrebbero includere ciascuna delle classi dipende dallo sviluppatore. Qui sto cercando di mostrare lo schema più generale, non un'implementazione specifica di una classe derivata. Pertanto, per ciascuna delle classi derivate possiamo creare uno schema separato con un elenco dettagliato di metodi e proprietà inclusi, come è stato fatto, ad esempio, in Fig.8.

Ora vediamo come possiamo usare lo schema di sequenza nel nostro lavoro. Permettetemi di ricordarvi che mostra come opera il nostro EA rispetto alla timeline.

Quindi, scriviamo i dettagli del lavoro di EA in ordine cronologico (Fig.26).

Fig.26. Lo schema di sequenza dell'Expert Advisor

Fig.26. Lo schema di sequenza dell'Expert Advisor

Il terminale funge da attore. A livello globale crea l'oggetto myTrader, un'istanza di CmyExpert (Passaggio 1.1). Il verde indica eventi predefiniti del client terminal (Init, Deinit, NewTick, Trade.) La logica dello schema di sequenza è stata descritta in precedenza. Qui vorrei sottolineare alcuni punti specifici. Quando il corpo dell'Expert Advisor cresce e c'è sempre più codice, diventa più difficile visualizzarlo in uno schema.

Per risolvere questo problema, utilizzare l'approccio a blocchi. Viene visualizzato un insieme di alcune funzioni comuni sotto forma di blocco. Di norma, è un altro schema di sequenza. Si dice che sia un uso di interazione.

Quindi, in questo caso, ho creato uno schema di sequenza chiamato OnInit per riflettere la logica di gestione dell'evento terminale Init in uno schema separato. Sintatticamente è definito come un bordo con la parola chiave ref (riferimento) e viene utilizzato quando il token di controllo passa da OnInit (passaggio 2.1) alla lifeline dell'oggetto Init.

Inoltre, ho impostato uno spostamento dell'interfaccia su questo schema di sequenza per OnInit. Cioè, se clicchi 2 volte sul bordo, puoi effettivamente aprire uno schema di sequenza dettagliato di OnInit (Fig.27).

Fig.27. Lo schema di sequenza di OnInit

Fig.27. Lo schema di sequenza di OnInit

Il passaggio ad altri diagrammi di sequenza è molto conveniente per le ripetizioni di alcune azioni.

Ad esempio, lo schema OnInit contiene azioni legate alla deinizializzazione EA, la cui elaborazione viene eseguita in myTrader_Deinit (Fig.28).

Fig.28. Lo schema di sequenza di myTrader_Deinit

Fig.28. Lo schema di sequenza di myTrader_Deinit

In generale, in questa fase della progettazione di EA ho quattro schemi di sequenza. Naturalmente, durante uno sviluppo più serio potresti aver bisogno di schemi aggiuntivi. Ad esempio, non ho gestito altri eventi del client terminal (NewTick, Trade).


Conclusioni

In questo articolo, ho suggerito di prendere in considerazione la natura multidimensionale del processo di sviluppo dell’Expert Advisor utilizzando il linguaggio grafico UML, usato per la modellazione visiva di sistemi software orientati agli oggetti. Il vantaggio principale di questo approccio è la visualizzazione del designer.

Come ogni fenomeno complesso, UML ha i suoi svantaggi di cui lo sviluppatore deve essere a conoscenza (ridondanza, semantica imprecisa, ecc.).

Spero che la metodologia descritta per lo sviluppo di EA sia interessante. Sarei grato per eventuali commenti e critiche costruttive.


Posizione dei file:

#
          File                
            Percorso               
Descrizione
 1  TradeExpert.mqh
  %MetaTrader%\MQL5\Include  Classe di Expert Advisor
 2  Test_TradeExpert.mq5
  %MetaTrader%\MQL5\Experts  Expert Advisor
 3  Expert.simp  %Documents%\UML projects  Progetto di diagrammi UML
 4   SoftwareIdeasModeler.4.103.zip  %Program Files%\SoftwareIdeasModeler
  File di distribuzione del software Ideas Modeler


Fonti:

  1. Free UML courses. The Internet University of Information Technology
  2. Jim Arlow, Ila Neutstadt. UML2 and the Unified Process Practical: Object-Oriented Analysis and Design
  3. Leonenkov A. Object-Oriented Analysis and Design Using UML and IBM Rational Rose.
  4. Martin Fowler UML Distilled: A Brief Guide to the Standard Object Modeling Language. - 192 стр.
  5. Paul Kimmel. UML Demystified. - 272 стр.
  6. F. A. Novikov, D. Y. Ivanov. Modeling in UML
  7. Mark Priestly. Practical Object-Oriented Design With Uml, Mcgraw Hill Higher Education; 2nd edition, 2007.

Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/304

File allegati |
expert.zip (82.35 KB)
tradeexpert.mqh (3.5 KB)
Come aggiungere nuove lingue dell'interfaccia utente alla piattaforma MetaTrader 5 Come aggiungere nuove lingue dell'interfaccia utente alla piattaforma MetaTrader 5
L'interfaccia utente della piattaforma MetaTrader 5 è tradotta in diverse lingue. Non preoccuparti se la tua lingua madre non è tra quelle supportate. Puoi facilmente completare la traduzione utilizzando la speciale utility MetaTrader 5 MultiLanguage Pack offerta da MetaQuotes Software Corp. gratuitamente a tutti i partecipanti. In questo articolo mostreremo alcuni esempi di come aggiungere una nuova interfaccia utente lingue alla piattaforma MetaTrader 5.
Applicazione della trasformata di Fisher e della trasformata inversa di Fisher all'analisi dei mercati su MetaTrader 5 Applicazione della trasformata di Fisher e della trasformata inversa di Fisher all'analisi dei mercati su MetaTrader 5
Ora sappiamo che la funzione di densità di probabilità (PDF) di un ciclo di mercato non ricorda un ciclo gaussiano, ma piuttosto un PDF di un'onda sinusoidale e che la maggior parte degli indicatori presuppone che il ciclo di mercato PDF sia gaussiano quindi abbiamo bisogno di un modo per "correggerlo". La soluzione è utilizzare la trasformata di Fisher. La trasformata di Fisher cambia il PDF di qualsiasi forma d'onda in una curva approssimativamente gaussiana. Questo articolo descrive la matematica dietro la trasformata di Fisher e la trasformata di Fisher inversa e la loro applicazione nel trading. Viene presentato e valutato un modulo di segnale di trading proprietario basato sulla trasformata di Fisher inversa.
Dottor Tradelove o come ho smesso di preoccuparmi e ho creato un Expert Advisor di auto-formazione Dottor Tradelove o come ho smesso di preoccuparmi e ho creato un Expert Advisor di auto-formazione
Poco più di un anno fa, joo, nel suo articolo "Genetic Algorithms - It's Easy!", ci ha dato uno strumento per l'implementazione dell'algoritmo genetico in MQL5. Ora, utilizzando quello strumento creeremo un Expert Advisor che ottimizzerà geneticamente i propri parametri in determinate condizioni di margine...
Pagamenti e metodi di pagamento Pagamenti e metodi di pagamento
I servizi MQL5.community offrono grandi opportunità per i trader e per gli sviluppatori di applicazioni per il terminale MetaTrader. In questo articolo spieghiamo come vengono eseguiti i pagamenti per i servizi MQL5, come è possibile prelevare il denaro guadagnato e come viene garantita la sicurezza dell'operazione.