CojoneAlAire/AsianFucker.mq5
super.admin 9721dd7967 convert
2025-05-30 14:46:52 +02:00

519 lines
No EOL
38 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'
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,"AsianFucker");
// 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);
//--- 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
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]);
LowForFutureSession=MathMin(low[rates_total-1],low[rates_total-2]);
MqlDateTime time1, time2;
//--- set position for beginning
if(prev_calculated==0)
{
i=ShiftTime+1;
ArrayInitialize(AsiaHigh, 0.0);
ArrayInitialize(AsiaLow, 0.0);
}
else
i=prev_calculated-ShiftTime;
//--- elaboro le timezone per ogni giorno
while(i<rates_total)
{
TimeToStruct(time[i-1], time1);
TimeToStruct(time[i], time2);
if(time1.day!=time2.day)
{
DrawTimeZone(time[i],i);
}
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;
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);
asianUnderMaxDelta = asianDelta < InpAsianMaxDelta;
//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){
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){
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)
{
int rates_total,shift,shift_end,_startIndex=Index;
double iHigh[], iLow[], HighSession, LowSession;
datetime AsiaStart, AsiaEnd;
datetime _start=Start+(TimeTradeServer()-TimeGMT());
// Processing of the Asian session
AsiaStart=_start+(Summertime(Start)?AsiaOpenSummertime:AsiaOpen)*PeriodSeconds(PERIOD_H1);
AsiaEnd=_start+(Summertime(Start)?AsiaCloseSummertime:AsiaClose)*PeriodSeconds(PERIOD_H1)-1;
rates_total=CopyHigh(NULL,_Period,AsiaStart,AsiaEnd,iHigh);
if(rates_total<=0)
HighSession=HighForFutureSession;
else
HighSession=iHigh[ArrayMaximum(iHigh,0,rates_total)];
rates_total=CopyLow(NULL,_Period,AsiaStart,AsiaEnd,iLow);
if(rates_total<=0)
LowSession=LowForFutureSession;
else
LowSession=iLow[ArrayMinimum(iLow,0,rates_total)];
shift=int((AsiaStart-Start)/PeriodSeconds(_Period));
shift_end=int((AsiaEnd-Start)/PeriodSeconds(_Period)+1);
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;
}