English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
I metodi di William Gann (Parte I): Creazione dell'indicatore Angoli di Gann

I metodi di William Gann (Parte I): Creazione dell'indicatore Angoli di Gann

MetaTrader 5Trading |
208 18
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Introduzione

William Delbert Gann è un trader leggendario e analista tecnico i cui metodi innovativi di analisi del mercato suscitano tuttora l'interesse dei trader moderni. Uno degli strumenti chiave dell'arsenale di Gann erano i suoi famosi angoli, utilizzati per prevedere i movimenti dei prezzi e identificare potenziali livelli di supporto e resistenza.

In questo articolo ci immergeremo nel mondo dei metodi di trading di William Gann, partendo dalla creazione dell'indicatore Angoli di Gann in MQL5. Analizzeremo la teoria alla base di questo strumento e lo implementeremo passo-passo come indicatore personalizzato per la piattaforma MetaTrader 5.

Che siate trader esperti alla ricerca di nuovi strumenti di analisi o principianti che desiderano ampliare il proprio arsenale di indicatori tecnici, questo articolo vi aiuterà a comprendere meglio e ad applicare uno dei metodi più intriganti di William Gann nel vostro trading.


Storia della creazione degli angoli di Gann

William Delbert Gann (1878-1955) sviluppò il suo sistema di angoli all'inizio del XX secolo, basandosi su anni di ricerca sui movimenti di mercato e sulla sua straordinaria comprensione della relazione tra tempo e prezzo.

Gann credeva che i mercati si muovessero secondo schemi geometrici prevedibili e che questi movimenti potessero essere previsti utilizzando una combinazione di matematica, geometria e astrologia. Ha sviluppato il concetto di angoli, ovvero linee diagonali su un grafico che riflettono il perfetto equilibrio tra tempo e movimento dei prezzi.

La chiave della teoria di Gann era l'idea che un angolo di 45 gradi (noto come angolo 1x1) rappresentasse il perfetto equilibrio tra tempo e prezzo. Egli riteneva che quando il prezzo si muove verso l'alto o verso il basso con questo angolo, indica una tendenza equilibrata e stabile.

Gann sviluppò anche altri angoli come 2x1, 3x1, 4x1 e i loro reciproci che rappresentano diverse relazioni tra tempo e prezzo. Questi angoli sono diventati la base del suo sistema di trading e delle sue analisi di mercato.

Sebbene alcuni aspetti del lavoro di Gann rimangano controversi, i suoi metodi, compresi gli angoli di Gann, continuano ad attirare l'attenzione di trader e analisti di tutto il mondo e rimangono rilevanti nel trading moderno.


La teoria dell'angolo di Gann e la sua importanza nell'analisi tecnica

La teoria degli angoli di Gann si basa sul concetto che i movimenti di mercato seguono modelli geometrici prevedibili che possono essere identificati utilizzando angolazioni particolari tracciati su un grafico. La teoria si basa sull'idea di un equilibrio tra tempo e prezzo, dove un angolo 1x1 (45 gradi) rappresenta un equilibrio perfetto, ipotizzando una variazione di prezzo di un'unità per periodo di tempo.

Gann ha sviluppato un sistema di differenti angoli come 2x1, 3x1, 4x1 e i loro reciproci, ognuno dei quali riflette una relazione specifica tra tempo e movimento dei prezzi. Questi angoli fungono da livelli dinamici di supporto e resistenza, aiutando i trader a determinare la forza e la direzione di un trend. Gli angoli più accentuati indicano una tendenza più forte, mentre quelli più piatti indicano un movimento più debole.


Principi di base della costruzione degli angoli di Gann


La costruzione degli angoli di Gann si basa su diversi principi chiave che consentono ai trader di utilizzare efficacemente questo strumento nell'analisi tecnica. La scelta del punto di partenza (che di solito è un minimo o un massimo significativo sul grafico) è di primaria importanza. È da questo punto che inizia la costruzione degli angoli.

L'angolo base è considerato l'angolo 1x1 che forma una linea di 45 gradi sul grafico. Questo angolo riflette il perfetto equilibrio tra tempo e prezzo, dove il prezzo cambia di un'unità in un periodo di tempo. Altri angoli, come 2x1, 3x1, 4x1 e i loro reciproci, sono costruiti rispetto a questo angolo base.

Quando si traccia, è importante considerare la scala del grafico. I trader spesso utilizzano modelli o strumenti speciali per garantire angoli precisi. Le linee angolari proseguono nel futuro, consentendo di prevedere potenziali livelli di supporto e resistenza.


Tipi di angoli di Gann e la loro interpretazione

William Gann ha sviluppato un sistema di angoli, ognuno con un significato e un'interpretazione unico nell'analisi tecnica. 1x1, o 45 gradi, è considerato l'angolo principale, che riflette l'equilibrio tra tempo e prezzo. Questo angolo serve come linea guida di base per valutare la forza del trend.

L'angolo 2x1 (63,75 gradi) indica un movimento di prezzo più forte, in cui il prezzo sale a una velocità doppia rispetto al tempo. Questo viene spesso interpretato come un segnale di un forte trend rialzista. Al contrario, un angolo 1x2 (26,25 gradi) indica un aumento dei prezzi più lento rispetto al tempo, che può indicare un trend debole.

Gli angoli 3x1 (71,25 gradi) e 4x1 (75 gradi) rappresentano un'azione di prezzo ancora più aggressiva e sono solitamente associati a trend molto forti o a un potenziale sovraeccitamento del mercato. I loro reciproci - 1x3 (18,75 gradi) e 1x4 (15 gradi) - possono indicare una forte resistenza o supporto.

L'interpretazione degli angoli di Gann non si limita alla sola pendenza. È inoltre importante considerare come il prezzo interagisce con queste linee. Un prezzo che attraversa la linea angolare può segnalare un potenziale cambiamento del trend. Se il prezzo si muove lungo la linea angolare, viene spesso interpretato come una conferma della forza de trend attuale.


Applicazione pratica degli angoli di Gann nel trading

I trader utilizzano questi strumenti per una serie di scopi, dall'identificazione dei trend alla scelta dei punti di entrata e uscita delle posizioni.

Per determinare un trend, di solito si inizia tracciando un angolo 1x1 da un minimo o un massimo significativo. Se il prezzo si muove al di sopra di questa linea, viene interpretato come un trend al rialzo, mentre se si muove al di sotto, come un trend al ribasso. Gli angoli più ripidi, come 2x1 o 3x1, vengono utilizzati per confermare la forza del trend.

Nella scelta dei punti di ingresso, molti trader cercano i momenti in cui il prezzo rimbalza o sfonda la linea angolare di Gann. Ad esempio, un rimbalzo dalla linea 1x1 in direzione del trend può essere visto come una potenziale opportunità di entrare in posizione.

Per la gestione del rischio, gli angoli di Gann vengono spesso utilizzati per impostare gli stop loss. Il trader può posizionare uno stop loss appena al di sotto della linea angolare più vicina per una posizione long o appena al di sopra di essa per una posizione short.

Nel trading a lungo termine, gli angoli di Gann aiutano a determinare la direzione generale del mercato. Possiamo utilizzare angoli meno profondi, come 1x2 o 1x4, per valutare i trend a lungo termine e prendere decisioni strategiche.


Esempi di strategie di trading che utilizzano gli angoli di Gann

Gli angoli di Gann offrono ai trader un'ampia gamma di opzioni per creare diverse strategie di trading. Ecco alcuni esempi di come possono essere utilizzati efficacemente nel trading reale.

La strategia Angle Bounce si basa sul presupposto che le linee angolari di Gann agiscono spesso come livelli di supporto o resistenza. Il trader cerca le situazioni in cui il prezzo si avvicina a una linea angolare di Gann (in particolare 1x1 o 2x1) e rimbalza da essa. L'entrata in posizione avviene dopo la conferma di un rimbalzo, ad esempio la formazione di un pattern di inversione delle candele.

Un'altra strategia popolare è l'Angle Breakout. In questo caso il trader attende che il prezzo sfondi un'importante linea angolare di Gann, soprattutto se questo è accompagnato da un aumento del volume di trading. Un breakout al rialzo può segnalare una potenziale posizione lunga, mentre un breakout al ribasso può segnalare una posizione corta.

La strategia Gann Fan utilizza angoli multipli che si irradiano da un singolo punto per formare una struttura a ventaglio. Il trader analizza il modo in cui il prezzo interagisce con le varie linee del ventaglio, utilizzandole per determinare i livelli di supporto e resistenza e i potenziali punti di inversione.

La combinazione di angoli e cicli temporali è una strategia più complessa in cui il trader combina gli angoli di Gann con il concetto di cicli temporali, anch'esso sviluppato da Gann. Qui vengono analizzati i punti di intersezione di importanti linee temporali con gli angoli di Gann per determinare i momenti critici per entrare o uscire dal mercato.

La strategia multi-timeframe prevede l'analisi degli angoli di Gann su diversi timeframe. Ad esempio, un trader potrebbe utilizzare un angolo 1x1 su un grafico giornaliero per determinare la tendenza generale, e poi passare a un grafico orario per cercare punti di ingresso utilizzando angoli più ripidi.


Creazione dell'indicatore Angoli di Gann in MQL5: Passaggi di base


La creazione dell’indicatore Angoli di Gann in MQL5 comporta diversi passaggi chiave. Questo processo richiede la comprensione sia dei principi di costruzione degli angoli di Gann sia delle specificità della programmazione nell'ambiente MetaTrader 5.

Il primo passo consiste nel definire la struttura dell'indicatore. Qui si impostano i parametri di base, come il nome dell'indicatore, i parametri di input per l'impostazione degli angoli e le librerie necessarie.

La logica principale per la costruzione degli angoli di Gann si trova nella funzione OnCalculate(). Qui si definisce il punto di partenza per tracciare gli angoli, si calcolano le coordinate di ciascun angolo e si tracciano le linee sul grafico.

Un aspetto importante è il calcolo corretto delle coordinate degli angoli, tenendo conto della scala del grafico e dell'intervallo di tempo selezionato. Ciò richiede un approccio matematico preciso e la comprensione della geometria degli angoli di Gann.

La fase finale consiste nella verifica e nel debug dell'indicatore. È necessario verificare la validità della costruzione degli angoli su diversi timeframe e strumenti.


Struttura del codice dell'indicatore

Ecco il codice di base dell'indicatore Angoli di Gann che può essere utilizzato in MetaTrader 5:

#property copyright "Copyright 2024, Evgeniy Shtenco"
#property link      "https://www.mql5.com/en/users/koshtenko"
#property version   "1.00"
#property indicator_chart_window

// Input parameters
input datetime StartDate = D'2023.01.01 00:00'; // Start date for analysis
input datetime EndDate = D'2023.12.31 23:59';   // End date for analysis
input color GannFanColor = clrBlue;             // Color for Gann Fan lines

// Global variables
double extremumPrice;
datetime extremumTime;
double oppositeExtremumPrice;
datetime oppositeExtremumTime;
bool isTrendUp;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    ObjectsDeleteAll(0, "GannFan_");
    ObjectsDeleteAll(0, "OppositeGannFan_");
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    if(rates_total < 1) return(0);

    // Clear previous objects
    if (prev_calculated == 0)
    {
        ObjectsDeleteAll(0, "GannFan_");
        ObjectsDeleteAll(0, "OppositeGannFan_");
    }

    // Find extremums within the specified date range
    FindExtremums(rates_total, high, low, time);

    // Draw Gann Fans
    DrawGannFan(extremumPrice, extremumTime);
    DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);

    return(rates_total);
}

//+------------------------------------------------------------------+
//| Find both extremums within the specified date range              |
//+------------------------------------------------------------------+
void FindExtremums(const int rates_total, const double &high[], const double &low[], const datetime &time[])
{
    int startIndex = -1;
    int endIndex = -1;

    for (int i = 0; i < rates_total; i++)
    {
        if (time[i] >= StartDate && startIndex == -1)
        {
            startIndex = i;
        }
        if (time[i] <= EndDate)
        {
            endIndex = i;
        }
    }

    if (startIndex == -1 || endIndex == -1 || startIndex > endIndex)
    {
        Print("Error: Invalid date range or no data available in the specified range");
        return;
    }

    int highestIndex = ArrayMaximum(high, startIndex, endIndex - startIndex + 1);
    int lowestIndex = ArrayMinimum(low, startIndex, endIndex - startIndex + 1);

    // Determine the most recent extremum
    if (time[highestIndex] > time[lowestIndex])
    {
        extremumPrice = high[highestIndex];
        extremumTime = time[highestIndex];
        oppositeExtremumPrice = low[lowestIndex];
        oppositeExtremumTime = time[lowestIndex];
        isTrendUp = false;
    }
    else
    {
        extremumPrice = low[lowestIndex];
        extremumTime = time[lowestIndex];
        oppositeExtremumPrice = high[highestIndex];
        oppositeExtremumTime = time[highestIndex];
        isTrendUp = true;
    }
}

//+------------------------------------------------------------------+
//| Draw Gann Fan                                                    |
//+------------------------------------------------------------------+
void DrawGannFan(double extremum, datetime extremumTime)
{
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    datetime endTime = extremumTime + PeriodSeconds() * 300;

    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "GannFan_" + angleNames[i];
        double angle = angles[i];
        
        double priceShift = MathTan(angle * M_PI / 180.0) * 300 * _Point;
        double endPrice;
        
        if(isTrendUp)
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // Invert the angle for a downtrend
        }

        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice))
        {
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//| Draw Opposite Gann Fan                                           |
//+------------------------------------------------------------------+
void DrawOppositeGannFan(double extremum, datetime extremumTime)
{
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    datetime endTime = extremumTime + PeriodSeconds() * 300;

    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "OppositeGannFan_" + angleNames[i];
        double angle = angles[i];
        
        double priceShift = MathTan(angle * M_PI / 180.0) * 300 * _Point;
        double endPrice;
        
        if(!isTrendUp) // Opposite trend
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // Invert the angle for a downtrend
        }

        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice))
        {
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Opposite Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Opposite Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    // Redraw objects when chart changes
    if(id == CHARTEVENT_CHART_CHANGE)
    {
        // Find extremums and redraw Gann Fans
        int rates_total = Bars(_Symbol, PERIOD_CURRENT);
        double high[], low[];
        datetime time[];
        ArraySetAsSeries(high, true);
        ArraySetAsSeries(low, true);
        ArraySetAsSeries(time, true);
        CopyHigh(_Symbol, PERIOD_CURRENT, 0, rates_total, high);
        CopyLow(_Symbol, PERIOD_CURRENT, 0, rates_total, low);
        CopyTime(_Symbol, PERIOD_CURRENT, 0, rates_total, time);
        
        FindExtremums(rates_total, high, low, time);
        DrawGannFan(extremumPrice, extremumTime);
        DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);
    }
}


Funzioni principali e loro scopo

Il codice è un indicatore MetaTrader 5 che disegna gli angoli del Ventaglio di Gann sul grafico. Ecco una descrizione delle funzioni principali e del loro scopo:

  1. OnInit() è la funzione di inizializzazione dell'indicatore. In questo caso, restituisce semplicemente il risultato del successo dell’inizializzazione.
  2. OnDeinit() è una funzione di deinizializzazione che rimuove tutti gli oggetti creati dall'indicatore quando questo viene rimosso dal grafico.
  3. OnCalculate() è la funzione principale dell'indicatore. Viene richiamato ad ogni tick. Cancella gli oggetti precedenti, trova gli estremi in un determinato intervallo di date e disegna gli angoli di Gann.
  4. FindExtremums() è una funzione che consente di trovare gli estremi (massimo e minimo) di un prezzo in un determinato intervallo di date. Determina quale estremo è più recente e stabilisce la direzione del trend.
  5. DrawGannFan() è una funzione per disegnare il ventaglio principale di Gann a partire dall'estremo trovato. Crea linee per nove diverse angolazioni.
  6. DrawOppositeGannFan() è una funzione che consente di disegnare il ventaglio di Gann opposto a partire da un altro estremo. Crea anche le linee per i nove angoli, ma in direzione opposta.
  7. OnChartEvent() è una funzione che risponde agli eventi del grafico. In questo caso, ridisegna i ventagli di Gann quando il grafico cambia.

L'indicatore utilizza gli input per impostare l’analisi dell'intervallo di date (StartDate e EndDate) e il colore delle linee (GannFanColor). Trova i prezzi estremi in questo intervallo, determina la direzione del trend e disegna due ventagli di Gann - uno dall'ultimo estremo, l'altro da quello opposto. Ogni ventaglio è composto da nove linee corrispondenti a diversi angoli di Gann (82.5°, 75°, 71.25°, 63.75°, 45°, 26.25°, 18.75°, 15° e 7.5°).

Il codice include anche la gestione degli errori e l'aggiornamento dinamico quando il grafico cambia, rendendolo abbastanza robusto e adattabile alle diverse condizioni di mercato. L'uso delle funzioni MQL5, come ArrayMaximum() e ArrayMinimum(), garantisce una gestione efficiente dei dati.

Algoritmo di calcolo dell'angolo di Gann

L'algoritmo per il calcolo degli angoli di Gann in questo indicatore si basa sulla costruzione geometrica di linee a partire dal punto estremo. Ecco gli aspetti principali di questo algoritmo:

  • Determinazione degli estremi: L'indicatore individua il prezzo massimo e minimo in un determinato intervallo di tempo. L'ultimo di questi estremi viene utilizzato come punto di partenza per il ventaglio principale di Gann, mentre quello precedente per il ventaglio opposto.
  • Impostazione degli angoli: Viene utilizzato un set di angoli fissi: 82.5°, 75°, 71.25°, 63.75°, 45°, 26.25°, 18.75°, 15° e 7.5°. Questi angoli corrispondono ai tradizionali rapporti di Gann: 1x8, 1x4, 1x3, 1x2, 1x1, 2x1, 3x1, 4x1 e 8x1.
  • Calcolo del punto finale: Per ogni angolo, viene calcolato il punto finale della linea. Il calcolo si basa sull'equazione:
endPrice = extremum + MathTan(angle * M_PI / 180.0) * 300 * Point
  • Qui 300 è il numero convenzionale di barre avanti utilizzato per costruire la linea.
  • Inversione per un trend ribassista: Se il trend è al ribasso, l'angolo viene invertito (cambia segno) in modo che le linee puntino verso il basso dal punto estremo.
  • Costruzione della linea: Per ogni angolo, viene creato un oggetto linea (OBJ_TREND) dal punto estremo al punto finale calcolato. Le linee sono estese a destra per coprire i dati futuri.
  • Doppio ventaglio: l'algoritmo viene applicato due volte - una volta per il ventaglio principale dell'ultimo estremo, la seconda volta per il ventaglio opposto dall'estremo iniziale. Questo ci permette di visualizzare i potenziali livelli di supporto e resistenza su entrambi i lati.
  • Aggiornamento dinamico: Quando il grafico cambia (ad esempio, quando arrivano nuovi dati), l'algoritmo ricalcola gli estremi e ricostruisce i ventagli, assicurando che l'analisi sia aggiornata.

L'algoritmo ci permette di visualizzare i classici angoli di Gann su un grafico, fornendo al trader uno strumento per analizzare i potenziali livelli di supporto e resistenza e la direzione del trend. 


È possibile fare trading con profitto?

È possibile fare trading con profitto utilizzando gli angoli di Gann? Questa domanda non ha una risposta chiara, ma con il giusto approccio fare trading in modo profittevole è al quanto possibile. La chiave del successo sta nell'uso completo di questo strumento.

Tuttavia, anche con l'analisi più attenta e meticolosa, non bisogna dimenticare la gestione del rischio. Questa è la chiave di volta di un trading profittevole. Nessun metodo garantisce il 100% di successo, quindi un'adeguata gestione del capitale e del rischio gioca un ruolo fondamentale nella redditività a lungo termine.


Prospettive di creazione di un EA basato sugli angoli di Gann


La creazione di un EA basato sugli angoli di Gann è un compito interessante e promettente per gli sviluppatori di sistemi di trading algoritmici. Un tale EA potrebbe automatizzare l'analisi e il trading utilizzando i principi stabiliti dalla teoria di Gann.

La base di tale EA può essere l'indicatore Angoli di Gann già implementato. L'algoritmo dell'EA potrebbe includere l'analisi dell'interazione del prezzo con le linee di Gann, determinando i punti di entrata e di uscita in base all'intersezione di queste linee, oltre a prendere in considerazione fattori aggiuntivi come il volume di trading e la volatilità del mercato.

Uno dei vantaggi principali di un sistema automatizzato basato sugli angoli di Gann sarebbe quello di eliminare il fattore emotivo dal processo decisionale di trading. L'EA potrebbe seguire rigorosamente la strategia data, senza cedere alla paura o all'avidità, che spesso influenzano le decisioni di un trader umano.

Tuttavia, lo sviluppo di un'EA di questo tipo deve affrontare una serie di sfide. Innanzitutto, è necessaria un'interpretazione accurata dei segnali generati dagli angoli di Gann. La teoria di Gann è in gran parte soggettiva e richiede una profonda comprensione del mercato, difficile da implementare completamente sotto forma di algoritmo.

Naturalmente, il successo di un EA di questo tipo dipenderà in larga misura dalla profondità della comprensione della teoria di Gann da parte dello sviluppatore, nonché dalla sua capacità di combinare efficacemente questa teoria con i moderni metodi di analisi del mercato e di gestione del rischio.


La sfida più grande: Ridimensionare gli angoli

Uno dei problemi più seri nella creazione e nell'utilizzo di indicatori ed EA basati sugli angoli di Gann è la difficoltà di ridimensionarli. Questo problema incide significativamente sull'accuratezza e sull'efficienza dei sistemi di trading basati sul metodo Gann.

L'essenza del problema è che gli angoli di Gann, essendo costruzioni geometriche, dipendono fortemente dalla scala del grafico. Quando si modifica la scala dell'asse temporale o dei prezzi, la rappresentazione visiva degli angoli può risultare notevolmente distorta. Quello che sembra un angolo perfetto 1x1 (45 gradi) in una scala può trasformarsi in un angolo completamente diverso quando si cambia scala.

Questo crea serie difficoltà per l'implementazione del software. L'indicatore o l'EA deve tenere costantemente conto della scala attuale del grafico e regolare di conseguenza i calcoli dell'angolo. Inoltre, il concetto stesso di "unità di tempo uguale unità di prezzo" su cui si basano gli angoli di Gann diventa ambiguo quando si lavora con strumenti finanziari e time frame diversi.

I tentativi di risolvere questo problema portano spesso a compromessi. Alcuni sviluppatori fissano la scala, il che limita l'applicabilità dello strumento. Altri introducono algoritmi complessi per il ricalcolo degli angoli, che possono ridurre la velocità dell'indicatore o dell'EA.

Inoltre, il problema del ridimensionamento rende difficile confrontare i risultati delle analisi tra strumenti o timeframe diversi. Un angolo che funziona efficacemente su un grafico giornaliero di una coppia di valute può produrre risultati completamente diversi su un grafico orario o per un altro strumento di trading.

Questo problema mette in discussione l'applicabilità universale degli angoli di Gann nel trading automatico. Richiede agli sviluppatori una profonda conoscenza non solo della teoria di Gann, ma anche delle specificità del lavoro con i grafici nelle piattaforme di trading.


Conclusioni

Gli angoli di Gann sono uno strumento di analisi tecnica unico che continua ad attirare l'attenzione dei trader e degli sviluppatori di sistemi di trading. La nostra analisi ha dimostrato che la creazione di un indicatore di angoli Gann in MQL5 è abbastanza fattibile e il codice fornito è un buon punto di partenza per ulteriori sviluppi.

Tuttavia, l'utilizzo degli angoli di Gann nel trading automatico comporta una serie di sfide significative. Il principale è il problema del ridimensionamento, che rende molto più difficile creare un EA di trading universale e affidabile basato su questo metodo.

Nonostante queste difficoltà, il potenziale degli angoli di Gann come strumento di analisi del mercato rimane elevato. Quando utilizzati correttamente, in combinazione con altri metodi di analisi tecnica e con una corretta gestione del rischio, possono essere un'aggiunta efficace al kit di strumenti di un trader.

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

File allegati |
Ultimi commenti | Vai alla discussione (18)
Bogard_11
Bogard_11 | 15 ago 2024 a 18:56
Eva-oren #:
Gunn era un brillante commerciante, astrologo e numerologo, un matematico che credeva nei numeri magici. Un grande indovino che ha previsto l'inizio e la fine della Prima e della Seconda Guerra Mondiale. Aveva un numero enorme di studenti, ma, come sostengono i suoi seguaci, non dava la sua strategia a nessuno. Aveva un enorme giro di denaro, e alla fine della sua vita arrivò con la modesta somma di 100.000 dollari. Attendo con ansia i prossimi articoli sulla personalità geniale di Gunn, molto interessanti.

Ho dimenticato di dire che aveva un jet privato, una rarità a quei tempi. Più 100.000 dollari di allora, sono almeno un millesimo di verde oggi, se non 10 millesimi.

P.S. - ha trasmesso la strategia. Nei suoi scritti. Chi ha voluto, ha raccolto da diversi capitoli del TC completo. Gunn sparse il tutto in modo che nessuno potesse ottenerlo gratuitamente.

Ivan Butko
Ivan Butko | 21 ago 2024 a 17:11
Trovato un modo per commerciare su google

Maxim Kuznetsov
Maxim Kuznetsov | 22 ago 2024 a 03:16
Ivan Butko #:
Ho trovato un modo per fare trading su Google

nella seconda immagine - non capisco il principio :-(

Bogard_11
Bogard_11 | 22 ago 2024 a 06:58

Vi darò un'immagine. Chi capisce Gunn, comprenderà immediatamente il principio del lavoro con gli angoli, dove cercare un'entrata lunga e dove fare un roll over.


Avatar2025
Avatar2025 | 25 giu 2025 a 09:50
Disclaimer: non conosco la sintassi di programmazione MQL5 per gli indicatori.

Ma credo che l'algoritmo della linea d'angolo non sia corretto (vedere l'indicatore della linea d'angolo allegato che ho scritto in un altro software), ecco il mio dialogo con DeepSeek:

下面代码是通达信的代码,里面计算斜率的方法才是正确的,请阅读理解后,把上面priceShift 的计算方法改为下列代码正确的范式:

涨周期数:= IF(低点k位置 > 高点k位置, 低点k位置 - 高点k位置 + 1, 低点k位置), NODRAW;
跌周期数:= IF(高点k位置 > 低点k位置, 高点k位置 - 低点k位置 + 1, 高点k位置), NODRAW;

天线:= CONST(IF(高点k位置 = 1, H, REF(H, 高点k位置 - 1))), NODRAW;
地线:= CONST(IF(低点k位置 = 1, L, REF(L, 低点k位置 - 1))), NODRAW;

上涨天数:= IF(ISVALID(地线), BARSLAST(L = 地线), DRAWNULL), NODRAW;
下跌天数:= IF(ISVALID(天线), BARSLAST(H = 天线), DRAWNULL), NODRAW;

上涨高度:= IF(低点k位置 > 高点k位置, 天线 - 地线, HHV(H, 上涨天数) - 地线), NODRAW;
下跌高度:= IF(高点k位置 > 低点k位置, 天线 - 地线, 天线 - LLV(L, 下跌天数)), NODRAW;

上涨斜率:= IF(上涨天数 > 0, ROUND2(上涨高度 / 涨周期数, 4), 0), NODRAW;
下跌斜率:= IF(下跌天数 > 0, ROUND2(下跌高度 / 跌周期数, 4), 0), NODRAW;

Tuttavia, DeepSeek mi ha dato un codice di modifica che non sembra funzionare per me:
//+------------------------------------------------------------------+
//Tracciare la linea del ventaglio di Venn & nbsp; |
//+------------------------------------------------------------------+
void DrawGannFan(double extremum, datetime extremumTime)
{
    // Definire l'angolo di Gann e il nome corrispondente.
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // Ottenere il numero di periodi dal punto estremo alla linea K corrente
    int extremumBar = iBarShift(_Symbol, PERIOD_CURRENT, extremumTime);
    int currentBar = 0; // La linea K corrente è 0
    int barDiff = currentBar - extremumBar; // Differenza del numero di ciclo
    
    // Calcolo della differenza di altezza del prezzo
    double priceDiff;
    if(isTrendUp)
    {
        // Uptrend: calcola l'altezza dal minimo estremo al prezzo massimo attuale
        double currentHigh = iHigh(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = currentHigh - extremum;
    }
    else
    {
        // Downtrend: calcola l'altezza dal massimo estremo al prezzo minimo attuale
        double currentLow = iLow(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = extremum - currentLow;
    }
    
    // Calcolo della pendenza di base (pendenza della linea 1x1)
    double baseSlope = (barDiff > 0) ? priceDiff / barDiff : 0;
    
    // Disegnare linee di settore per ogni angolo
    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "GannFan_" + angleNames[i];  // Etichette degli oggetti
        double angle = angles[i];                  // Angolo corrente
        
        // Calcolare il moltiplicatore della pendenza in base all'angolo
        double slopeMultiplier = MathTan(angle * M_PI / 180.0) / MathTan(45 * M_PI / 180.0);
        
        // Calcolo dell'offset del prezzo (in base alla pendenza sottostante e al moltiplicatore dell'angolo)
        double priceShift = baseSlope * barDiff * slopeMultiplier * _Point;
        double endPrice;
        
        // Calcolo del prezzo di chiusura in base alla direzione del trend
        if(isTrendUp)
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // Angolo di inversione nel downtrend
        }

        // Creare un oggetto linea di tendenza
        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, TimeCurrent(), endPrice))
        {
            // Impostare le proprietà della linea di tendenza
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//|| Tracciare una linea del ventaglio di Gann inverso & nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
void DrawOppositeGannFan(double extremum, datetime extremumTime)
{
    // Definire l'angolo di Gann e il nome corrispondente.
    double angles[] = {82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = {"1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // Ottenere il numero di periodi dal punto estremo alla linea K corrente
    int extremumBar = iBarShift(_Symbol, PERIOD_CURRENT, extremumTime);
    int currentBar = 0; // La linea K corrente è 0
    int barDiff = currentBar - extremumBar; // Differenza del numero di ciclo
    
    // Calcolo della differenza di altezza del prezzo
    double priceDiff;
    if(!isTrendUp)
    {
        // Inversione di tendenza (up): calcola l'altezza dal minimo estremo al prezzo massimo attuale
        double currentHigh = iHigh(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = currentHigh - extremum;
    }
    else
    {
        // Tendenza inversa (al ribasso): calcola l'altezza dal massimo estremo al prezzo minimo attuale
        double currentLow = iLow(_Symbol, PERIOD_CURRENT, 0);
        priceDiff = extremum - currentLow;
    }
    
    // Calcolo della pendenza di base (pendenza della linea 1x1)
    double baseSlope = (barDiff > 0) ? priceDiff / barDiff : 0;
    
    // Disegnare linee di settore per ogni angolo
    for(int i = 0; i < ArraySize(angles); i++)
    {
        string label = "OppositeGannFan_" + angleNames[i];  // Etichette degli oggetti
        double angle = angles[i];                          // Angolo corrente
        
        // Calcolare il moltiplicatore della pendenza in base all'angolo
        double slopeMultiplier = MathTan(angle * M_PI / 180.0) / MathTan(45 * M_PI / 180.0);
        
        // Calcolo dell'offset del prezzo (in base alla pendenza sottostante e al moltiplicatore dell'angolo)
        double priceShift = baseSlope * barDiff * slopeMultiplier * _Point;
        double endPrice;
        
        // Calcolo del prezzo di chiusura in base alla direzione del trend inverso
        if(!isTrendUp)
        {
            endPrice = extremum + priceShift;
        }
        else
        {
            endPrice = extremum - priceShift;
            angle = -angle; // Angolo di inversione nel downtrend
        }

        // Creare un oggetto linea di tendenza
        if(ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, TimeCurrent(), endPrice))
        {
            // Impostare le proprietà della linea di tendenza
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Opposite Gann Fan " + angleNames[i]);
        }
        else
        {
            Print("Failed to create Opposite Gann Fan line: ", GetLastError());
        }
    }
}





Alla fine, ho dovuto chiedere a DeepSeek di modificare il suo codice sorgente (che funziona bene e disegna le linee automaticamente):
#property copyright "Copyright 2024, Evgeniy Shtenco"  // Informazioni sul copyright
#property link      "https://www.mql5.com/en/users/koshtenko"  // Link d'autore
#property version   "1.00"  // Numero di versione dell'indicatore
#property indicator_chart_window  // Gli indicatori sono visualizzati nella finestra del grafico

// Parametri di ingresso
input int LookBackBars = 300;      // Numero di K-linee analizzate di nuovo
input color GannFanColor = clrBlue; // I colori della linea dei fan di Vaughan

// Variabili globali
double extremumPrice;        // Prezzo estremo
datetime extremumTime;       // Punto estremo tempo
double oppositeExtremumPrice; // Prezzo estremo inverso
datetime oppositeExtremumTime; // Tempo di inversione del punto di polarità
bool isTrendUp;              // Flag di direzione del trend (vero per il trend rialzista)

//+------------------------------------------------------------------+
//| Funzioni di inizializzazione degli indicatori personalizzati & nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
int OnInit()
{
    return (INIT_SUCCEEDED);  // Inizializzazione riuscita
}

//+------------------------------------------------------------------+
//| Funzioni personalizzate di deinizializzazione degli indicatori & nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
    {
        // Cancellare tutti gli oggetti del settore Gann
        ObjectsDeleteAll(0, "GannFan_");
ObjectsDeleteAll(0, "OppositeGannFan_");
}

//+------------------------------------------------------------------+
//| Funzioni di calcolo degli indicatori personalizzati & nbsp; &nbsp ; | | | | | | | |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,          // Numero attuale di cicli
const int prev_calculated,      // Numero di cicli calcolati in precedenza
const datetime & time[],         // Array di tempo
                const double & open[],          // Array di prezzi di apertura
                const double & high[],           // Array dei prezzi più alti
                const double & low[],            // Array di prezzi più bassi
                const double & close[],         // Array del prezzo di chiusura
                const long & tick_volume[],      // Array di volumi
                const long & volume[],           // Array di volumi reali
                const int & spread[])            // Array di punti di diffusione
{
    if (rates_total < LookBackBars) return (0);  // Ritorno se non ci sono abbastanza dati

    // Cancella gli oggetti disegnati in precedenza
    if (prev_calculated == 0) {
        ObjectsDeleteAll(0, "GannFan_");
        ObjectsDeleteAll(0, "OppositeGannFan_");
    }

    // Trovare i punti estremi nelle ultime 300 righe K
    FindExtremums(rates_total, high, low, time);

    // Disegnare la linea del ventaglio di Venn
    DrawGannFan(extremumPrice, extremumTime);
    DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);

    return (rates_total);  // Restituisce il numero totale di colonne elaborate
}

//+------------------------------------------------------------------+
//| Trova i punti estremi all'interno di un numero specifico di linee K. |
//+------------------------------------------------------------------+
void FindExtremums(const int rates_total, const double & high[], const double & low[], const datetime & time[])
{
    int startIndex = rates_total - LookBackBars;  // Iniziare l'indicizzazione (300 K righe fa)
    int endIndex = rates_total - 1;               // Indice finale (ultima riga K)

    // Trovare alti e bassi
    int highestIndex = ArrayMaximum(high, startIndex, LookBackBars);
    int lowestIndex = ArrayMinimum(low, startIndex, LookBackBars);

    // Determinare la direzione del trend (confrontare la tempistica dei massimi e dei minimi)
    if (time[highestIndex] > time[lowestIndex]) {
        // Tendenza al ribasso se il punto più alto è successivo al punto più basso
        extremumPrice = high[highestIndex];
        extremumTime = time[highestIndex];
        oppositeExtremumPrice = low[lowestIndex];
        oppositeExtremumTime = time[lowestIndex];
        isTrendUp = false;
    }
    else {
        // altrimenti tendenza al rialzo
        extremumPrice = low[lowestIndex];
        extremumTime = time[lowestIndex];
        oppositeExtremumPrice = high[highestIndex];
        oppositeExtremumTime = time[highestIndex];
        isTrendUp = true;
    }
}

//+------------------------------------------------------------------+
//Tracciare la linea del ventaglio di Venn & nbsp; |
//+------------------------------------------------------------------+
void DrawGannFan(double extremum, datetime extremumTime)
{
    // Definire l'angolo di Gann e il nome corrispondente.
    double angles[] = { 82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = { "1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // Calcolare il tempo di fine della linea di settore (tempo corrente + 300 cicli)
    datetime endTime = TimeCurrent();  // Utilizzare l'ora corrente come ora di fine

    // Disegnare linee di settore per ogni angolo
    for (int i = 0; i < ArraySize(angles); i++)
    {
        string label = "GannFan_" + angleNames[i];  // Etichette degli oggetti
        double angle = angles[i];                  // Angolo corrente

        // Calcolo dello scostamento dei prezzi (in base alla differenza di orario)
        double secondsDiff = endTime - extremumTime;
        double priceShift = MathTan(angle * M_PI / 180.0) * secondsDiff / PeriodSeconds();
        double endPrice;

        // Calcolo del prezzo di chiusura in base alla direzione del trend
        if (isTrendUp) {
            endPrice = extremum + priceShift;
        }
        else {
            endPrice = extremum - priceShift;
            angle = -angle; // Angolo di inversione nel downtrend
        }

        // Creare un oggetto linea di tendenza
        if (ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice)) {
            // Impostare le proprietà della linea di tendenza
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Gann Fan " + angleNames[i]);
        }
        else {
            Print("Failed to create Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//|| Tracciare una linea del ventaglio di Gann inverso & nbsp; &nbsp ; ||
//+------------------------------------------------------------------+
void DrawOppositeGannFan(double extremum, datetime extremumTime)
{
    // Definire l'angolo di Gann e il nome corrispondente.
    double angles[] = { 82.5, 75, 71.25, 63.75, 45, 26.25, 18.75, 15, 7.5};
    string angleNames[] = { "1x8", "1x4", "1x3", "1x2", "1x1", "2x1", "3x1", "4x1", "8x1"};

    // Calcolare l'ora di fine della linea di settore (ora corrente)
    datetime endTime = TimeCurrent();

    // Disegnare linee di settore per ogni angolo
    for (int i = 0; i < ArraySize(angles); i++)
    {
        string label = "OppositeGannFan_" + angleNames[i];  // Etichette degli oggetti
        double angle = angles[i];                          // Angolo corrente

        // Calcolo dello scostamento dei prezzi (in base alla differenza di orario)
        double secondsDiff = endTime - extremumTime;
        double priceShift = MathTan(angle * M_PI / 180.0) * secondsDiff / PeriodSeconds();
        double endPrice;

        // Calcolo del prezzo finale in base alla direzione del trend opposto
        if (!isTrendUp) // Invertire la tendenza
        {
            endPrice = extremum + priceShift;
        }
        else {
            endPrice = extremum - priceShift;
            angle = -angle; // Angolo di inversione nel downtrend
        }

        // Creare un oggetto linea di tendenza
        if (ObjectCreate(0, label, OBJ_TREND, 0, extremumTime, extremum, endTime, endPrice)) {
            // Impostare le proprietà della linea di tendenza
            ObjectSetInteger(0, label, OBJPROP_COLOR, GannFanColor);
            ObjectSetInteger(0, label, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSetInteger(0, label, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, label, OBJPROP_RAY_RIGHT, true);
            ObjectSetString(0, label, OBJPROP_TOOLTIP, "Opposite Gann Fan " + angleNames[i]);
        }
        else {
            Print("Failed to create Opposite Gann Fan line: ", GetLastError());
        }
    }
}

//+------------------------------------------------------------------+
//| Funzioni di gestione degli eventi del grafico &nbsp nbsp; & & nbsp; |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,                  // ID evento
const long & lparam,            // Parametri interi lunghi
                  const double & dparam,          // Parametri a doppia precisione
                  const string & sparam)         // Parametri stringa
{
    // Ridisegna gli oggetti quando il grafico cambia
    if (id == CHARTEVENT_CHART_CHANGE || id == CHARTEVENT_CLICK) {
        // Rilevare nuovamente gli estremi e tracciare la linea di Venn a ventaglio.
        int rates_total = Bars(_Symbol, PERIOD_CURRENT);
        double high[], low[];
        datetime time[];
        ArraySetAsSeries(high, true);
        ArraySetAsSeries(low, true);
        ArraySetAsSeries(time, true);
        CopyHigh(_Symbol, PERIOD_CURRENT, 0, rates_total, high);
        CopyLow(_Symbol, PERIOD_CURRENT, 0, rates_total, low);
        CopyTime(_Symbol, PERIOD_CURRENT, 0, rates_total, time);

        FindExtremums(rates_total, high, low, time);
        DrawGannFan(extremumPrice, extremumTime);
        DrawOppositeGannFan(oppositeExtremumPrice, oppositeExtremumTime);
    }
}
I metodi di William Gann (parte II): Creazione dell'indicatore Quadrato di Gann I metodi di William Gann (parte II): Creazione dell'indicatore Quadrato di Gann
Creeremo un indicatore basato sul Quadrato del 9 di Gann, costruito squadrando tempo e prezzo. Prepareremo il codice e testeremo l'indicatore nella piattaforma su differenti intervalli di tempo.
Classi di Tabelle e Intestazioni basate su un modello di tabella in MQL5: Applicazione del concetto MVC Classi di Tabelle e Intestazioni basate su un modello di tabella in MQL5: Applicazione del concetto MVC
Questa è la seconda parte dell'articolo dedicato all'implementazione del modello di tabella in MQL5 utilizzando il paradigma architettonico MVC (Model-View-Controller). L'articolo discute lo sviluppo di classi di tabella e della sua intestazione basate su un modello di tabella creato in precedenza. Le classi sviluppate costituiranno la base per l'ulteriore implementazione dei componenti View e Controller, che saranno discussi nei seguenti articoli.
I metodi di William Gann (Parte III): L'astrologia funziona? I metodi di William Gann (Parte III): L'astrologia funziona?
Le posizioni di pianeti e stelle influenzano i mercati finanziari? Armiamoci di statistiche e big data e intraprendiamo un viaggio emozionante nel mondo in cui stelle e grafici azionari si intersecano.
Implementazione di un modello di tabella in MQL5: Applicazione del concetto MVC Implementazione di un modello di tabella in MQL5: Applicazione del concetto MVC
In questo articolo, esaminiamo il processo di sviluppo di un modello di tabella in MQL5 utilizzando il modello architettonico MVC (Model-View-Controller) per separare la logica dei dati, la presentazione e il controllo, consentendo un codice strutturato, flessibile e scalabile. Consideriamo l'implementazione di classi per la costruzione di un modello di tabella, compreso l'uso di liste collegate per la memorizzazione dei dati.