#property description "L'indicatore analizza i dati per l'ultimo mese e disegna tutte le candele con piccoli"
#property description "e larghi volumi tick. L'array volume tick è stato ordinato"
#property description "per definire tali candele. Le candele hanno i volumi che compongono il primo InpSmallVolume "
#property description "percentuale dell'array è considerata piccola. Le candle hanno i volumi tick che compongono"
#property description "l'ultima InpBigVolume percentuale dell'array sono considerate grandi."
//--- impostazioni indicatore
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//--- plot
#property indicator_label1 "VolumeFactor"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrDodgerBlue,clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- costanti predefinite
#define INDICATOR_EMPTY_VALUE 0.0
//--- parametri di input
input int InpSmallVolume=15; // Valore percentuale di volumi piccoli (<50)
input int InpBigVolume=20; // Valore percentuale di volumi grandi (>50)
//--- orario di inizio analisi (verrà slittato)
datetime ExtStartTime;
//--- buffers indicatore
double ExtOpenBuff[];
double ExtHighBuff[];
double ExtLowBuff[];
double ExtCloseBuff[];
double ExtColorBuff[];
//--- valori limite di volume per la visualizzazione delle candele
long ExtLeftBorder=0;
long ExtRightBorder=0;
//+--------------------------------------------------------------------------------+
//| Riceve i valori limite per i volumi tick |
//+--------------------------------------------------------------------------------+
bool GetVolumeBorders(void)
{
//--- variabili
datetime stop_time; // orario di fine della copia
long buff[]; // buffer per la copia
//--- l'orario di fine è quello corrente
stop_time=TimeCurrent();
//--- l'orario d'inizio è un mese prima di quello corrente
ExtStartTime=GetStartTime(stop_time);
//--- riceve i valori dei volumi tick
ResetLastError();
if(CopyTickVolume(Symbol(),Period(),ExtStartTime,stop_time,buff)==-1)
{
//--- fallimento nel ricevere i dati, restituizioe false per lanciare il comando di ricalcolo
PrintFormat("Fallimento nel ricevere i valori dei volumi tick. Codice Errore = %d",GetLastError());
return(false);
}
//--- calcola la grandezza dell'array
int size=ArraySize(buff);
//--- ordina l'array
ArraySort(buff);
//--- definisce i valori dei bordi sinistro e destro per i volumi tick
ExtLeftBorder=buff[size*InpSmallVolume/100];
ExtRightBorder=buff[(size-1)*(100-InpBigVolume)/100];
//--- esecuzione avvenuta
return(true);
}
//+--------------------------------------------------------------------------------+
//| Riceve i dati che sono di un mese in meno rispetto a quello passato |
//+--------------------------------------------------------------------------------+
datetime GetStartTime(const datetime stop_time)
{
//--- converte l'orario finale in tipo variabile di struttura MqlDateTime
MqlDateTime temp;
TimeToStruct(stop_time,temp);
//--- riceve i dati che sono un mese in meno
if(temp.mon>1)
temp.mon-=1; // il mese corrente non è il primo dell'anno, quindi, il numero di quello precedente è uno in meno
else
{
temp.mon=12; // il mese corrente è il primo dell'anno, quindi, il numero di quello precedente è 12,
temp.year-=1; // mentre il numero dell'anno è uno in meno
}
//--- il numero del giorno non eccederà 28
if(temp.day>28)
temp.day=28;
//--- restituisce la data ottenuta
return(StructToTime(temp));
}
//+--------------------------------------------------------------------------------+
//| Funzione di inizializzazione Indicatore Personalizzato |
//+--------------------------------------------------------------------------------+
int OnInit()
{
//--- controlla se i parametri di input soddisfano le condizioni
if(InpSmallVolume<0 || InpSmallVolume>=50 || InpBigVolume<0 || InpBigVolume>=50)
{
Print("Parametri di input non corretti");
return(INIT_PARAMETERS_INCORRECT);
}
//--- mappatura buffers indicatore
SetIndexBuffer(0,ExtOpenBuff);
SetIndexBuffer(1,ExtHighBuff);
SetIndexBuffer(2,ExtLowBuff);
SetIndexBuffer(3,ExtCloseBuff);
SetIndexBuffer(4,ExtColorBuff,INDICATOR_COLOR_INDEX);
//--- imposta il valore che non verrà visualizzato
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- imposta le etichette per i buffer indicatore
PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
return(INIT_SUCCEEDED);
}
//+--------------------------------------------------------------------------------+
//| Funzione di iterazione indicatore personalizato |
//+--------------------------------------------------------------------------------+
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[])
{
//--- controlla se le barre non gestite sono ancora presenti
if(prev_calculated<rates_total)
{
//--- riceve nuovi valori dei bordi destro e sinistro per i volumi
if(!GetVolumeBorders())
return(0);
}
//--- variabile di inizio per il calcolo della barra
int start=prev_calculated;
//--- lavora all'ultima barra se i valori degli indicatori sono già stati calcolati al tick precedente
if(start>0)
start--;
//--- imposta l'indicizzazione nelle timeseries
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
ArraySetAsSeries(tick_volume,false);
//--- il loop di calcolo dei valori dell'indicatore
for(int i=start;i<rates_total;i++)
{
//--- riempie le candele partendo dalla data iniziale
if(ExtStartTime<=time[i])
{
//--- se il valore non è inferiore a quello del bordo destro, riempie la candela
if(tick_volume[i]>=ExtRightBorder)
{
//--- riceve i dati per il disegno della candela
ExtOpenBuff[i]=open[i];
ExtHighBuff[i]=high[i];
ExtLowBuff[i]=low[i];
ExtCloseBuff[i]=close[i];
//--- colore DodgerBlue
ExtColorBuff[i]=0;
//--- continua il loop
continue;
}
//--- riempie la candela se il valore non supera quello del bordo sinistro
if(tick_volume[i]<=ExtLeftBorder)
{
//--- riceve i dati per il disegno della candela
ExtOpenBuff[i]=open[i];
ExtHighBuff[i]=high[i];
ExtLowBuff[i]=low[i];
ExtCloseBuff[i]=close[i];
//--- Colore Orange
ExtColorBuff[i]=1;
//--- continua il loop
continue;
}
}
//--- imposta valori vuoti per le barre che non sono state incluse nel calcolo
ExtOpenBuff[i]=INDICATOR_EMPTY_VALUE;
ExtHighBuff[i]=INDICATOR_EMPTY_VALUE;
ExtLowBuff[i]=INDICATOR_EMPTY_VALUE;
ExtCloseBuff[i]=INDICATOR_EMPTY_VALUE;
}
//--- restituisce il valore di prev_calculated per la prossima chiamata
return(rates_total);
}
|