Chi vuole una strategia? Molto e gratis) - pagina 58

 
1. Posso riscrivere gli indicatori per sostituire float con double.
2. protected static float fMicron = 0.000075f; // Coef usato quando confrontiamo due float
3. Costruttore di base dell'indicatore:

/// <summary>
/// The default constructor
/// </summary>
public Indicator()
{
    sIndicatorName  = string. Empty;
    bSeparatedChart = false;
    bIsDescreteValues = false;
    afSpecValue     = new float[] { };
    fMinValue       = float. MaxValue;
    fMaxValue       = float. MinValue;
    bIsCalculated   = false;
    parameters      = new IndicatorParam();
    component       = new IndicatorComp[] { };
}




4. Prezzo base:



/// <summary>
/// Calculates the base price.
/// </summary>
/// <param name="price">The base price type.</param>
/// <returns>Base price.</returns>
protected static float[] Price( BasePrice price)
{
    float[] afPrice = new float[Bars];

    switch( price)
    {
        case BasePrice.Open:
            afPrice = Open;
            break;
        case BasePrice.High:
            afPrice = High;
            break;
        case BasePrice.Low:
            afPrice = Low;
            break;
        case BasePrice.Close:
            afPrice = Close;
            break;
        case BasePrice. Median:
            for (int iBar = 0; iBar < Bars; iBar++)
                afPrice[ iBar] = (Low[ iBar] + High[ iBar]) / 2;
            break;
        case BasePrice. Typical:
            for (int iBar = 0; iBar < Bars; iBar++)
                afPrice[ iBar] = (Low[ iBar] + High[ iBar] + Close[ iBar]) / 3;
            break;
        case BasePrice. Weighted:
            for (int iBar = 0; iBar < Bars; iBar++)
                afPrice[ iBar] = (Low[ iBar] + High[ iBar] + 2 * Close[ iBar]) / 4;
            break;
        default:
            break;
    }
    return afPrice;
}

6. Ho fatto funzionare il ponte NET <-> MT. Il suo tempo di fare trading FSB attraverso MT. Naturalmente sarà solo per i conti demo fino a quando non sarà diventato "solido come una roccia".

 

Come penso che l'indicatore Aroon usi solo: bIsDescreteValues = true;


A proposito di RSI, ricordo che mi chiedevo quale fosse la formula. È stato 5-6 anni fa. Credo di aver usato questa formula da un popolare libro di TA. Non ricordo esattamente quale.

 

"Usa il valore della barra precedente"

Personalmente penso che questa sia una delle caratteristiche più importanti di FSB.


        /// <summary>
        /// Sets the "Use previous bar value" checkbox
        /// </summary>
        /// <returns>Is any Changes</returns>
        public bool SetUsePrevBarValueCheckBox(int iSlot)
        {
            bool isChanged = false;

            for (int iParam = 0; iParam < Slot[ iSlot]. IndParam. CheckParam. Length; iParam++)
            {
                if ( Slot[ iSlot]. IndParam. CheckParam[ iParam]. Caption == "Use previous bar value")
                {
                    bool bOrigChecked = Slot[ iSlot]. IndParam. CheckParam[ iParam]. Checked;
                    bool bChecked = true;

                    // Entry slot
                    if ( Slot[ iSlot]. SlotType == SlotTypes.Open)
                    {
                        bChecked = true;
                    }

                    // Open filter slot
                    else if ( Slot[ iSlot]. SlotType == SlotTypes. OpenFilter)
                    {
                        bChecked = EntryExecutionTime != TimeExecution. Closing;
                    }

                    // Close slot
                    else if ( Slot[ iSlot]. SlotType == SlotTypes.Close)
                    {
                        bChecked = true;
                    }

                    // Close filter slot
                    else if ( Slot[ iSlot]. SlotType == SlotTypes. CloseFilter)
                    {
                        bChecked = false;
                    }

                    if ( bChecked)
                    {
                        for (int iPar = 0; iPar < Slot[ iSlot]. IndParam. ListParam. Length; iPar++)
                        {
                            if ( Slot[ iSlot]. IndParam. ListParam[ iPar]. Caption == "Base price" &&
                                Slot[ iSlot]. IndParam. ListParam[ iPar]. Text    == "Open")
                            {
                                bChecked = false;
                            }
                        }
                    }

                    if ( bChecked != bOrigChecked)
                    {
                        isChanged = true;
                        Slot[ iSlot]. IndParam. CheckParam[ iParam]. Checked = bChecked;
                    }
                }
            }

            return isChanged;
        }
 

Per vedere i valori dell'indicatore nella loro piena precisione premete F12 nella finestra del grafico.


Un'altra opzione è quella di utilizzare la "Console di comando". ind xxxx mostra gli indicatori per la barra xxxx




Non scavo a fondo nelle formule di MT. Probabilmente non sono troppo diversi. Qui ci sono l'RSI FSB e l'RSI MT di default.







___________________--

Modifica:

Ho provato a calcolare l'RSI senza questo smussamento aggiuntivo:

            for (int iBar = 1; iBar < Bars; iBar++)
            {
                if ( afBasePrice[ iBar] > afBasePrice[ iBar - 1]) afPos[ iBar] = afBasePrice[ iBar] - afBasePrice[ iBar - 1];
                if ( afBasePrice[ iBar] < afBasePrice[ iBar - 1]) afNeg[ iBar] = afBasePrice[ iBar - 1] - afBasePrice[ iBar];
            }

            float[] afPosMA = MovingAverage( iPeriod, 0, maMethod, afPos);
            float[] afNegMA = MovingAverage( iPeriod, 0, maMethod, afNeg);

            //for (int iBar = iFirstBar; iBar < Bars; iBar++)
            //{
            //    afPosMA[iBar] = (afPosMA[iBar - 1] * (iPeriod - 1) + afPos[iBar]) / iPeriod;
            //    afNegMA[iBar] = (afNegMA[iBar - 1] * (iPeriod - 1) + afNeg[iBar]) / iPeriod;
            //}

            for (int iBar = iFirstBar; iBar < Bars; iBar++)
            {
                if ( afNegMA[ iBar] == 0)
                    afRSI[ iBar] = 100;
                else
                    afRSI[ iBar] = 100 - (100 / (1 + afPosMA[ iBar] / afNegMA[ iBar]));
            }


Ma in questo caso il valore RSI per 2009.3.24 salta a 74.800.



----------------------


Grazie Stellarator per le buone parole!

Non abbandonerò Forex Strategy Builder, e solo a causa di persone come te. Anche al contrario sono aperto alla discussione per rendere FSb più robusto e facile da usare.

In questa direzione penso di poter aggiungere indicatori MT in FSB. Qualcosa come la modalità di compatibilità MT:)

MT_MACD, MT_RSI, ... Questi devono essere con gli stessi parametri di quelli standard di MT.


Dobbiamo trovare una soluzione ai punti di entrata/uscita di apertura e di chiusura delle barre. Sono vitali per l'integrazione FSB -> MT.


 
Stellarator >> :

.........Combinarli (due buffer) in uno solo (stavo pensando... Ci possono essere non solo 1/0 (che potrebbe essere trasformato in una bitmask), ma anche etichette di prezzo). Molto probabilmente dovrò fare qualcosa con i valori degli indicatori stessi... Vedremo... Come vado...

Perché non può funzionare?

Per molto tempo ho usato una singola chiamata icustom per ottenere diversi valori da diversi buffer di indicatori, è troppo dispendioso usare questa funzione diverse volte nel codice, specialmente durante l'ottimizzazione, e anche con indicatori "pesanti". Infatti, tutto ciò di cui abbiamo bisogno (al massimo) è di ottenere la direzione del trade e il livello di SL & TP..... il problema è risolto da una semplice aritmetica.

Ecco un frammento di codice dell'indicatore con un solo buffer aggiuntivo (Signal):

// в самом кончике start такой фрагмент

      
   if ( Direction[0] !=0)
      {
      if ( Direction[0] > 0) Signal[0]= Set_TP[0]/Point*1000000 + Set_SL[0]/Point;
      if ( Direction[0] < 0) Signal[0]=-( Set_TP[0]/Point*1000000 + Set_SL[0]/Point);
      }
   return(0);

Ed ecco la conversione inversa nel codice di Expert Advisor:

int start()
  {
   // Получение значений из буфера индикатора в последней фазе формирования бара
   if (TimeCurrent() > (Time[0]+ CP60)
      {
      Signal=iCustom(NULL, 0, "_iK_tay_v01M1", Discret,6,0)
      }     

   if(Time[0] != prevtime)
      { 
      Calcul();
      //if (Tral !=0) CalcLevel();
      prevtime = Time[0];
      }
   else return;

.........

void Calcul()
  {
   OpenSell=0; OpenBuy=0; CloseBuy=0; CloseSell=0;
   
   if( Signal > 0) 
      {
      OpenBuy=1; CloseSell=1;
      TP=NormalizeDouble ( Signal*Point/1000000, Digits-1);      
      SL=( Signal- TP/Point*1000000)*Point;   
      }
   if( Signal < 0) 
      {
      CloseBuy=1; OpenSell=1;
      TP=NormalizeDouble (MathAbs( Signal)*Point/1000000, Digits-1);      
      SL=(MathAbs( Signal)- TP/Point*1000000)*Point;   
      }   
   return;
  }

Così, otteniamo 3 valori dell'indicatore (direzione, TP e SL) con una sola chiamata dell'indicatore. I risultati ottenuti possono essere ulteriormente manipolati come si vuole :)

Spero che tu capisca il principio.

 

Buongiorno a tutti!


Miroslav_Popov писал(а) >>

1. Posso riscrivere gli indicatori per sostituire float con double.

Miroslav - è importante! Ho già dato alcune delle ragioni nei miei post. Ma sono anche ben consapevole del lavoro che comporta... E che ora (molto probabilmente) stai lavorando al ponte che stai cercando o a qualcosa di sostanziale.


Ma bisogna trovare il tempo. La mia previsione è non più di un certo numero di ore (entro un giorno). Perché non si tratta solo di sostituire l'uno con l'altro quando si dichiarano le variabili (il che comporterà anche almeno un controllo visivo e una correzione visiva "per bellezza" (dove le variabili sono descritte con tabulazioni, per esempio, ecc.) :) - anche se non è una questione di principio).

Prima di tutto, ci possono essere casi in cui il float è usato di proposito (per forzare una diminuzione della precisione). Dovete vedere l'intero codice qui.

In secondo luogo, c'è una questione di confronto tra questi ("nuovi") numeri e la loro mappatura al FSB (ne parliamo più avanti, nella sezione 2).

Più breve - dovremo analizzare attentamente tutto il codice e almeno pensare ai possibili inconvenienti associati al passaggio dalla matematica reale a quella doppia.


Miroslav_Popov ha scritto (a) >>.

2. protected static float fMicron = 0.000075f; // Coef usato quando confrontiamo due float


(e sotto):

Per vedere i valori dell'indicatore in tutta la sua precisione premi F12 nella finestra del grafico.

E questo è uno dei problemi! Perché 0,000075? E non 0,00005? O 0,000001? (come ho fatto io).

Un problema esteso (per chi è interessato) e una domanda:

Come sapete, il confronto di due numeri reali per l'uguaglianza non dovrebbe mai essere fatto con tali costruzioni:

double Value1, Value2;

if (Value1 == Value2) {
  // Some useful code there
}

Questo perché dopo i risultati di alcuni calcoli (specialmente le variazioni su moltiplica/dividi), i valori di queste variabili possono essere visivamente simili (1.0 e 1.0, per esempio), ma in realtà NON sono gli stessi. (1,000001 e 1,000000, infatti). Questa proprietà deriva da una certa discretezza della rappresentazione dei numeri reali nei computer e da una certa (finita) discretezza (precisione) del calcolo. In generale, il confronto per l'uguaglianza è fatto da variazioni su un tema classico (che, tra l'altro, Miroslav usa):

if (Math.Abs(afIndValue[iCurrBar] - afIndValue[iBaseBar]) < fMicron) {
  // Some code there
}

Questo è il confronto "classico" di due numeri reali per l'uguaglianza con una certa precisione finita, definita da fMicron, in questo caso.


E qui sta uno dei potenziali problemi. Come, chi e per quali casi dovrebbe determinare il valore di questo fMicron? È sempre una buona costante, come quella di Miroslav (anche la questione di quale valore è ancora in discussione)?


In generale, se non per aggiungere intrigo - sono per la seguente teoria:

1. In generale ci sono due tipi di confronto di tali variabili, per uguaglianza e per disuguaglianza (<, >).

2. Ci sono due tipi di variabili: variabili con precisione fissa garantita (prezzi, lotti, ecc.), e valori astratti senza alcuna precisione definita (come i valori indicatori).

Per la disuguaglianza, le variabili (di qualsiasi tipo) sono confrontate (in generale) "testa a testa" (se (Valore1 < Valore2) { ...}). Se è necessario limitare la precisione (cosa abbastanza rara), si può usare una costruzione come quella di Miroslav:

if (afIndValue[iBaseBar] < afIndValue[iCurrBar] - fMicron) {
  // Some code there
}

4. Per l'uguaglianza, tuttavia, il problema viene (di solito) affrontato in modo diverso, a seconda dei dati in questione.

4.1 Se abbiamo bisogno di confrontare due numeri con precisione fissa (per esempio, due valori di prezzo per decidere se modificare o meno l'ordine (per evitare di ottenere un "No Result")), di solito lo facciamo così (anche "classico"):

int ComparePriceInt(double Value1, double Value2) {
   Value1 -= Value2;
   Value2 = Point / 2.0;
   if ( Value1 > Value2)
      return(1);
   if ( Value1 < - Value2)
      return(-1);
   return(0);
}

La funzione è ridondante nel nostro caso, ma non è questo il punto. Il costrutto chiave in esso è Point / 2.0. È questo fMicron che ci dà la precisione di calcolo necessaria, corretta e sufficiente... IN QUESTO CASO PARTICOLARE! Quando si confrontano due prezzi (con le stesse cifre e, di conseguenza, punto ), cioè nel caso di (Punto = 0,0001), per esempio

fMicron = 0,00005

e confrontando 1,2345 (prezzo dell'ordine) con 1,23451 (valore dell'indicatore) - otteniamo l'uguaglianza, e 1,2345 con 1,23456 - disuguaglianza... Indovina cosa succede nell'ultimo caso quando fMicron = 0,000075? ;) Si potrebbe, naturalmente, pre-normalizzare le variabili ad una precisione (inferiore). Ma questo non è il nostro metodo :D...

Ancora una volta - la scelta di questo parametro è importante, e per ogni caso "un po' unico" :)1


Suggerirei il seguente paradigma:

1. Le variabili a precisione fissa sono confrontate con un valore fMicron calcolato (Punto / 2, ad esempio per il caso del prezzo)

2. I valori degli indicatori e altre cose simili "infinitamente accurate" :), sono confrontati con la costante fMicron uguale al valore minimo di Point, strumenti utilizzati, diviso per 10. Cioè nel caso di strumenti in cui Digits non supera 4 - fMicron = 0,00001, se Digits = 5, fMicron = 0,000001 e similmente.

Miroslav - è necessaria l'opinione di un esperto :)?!


Ora una domanda per il pubblico:

PERCHÉ in tutti i tipi di DataWindow (in MT o in FSB (Indicator Charts)) - i valori degli indicatori sono sempre mostrati con una precisione fissa (Digits = 4)? Perché non 3 cifre decimali? O 5, 6, 7, ...? :)?! No, davvero?

Miroslav aveva una "caratteristica nascosta? ;)) - Voglio dire F12! E in MT cosa premere?

E in generale, beh, chi ha definito questa costante? (4 cifre decimali).

La mia ipotesi è che sia quasi direttamente collegata alla dimensione delle quotazioni in entrata (1,2345), per la maggior parte degli strumenti (qualcuno l'ha appena compilato). Ma non è un segreto che molte società di intermediazione passano a valori più grandi (5 per esempio). Allora perché non mostrare i valori dell'indicatore nella dimensionalità che coincide con la dimensione delle quotazioni dello strumento (Digits)?

O forse non "capisco" qualcosa in linea di principio nel soggetto (per favore - qualcuno mi spieghi, forse è "necessario" perché...)!


Miroslav_Popov ha scritto (a) >>.

3. Costruttore di base dell'indicatore:

4. Prezzo base:

Miroslav, ho capito molto bene il codice della pagina Source :). Capisco bene cosa fa il protected static float[] Price( BasePrice price). Se questo è un indizio della poca maneggevolezza del mio codice - rispondo che ho intenzionalmente rifiutato di usare buffer aggiuntivi per la memorizzazione (in generale - o copie dei buffer dei prezzi o copie calcolate di essi (Tipico, ecc.)). E si risparmia spazio, e dove ci sono tutti i tipi di Tipi, devono SEMPRE essere calcolati!


Qui dobbiamo menzionare la differenza critica nell'approccio al calcolo dei valori degli indicatori in FSB e MT:

1. In primo luogo, almeno al momento - le quotazioni che vengono caricate in FSB sono statiche, una volta le ha caricate, ha calcolato UNA volta i valori degli indicatori richiesti per l'intera gamma di barre e poi semplicemente "guida" da loro, emulando il comportamento del robot di trading. Ancora una volta, i valori degli indicatori sono calcolati solo una volta, PRIMA di eseguire la virtualizzazione del robot di trading. Questo, in particolare, spiega la velocità di emulazione delle transazioni commerciali. Ma le quotazioni in MT arrivano di continuo e il tester di strategia nativo non vede il futuro, cioè dobbiamo calcolare i valori dell'indicatore ogni volta. E se uso solo l'approccio di Miroslav (calcolo dell'intero buffer)... Sarò lanciato con uova marce :). Pertanto, è necessario prestare particolare attenzione all'uso di IndicatorCounted()! Gli indicatori sono calcolati con una velocità quasi massima possibile in ogni caso (se tutte le barre devono essere contate, o solo una). Da qualche parte, alcune cose possono ancora essere ottimizzate, ma a vostro piacimento...

2. Pertanto, ogni volta (quando arriva un nuovo tick), è ridondante generare valori di prezzo in buffer aggiuntivi. Dovete comunque calcolarli tutti, quindi lasciate che le funzioni (la stessa MovingAverage, ecc.) lo facciano da sole. Risparmia spazio, semplifica la logica (non c'è bisogno di analizzare ogni volta quali barre devono essere ricalcolate in questi buffer), e risparmia velocità (anche da qualche parte più alta, nel caso generale). "A me sembra così" (c) Winnie the Pooh


Se vogliamo discutere ancora della mia conversione degli indicatori, forse è importante che io conservi completamente la logica delle funzioni (e degli indicatori stessi), ma la modifichi leggermente per un caso d'uso specifico in MT. Salvo anche l'ordine e i nomi dei parametri per controllare l'indicatore stesso.

Ragazzi, guardate il codice sorgente, però. Ho cercato di fare "bene" :).


L'idea finale della mia conversione è la seguente. Per esempio, abbiamo un punto di apertura della posizione e tre indicatori per una logica aggiuntiva. Ecco come sarà il codice per il piazzamento degli ordini (beh, più o meno, ovviamente):

if ( IsSignal(iCustom(NULL, 0, "fsbIndicator1", SLOT_TYPE_LC, Param2, Param3, ..., 0, 0))
    && IsSignal(iCustom(NULL, 0, "fsbIndicator2", SLOT_TYPE_LC, Param2, Param3, ..., 0, 0))
    && IsSignal(iCustom(NULL, 0, "fsbIndicator3", SLOT_TYPE_LC, Param2, Param3, ..., 0, 0)) )
{    
// Открываем длинную позицию (предпоследний 0 в значениях индикаторов - указатель на буфер логики длинных позиций (1, соотв. - на буфер логики коротких))
    // Если у нас значение POP берется из еще одного индикатора, то это значение берется аналогично, только меняется логика поведения индикатора:
    // iCustom(NULL, 0, "fsbIndicator", SLOT_TYPE_POP, Param2, Param3, ..., 0, 0)
}

Qualcosa del genere. Si alimenta iCustom con i valori dei parametri e si aspetta che tutti diano un segnale. Questo è tutto. Non c'è un'analisi dei valori degli indicatori stessi... Per quale motivo?

Sembra bello... o no :)?

 

A proposito degli indicatori:

Circa (Aroon e bIsDescreteValues = true;) presi in considerazione.


A proposito di RSI...

Miroslav - la costruzione che stai cercando ti ha confuso :). Non siate pigri a mettere ancora una volta dei commenti intorno ad esso e usate l'indicatore CORRETTAMENTE LAVORATO per ottenere valori "corrispondenti" :). Lasciate che vi ricordi che la formula classica per calcolare l'RSI si basa sulla varietà esponenziale del MA (levigato, in particolare). Quindi, specificate questa modalità di lisciatura (smoothed) nei parametri dell'indicatore... e sarete "piacevolmente sorpresi" dai risultati :) (di default, vi ricordo, viene usato Simple, che dà una divergenza dal classico)! Non posso fare la procedura di cui sopra da solo - ma sono sicuro al 100% di quello che sto dicendo. Convincimi :)?

Come risultato dei test abbiamo il seguente suggerimento, per rimuovere il codice richiesto e rendere il valore predefinito del parametro maMethod in Smoothed in tutti gli indicatori, che utilizzano RSI (e RSI stesso, rispettivamente). Che per default gli utenti non avrebbero queste domande. Ma così facendo renderemo la selezione di questo parametro negli indicatori FUNZIONANTE! (per esempio ho convertito RSI MA Oscillator, che, sulla base del risultato dei calcoli RSI, anche, con il comportamento attuale di RSI stesso - non importa ciò che è specificato nel parametro appropriato)

 
Miroslav_Popov >> :

"Usa il valore della barra precedente"

Personalmente penso che questa sia una delle caratteristiche più importanti di FSB.

OH, SI!

Questa è davvero una delle caratteristiche più importanti di FSB. E ho cercato di prestare la giusta attenzione alla verifica della correttezza della logica degli indicatori, considerando questa caratteristica.

Grazie per il codice che mostra il calcolo del valore "predefinito"! Lo prenderà in considerazione...

 
rider >> :

Perché non può funzionare(?).

Per molto tempo ho usato una singola chiamata icustom per ottenere diversi valori da diversi buffer di indicatori, è troppo dispendioso usare questa funzione più volte nel codice, specialmente durante l'ottimizzazione, e anche con indici "pesanti". Infatti, tutto ciò di cui abbiamo bisogno (al massimo) è di ottenere una direzione di trading e livelli SL & TP..... il problema è risolto da una semplice aritmetica.

...

Il principio, spero, è chiaro.




:), lo otterrete (ho fatto intenzionalmente la mia dichiarazione più grossolana), so del problema con il collasso dei valori in un solo parametro :). E grazie per il codice citato (domanda veloce - ci sono mai state differenze tra i valori originali e quelli "successivamente espansi"? tutti lo stesso doppio...)

La domanda chiave è... È NECESSARIO IN QUESTO CASO PARTICOLARE.

Ci possono essere due ragioni:

1. 1... Lo scopo dell'utilizzo del buffer aggiuntivo (è importante per me) - gli indicatori non ne hanno così tanti. Ne ho abbastanza MA PER ORA (sembra che devo già usare Ishimoku - e tutto diventerà chiaro :))

2. La velocità di chiamata dell'indicatore dal suo codice (il tuo esempio). La mia risposta è: non è essenziale! Lo dichiaro con tutta la responsabilità. Motivazione:

Con ogni nuovo tick - dovrai (dovrai) guardare comunque l'indicatore. Giusto? (per esempio - per prendere i prezzi o qualcos'altro) Anche se non ad ogni spunta, ma quando ne hai bisogno. Il suggerimento principale, forse, è che una chiamata multipla di iCustom all'interno di un'iterazione dell'EA porta al ricalcolo multiplo dell'indicatore? Sono costretto a dissuadervi! Il punto chiave è "un limite di una iterazione dell'Expert Advisor". Quindi, all'interno di questo intervallo, l'indicatore viene calcolato UNA volta (alla sua prima chiamata)! Lo dichiaro con il 100% di fiducia. Tutte le chiamate successive non lo avviano affatto, ma prendono solo i valori necessari dai buffer necessari. La condizione è 100% se i parametri di ingresso rimangono invariati (tranne il buffer e l'offset). La regola è valida per i calcoli nei limiti di uno strumento. Ma penso che il principio sia valido anche quando iCustom si riferisce ad altri TF e strumenti.


Comunque, darò un'occhiata all'Ishimoku stasera e deciderò con certezza se userò due buffer per la logica... o uno :)

 

Comunque, ci vediamo tutti stasera (sono andato a lavorare).

Sul problema.

We have to find solution to Bar Opening and Bar closing entry/exit points. They are vital for FSB -> MT integration.

Ci penserò.


Ma molto probabilmente (data la mancanza di segnali da MT su questo argomento) - il codice di cui sopra (template nella pagina precedente) è più o meno ottimale (potrebbe aver bisogno di una piccola messa a punto... Cercherò di "approfondire" il problema in serata)