557 lines
45 KiB
MQL5
557 lines
45 KiB
MQL5
// ha dentro ichimoku, medie, atr
|
|
//+------------------------------------------------------------------
|
|
#property copyright "© KKxFF, 2020"
|
|
//#property link "mladenfx@gmail.com"
|
|
#property description "Strategy"
|
|
//+------------------------------------------------------------------
|
|
#property indicator_chart_window // l'indicatore sta nella stessa finestra delle candele'
|
|
#property indicator_buffers 17 // predispongo 17 buffer per i dati di memoria per l'indicatore'
|
|
#property indicator_plots 9 // quante cose disegno sul grafico (linee, riempimenti...)
|
|
|
|
// 3 buffer per ichimoku (due linee e riempimento)
|
|
|
|
//EMA media a (50) periodi
|
|
#property indicator_label1 "EMA_A" // etichetta sul grafico
|
|
#property indicator_type1 DRAW_COLOR_LINE // segnalo che e' una linea'
|
|
#property indicator_color1 clrDeepSkyBlue, clrDeepSkyBlue //color contiene una lista di colori che deve avere la linea.
|
|
// in questo caso ha due colori nel caso per esigenze di codice lo volessimo cambiare
|
|
#property indicator_style1 STYLE_SOLID // tratteggio, puntini...
|
|
#property indicator_width1 2 // ampiezza
|
|
|
|
//EMA
|
|
#property indicator_label2 "EMA_B"
|
|
#property indicator_type2 DRAW_COLOR_LINE
|
|
#property indicator_color2 clrOrange, clrOrange
|
|
#property indicator_style2 STYLE_SOLID
|
|
#property indicator_width2 2
|
|
|
|
//Ichimoku
|
|
#property indicator_label3 "Tenkan-sen"
|
|
#property indicator_type3 DRAW_LINE // segnalo che e' una linea' [potrebbero essere simili]
|
|
#property indicator_color3 clrNONE // colore speciale che mi permette di identificare una linea trasparente
|
|
|
|
#property indicator_label4 "Kijun-sen"
|
|
#property indicator_type4 DRAW_LINE
|
|
#property indicator_color4 clrNONE
|
|
|
|
#property indicator_label5 "Senkou Span A;Senkou Span B"
|
|
#property indicator_type5 DRAW_FILLING //riempimento tra le due linee senza contorno
|
|
#property indicator_color5 SandyBrown, Thistle
|
|
|
|
#property indicator_label6 "Chikou Span"
|
|
#property indicator_type6 DRAW_LINE
|
|
#property indicator_color6 clrNONE
|
|
|
|
#property indicator_label7 "Asian session High; Asian session Low"
|
|
#property indicator_type7 DRAW_FILLING
|
|
#property indicator_color7 MistyRose
|
|
#property indicator_style7 STYLE_SOLID
|
|
#property indicator_width7 1
|
|
|
|
//trigger buy
|
|
#property indicator_label8 "TriggerBuy"
|
|
#property indicator_type8 DRAW_COLOR_ARROW // pallini per indicare il segnale di sell e di buy
|
|
#property indicator_color8 clrGreen, clrRed //verde compra, rosso vendi
|
|
#property indicator_style8 STYLE_SOLID
|
|
#property indicator_width8 10
|
|
|
|
// input tipoDiDato nomeVariabile = valoreIniziale // con input significa che posso modificare da GUI
|
|
//EMA1 & EMA2
|
|
input int inpPeriodA = 50; // Period
|
|
|
|
// mi permette di identificare il prezzo, da ora si chiamerà inpPrice
|
|
// dal pdv del GUI, l'utente può decidere se prendere HLOC
|
|
// dal pdv dello script, si fanno i calcoli con il dato selezionato'
|
|
input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price
|
|
input int inpPeriodB = 169; // Period
|
|
|
|
// buffer per tenere i dati delle due medie
|
|
double valA[], valcA[];
|
|
double valB[], valcB[];
|
|
|
|
//Ichimoku
|
|
input int InpTenkan = 24; // Tenkan-sen
|
|
input int InpKijun = 60; // Kijun-sen
|
|
input int InpSenkou = 180; // Senkou Span B
|
|
input int InpCloudOffset = 40; // Cloud offset
|
|
|
|
// vettori dinamici in cui lo spazio non è ancora allocato. Servono per il grafico
|
|
double ExtTenkanBuffer[];
|
|
double ExtKijunBuffer[];
|
|
double ExtSpanABuffer[];
|
|
double ExtSpanBBuffer[];
|
|
double ExtChikouBuffer[];
|
|
|
|
//Asia session
|
|
input int InpAsianMaxDelta = 16; // massima altezza in pips dell'asiatica
|
|
|
|
//Calcolo delle medie
|
|
input int lunghezzaMedia = 20; // ampiezza della media per i volumi
|
|
|
|
double AsiaHigh[];
|
|
double AsiaLow[];
|
|
|
|
// Time constants are specified across Greenwich
|
|
// si tiene conto anche del cambio d'ora
|
|
const int AsiaOpen = 0;
|
|
const int AsiaClose = 5;
|
|
const int AsiaOpenSummertime = 1; // The Asian session shifts
|
|
const int AsiaCloseSummertime = 7; // after the time changes
|
|
|
|
// variabili temporanee per i conti dell'asiatica'
|
|
int ShiftTime; //Displacement of the buffer for construction of the future sessions
|
|
double HighForFutureSession; // High for the future session
|
|
double LowForFutureSession; // Low for the future session
|
|
|
|
//buy trigger
|
|
// ushort=16bit interi senza segno
|
|
input ushort code = 159; // Symbol code to draw in DRAW_ARROW
|
|
double ColorArrowBuffer[]; //indica dove va posizionato il pallino
|
|
double triggerColorIndex[]; // indica il colore del pallino
|
|
// lavora con i double anche se sono array
|
|
|
|
//signal window
|
|
input string InpStartTime = "06:00"; // Do not trade before (server time)...
|
|
input string InpEndTime = "16:15"; // Do not trade after (server time)...
|
|
|
|
// conversione dei tempi in secondi
|
|
datetime startTrading = StringToTime(InpStartTime) % 86400; //secondi in un giorno
|
|
datetime stopTrading = StringToTime(InpEndTime) % 86400;
|
|
|
|
//trigger buy
|
|
int OnInit() //metodo che si esegue all'accensione dello script'
|
|
{ // int come il main di C che deve restituire 0
|
|
|
|
// IndicatorSetString permette di modificare i vari parametri
|
|
// IndicatorSetString(parametroDaModificare, nuovoValore)
|
|
IndicatorSetString(INDICATOR_SHORTNAME, "AsianFuckerConVolumi");
|
|
|
|
// alloco la posizione dell'indicatore nel buffer il dato corrispondente a valA'
|
|
//EMA1 & EMA2
|
|
SetIndexBuffer(0, valA, INDICATOR_DATA); // valore effettivo della media
|
|
SetIndexBuffer(1, valcA, INDICATOR_COLOR_INDEX); // colore che deve avere la media
|
|
|
|
_emaA.init(inpPeriodA); // inizializzo con il valore inpPerdioA
|
|
|
|
// stessa cosa di sopra
|
|
SetIndexBuffer(2, valB, INDICATOR_DATA);
|
|
SetIndexBuffer(3, valcB, INDICATOR_COLOR_INDEX);
|
|
_emaB.init(inpPeriodB);
|
|
|
|
//Ichimoku
|
|
//--- indicator buffers mapping
|
|
SetIndexBuffer(4, ExtTenkanBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(5, ExtKijunBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(6, ExtSpanABuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(7, ExtSpanBBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(8, ExtChikouBuffer, INDICATOR_DATA);
|
|
//--- sets first bar from what index will be drawn
|
|
PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, InpTenkan); //PLOT_DRAW_BEGIN indica quanto far partire il disegno (shift per fare in modo...
|
|
//... che sia disegnabile rispettando il numero di elementi)
|
|
PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, InpKijun);
|
|
PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, InpSenkou - 1);
|
|
//--- lines shifts when drawing
|
|
PlotIndexSetInteger(4, PLOT_SHIFT, InpCloudOffset); //PLOT_SHIFT shifto esattamente
|
|
PlotIndexSetInteger(5, PLOT_SHIFT, -InpKijun); // tiro indietro il grafico
|
|
//--h- change labels for DataWindow
|
|
PlotIndexSetString(2, PLOT_LABEL, "Tenkan-sen(" + string(InpTenkan) + ")"); //PLOT_LABEL sovrascrive l'etichetta prima dichiarata'
|
|
PlotIndexSetString(3, PLOT_LABEL, "Kijun-sen(" + string(InpKijun) + ")");
|
|
PlotIndexSetString(4, PLOT_LABEL, "Senkou Span A;Senkou Span B(" + string(InpSenkou) + ")");
|
|
|
|
//asian range
|
|
//--- Verify Time Period
|
|
if (PeriodSeconds(_Period) >= PeriodSeconds(PERIOD_H2))
|
|
{
|
|
return (-1);
|
|
}
|
|
|
|
//--- Displacement of the buffer for construction of the future sessions
|
|
ShiftTime = PeriodSeconds(PERIOD_D1) / PeriodSeconds(_Period);
|
|
// quanti secondi in una giornata / quanti secondi nel periodo che usiamo adesso
|
|
// se sono in h1 ho una shift time di 24candele, una all'ora. La 24esima, partendo il vettore da 0 corrisponde alla prima ora del secondo giorno
|
|
// con m5 sono 288 candele
|
|
|
|
//--- indicators
|
|
SetIndexBuffer(9, AsiaHigh, INDICATOR_DATA);
|
|
SetIndexBuffer(10, AsiaLow, INDICATOR_DATA);
|
|
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
|
|
|
//trigger
|
|
//--- indicator buffers mapping
|
|
SetIndexBuffer(11, ColorArrowBuffer, INDICATOR_DATA);
|
|
//--- Define the symbol code for drawing in PLOT_ARROW
|
|
PlotIndexSetInteger(11, PLOT_ARROW, code);
|
|
//--- Set the vertical shift of arrows in pixels
|
|
PlotIndexSetInteger(11, PLOT_ARROW_SHIFT, 5);
|
|
//--- Set as an empty value 0
|
|
PlotIndexSetDouble(11, PLOT_EMPTY_VALUE, 0);
|
|
SetIndexBuffer(12, triggerColorIndex, INDICATOR_COLOR_INDEX);
|
|
|
|
return (INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| get highest value for range |
|
|
//+------------------------------------------------------------------+
|
|
double Highest(const double &array[], int range, int fromIndex)
|
|
{
|
|
double res = 0;
|
|
//---
|
|
res = array[fromIndex];
|
|
for (int i = fromIndex; i > fromIndex - range && i >= 0; i--)
|
|
{
|
|
if (res < array[i])
|
|
res = array[i];
|
|
}
|
|
//---
|
|
return (res);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| get lowest value for range |
|
|
//+------------------------------------------------------------------+
|
|
double Lowest(const double &array[], int range, int fromIndex)
|
|
{
|
|
double res = 0;
|
|
//---
|
|
res = array[fromIndex];
|
|
for (int i = fromIndex; i > fromIndex - range && i >= 0; i--)
|
|
{
|
|
if (res > array[i])
|
|
res = array[i];
|
|
}
|
|
//---
|
|
return (res);
|
|
}
|
|
|
|
int OnCalculate(const int rates_total, // indica le lunghezza dei vettori che seguono
|
|
const int prev_calculated, // per tenere il conto del punto di partenza del calcolo degli indicatori
|
|
const datetime &time[], // time[i] indica il momento di apertura della candela.
|
|
// la candela piu' recente e' quella a cui ci si riferisce con [rates_total-1], quella più vecchia e' time[0]'
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[],
|
|
const long &tick_volume[], // indica la quantita' di denaro spostata'
|
|
const long &volume[], // per il momento non lo usiamo
|
|
const int &spread[]) // differenza tra valore di buy e sell
|
|
{
|
|
|
|
//medie e Ichimoku
|
|
int i = prev_calculated - 1;
|
|
if (i < 0)
|
|
{
|
|
i = 0;
|
|
}
|
|
// se i è minore di 0, lo setto a 0, e poi procedo, altrimenti procedo direttamente
|
|
for (; i < rates_total && !_StopFlag; i++)
|
|
{ // nessuna condizione di partenza, solo arresto e aggiornamento
|
|
// _StopFlag è una variabile d'ambiente (posso interagire mentre si esegue il codice da GUI)
|
|
valA[i] = _emaA.calculate(getPrice(inpPrice, open, high, low, close, i), i, rates_total); //valore emaA
|
|
valcA[i] = 0; // prendo il primo colore dei vettori di A di quelli prima definiti con property
|
|
|
|
valB[i] = _emaB.calculate(getPrice(inpPrice, open, high, low, close, i), i, rates_total); //valore emaB
|
|
valcB[i] = 0; // prendo il primo colore dei vettori di B di quelli prima definiti con property
|
|
|
|
// calcolo di ichimoku
|
|
ExtChikouBuffer[i] = close[i];
|
|
//--- tenkan sen
|
|
double _high = Highest(high, InpTenkan, i);
|
|
double _low = Lowest(low, InpTenkan, i);
|
|
ExtTenkanBuffer[i] = (_high + _low) / 2.0;
|
|
//--- kijun sen
|
|
_high = Highest(high, InpKijun, i);
|
|
_low = Lowest(low, InpKijun, i);
|
|
ExtKijunBuffer[i] = (_high + _low) / 2.0;
|
|
//--- senkou span a
|
|
ExtSpanABuffer[i] = (ExtTenkanBuffer[i] + ExtKijunBuffer[i]) / 2.0;
|
|
//--- senkou span b
|
|
_high = Highest(high, InpSenkou, i);
|
|
_low = Lowest(low, InpSenkou, i);
|
|
ExtSpanBBuffer[i] = (_high + _low) / 2.0;
|
|
}
|
|
|
|
//max e min sessione asiatica
|
|
HighForFutureSession = MathMax(high[rates_total - 1], high[rates_total - 2]); // ?? come aggiorna il massimo? prendo il massimo considerando anche l'ombra della candela (high)
|
|
LowForFutureSession = MathMin(low[rates_total - 1], low[rates_total - 2]);
|
|
MqlDateTime time1, time2; //contiene data e orario
|
|
|
|
//--- set position for beginning
|
|
if (prev_calculated == 0) // è la prima volta che eseguo il metodo on calculate: non ci sono candele precedentemente calcolate
|
|
{
|
|
i = ShiftTime + 1; //mi sposto di un giorno in avanti
|
|
ArrayInitialize(AsiaHigh, 0.0); //inizializzo esplicitamente l'array dinamico
|
|
ArrayInitialize(AsiaLow, 0.0);
|
|
}
|
|
else
|
|
i = prev_calculated - ShiftTime; // vado indietro di un giorno
|
|
|
|
//--- elaboro le timezone (sessione asiatica) per ogni giorno
|
|
while (i < rates_total)
|
|
{
|
|
|
|
TimeToStruct(time[i - 1], time1); //conversione del tipo di variabile da time[i-1] che è di tipo datetime a MqlDateTime che è una struct
|
|
// time1=time[i-1]; ma con cast esplicito
|
|
TimeToStruct(time[i], time2); //idem come sopra
|
|
if (time1.day != time2.day) //se la variabile day dell'elemento MqlDateTime time1 e di time2 sono diverse => cambio di giorno
|
|
{
|
|
DrawTimeZone(time[i], i); // funzione che disegna il blocco dell'asiatica
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
//trigger buy & sell
|
|
bool asianUnderMaxDelta = false;
|
|
|
|
bool medieBuy = false;
|
|
bool ichBuy = false;
|
|
bool asianTopBreakout = false;
|
|
|
|
bool medieSell = false;
|
|
bool ichSell = false;
|
|
bool asianBottomBreakout = false;
|
|
|
|
bool medieFavore = false;
|
|
|
|
i = 0;
|
|
|
|
datetime barTime;
|
|
|
|
for (; i < rates_total && !_StopFlag; i++)
|
|
{
|
|
barTime = time[i] + TimeGMTOffset();
|
|
|
|
//filtro candele dalle 06:00 alle 16:15 per evitare problemi con ora legale
|
|
if (barTime % 86400 >= startTrading && barTime % 86400 <= stopTrading)
|
|
{
|
|
|
|
double highLevelAsianOfDay = getHighLevelAsianByDay(time[i]);
|
|
double lowLevelAsianOfDay = getLowLevelAsianByDay(time[i]);
|
|
|
|
double asianDelta = (highLevelAsianOfDay - lowLevelAsianOfDay) / (_Point * 10); //_Point*10 = 1 pip ma siccome il pip può essere la quarta o la terza o un'altra cifra decimale, parto dall'ultima e moltiplico per 10: 0.001
|
|
|
|
asianUnderMaxDelta = asianDelta < InpAsianMaxDelta; // setto a true asianUnderMaxDelta
|
|
|
|
// calcolo della media
|
|
double mediaVolumi = 0; // dichiaro la variabile di tipo double
|
|
|
|
// calcolo delle medie
|
|
if (i > lunghezzaMedia + 1) // altrimenti non posso calcolarla
|
|
{
|
|
for (int x = i - mediaVolumi; x < i; x = x + 1) // lunghezzaMedia è definita sopra come property
|
|
{
|
|
mediaVolumi = mediaVolumi + tick_volume[x];
|
|
}
|
|
mediaVolumi = mediaVolumi / lunghezzaMedia;
|
|
|
|
// trigger medie
|
|
medieFavore = mediaVolumi < tick_volume[i];
|
|
}
|
|
//trigger buy
|
|
medieBuy = valA[i] > valB[i] && open[i] < close[i] && open[i] >= valA[i];
|
|
ichBuy = ExtSpanABuffer[i] > ExtSpanBBuffer[i];
|
|
asianTopBreakout = open[i] <= highLevelAsianOfDay && close[i] > highLevelAsianOfDay;
|
|
|
|
if (medieBuy && ichBuy && asianTopBreakout && medieFavore)
|
|
{
|
|
ColorArrowBuffer[i] = low[i] - (_Point * 10 * 2);
|
|
triggerColorIndex[i] = 0;
|
|
}
|
|
|
|
//trigger sell
|
|
medieSell = valA[i] < valB[i] && open[i] > close[i] && open[i] <= valA[i];
|
|
ichSell = ExtSpanABuffer[i] < ExtSpanBBuffer[i];
|
|
asianBottomBreakout = open[i] >= lowLevelAsianOfDay && close[i] < lowLevelAsianOfDay;
|
|
|
|
if (medieSell && ichSell && asianBottomBreakout && medieFavore)
|
|
{
|
|
ColorArrowBuffer[i] = high[i] + (_Point * 10 * 2);
|
|
triggerColorIndex[i] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (rates_total);
|
|
}
|
|
|
|
class CEma //nome della classe
|
|
{
|
|
private: //attributi o metodi privati
|
|
double m_period;
|
|
double m_alpha;
|
|
double m_array[];
|
|
int m_arraySize;
|
|
|
|
public: // attributi o metodi pubblici
|
|
CEma() : m_period(1), m_alpha(1), m_arraySize(-1) { return; } // costruttore HA LO STESSO NOME DELLA CLASSE
|
|
// le istruzioni inizializzano le variabili della classe quando viene chiamato il costruttore
|
|
|
|
~CEma() { return; } // distruttore
|
|
|
|
void init(int period) // in base al periodo calcola altri parametri
|
|
{
|
|
m_period = (period > 1) ? period : 1;
|
|
m_alpha = 2.0 / (1.0 + m_period); // peso della media (?)
|
|
}
|
|
double calculate(double value, int i, int bars) // calcola il valore della media quando ho una nuova candela
|
|
{
|
|
if (m_arraySize < bars)
|
|
{
|
|
m_arraySize = ArrayResize(m_array, bars + 500);
|
|
if (m_arraySize < bars)
|
|
return (0);
|
|
}
|
|
|
|
if (i > 0)
|
|
m_array[i] = m_array[i - 1] + m_alpha * (value - m_array[i - 1]);
|
|
else
|
|
m_array[i] = value;
|
|
return (m_array[i]);
|
|
}
|
|
};
|
|
|
|
// dichiaro due oggetti di classe ema
|
|
CEma _emaA;
|
|
CEma _emaB;
|
|
|
|
template <typename T>
|
|
double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i)
|
|
{
|
|
switch (tprice)
|
|
{
|
|
case PRICE_CLOSE:
|
|
return (close[i]);
|
|
case PRICE_OPEN:
|
|
return (open[i]);
|
|
case PRICE_HIGH:
|
|
return (high[i]);
|
|
case PRICE_LOW:
|
|
return (low[i]);
|
|
case PRICE_MEDIAN:
|
|
return ((high[i] + low[i]) / 2.0);
|
|
case PRICE_TYPICAL:
|
|
return ((high[i] + low[i] + close[i]) / 3.0);
|
|
case PRICE_WEIGHTED:
|
|
return ((high[i] + low[i] + close[i] + close[i]) / 4.0);
|
|
}
|
|
return (0);
|
|
}
|
|
//------------------------------------------------------------------
|
|
|
|
//+--------------------------------------------------------------------+
|
|
// Summertime determination is reserved for the future calculations
|
|
//+--------------------------------------------------------------------+
|
|
bool Summertime(datetime time)
|
|
{
|
|
if (TimeDaylightSavings() != 0)
|
|
return (true);
|
|
else
|
|
return (false);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------+
|
|
// Calculation and filling of buffers of time zones
|
|
//+--------------------------------------------------------------------+
|
|
void DrawTimeZone(datetime Start, int Index) // disegna il blocchetto per ogni sessione, noi lo usiamo per l'asiatica
|
|
{
|
|
int rates_total, shift, shift_end, _startIndex = Index;
|
|
double iHigh[], iLow[], HighSession, LowSession; // dichiaro qui i vettori iHIgh e iLOw che manterranno tutti i valori assunti da High e Low nella sessione nel pair nel periodo...
|
|
datetime AsiaStart, AsiaEnd;
|
|
datetime _start = Start + (TimeTradeServer() - TimeGMT());
|
|
|
|
// DISEGNO DEL RETTANGOLO / DESTRA E SINISTRA
|
|
// Processing of the Asian session //AsiaStart e AsiaEnd indicano l'inizio e la fine dell'asiatica
|
|
AsiaStart = _start + (Summertime(Start) ? AsiaOpenSummertime : AsiaOpen) * PeriodSeconds(PERIOD_H1);
|
|
AsiaEnd = _start + (Summertime(Start) ? AsiaCloseSummertime : AsiaClose) * PeriodSeconds(PERIOD_H1) - 1;
|
|
// condizione? se true: false
|
|
// se summertime(Start) è vero, allora assegno AsiaOpenSummerTime, altirmenti AsiaOpen
|
|
// Summertime verifica se c'è o meno l'ora legale
|
|
|
|
// DISEGNO DEL RETTANGOLO / SOPRA E SOTTO
|
|
rates_total = CopyHigh(NULL, _Period, AsiaStart, AsiaEnd, iHigh);
|
|
// NULL indica pair su cui si sta lavorando, se voglio tenerne quella selezionata dò null
|
|
// _Period è una variabile d'ambiente e fa riferimento al periodo su cui è inserito l'indicatore
|
|
// AsiaStart e AsiaEnd è il periodo dell'asiatica
|
|
// iHigh è un vettore nostro in cui salviamo i valori degli spike positivi del pair selezionato nella sessione asiatica corrispondente
|
|
// CopyHigh mette in iHigh e restituisce il numero di candele messe in iHigh, che è la lunghezza di quel vettore. In questo caso ratesTotal assume questo valore
|
|
|
|
if (rates_total <= 0) // torna -1 in caso di errore (forse questo accade quando c'è la sessione asiatica)
|
|
HighSession = HighForFutureSession;
|
|
else // quando la sessione asiatica è fatta
|
|
HighSession = iHigh[ArrayMaximum(iHigh, 0, rates_total)]; //ArrayMaximum(vettore, indice di partenza, indice di fine) TORNA L'INDICE, NON IL VALORE
|
|
|
|
// fa lo stesso con il low
|
|
rates_total = CopyLow(NULL, _Period, AsiaStart, AsiaEnd, iLow);
|
|
|
|
if (rates_total <= 0)
|
|
LowSession = LowForFutureSession;
|
|
else
|
|
LowSession = iLow[ArrayMinimum(iLow, 0, rates_total)];
|
|
|
|
// trovo gli indici delle candele di dove inizia l'asiatica e dove finisce
|
|
shift = int((AsiaStart - Start) / PeriodSeconds(_Period));
|
|
shift_end = int((AsiaEnd - Start) / PeriodSeconds(_Period) + 1);
|
|
|
|
// definisco le due linee alto e basso
|
|
for (int i = shift; i < shift_end; i++)
|
|
{
|
|
AsiaHigh[_startIndex + i] = HighSession;
|
|
AsiaLow[_startIndex + i] = LowSession;
|
|
}
|
|
|
|
// Memory clearing
|
|
ArrayResize(iHigh, 0);
|
|
ArrayResize(iLow, 0);
|
|
}
|
|
|
|
double getHighLevelAsianByDay(datetime barTime)
|
|
{
|
|
MqlDateTime barTimeStruct;
|
|
TimeToStruct(barTime, barTimeStruct);
|
|
|
|
barTimeStruct.hour = 0;
|
|
barTimeStruct.min = 0;
|
|
|
|
datetime offset = StructToTime(barTimeStruct);
|
|
datetime _start = offset + (TimeTradeServer() - TimeGMT());
|
|
|
|
datetime AsiaStart = _start + (Summertime(offset) ? AsiaOpenSummertime : AsiaOpen) * PeriodSeconds(PERIOD_H1);
|
|
datetime AsiaEnd = _start + (Summertime(offset) ? AsiaCloseSummertime : AsiaClose) * PeriodSeconds(PERIOD_H1) - 1;
|
|
|
|
double barsHigh[];
|
|
int rates_total = CopyHigh(NULL, _Period, AsiaStart, AsiaEnd, barsHigh);
|
|
int maximumIndex = ArrayMaximum(barsHigh, 0, rates_total);
|
|
|
|
double MaximumOfSession = barsHigh[maximumIndex];
|
|
|
|
// Memory clearing
|
|
ArrayResize(barsHigh, 0);
|
|
|
|
return MaximumOfSession;
|
|
}
|
|
|
|
double getLowLevelAsianByDay(datetime barTime)
|
|
{
|
|
MqlDateTime barTimeStruct;
|
|
TimeToStruct(barTime, barTimeStruct);
|
|
|
|
barTimeStruct.hour = 0;
|
|
barTimeStruct.min = 0;
|
|
|
|
datetime offset = StructToTime(barTimeStruct);
|
|
datetime _start = offset + (TimeTradeServer() - TimeGMT());
|
|
|
|
datetime AsiaStart = _start + (Summertime(offset) ? AsiaOpenSummertime : AsiaOpen) * PeriodSeconds(PERIOD_H1);
|
|
datetime AsiaEnd = _start + (Summertime(offset) ? AsiaCloseSummertime : AsiaClose) * PeriodSeconds(PERIOD_H1) - 1;
|
|
|
|
double barsLow[];
|
|
int rates_total = CopyLow(NULL, _Period, AsiaStart, AsiaEnd, barsLow);
|
|
int minimumIndex = ArrayMinimum(barsLow, 0, rates_total);
|
|
|
|
double MinimumOfSession = barsLow[minimumIndex];
|
|
|
|
// Memory clearing
|
|
ArrayResize(barsLow, 0);
|
|
|
|
return MinimumOfSession;
|
|
}
|