E poi devi cercare a cosa si riferiscono quelle quattro parentesi in basso.
A proposito, mi rende molto nervoso quando l'annidamento è più di due livelli. Cerco di non scriverlo mai in questo modo, distribuendo il codice sulle funzioni.
E anche quando ci sono due livelli di annidamento - assicuratevi di scrivere commenti dopo ogni parentesi di chiusura - quale blocco seppellisce (diciamo, l'intestazione di un ciclo duplicato).
Per quanto riguarda lo stile, ecco il mio codice per selezionareuna posizione storica per MT5 (da un mago specificato, simbolo, con un intervallo di date specificato):
int CMT5TradeHistory::Select(ulong ulMagic,ECurrencySymbol csSymbol,datetime dtFrom = MIN_DATETIME,datetime dtTill = NEVER_EXPIRES)
{
ASSERT(dtFrom <= dtTill);
// Очистим список ядер позиции
m_aoPosCores.Clear();
// Запросим историю ордеров и сделокif(HistorySelect(dtFrom,dtTill)!=true)
return(WRONG_VALUE);
// Соберем тикеты исторических позиций// Просмотрим все сделки выхода, и выпишем оттуда тикеты позиций.int iHistoryDealsTotal=HistoryDealsTotal();
CArrayLong alHistoryPosIDs;
int iI = WRONG_VALUE;
ulong ulCurTicket = 0;
long lCurPosID = 0;
long lCurMagic = 0;
long lCurEntry = 0;
string strCurSymbol;
for(iI=0;iI<iHistoryDealsTotal; ++iI)
{
ulCurTicket = HistoryDealGetTicket(iI);
if(ulCurTicket == 0)
return(WRONG_VALUE);
// Получим направление сделки if(HistoryDealGetInteger(ulCurTicket,DEAL_ENTRY,lCurEntry)!=true)
{
TRACE_INTEGER("Не удалось получить направление сделки ! Тикет: ",ulCurTicket);
continue;
};
// Проверим направление сделкиif(lCurEntry != DEAL_ENTRY_OUT)
continue;
// Получим магик сделкиif(HistoryDealGetInteger(ulCurTicket,DEAL_MAGIC,lCurMagic)!=true)
{
TRACE_INTEGER("Не удалось получить магик сделки ! Тикет: ",ulCurTicket);
continue;
};
// Проверим магикif(ulMagic != NULL && lCurMagic != ulMagic)
{
//TRACE_INTEGER("Сделка не подходит ! Имеет неверный магик ! Magic сделки: ",lCurMagic);//TRACE_INTEGER("Требуемый Magic : ",ulMagic);continue;
};
// Получим символ сделкиif(HistoryDealGetString(ulCurTicket,DEAL_SYMBOL,strCurSymbol)!=true)
{
TRACE_INTEGER("Не удалось получить символ ордера ! Тикет: ",ulCurTicket);
continue;
};
// Проверим символif(csSymbol != CS_UNKNOWN)
if(csSymbol == CS_CURRENT)
{
if(_Symbol2CurrencyEnum(strCurSymbol) != _Symbol2CurrencyEnum(Symbol()))
{
//TRACE2("Symbol выбираемой позиции: ",_Enum2CurrencySymbol(csSymbol));//TRACE2("Выбранный ордер имеет неверный символ: ",strCurSymbol);continue;
};
}
else
{
if(_Symbol2CurrencyEnum(strCurSymbol) != csSymbol)
{
//TRACE2("Symbol выбираемой позиции: ",_Enum2CurrencySymbol(csSymbol));//TRACE2("Выбранный ордер имеет неверный символ ! Символ ордера: ",poiBuffer.GetSymbolString());continue;
};
};
// Получим ID позицииif(HistoryDealGetInteger(ulCurTicket,DEAL_POSITION_ID,lCurPosID)!=true)
{
TRACE_INTEGER("Не удалось получить ID позиции ! Тикет: ",ulCurTicket);
continue;
};
// Проверим ID позицииif(lCurPosID <= NULL)
continue;
if(alHistoryPosIDs.Add(lCurPosID)!=true)
return(WRONG_VALUE);
}; // цикл перебора всех сделок// Здесь ID всех позиций собраны в массиве alHistoryPosIDs, необходимо убрать повторения (в позиции может быть много ордеров)
CArrayLong alUnicalHistoryPosIDs;
if(_DeleteDoubles(GetPointer(alHistoryPosIDs),GetPointer(alUnicalHistoryPosIDs))!=true)
return(WRONG_VALUE);
TRACE_INTEGER("Уникальных ID позиций в истории: ",alUnicalHistoryPosIDs.Total());
// Здесь массив alUnicalHistoryPosIDs заполнен уникальными ID позиций в истории.// Заполним ядра позиции
CMT5HistoryPositionInfoCore* phpiHistPosCore = NULL;
for(iI=0;iI<alUnicalHistoryPosIDs.Total(); ++iI)
{
//TRACE_INTEGER("Выберем позицию: ",iI);// Выберем очередной тикет
lCurPosID = alUnicalHistoryPosIDs.At(iI);
// Позиция является нужной компонентой
ASSERT(phpiHistPosCore == NULL);
phpiHistPosCore = new CMT5HistoryPositionInfoCore;
if(phpiHistPosCore == NULL)
{
m_aoPosCores.Clear();
ASSERT_DSC(false,"Не удалось создать объект CMT5HistoryPositionInfoCore по new");
return(WRONG_VALUE);
};
ASSERT_MYPOINTER(phpiHistPosCore);
if(phpiHistPosCore.SelectByID(lCurPosID)!=true)
{
TRACE("Не удалось создать выбрать позицию ! Возможно, позиция открыта, и еще не полностью в истории.");
TRACE_INTEGER("ID невыбранной позиции: ",lCurPosID);
delete phpiHistPosCore;
phpiHistPosCore = NULL;
continue;
};
ASSERT(phpiHistPosCore.GetTPCOpenTime() > MIN_DATETIME && phpiHistPosCore.GetTPCOpenTime() < phpiHistPosCore.GetTPCCloseTime() && phpiHistPosCore.GetTPCCloseTime() < NEVER_EXPIRES);
// Найдена и выбрана еще одна компонента позицииif(m_aoPosCores.Add(phpiHistPosCore) == false)
{
delete phpiHistPosCore;
m_aoPosCores.Clear();
ASSERT_DSC(false,"Не удалось добавить новый объект в список ядер позиции");
return(WRONG_VALUE);
};
phpiHistPosCore = NULL;
}; // цикл перебора уникальных PosID// TRACE_INTEGER("Ядер в выбранной позиции: ",m_aoPosCores.Total()); return(m_aoPosCores.Total());
};
La classe storia stessa è una discendente dell'interfaccia astratta CTradeHistoryI:
class CTradeHistoryI: public CMyObject
{
public:
void CTradeHistoryI() { SetMyObjectType(MOT_TRADE_HISTORY_I); };
virtualvoid ~CTradeHistoryI() {};
// Выбор существующей истории. // Указывается магик и символ, по которому выбираются исторические ордера, а также промежуток времени, в котором необходимо искать их.// Если ulMagic = 0 - выбираются все позиции по всем магикам.// Если ECurrencySymbol = CS_UNKNOWN - выбираются все позиции по всем символам// Если ECurrencySymbol = CS_CURRENT - запрашивается функция Symbol(), и выбираются все позиции по этому символу// Возвращает число компонент позиции внутри истории (может быть нулевым если ничего не найдено) или WRONG_VALUE в случае ошибок// NOTE !!! // При выборе - отложенные ордера не учитываются.virtualint Select(ulong ulMagic = 0,ECurrencySymbol csSymbol = CS_CURRENT,datetime dtFrom = MIN_DATETIME,datetime dtTill = NEVER_EXPIRES) = 0;
virtualuint GetTotalComponents() const = 0; // Получение общего числа компонентvirtual CHistoryPosComponentI* GetComponent(uint uiComponentIdx) const = 0;
// Расширенный интерфейсvirtualvoid Sort(ESortTPCMode stmMode = STM_BY_OPEN_TIME_A) = 0;
// Функция ищет внутри истории компоненту с указанным тикетом. // В случае, если ее нет - возвращается false.// Если компонента найдена - возвращается true, и uiComponentIdx устанавливается на индекс компоненты внутри позиции.virtualbool FindComponentByTicket(long lTicket,uint &uiComponentIdx) const = 0;
};
Selezionando la storia richiesta - è possibile ricalcolare i suoi componenti (posizioni per MT5 o ordini per MT4), e ottenere un'interfaccia a qualsiasi componente come interfaccia astratta:
class CTradePosComponentI: public CMyObject
{
public:
void CTradePosComponentI() { SetMyObjectType(MOT_TRADEPOS_COMPONENT_I); };
virtualvoid ~CTradePosComponentI() {};
// Основной интерфейсvirtuallong GetTPCTicket() const = 0;
virtuallong GetTPCMagic() const = 0;
virtual ECurrencySymbol GetTPCSymbol() const = 0;
virtualENUM_POSITION_TYPE GetTPCType() const = 0;
virtualdatetime GetTPCOpenTime() const = 0;
virtualdouble GetTPCVolume() const = 0;
virtualdouble GetTPCOpenPrice() const = 0;
virtualdouble GetTPCStopLoss() const = 0;
virtualdouble GetTPCTakeProfit() const = 0;
virtualstring GetTPCCommentary() const = 0;
virtualbool IsTPCInUnloss() const { if(GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE) return(false); if(GetTPCType() == POSITION_TYPE_BUY) { if(GetTPCStopLoss() >= GetTPCOpenPrice()) return(true); } else { if(GetTPCStopLoss() <= GetTPCOpenPrice())return(true); }; return (false); };
virtualdouble GetTPDistance() const { if(GetTPCTakeProfit() == 0 || GetTPCTakeProfit() == EMPTY_VALUE) return(EMPTY_VALUE); if(GetTPCType() == POSITION_TYPE_BUY) return(GetTPCTakeProfit() - GetTPCOpenPrice()); return(GetTPCOpenPrice() - GetTPCTakeProfit()); };
virtualdouble GetSLDistance() const { if(GetTPCStopLoss() == 0 || GetTPCStopLoss() == EMPTY_VALUE) return(EMPTY_VALUE); if(GetTPCType() == POSITION_TYPE_BUY) return(GetTPCOpenPrice()- GetTPCStopLoss()); return(GetTPCStopLoss() - GetTPCOpenPrice()); };
};
class CHistoryPosComponentI: public CTradePosComponentI
{
public:
void CHistoryPosComponentI() { SetMyObjectType(MOT_HISTORYPOS_COMPONENT_I); };
virtualvoid ~CHistoryPosComponentI() {};
virtualdatetime GetTPCCloseTime() const = 0;
virtualdouble GetTPCClosePrice() const = 0;
virtualdouble GetTPCProfit() const = 0; // Возвращает профит по исторической позицииvirtualbool IsProfitClosePrice() const = 0; // Возвращает true, если цена зарытия отличается от цены открытия в прибыльную сторону // Возвращает профит исторической позиции для случая, когда бы ход цены (в сторону профита) был бы равен dPriceMove, а лот был бы единичным.// Функция используется для расчета лота для такой же позиции с нужным ходом цены // Рекомендуется отнимать от цены двойной спред.virtualdouble CalculateOneLotProfit(double dPriceMove) const = 0;
};
Per MT4 - ci sono classi di storia corrispondenti anche ereditate da queste interfacce - così, allo stesso tempo, la multipiattaforma è fornita - un EA non ha bisogno di scoprire dove lavora, tutto il lavoro con la storia è fatto attraverso le interfacce astratte.
Non scrivere funzioni che sono sempre costanti e non cambiano mai in questo stile
Scrivili in modo conciso, tanto nessuno li guarda mai, e ci vogliono la metà delle righe
Dato che queste funzioni non cambiano mai, perché ci mettete un mucchio di parentesi graffe inutili? Rimuoveteli e tutto si ridurrà da solo. Perché il tuo esempio sembra assurdo: tu stesso hai offuscato il codice e poi inventi delle stampelle per ridurlo.
Alexey Navoykov: Dato che queste funzioni non cambiano, perché hai messo un mucchio di parentesi graffe inutili? Rimuoveteli e tutto sarà compresso. Perché il tuo esempio sembra assurdo: tu stesso hai offuscato il codice e poi inventi delle stampelle per ridurlo.
Sono d'accordo, si possono tagliare altre 3 righe, e accorciare il codice, ma lo scopo non era quello di mettere il codice in uso, infatti non è nemmeno mio, ma di accorciare, e tali funzioni possono essere messe cinque in una schermata, non una. Dopo di che i programmi sono più facili da leggere e non devi scorrere 150 volte. E il peso del file diminuisce.
Buon lavoro, mi piace, ma non mi piace l'OOP e cerco di farne a meno. Non mi piacciono i processori con threads splitting (per esempio, 4 core e 8 threads). Deve essere chiaro che lo splitting e qualsiasi virtualizzazione è una perdita di prestazioni e perdita di tempo macchina per la sua implementazione, sia che si tratti di threads splitting nel kernel o di virtualizzazione di funzioni nel codice.
Vitaly Muzichenko:
Sono d'accordo, si possono tagliare altre 3 righe, e accorciare il codice, ma lo scopo non era quello di mettere il codice in uso, infatti non è nemmeno mio, ma di accorciare, e tali funzioni possono essere messe cinque in una schermata, non una. Dopo di che i programmi sono più facili da leggere e non devi scorrere 150 volte. E il peso del file è ridotto.
La brevità è la sorella del talento, penso che suoni meglio.
Non ho intenzione di rileggerlo, mi limiterò a citare:"Non scrivere funzioni che sono sempre costanti e non cambiano mai in quello stile"
Perché puntare gli occhi su una funzione che viene scritta una volta sola quando la piattaforma viene rilasciata e non cambierà mai in futuro? Modificate spesso il codice nelle funzioni per ottenere la dimensione del lotto, il numero di ordini e il tipico? Allora perché allungarlo su 3 schermi di un monitor 32"?
P.S. Il codice allegato è falsificato da kodobase.
Contro domanda ))) Ho tali funzioni sono nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? E francamente parlando, tale codestream mi fa star male ))
Contro domanda ))) Ho tali funzioni nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? Per essere onesti, questo codestream mi fa star male )).
Anche io uso gli include file, è comodo. Specialmente quando si scrive uno script personalizzato, ci sono un sacco di funzioni identiche ed è stupido scrivere una e la stessa cosa, basta includere il file e la funzione è nel vostro EA. Per quanto mi riguarda, il codice dovrebbe essere chiaro, breve, veloce da lavorare e dovrebbe funzionare in tutte le condizioni senza errori.
Contro domanda ))) Ho tali funzioni nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? E francamente parlando, un tale codestream mi fa star male ))
Il programmatore ha scritto che il principio "porto tutto io"; l'intero codice dell'Expert Advisor è stipato in un unico file. Di conseguenza, copia tutte queste funzioni in ogni EA. Quindi, conta: 1000 EAs x 10 Kb = 10 Mb - devi già pensare ad economizzare ))
Contro domanda ))) Ho tali funzioni nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? E francamente parlando, tale codestream mi fa star male ))
Anch'io, ma molto tempo fa sono arrivato alla conclusione che il codice deve essere compatto in posti dove non lo si guarda mai, dove non viene mai corretto e mai lo sarà.
La dispersione del codice utente con tutti questi slot è un ulteriore mal di testa, perché sarà necessario trascinare e rilasciare i file in diversi terminali o condividerli. Naturalmente, potete trasferire gli includenti a tutti i terminali, ma se cambiate o aggiungete qualcosa in un terminale, allora tutti devono essere sostituiti con uno nuovo.
Gli Expert Advisors e gli indicatori sono così piccoli che non ha senso distanziarli dal corpo del programma. Per essere più corretti, non sono piccoli, sono file singoli, non è come un sito con 10 000 pagine dove non si può fare a meno di classi e inludi. Inoltre, ci sono strutture ora, e sono sufficienti per scrivere codice compatto e funzionante al 100%.
A proposito, mi rende molto nervoso quando l'annidamento è più di due livelli. Cerco di non scriverlo mai in questo modo, distribuendo il codice sulle funzioni.
E anche quando ci sono due livelli di annidamento - assicuratevi di scrivere commenti dopo ogni parentesi di chiusura, quale blocco seppellisce (per esempio, l'intestazione di un ciclo duplicato).
Per quanto riguarda lo stile, ecco il mio codice per selezionare laposizione storica per MT5 (per mago specificato, simbolo, con intervallo di date specificato):
La classe storia stessa è una discendente dell'interfaccia astratta CTradeHistoryI:
Selezionando la storia richiesta - è possibile ricalcolare i suoi componenti (posizioni per MT5 o ordini per MT4), e ottenere un'interfaccia a qualsiasi componente come interfaccia astratta:
Per MT4 ci sono classi di storia corrispondenti che ereditano anche da queste interfacce - così allo stesso tempo viene fornita la multipiattaforma - l'Expert Advisor non ha bisogno di scoprire dove lavora, tutto il lavoro con la storia viene fatto attraverso interfacce astratte.
Sembra bello, possiamo anche guardare TRACE_*** e ASSERT?
Per trascinare un file su un altro terminale, o per condividerlo, è necessario trascinare non solo un file, ma diversi. Potete, naturalmente, trasferire gli inludi a tutti i terminali, ma se cambiate o aggiungete qualcosa in un terminale, allora dovete sostituirlo con uno nuovo in tutti i terminali.
Raccomando di usare collegamenti simbolici o collegamenti di giunzione per la cartella MQL. Tutti i terminali cercheranno in una cartella.
E poi devi cercare a cosa si riferiscono quelle quattro parentesi in basso.
A proposito, mi rende molto nervoso quando l'annidamento è più di due livelli. Cerco di non scriverlo mai in questo modo, distribuendo il codice sulle funzioni.
E anche quando ci sono due livelli di annidamento - assicuratevi di scrivere commenti dopo ogni parentesi di chiusura - quale blocco seppellisce (diciamo, l'intestazione di un ciclo duplicato).
Per quanto riguarda lo stile, ecco il mio codice per selezionareuna posizione storica per MT5 (da un mago specificato, simbolo, con un intervallo di date specificato):
La classe storia stessa è una discendente dell'interfaccia astratta CTradeHistoryI:
Selezionando la storia richiesta - è possibile ricalcolare i suoi componenti (posizioni per MT5 o ordini per MT4), e ottenere un'interfaccia a qualsiasi componente come interfaccia astratta:
Per MT4 - ci sono classi di storia corrispondenti anche ereditate da queste interfacce - così, allo stesso tempo, la multipiattaforma è fornita - un EA non ha bisogno di scoprire dove lavora, tutto il lavoro con la storia è fatto attraverso le interfacce astratte.
Non scrivere funzioni che sono sempre costanti e non cambiano mai in questo stile
Scrivili in modo conciso, tanto nessuno li guarda mai, e ci vogliono la metà delle righe
Dato che queste funzioni non cambiano, perché hai messo un mucchio di parentesi graffe inutili? Rimuoveteli e tutto sarà compresso. Perché il tuo esempio sembra assurdo: tu stesso hai offuscato il codice e poi inventi delle stampelle per ridurlo.
Sono d'accordo, si possono tagliare altre 3 righe, e accorciare il codice, ma lo scopo non era quello di mettere il codice in uso, infatti non è nemmeno mio, ma di accorciare, e tali funzioni possono essere messe cinque in una schermata, non una. Dopo di che i programmi sono più facili da leggere e non devi scorrere 150 volte. E il peso del file diminuisce.
Buon lavoro, mi piace, ma non mi piace l'OOP e cerco di farne a meno. Non mi piacciono i processori con threads splitting (per esempio, 4 core e 8 threads). Deve essere chiaro che lo splitting e qualsiasi virtualizzazione è una perdita di prestazioni e perdita di tempo macchina per la sua implementazione, sia che si tratti di threads splitting nel kernel o di virtualizzazione di funzioni nel codice.
Sono d'accordo, si possono tagliare altre 3 righe, e accorciare il codice, ma lo scopo non era quello di mettere il codice in uso, infatti non è nemmeno mio, ma di accorciare, e tali funzioni possono essere messe cinque in una schermata, non una. Dopo di che i programmi sono più facili da leggere e non devi scorrere 150 volte. E il peso del file è ridotto.
Sinceramente.
Schermo di lavoro da 27 pollici
Non ho intenzione di rileggerlo, mi limiterò a citare:"Non scrivere funzioni che sono sempre costanti e non cambiano mai in quello stile"
Perché puntare gli occhi su una funzione che viene scritta una volta sola quando la piattaforma viene rilasciata e non cambierà mai in futuro? Modificate spesso il codice nelle funzioni per ottenere la dimensione del lotto, il numero di ordini e il tipico? Allora perché allungarlo su 3 schermi di un monitor 32"?
P.S. Il codice allegato è falsificato da kodobase.
Contro domanda ))) Ho tali funzioni sono nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? E francamente parlando, tale codestream mi fa star male ))
Contro domanda ))) Ho tali funzioni nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? Per essere onesti, questo codestream mi fa star male )).
Per quanto mi riguarda, il codice dovrebbe essere chiaro, breve, veloce da lavorare e dovrebbe funzionare in tutte le condizioni senza errori.
Sinceramente.
Contro domanda ))) Ho tali funzioni nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? E francamente parlando, un tale codestream mi fa star male ))
Quindi, conta: 1000 EAs x 10 Kb = 10 Mb - devi già pensare ad economizzare ))
Contro domanda ))) Ho tali funzioni nel file MyFunc.mqh, non vedo il minimo senso nel comprimerlo. Perché, per risparmiare 10-20 KB sul disco? E francamente parlando, tale codestream mi fa star male ))
Anch'io, ma molto tempo fa sono arrivato alla conclusione che il codice deve essere compatto in posti dove non lo si guarda mai, dove non viene mai corretto e mai lo sarà.
La dispersione del codice utente con tutti questi slot è un ulteriore mal di testa, perché sarà necessario trascinare e rilasciare i file in diversi terminali o condividerli. Naturalmente, potete trasferire gli includenti a tutti i terminali, ma se cambiate o aggiungete qualcosa in un terminale, allora tutti devono essere sostituiti con uno nuovo.
Gli Expert Advisors e gli indicatori sono così piccoli che non ha senso distanziarli dal corpo del programma. Per essere più corretti, non sono piccoli, sono file singoli, non è come un sito con 10 000 pagine dove non si può fare a meno di classi e inludi. Inoltre, ci sono strutture ora, e sono sufficienti per scrivere codice compatto e funzionante al 100%.
A proposito, mi rende molto nervoso quando l'annidamento è più di due livelli. Cerco di non scriverlo mai in questo modo, distribuendo il codice sulle funzioni.
E anche quando ci sono due livelli di annidamento - assicuratevi di scrivere commenti dopo ogni parentesi di chiusura, quale blocco seppellisce (per esempio, l'intestazione di un ciclo duplicato).
Per quanto riguarda lo stile, ecco il mio codice per selezionare laposizione storica per MT5 (per mago specificato, simbolo, con intervallo di date specificato):
La classe storia stessa è una discendente dell'interfaccia astratta CTradeHistoryI:
Selezionando la storia richiesta - è possibile ricalcolare i suoi componenti (posizioni per MT5 o ordini per MT4), e ottenere un'interfaccia a qualsiasi componente come interfaccia astratta:
Per MT4 ci sono classi di storia corrispondenti che ereditano anche da queste interfacce - così allo stesso tempo viene fornita la multipiattaforma - l'Expert Advisor non ha bisogno di scoprire dove lavora, tutto il lavoro con la storia viene fatto attraverso interfacce astratte.
Sembra bello, possiamo anche guardare TRACE_*** e ASSERT?
Per trascinare un file su un altro terminale, o per condividerlo, è necessario trascinare non solo un file, ma diversi. Potete, naturalmente, trasferire gli inludi a tutti i terminali, ma se cambiate o aggiungete qualcosa in un terminale, allora dovete sostituirlo con uno nuovo in tutti i terminali.