top of page

RiskGuard Strategy
Specification Config. 2

Versione B2.01 del 15/07/2026 BETA

​​

Questa pagina contiene l'intera specifica tecnica necessaria per creare indicatori compatibili con RiskGuard Config 2.

L'unico metodo supportato per l'invio dei segnali è la funzione SendRiskGuardConfig2Signal().

​

Scopo della pagina
 

Questa pagina definisce le regole obbligatorie per creare un indicatore MQL5 compatibile con la modalità Strategy di RiskGuard Management.

​

Il documento è destinato a:

​

  • Sviluppatori MQL5

  • Sistemi di Intelligenza Artificiale

  • Generatori automatici di codice

  • Creatori di strategie compatibili con RiskGuard

​

Quando una regola è indicata come obbligatoria deve essere rispettata senza eccezioni.

​

L'obiettivo dell'indicatore è esclusivamente generare segnali operativi.

​

Tutta la gestione del trading viene eseguita da RiskGuard.

​

Cosa deve fare l'indicatore
 

L'indicatore deve:

​

  • Analizzare il mercato

  • Generare segnali operativi

  • Calcolare lo Stop Loss

  • Calcolare il Take Profit

  • Calcolare opzionalmente il prezzo di un ordine pendente

  • Inviare il segnale a RiskGuard tramite la funzione ufficiale SendRiskGuardConfig2Signal()

​

Cosa non deve fare l'indicatore
 

L'indicatore non deve:

​

  • Aprire operazioni

  • Chiudere operazioni

  • Modificare operazioni

  • Calcolare il lotto

  • Gestire il rischio

  • Gestire Break Even

  • Gestire Take Profit parziali

  • Gestire Trailing Stop

  • Gestire limiti di perdita giornalieri

  • Gestire Quantum

​

Tutte queste funzioni sono gestite esclusivamente da RiskGuard.

​

Nome dell'indicatore
 

Il nome dell'indicatore deve iniziare con:

​

RiskGuard_

​

Esempi validi:

​

RiskGuard_ORB

RiskGuard_MACD

RiskGuard_Stochastic

RiskGuard_Breakout

​

Esempi non validi:

​

ORB

MACD

RG_ORB

AutoStrategy

​

RiskGuard può rifiutare automaticamente indicatori che non iniziano con il prefisso RiskGuard_.

​

Indipendenza dal timeframe del grafico
 

RiskGuard è progettato per operare con una sola finestra grafico per ogni simbolo e salvato come modello default.

​

L'utente può cambiare liberamente il timeframe del grafico in qualsiasi momento.

​

L'indicatore deve garantire che il cambio timeframe del grafico non alteri il comportamento della strategia.

​

Il cambio timeframe non deve:

​

  • Modificare la logica della strategia

  • Modificare i segnali generati

  • Generare nuovi segnali

  • Generare segnali duplicati

  • Generare segnali retroattivi

​

Se la strategia utilizza uno o più timeframe specifici, questi devono essere definiti internamente dall'indicatore.

​

La logica della strategia non deve dipendere dal timeframe attualmente visualizzato sul grafico.

​

Divieto di segnali retroattivi
 

L'indicatore deve generare segnali esclusivamente in tempo reale.

​

Se una condizione operativa si è verificata prima del caricamento dell'indicatore, il segnale deve essere ignorato.

​

Esempio:

​

Breakout alle ore 11:00.

​

Indicatore caricato alle ore 15:00.

​

Comportamento corretto:

​

Nessun segnale.

​

Comportamento errato:

​

Generare alle 15:00 un segnale relativo al breakout delle 11:00.

​

Divieto di segnali duplicati
 

Lo stesso segnale non deve essere inviato più volte.

​

Lo sviluppatore dell'indicatore è completamente responsabile della prevenzione dei segnali duplicati.

​

L'indicatore deve garantire che:

​

  • Un refresh del grafico non generi duplicati

  • Un cambio timeframe non generi duplicati

  • Una reinizializzazione dell'indicatore non generi duplicati

  • Lo stesso evento operativo non venga inviato più volte

​

Divieto di funzioni operative
 

Un indicatore compatibile con RiskGuard non deve eseguire direttamente operazioni di trading.

​

Non devono essere utilizzate funzioni come:

​

OrderSend()

Buy()

Sell()

PositionOpen()

PositionClose()

PositionModify()

 

RiskGuard è l'unico componente autorizzato ad eseguire operazioni.

 

Gestione della rimozione dell’indicatore
 

Quando un indicatore compatibile con RiskGuard viene rimosso dal grafico, è consigliato ripulire correttamente tutte le risorse create dall’indicatore.

​

Ad esempio:

​

  • Global Variables interne all’indicatore

  • Oggetti grafici

  • Box

  • Linee

  • Label

  • Variabili di stato persistenti

​

Questo riduce il rischio di:

​

  • segnali duplicati

  • segnali residui

  • oggetti lasciati sul grafico

  • comportamenti inattesi al riavvio dell’indicatore

​

È consigliato implementare questa logica all’interno di:

​

OnDeinit()

​

Particolare attenzione deve essere posta al caso:

​

REASON_CHARTCHANGE

​

MetaTrader reinizializza l’indicatore anche durante il cambio timeframe.

​

In molti casi, cancellare tutte le variabili durante REASON_CHARTCHANGE può causare segnali duplicati dopo il reload.

​

Per questo motivo, la logica di cleanup deve essere progettata con attenzione in base al comportamento della strategia.

​

Esempio:

​

void OnDeinit(const int reason)

  {

   if(reason == REASON_CHARTCHANGE)

      return;

​

      GlobalVariableDel(LastSignalGVName());
      ObjectDelete(0, "MyStrategyBox");
      ObjectDelete(0, "MyStrategyLine");

​

  }

​

La logica di cleanup dipende interamente dal comportamento della strategia.

​

Non tutti gli indicatori richiedono la stessa gestione in OnDeinit().

​

Lo sviluppatore è responsabile di implementare una logica coerente con il comportamento della propria strategia.

​

Funzione ufficiale SendRiskGuardConfig2Signal()
 

ATTENZIONE

 

La funzione SendRiskGuardConfig2Signal() riportata in questa pagina è parte integrante del protocollo ufficiale RiskGuard.

 

La funzione deve essere copiata integralmente senza alcuna modifica.

 

Non è consentito:

 

- modificare il codice

- ottimizzare il codice

- rifattorizzare il codice

- riscrivere il codice

- sostituire istruzioni equivalenti

- aggiungere istruzioni

- rimuovere istruzioni

 

La funzione deve essere riportata identica carattere per carattere.

 

Qualsiasi modifica rende l'indicatore non conforme alle specifiche RiskGuard.

 

 

//+------------------------------------------------------------------+

//| Official RiskGuard signal function - Config. 2                   |

//|                                                                  |

//| pendingPrice = 0.0  -> market order                              |

//| pendingPrice > 0.0  -> pending order                             |

//|                                                                  |

//| DO NOT MODIFY THIS FUNCTION.                                     |

//| This function must remain identical in all RiskGuard-compatible  |

//| indicators.                                                      |

//+------------------------------------------------------------------+

void SendRiskGuardConfig2Signal(double stopPrice,

                         double takePrice,

                         double pendingPrice = 0.0)

  {

   //--- Always delete old RiskGuard variables first

   GlobalVariableDel("RG_Strategy_Config2_Symbol_" + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Stop_"   + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Take_"   + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Price_"  + _Symbol);

 

   //--- Normalize prices

   stopPrice = NormalizeDouble(stopPrice, _Digits);

   takePrice = NormalizeDouble(takePrice, _Digits);

 

   if(pendingPrice > 0.0)

      pendingPrice = NormalizeDouble(pendingPrice, _Digits);

 

   bool isPending = (pendingPrice > 0.0);

 

   //--- Create variables in the correct order

   GlobalVariableSet("RG_Strategy_Config2_Stop_" + _Symbol, stopPrice);

   GlobalVariableSet("RG_Strategy_Config2_Take_" + _Symbol, takePrice);

 

   if(isPending)

      GlobalVariableSet("RG_Strategy_Config2_Price_" + _Symbol, pendingPrice);

 

   //--- RG_Strategy_Symbol must always be created last

   GlobalVariableSet("RG_Strategy_Config2_Symbol_" + _Symbol, 1);

 

   //--- Log

   if(isPending)

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][SIGNAL] Pending signal variables created",

            " | Symbol=", _Symbol,

            " | Stop=", DoubleToString(stopPrice, _Digits),

            " | Take=", DoubleToString(takePrice, _Digits),

            " | Price=", DoubleToString(pendingPrice, _Digits),

            " | Bid=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits),

            " | Ask=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));

     }

   else

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][SIGNAL] Market signal variables created",

            " | Symbol=", _Symbol,

            " | Stop=", DoubleToString(stopPrice, _Digits),

            " | Take=", DoubleToString(takePrice, _Digits),

            " | Bid=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits),

            " | Ask=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));

     }

  }

Invio di un segnale a mercato
 

Esempio:​

 

SendRiskGuardConfig2Signal(stopPrice, takePrice);

 

Invio di un segnale pendente
 

Esempio:

 

SendRiskGuardConfig2Signal(stopPrice, takePrice, pendingPrice);

 

Cosa fa RiskGuard dopo aver ricevuto un segnale
 

Dopo aver ricevuto un segnale, RiskGuard può:

​

  • Validare i prezzi

  • Determinare automaticamente BUY o SELL

  • Calcolare il lotto

  • Calcolare il rischio

  • Applicare Quantum

  • Applicare limiti di esposizione

  • Applicare Break Even

  • Applicare Take Profit parziali

  • Applicare Trailing Stop

  • Aprire ordini a mercato

  • Aprire ordini pendenti

  • Gestire le posizioni aperte

​

L'indicatore non è responsabile di nessuna di queste operazioni.

​

Magic Number utilizzati da RiskGuard
 

Quando RiskGuard apre operazioni tramite la modalità Strategy in "CONFIG. 2", utilizza sempre il seguente Magic Number fisso:

​

30032999

​

Questo vale sia per:

​

  • ordini a mercato

  • ordini pendenti

​​

aperti in seguito a un segnale generato da un indicatore compatibile con RiskGuard.

​

Questo permette allo sviluppatore dell’indicatore di identificare facilmente ordini e posizioni generate dalla modalità Strategy.

​

Ad esempio, un indicatore può verificare se esistono posizioni o ordini aperti da RiskGuard Strategy filtrando il Magic Number:

​

30032999

​

Tutti gli altri trade aperti direttamente da RiskGuard (non tramite Strategy Mode) utilizzano invece Magic Number appartenenti al range riservato RiskGuard.

​

Per questo motivo, se uno sviluppatore desidera monitorare esclusivamente l’attività generata dalla Strategy Mode "CONFIG. 2", deve filtrare esclusivamente il Magic Number:

​

30032999

​

Responsabilità e supporto
 

L'indicatore e RiskGuard sono componenti separati.

​

RiskGuard non conosce la logica utilizzata dall'indicatore per generare il segnale.

​

Dopo aver ricevuto un segnale valido, RiskGuard si comporta esattamente come se l'utente avesse premuto il pulsante "CALC" nel pannello, inserito manualmente i prezzi e premuto il pulsante "OPEN".

​

​

L'unica informazione ricevuta da RiskGuard è:

​

  • Prezzo di apertura (solo per ordini pendenti)

  • Stop Loss

  • Take Profit

​​

RiskGuard non riceve informazioni sulla logica della strategia.

​

Supporto tecnico
 

RiskGuard fornisce supporto esclusivamente per:

​

  • Installazione di RiskGuard

  • Configurazione di RiskGuard

  • Funzionamento delle funzioni di RiskGuard

  • Problemi relativi a RiskGuard

​

RiskGuard non fornisce supporto gratuito per:

​

  • Strategie sviluppate da terze parti

  • Indicatori sviluppati da terze parti

  • Codice creato tramite Intelligenza Artificiale

  • Modifiche personalizzate richieste dagli utenti

​

Per qualsiasi problema relativo alla logica della strategia o al funzionamento dell'indicatore, l'utente deve contattare direttamente lo sviluppatore dell'indicatore.

​

Validazione del segnale
 

La ricezione di un segnale non garantisce l'apertura di un'operazione.

​

Prima dell'apertura, RiskGuard applica tutti i controlli normalmente previsti dal sistema.

​

Ad esempio:

​

  • Stop Loss & DD Block

  • Limiti di esposizione

  • Controlli sui prezzi

  • Controlli sul rischio

  • Altri controlli interni di sicurezza

​

Se uno dei controlli impedisce l'apertura dell'operazione, il segnale viene ignorato ed eliminato e nessun trade viene aperto.

​

Compatibilità con Strategy Tester
 

RiskGuard può essere utilizzato all'interno dello Strategy Tester di MetaTrader.

​

Quando RiskGuard carica un indicatore tramite il parametro:

​

StrategyIndicator

​

MetaTrader consente di modificare esclusivamente gli input di RiskGuard.

​

Gli input dell'indicatore strategico non sono accessibili direttamente dalla finestra dello Strategy Tester di RiskGuard.

​

Per consentire all'utente finale di modificare gli input della strategia durante i test, lo sviluppatore deve fornire un file .mq5

contenente almeno la definizione degli input della strategia.

​

Esempio:

​

input int SignalHour = 9;

​

input int SignalMinute = 0;

​

input int StopDistancePoints = 1000;

​

Questo permette all'utente di compilare l'indicatore con i parametri desiderati e utilizzarlo nello Strategy Tester insieme a RiskGuard.

 

Consigli per lo sviluppo e il backtest
 

Per migliorare le prestazioni durante il backtest, è consigliabile separare completamente la logica della strategia dalla sua rappresentazione grafica.

​

Gli indicatori, le linee, le medie mobili, le bande, i livelli e tutti gli altri elementi grafici utilizzati dalla strategia dovrebbero essere visualizzati:

​

  • durante il normale utilizzo sul grafico;

  • durante un backtest eseguito in modalità visuale.

​

Quando invece il backtest viene eseguito senza modalità visuale, è consigliabile non creare, non aggiornare e non disegnare alcun elemento grafico.

​

Questa soluzione permette di:

​

  • velocizzare sensibilmente il backtest;

  • ridurre il carico sulla piattaforma;

  • evitare elaborazioni grafiche inutili;

  • mantenere comunque tutti gli elementi visibili durante lo sviluppo, il controllo della strategia e l’utilizzo reale.

​

La logica che calcola i segnali deve continuare a funzionare normalmente anche quando la parte grafica è disattivata. Gli elementi visivi devono quindi essere utilizzati esclusivamente come supporto grafico e non devono essere necessari per generare i segnali della strategia.

​

In MQL5 è possibile verificare la modalità di esecuzione utilizzando le proprietà del programma, ad esempio:​​

 

bool showGraphics = true;

 

if(MQLInfoInteger(MQL_TESTER) &&

!MQLInfoInteger(MQL_VISUAL_MODE))

{

showGraphics = false;

}

 

La variabile showGraphics può quindi essere controllata prima di creare indicatori grafici, buffer visibili, oggetti, linee, etichette o altri elementi destinati esclusivamente alla visualizzazione.

​

Esempio:

 

if(showGraphics)

{

// Creazione o aggiornamento degli elementi grafici

}

 

È inoltre consigliabile:

​

  • creare gli handle degli indicatori necessari ai calcoli anche nel backtest non visuale;

  • evitare invece di aggiungerli graficamente al chart quando la modalità visuale non è attiva;

  • non utilizzare oggetti grafici per memorizzare informazioni indispensabili alla strategia;

  • mantenere separati il blocco di calcolo, il blocco di generazione dei segnali e il blocco grafico;

  • evitare aggiornamenti grafici a ogni tick quando non sono realmente necessari.

​

Durante la creazione della strategia è consigliabile effettuare inizialmente alcuni test in modalità visuale, verificando che segnali, ingressi, Stop Loss e Take Profit siano coerenti con gli elementi mostrati sul grafico. Una volta verificato il corretto funzionamento, i test più lunghi possono essere eseguiti senza modalità visuale per ottenere una maggiore velocità.

 

Protezione della logica della strategia
 

Lo sviluppatore può scegliere liberamente come distribuire la propria strategia.

​

Sono supportati entrambi gli approcci.

​

Strategia completamente aperta:

​

Indicatore.mq5

​

Strategia con logica protetta:

​

Indicatore.mq5

​

LibreriaProtetta.ex5

​

Il file .mq5 può contenere:

​

  • Gli input della strategia

  • La funzione SendRiskGuardConfig2Signal()

  • Il collegamento alla libreria

​

La logica proprietaria può essere mantenuta all'interno di una o più librerie compilate.

​

In questo modo l'utente finale può modificare gli input della strategia durante i test senza avere accesso al codice proprietario.

​

Utilizzo su conto Demo o Reale
 

Per l'utilizzo normale su conto Demo o Reale non è necessario distribuire il file .mq5.

​

L'utente può utilizzare normalmente il solo file:

​

Indicatore.ex5

​

e modificare gli input direttamente dalle proprietà dell'indicatore sul grafico.

​

Checklist finale
 

Prima di considerare compatibile un indicatore verificare che:

​

✓ Il nome inizi con RiskGuard_

​

✓ Non utilizzi funzioni operative

​

✓ Non generi segnali retroattivi

​

✓ Non generi segnali duplicati

​

✓ Il comportamento non cambi al cambio timeframe del grafico

​

✓ Utilizzi SendRiskGuardConfig2Signal()

​

✓ La funzione SendRiskGuardConfig2Signal() non sia stata modificata

​

✓ Stop Loss e Take Profit siano calcolati dall'indicatore

​

✓ La gestione del rischio sia lasciata interamente a RiskGuard

​

Indicatori di esempio
 

Questa pagina include due indicatori di esempio completi e funzionanti.

​

Entrambi rispettano integralmente le specifiche ufficiali di RiskGuard Strategy e possono essere usati come riferimento per sviluppare strategie personalizzate.

​

Gli esempi hanno lo scopo di mostrare:

​

  • come strutturare un indicatore compatibile con RiskGuard

  • come prevenire segnali duplicati

  • come evitare segnali retroattivi

  • come inviare correttamente segnali a mercato o pendenti

​

Esempio 1 — RiskGuard_auto.mq5
 

Indicatore di esempio estremamente semplice.

​

Questo indicatore genera un segnale automatico a un orario specifico definito dall’utente.

​

L’obiettivo è mostrare il funzionamento minimo richiesto per un indicatore compatibile con RiskGuard.

​

Funzioni principali:

​

  • Generazione di un segnale a un orario preciso

  • Supporto ordini a mercato o pendenti

  • Calcolo automatico di Stop Loss e Take Profit

  • Protezione da segnali duplicati

  • Protezione da segnali retroattivi

  • Protezione da cambio timeframe

​

Questo esempio è consigliato come punto di partenza per comprendere la logica base di integrazione con RiskGuard.

 

//+------------------------------------------------------------------+

//|                                           RiskGuard_auto.mq5     |

//+------------------------------------------------------------------+

//| RiskGuard Example Strategy Indicator                             |

//|                                                                  |

//| This indicator shows the minimum logic needed to send a trading  |

//| signal from a custom indicator to RiskGuard.                     |

//|                                                                  |

//| The example generates a signal at a specific broker/server time. |

//|                                                                  |

//| Developers can replace the example signal logic with their own   |

//| strategy while keeping SendRiskGuardConfig2Signal() unchanged.          |

//|                                                                  |

//| IMPORTANT                                                        |

//| SendRiskGuardConfig2Signal() is the official RiskGuard integration      |

//| function and should not be modified.                             |

//+------------------------------------------------------------------+

#property indicator_chart_window

#property indicator_plots 0

 

input int SignalHour          = 11;      // Broker/server hour when the signal must be generated

input int SignalMinute        = 0;       // Broker/server minute when the signal must be generated

input int StopDistancePoints  = 40000;   // Stop Loss distance from entry price, in points

input int TakeDistancePoints  = 40000;   // Take Profit distance from entry price, in points

input int PriceDistancePoints = 0;   // 0 = market order, >0 = pending order distance from current price, in points

 

 

//+------------------------------------------------------------------+

//| Last signal Global Variable name                                 |

//+------------------------------------------------------------------+

//| The Global Variable name includes:                               |

//| - RG prefix                                                      |

//| - indicator program name                                         |

//| - symbol                                                         |

//| - variable purpose                                               |

//|                                                                  |

//| This prevents conflicts when the same indicator is used on        |

//| multiple symbols or charts.                                      |

//+------------------------------------------------------------------+

string LastSignalGVName()

  {

   return "RG_" + MQLInfoString(MQL_PROGRAM_NAME) + "_" + _Symbol + "_LastSignal";

  }

 

 

//+------------------------------------------------------------------+

//| Check if a signal was already generated in this server minute    |

//+------------------------------------------------------------------+

//| MetaTrader reloads indicators when the chart timeframe changes.  |

//|                                                                  |

//| Without this protection, changing timeframe during the same      |

//| signal minute could generate the same RiskGuard signal again.    |

//|                                                                  |

//| The Global Variable stores TimeCurrent() when the signal is sent. |

//| The comparison ignores seconds and checks only:                  |

//| year, month, day, hour and minute.                               |

//|                                                                  |

//| This means:                                                      |

//| - 11:10:03 and 11:10:25 are treated as the same signal minute    |

//| - 11:10 and 11:45 are treated as different possible signals      |

//+------------------------------------------------------------------+

bool SignalAlreadySentThisMinute()

  {

   string gvName = LastSignalGVName();

 

   if(!GlobalVariableCheck(gvName))

      return false;

 

   datetime lastSignal = (datetime)GlobalVariableGet(gvName);

 

   MqlDateTime lastTm;

   MqlDateTime nowTm;

 

   TimeToStruct(lastSignal, lastTm);

   TimeToStruct(TimeCurrent(), nowTm);

 

   if(lastTm.year == nowTm.year &&

      lastTm.mon  == nowTm.mon  &&

      lastTm.day  == nowTm.day  &&

      lastTm.hour == nowTm.hour &&

      lastTm.min  == nowTm.min)

      return true;

 

   return false;

  }

 

 

//+------------------------------------------------------------------+

//| Save last signal timestamp                                       |

//+------------------------------------------------------------------+

//| The exact server timestamp is stored.                            |

//| Seconds are useful for logs/debugging, but duplicate protection  |

//| compares only up to the minute.                                  |

//+------------------------------------------------------------------+

void SaveLastSignal()

  {

   GlobalVariableSet(LastSignalGVName(), (double)TimeCurrent());

  }

 

 

//+------------------------------------------------------------------+

//| Official RiskGuard signal function - Config. 2                   |

//|                                                                  |

//| pendingPrice = 0.0  -> market order                              |

//| pendingPrice > 0.0  -> pending order                             |

//|                                                                  |

//| DO NOT MODIFY THIS FUNCTION.                                     |

//| This function must remain identical in all RiskGuard-compatible  |

//| indicators.                                                      |

//+------------------------------------------------------------------+

void SendRiskGuardConfig2Signal(double stopPrice,

                         double takePrice,

                         double pendingPrice = 0.0)

  {

   //--- Always delete old RiskGuard variables first

   GlobalVariableDel("RG_Strategy_Config2_Symbol_" + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Stop_"   + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Take_"   + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Price_"  + _Symbol);

 

   //--- Normalize prices

   stopPrice = NormalizeDouble(stopPrice, _Digits);

   takePrice = NormalizeDouble(takePrice, _Digits);

 

   if(pendingPrice > 0.0)

      pendingPrice = NormalizeDouble(pendingPrice, _Digits);

 

   bool isPending = (pendingPrice > 0.0);

 

   //--- Create variables in the correct order

   GlobalVariableSet("RG_Strategy_Config2_Stop_" + _Symbol, stopPrice);

   GlobalVariableSet("RG_Strategy_Config2_Take_" + _Symbol, takePrice);

 

   if(isPending)

      GlobalVariableSet("RG_Strategy_Config2_Price_" + _Symbol, pendingPrice);

 

   //--- RG_Strategy_Symbol must always be created last

   GlobalVariableSet("RG_Strategy_Config2_Symbol_" + _Symbol, 1);

 

   //--- Log

   if(isPending)

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][SIGNAL] Pending signal variables created",

            " | Symbol=", _Symbol,

            " | Stop=", DoubleToString(stopPrice, _Digits),

            " | Take=", DoubleToString(takePrice, _Digits),

            " | Price=", DoubleToString(pendingPrice, _Digits),

            " | Bid=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits),

            " | Ask=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));

     }

   else

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][SIGNAL] Market signal variables created",

            " | Symbol=", _Symbol,

            " | Stop=", DoubleToString(stopPrice, _Digits),

            " | Take=", DoubleToString(takePrice, _Digits),

            " | Bid=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits),

            " | Ask=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));

     }

  }

 

 

//+------------------------------------------------------------------+

//| OnInit                                                           |

//+------------------------------------------------------------------+

int OnInit()

  {

   Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][OnInit] Indicator started",

         " | Symbol=", _Symbol);

 

   return(INIT_SUCCEEDED);

  }

 

 

//+------------------------------------------------------------------+

//| OnDeinit                                                         |

//+------------------------------------------------------------------+

//| Do not delete LastSignal during timeframe changes.               |

//| Otherwise the same signal could be generated again after reload. |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

   if(reason == REASON_REMOVE)

     {

      GlobalVariableDel(LastSignalGVName());

 

      Print("[", MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][OnDeinit] Indicator manually removed",

            " | Symbol=", _Symbol,

            " | LastSignalGV deleted");

     }

  }

 

 

//+------------------------------------------------------------------+

//| OnCalculate                                                      |

//+------------------------------------------------------------------+

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[])

  {

   MqlDateTime tm;

   TimeToStruct(TimeCurrent(), tm);

 

   //--- This example uses broker/server time.

   if(tm.hour != SignalHour || tm.min != SignalMinute)

      return(rates_total);

 

   //--- Prevent duplicate signals in the same server minute.

   if(SignalAlreadySentThisMinute())

      return(rates_total);

 

   //--- The current Bid price is used as reference price.

   double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

 

   if(price <= 0.0)

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][ERROR] Invalid price",

            " | Symbol=", _Symbol);

      return(rates_total);

     }

 

   double stopPrice;

   double takePrice;

   double pendingPrice = 0.0;

 

   //--- Pending order example.

   if(PriceDistancePoints > 0)

     {

      pendingPrice = price + PriceDistancePoints * _Point;

 

      stopPrice = pendingPrice - StopDistancePoints * _Point;

      takePrice = pendingPrice + TakeDistancePoints * _Point;

 

      SendRiskGuardConfig2Signal(stopPrice, takePrice, pendingPrice);

     }

 

   //--- Market order example.

   else

     {

      stopPrice = price - StopDistancePoints * _Point;

      takePrice = price + TakeDistancePoints * _Point;

 

      SendRiskGuardConfig2Signal(stopPrice, takePrice);

     }

 

   //--- Save only after the RiskGuard variables have been created.

   SaveLastSignal();

 

   return(rates_total);

  }

//+------------------------------------------------------------------+

Esempio 2 — RiskGuard_ORB.mq5
 

Indicatore di esempio avanzato basato su strategia ORB (Opening Range Breakout).

​

L’indicatore calcola un range orario definito dall’utente, disegna il box sul grafico e genera un segnale quando una candela chiusa rompe il range verso l’alto o verso il basso.

​

Questo esempio mostra una struttura più realistica e vicina a una strategia automatica completa.

​

Funzioni principali:

​

  • Calcolo automatico del range ORB

  • Disegno del box direttamente sul grafico

  • Rilevazione breakout BUY e SELL su chiusura candela

  • Supporto ordini a mercato o pendenti

  • Calcolo dei prezzi di Stop Loss e Take Profit in base al rapporto Risk:Reward

  • Protezione da segnali duplicati

  • Protezione da segnali retroattivi

  • Protezione da cambio timeframe

  • Rilevazione ordini Strategy tramite Magic Number 30032999

​

Questo esempio è consigliato per sviluppatori che vogliono costruire strategie più complesse compatibili con RiskGuard.

​

//+------------------------------------------------------------------+

//|                                      RiskGuard_ORB_Example.mq5   |

//|                                                                  |

//| Example indicator for RiskGuard Strategy Mode - Config. 2        |

//|                                                                  |

//| This indicator does NOT open trades directly.                    |

//| It only sends market or pending signals to RiskGuard using the   |

//| official RiskGuard Config. 2 protocol.                           |

//|                                                                  |

//| RiskGuard manages the order, lot size, risk, Stop Loss,           |

//| Take Profit, Break Even, partial profits, trailing stop,          |

//| daily loss limits, Quantum and all other trading operations.      |

//+------------------------------------------------------------------+

#property strict

#property indicator_chart_window

#property indicator_plots 0

 

 

//+------------------------------------------------------------------+

//| Strategy inputs                                                  |

//+------------------------------------------------------------------+

input int RangeStartHour   = 6;   // ORB range start hour

input int RangeStartMinute = 0;   // ORB range start minute

 

input int RangeEndHour     = 11;  // ORB range end hour

input int RangeEndMinute   = 0;   // ORB range end minute

 

input ENUM_TIMEFRAMES BreakoutTimeframe = PERIOD_M1; // Breakout detection timeframe

 

input double EntryPercent = 0.0;  // 0 = market, 50 = pending at 50% of the box

input double RiskReward   = 2.0;  // Take Profit expressed as Risk:Reward ratio

 

input color BoxColor = clrDodgerBlue; // ORB box color

 

 

//+------------------------------------------------------------------+

//| Internal variables                                               |

//+------------------------------------------------------------------+

datetime IndicatorLoadTime = 0;

datetime LastBreakoutBarTime = 0;

 

bool ActivityDetectedAfterSignal = false;

bool ShowGraphics = true;

 

 

//+------------------------------------------------------------------+

//| Official RiskGuard signal function - Config. 2                   |

//|                                                                  |

//| pendingPrice = 0.0  -> market order                              |

//| pendingPrice > 0.0  -> pending order                             |

//|                                                                  |

//| DO NOT MODIFY THIS FUNCTION.                                     |

//| This function must remain identical in all RiskGuard-compatible  |

//| indicators.                                                      |

//+------------------------------------------------------------------+

void SendRiskGuardConfig2Signal(double stopPrice,

                         double takePrice,

                         double pendingPrice = 0.0)

  {

   //--- Always delete old RiskGuard variables first

   GlobalVariableDel("RG_Strategy_Config2_Symbol_" + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Stop_"   + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Take_"   + _Symbol);

   GlobalVariableDel("RG_Strategy_Config2_Price_"  + _Symbol);

 

   //--- Normalize prices

   stopPrice = NormalizeDouble(stopPrice, _Digits);

   takePrice = NormalizeDouble(takePrice, _Digits);

 

   if(pendingPrice > 0.0)

      pendingPrice = NormalizeDouble(pendingPrice, _Digits);

 

   bool isPending = (pendingPrice > 0.0);

 

   //--- Create variables in the correct order

   GlobalVariableSet("RG_Strategy_Config2_Stop_" + _Symbol, stopPrice);

   GlobalVariableSet("RG_Strategy_Config2_Take_" + _Symbol, takePrice);

 

   if(isPending)

      GlobalVariableSet("RG_Strategy_Config2_Price_" + _Symbol, pendingPrice);

 

   //--- RG_Strategy_Symbol must always be created last

   GlobalVariableSet("RG_Strategy_Config2_Symbol_" + _Symbol, 1);

 

   //--- Log

   if(isPending)

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][SIGNAL] Pending signal variables created",

            " | Symbol=", _Symbol,

            " | Stop=", DoubleToString(stopPrice, _Digits),

            " | Take=", DoubleToString(takePrice, _Digits),

            " | Price=", DoubleToString(pendingPrice, _Digits),

            " | Bid=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits),

            " | Ask=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));

     }

   else

     {

      Print("[", MQLInfoString(MQL_PROGRAM_NAME), "][INDICATOR][SIGNAL] Market signal variables created",

            " | Symbol=", _Symbol,

            " | Stop=", DoubleToString(stopPrice, _Digits),

            " | Take=", DoubleToString(takePrice, _Digits),

            " | Bid=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits),

            " | Ask=", DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));

     }

  }

 

 

//+------------------------------------------------------------------+

//| Returns a numeric key for the trading day                        |

//+------------------------------------------------------------------+

int DayKey(datetime timeValue)

  {

   MqlDateTime dateTime;

   TimeToStruct(timeValue, dateTime);

 

   return(dateTime.year * 10000 +

          dateTime.mon  * 100 +

          dateTime.day);

  }

 

 

//+------------------------------------------------------------------+

//| Builds today's broker/server time                                |

//+------------------------------------------------------------------+

datetime TodayTime(int hour, int minute)

  {

   MqlDateTime dateTime;

   TimeToStruct(TimeCurrent(), dateTime);

 

   dateTime.hour = hour;

   dateTime.min  = minute;

   dateTime.sec  = 0;

 

   return(StructToTime(dateTime));

  }

 

 

//+------------------------------------------------------------------+

//| Internal Global Variable used for duplicate protection           |

//|                                                                  |

//| This is NOT a RiskGuard trade signal.                            |

//|                                                                  |

//| It remembers that the ORB signal for the current day has already |

//| been sent. It must remain available during timeframe changes,    |

//| input changes, refreshes and indicator reinitializations.         |

//+------------------------------------------------------------------+

string LastSignalGVName()

  {

   return("RiskGuard_ORB_LastSignal_" +

          MQLInfoString(MQL_PROGRAM_NAME) +

          "_" +

          _Symbol);

  }

 

 

//+------------------------------------------------------------------+

//| Checks if today's ORB signal has already been sent               |

//+------------------------------------------------------------------+

bool AlreadySentToday()

  {

   string globalVariableName = LastSignalGVName();

 

   if(!GlobalVariableCheck(globalVariableName))

      return(false);

 

   int savedDay = (int)GlobalVariableGet(globalVariableName);

 

   return(savedDay == DayKey(TimeCurrent()));

  }

 

 

//+------------------------------------------------------------------+

//| Saves today's ORB signal status                                  |

//+------------------------------------------------------------------+

void SaveSignalToday()

  {

   GlobalVariableSet(LastSignalGVName(),

                     (double)DayKey(TimeCurrent()));

  }

 

 

//+------------------------------------------------------------------+

//| Returns today's ORB box name                                     |

//+------------------------------------------------------------------+

string BoxName()

  {

   return("RiskGuard_ORB_Box_" +

          MQLInfoString(MQL_PROGRAM_NAME) +

          "_" +

          _Symbol +

          "_" +

          IntegerToString(DayKey(TimeCurrent())));

  }

 

 

//+------------------------------------------------------------------+

//| Deletes today's ORB box                                          |

//+------------------------------------------------------------------+

void DeleteBox()

  {

   if(!ShowGraphics)

      return;

 

   ObjectDelete(0, BoxName());

  }

 

 

//+------------------------------------------------------------------+

//| Deletes ORB boxes belonging to previous days                     |

//+------------------------------------------------------------------+

void DeleteOldBoxes()

  {

   if(!ShowGraphics)

      return;

 

   string prefix =

      "RiskGuard_ORB_Box_" +

      MQLInfoString(MQL_PROGRAM_NAME) +

      "_" +

      _Symbol +

      "_";

 

   string today = IntegerToString(DayKey(TimeCurrent()));

 

   int totalObjects = ObjectsTotal(0);

 

   for(int i = totalObjects - 1; i >= 0; i--)

     {

      string objectName = ObjectName(0, i);

 

      if(StringFind(objectName, prefix) != 0)

         continue;

 

      if(StringFind(objectName, today) >= 0)

         continue;

 

      ObjectDelete(0, objectName);

     }

  }

 

 

//+------------------------------------------------------------------+

//| Checks RiskGuard Strategy positions and pending orders           |

//|                                                                  |

//| RiskGuard Config. 2 Strategy orders use Magic Number 30032999.   |

//+------------------------------------------------------------------+

bool HasRiskGuardStrategyPositionOrOrder()

  {

   const long strategyMagic = 30032999;

 

   for(int i = PositionsTotal() - 1; i >= 0; i--)

     {

      string positionSymbol = PositionGetSymbol(i);

 

      if(positionSymbol != _Symbol)

         continue;

 

      long positionMagic = PositionGetInteger(POSITION_MAGIC);

 

      if(positionMagic == strategyMagic)

         return(true);

     }

 

   for(int i = OrdersTotal() - 1; i >= 0; i--)

     {

      ulong ticket = OrderGetTicket(i);

 

      if(ticket == 0)

         continue;

 

      string orderSymbol = OrderGetString(ORDER_SYMBOL);

 

      if(orderSymbol != _Symbol)

         continue;

 

      long orderMagic = OrderGetInteger(ORDER_MAGIC);

 

      if(orderMagic == strategyMagic)

         return(true);

     }

 

   return(false);

  }

 

 

//+------------------------------------------------------------------+

//| Calculates today's ORB range                                     |

//+------------------------------------------------------------------+

bool GetOrbRange(double &rangeHigh,

                 double &rangeLow)

  {

   datetime startTime =

      TodayTime(RangeStartHour, RangeStartMinute);

 

   datetime endTime =

      TodayTime(RangeEndHour, RangeEndMinute);

 

   if(endTime <= startTime)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] Invalid ORB time range",

            " | Start=",

            TimeToString(startTime, TIME_DATE | TIME_MINUTES),

            " | End=",

            TimeToString(endTime, TIME_DATE | TIME_MINUTES));

 

      return(false);

     }

 

   MqlRates rangeRates[];

   ArraySetAsSeries(rangeRates, false);

 

   int copiedBars =

      CopyRates(_Symbol,

                BreakoutTimeframe,

                startTime,

                endTime,

                rangeRates);

 

   if(copiedBars <= 0)

      return(false);

 

   rangeHigh = rangeRates[0].high;

   rangeLow  = rangeRates[0].low;

 

   for(int i = 1; i < copiedBars; i++)

     {

      if(rangeRates[i].high > rangeHigh)

         rangeHigh = rangeRates[i].high;

 

      if(rangeRates[i].low < rangeLow)

         rangeLow = rangeRates[i].low;

     }

 

   rangeHigh = NormalizeDouble(rangeHigh, _Digits);

   rangeLow  = NormalizeDouble(rangeLow, _Digits);

 

   if(rangeHigh <= rangeLow)

      return(false);

 

   return(true);

  }

 

 

//+------------------------------------------------------------------+

//| Creates or updates today's ORB box                               |

//+------------------------------------------------------------------+

void DrawBox(double rangeHigh,

             double rangeLow)

  {

   if(!ShowGraphics)

      return;

 

   datetime startTime =

      TodayTime(RangeStartHour, RangeStartMinute);

 

   datetime endTime =

      TodayTime(RangeEndHour, RangeEndMinute);

 

   string objectName = BoxName();

 

   if(ObjectFind(0, objectName) < 0)

     {

      if(!ObjectCreate(0,

                       objectName,

                       OBJ_RECTANGLE,

                       0,

                       startTime,

                       rangeHigh,

                       endTime,

                       rangeLow))

        {

         Print("[",

               MQLInfoString(MQL_PROGRAM_NAME),

               "][INDICATOR][ERROR] Unable to create ORB box",

               " | Error=",

               GetLastError());

 

         return;

        }

 

      ObjectSetInteger(0, objectName, OBJPROP_COLOR, BoxColor);

      ObjectSetInteger(0, objectName, OBJPROP_BACK, true);

      ObjectSetInteger(0, objectName, OBJPROP_FILL, false);

      ObjectSetInteger(0, objectName, OBJPROP_WIDTH, 1);

      ObjectSetInteger(0, objectName, OBJPROP_SELECTABLE, false);

      ObjectSetInteger(0, objectName, OBJPROP_HIDDEN, true);

     }

   else

     {

      ObjectMove(0,

                 objectName,

                 0,

                 startTime,

                 rangeHigh);

 

      ObjectMove(0,

                 objectName,

                 1,

                 endTime,

                 rangeLow);

     }

  }

 

 

//+------------------------------------------------------------------+

//| Validates the strategy inputs                                    |

//+------------------------------------------------------------------+

bool ValidateInputs()

  {

   if(RangeStartHour < 0 || RangeStartHour > 23)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] Invalid RangeStartHour");

 

      return(false);

     }

 

   if(RangeEndHour < 0 || RangeEndHour > 23)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] Invalid RangeEndHour");

 

      return(false);

     }

 

   if(RangeStartMinute < 0 || RangeStartMinute > 59)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] Invalid RangeStartMinute");

 

      return(false);

     }

 

   if(RangeEndMinute < 0 || RangeEndMinute > 59)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] Invalid RangeEndMinute");

 

      return(false);

     }

 

   if(RiskReward <= 0.0)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] RiskReward must be greater than zero");

 

      return(false);

     }

 

   datetime startTime =

      TodayTime(RangeStartHour, RangeStartMinute);

 

   datetime endTime =

      TodayTime(RangeEndHour, RangeEndMinute);

 

   if(endTime <= startTime)

     {

      Print("[",

            MQLInfoString(MQL_PROGRAM_NAME),

            "][INDICATOR][ERROR] Range end time must be later than range start time");

 

      return(false);

     }

 

   return(true);

  }

 

 

//+------------------------------------------------------------------+

//| OnInit                                                           |

//+------------------------------------------------------------------+

int OnInit()

  {

   IndicatorLoadTime = TimeCurrent();

   LastBreakoutBarTime = 0;

   ActivityDetectedAfterSignal = false;

 

   ShowGraphics = true;

 

   if(MQLInfoInteger(MQL_TESTER) &&

      !MQLInfoInteger(MQL_VISUAL_MODE))

     {

      ShowGraphics = false;

     }

 

   if(!ValidateInputs())

      return(INIT_PARAMETERS_INCORRECT);

 

   Print("[",

         MQLInfoString(MQL_PROGRAM_NAME),

         "][INDICATOR][OnInit] ORB indicator started",

         " | Symbol=",

         _Symbol,

         " | BreakoutTimeframe=",

         EnumToString(BreakoutTimeframe),

         " | ShowGraphics=",

         ShowGraphics ? "true" : "false",

         " | LoadTime=",

         TimeToString(IndicatorLoadTime,

                      TIME_DATE | TIME_SECONDS));

 

   return(INIT_SUCCEEDED);

  }

 

 

//+------------------------------------------------------------------+

//| OnDeinit                                                         |

//|                                                                  |

//| The duplicate-protection Global Variable is not deleted during   |

//| timeframe changes, input changes or other reinitializations.      |

//|                                                                  |

//| It is deleted only when the indicator is manually removed.       |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

   if(reason == REASON_REMOVE)

     {

      GlobalVariableDel(LastSignalGVName());

 

      if(ShowGraphics)

         DeleteBox();

     }

 

   Print("[",

         MQLInfoString(MQL_PROGRAM_NAME),

         "][INDICATOR][OnDeinit] ORB indicator stopped",

         " | Symbol=",

         _Symbol,

         " | Reason=",

         reason);

  }

 

 

//+------------------------------------------------------------------+

//| OnCalculate                                                      |

//|                                                                  |

//| Main workflow:                                                   |

//|                                                                  |

//| 1. Wait until the ORB range is completed.                        |

//| 2. Calculate the ORB high and low.                               |

//| 3. Draw the box only when graphics are enabled.                  |

//| 4. Detect a breakout using a closed candle.                      |

//| 5. Calculate Stop Loss and Take Profit.                          |

//| 6. Send the signal to RiskGuard.                                 |

//| 7. Save the daily duplicate-protection status.                   |

//+------------------------------------------------------------------+

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(ShowGraphics)

      DeleteOldBoxes();

 

   datetime now = TimeCurrent();

 

   datetime endTime =

      TodayTime(RangeEndHour, RangeEndMinute);

 

   //--- Wait until the ORB range is completed.

   if(now < endTime)

      return(rates_total);

 

   double rangeHigh = 0.0;

   double rangeLow  = 0.0;

 

   if(!GetOrbRange(rangeHigh, rangeLow))

      return(rates_total);

 

   bool signalAlreadySent = AlreadySentToday();

 

   //--- Draw the box only in live use or visual backtests.

   if(ShowGraphics && !signalAlreadySent)

      DrawBox(rangeHigh, rangeLow);

 

   //--- Manage the box after a signal has already been sent.

   if(signalAlreadySent)

     {

      bool hasStrategyActivity =

         HasRiskGuardStrategyPositionOrOrder();

 

      if(hasStrategyActivity)

         ActivityDetectedAfterSignal = true;

 

      if(ShowGraphics &&

         ActivityDetectedAfterSignal &&

         !hasStrategyActivity)

        {

         DeleteBox();

        }

 

      return(rates_total);

     }

 

   //--- Prevent retroactive signals.

   //--- If the indicator is loaded today after the range has ended,

   //--- no breakout that occurred before loading may be recovered.

   if(DayKey(IndicatorLoadTime) == DayKey(now) &&

      IndicatorLoadTime > endTime)

     {

      return(rates_total);

     }

 

   MqlRates breakoutRates[];

   ArraySetAsSeries(breakoutRates, true);

 

   int copiedBars =

      CopyRates(_Symbol,

                BreakoutTimeframe,

                0,

                3,

                breakoutRates);

 

   if(copiedBars < 3)

      return(rates_total);

 

   //--- Use only the last closed candle.

   datetime closedBarTime = breakoutRates[1].time;

 

   //--- Process each closed candle only once.

   if(closedBarTime == LastBreakoutBarTime)

      return(rates_total);

 

   LastBreakoutBarTime = closedBarTime;

 

   //--- Ignore candles closed before completion of the ORB range.

   if(closedBarTime < endTime)

      return(rates_total);

 

   double barClose = breakoutRates[1].close;

   double boxSize  = rangeHigh - rangeLow;

 

   if(boxSize <= 0.0)

      return(rates_total);

 

   double normalizedEntryPercent = EntryPercent;

 

   if(normalizedEntryPercent < 0.0)

      normalizedEntryPercent = 0.0;

 

   if(normalizedEntryPercent > 99.0)

      normalizedEntryPercent = 99.0;

 

   double ask =

      SymbolInfoDouble(_Symbol, SYMBOL_ASK);

 

   double bid =

      SymbolInfoDouble(_Symbol, SYMBOL_BID);

 

   if(ask <= 0.0 || bid <= 0.0)

      return(rates_total);

 

 

   //+---------------------------------------------------------------+

   //| BUY breakout                                                  |

   //+---------------------------------------------------------------+

   if(barClose > rangeHigh)

     {

      double stopPrice    = 0.0;

      double takePrice    = 0.0;

      double pendingPrice = 0.0;

 

      //--- Market BUY signal.

      if(normalizedEntryPercent <= 0.0)

        {

         stopPrice = rangeLow;

 

         double riskDistance = ask - stopPrice;

 

         if(riskDistance <= 0.0)

            return(rates_total);

 

         takePrice =

            ask + riskDistance * RiskReward;

 

         SendRiskGuardConfig2Signal(stopPrice,

                                    takePrice);

        }

 

      //--- Pending BUY signal inside the ORB box.

      else

        {

         pendingPrice =

            rangeHigh -

            boxSize *

            normalizedEntryPercent /

            100.0;

 

         stopPrice = rangeLow;

 

         double riskDistance =

            pendingPrice - stopPrice;

 

         if(riskDistance <= 0.0)

            return(rates_total);

 

         takePrice =

            pendingPrice +

            riskDistance *

            RiskReward;

 

         SendRiskGuardConfig2Signal(stopPrice,

                                    takePrice,

                                    pendingPrice);

        }

 

      //--- Save only after the RiskGuard signal variables exist.

      SaveSignalToday();

 

      return(rates_total);

     }

 

 

   //+---------------------------------------------------------------+

   //| SELL breakout                                                 |

   //+---------------------------------------------------------------+

   if(barClose < rangeLow)

     {

      double stopPrice    = 0.0;

      double takePrice    = 0.0;

      double pendingPrice = 0.0;

 

      //--- Market SELL signal.

      if(normalizedEntryPercent <= 0.0)

        {

         stopPrice = rangeHigh;

 

         double riskDistance =

            stopPrice - bid;

 

         if(riskDistance <= 0.0)

            return(rates_total);

 

         takePrice =

            bid -

            riskDistance *

            RiskReward;

 

         SendRiskGuardConfig2Signal(stopPrice,

                                    takePrice);

        }

 

      //--- Pending SELL signal inside the ORB box.

      else

        {

         pendingPrice =

            rangeLow +

            boxSize *

            normalizedEntryPercent /

            100.0;

 

         stopPrice = rangeHigh;

 

         double riskDistance =

            stopPrice - pendingPrice;

 

         if(riskDistance <= 0.0)

            return(rates_total);

 

         takePrice =

            pendingPrice -

            riskDistance *

            RiskReward;

 

         SendRiskGuardConfig2Signal(stopPrice,

                                    takePrice,

                                    pendingPrice);

        }

 

      //--- Save only after the RiskGuard signal variables exist.

      SaveSignalToday();

 

      return(rates_total);

     }

 

   return(rates_total);

  }

//+------------------------------------------------------------------+

bottom of page