//+---------------------------------------------------------------------+
//| AFL_WinnerSign.mq5 |
//| Copyright © 2011, Andrey Voytenko |
//| https://login.mql5.com/en/users/avoitenko |
//+---------------------------------------------------------------------+
#property copyright "Copyright © 2011, Andrey Voytenko"
#property link "https://login.mql5.com/en/users/avoitenko"
#property version "1.00"
#property indicator_chart_window #property indicator_buffers 5
#property indicator_plots 2 //--- Sell signal
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrMagenta
#property indicator_width1 4
#property indicator_label1 "NRatioSign Sell" //--- Buy signal
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrBlueViolet
#property indicator_width2 4
#property indicator_label2 "NRatioSign Buy" #define RESET 0 //--- Applied price enumeration
enum Applied_price_ { PRICE_CLOSE_ = 1, //Close PRICE_OPEN_, //Open PRICE_HIGH_, //High PRICE_LOW_, //Low PRICE_MEDIAN_, //Median Price (HL/2) PRICE_TYPICAL_, //Typical Price (HLC/3) PRICE_WEIGHTED_, //Weighted Close (HLCC/4) PRICE_SIMPL_, //Simple Price (OC/2) PRICE_QUARTER_, //Quarted Price (HLOC/4) PRICE_TRENDFOLLOW0_, //TrendFollow_1 Price PRICE_TRENDFOLLOW1_, //TrendFollow_2 Price PRICE_DEMARK_ //Demark Price }; //--- Input parameters
input uint iAverage=5; // Average period
input uint iPeriod=10; // Main period
input uint iLength=5; // Smoothing length
input Applied_price_ IPC=PRICE_WEIGHTED_; // Applied price
input ENUM_APPLIED_VOLUME VolumeType=VOLUME_TICK; // Volume type
input int Shift=0; // Indicator shift //--- Indicator buffers
double SellBuffer[], BuyBuffer[];
double RSVBuffer[], XMA1Buffer[], XMA2Buffer[]; //--- Indicator handles
int ATR_Handle; //--- Variables for minimum bars
int min_rates_total; //+------------------------------------------------------------------+
//| PriceSeries function |
//+------------------------------------------------------------------+
double PriceSeries(Applied_price_ applied_price, int bar, const double &open[], const double &low[], const double &high[], const double &close[]) { switch(applied_price) { case PRICE_CLOSE_: return(close[bar]); case PRICE_OPEN_: return(open[bar]); case PRICE_HIGH_: return(high[bar]); case PRICE_LOW_: return(low[bar]); case PRICE_MEDIAN_: return((high[bar]+low[bar])/2.0); case PRICE_TYPICAL_: return((high[bar]+low[bar]+close[bar])/3.0); case PRICE_WEIGHTED_: return((high[bar]+low[bar]+close[bar]+close[bar])/4.0); case PRICE_SIMPL_: return((open[bar]+close[bar])/2.0); case PRICE_QUARTER_: return((high[bar]+low[bar]+open[bar]+close[bar])/4.0); case PRICE_TRENDFOLLOW0_: if(close[bar] open[bar]) return((low[bar]+close[bar])/2.0); else return((low[bar]+close[bar])/2.0); case PRICE_DEMARK_: { double x=open[bar]; if(close[bar] open[bar]) x=(high[bar]+low[bar])/2.0+close[bar]; if(close[bar]==open[bar]) x=(high[bar]+low[bar]+close[bar]+close[bar])/4.0; return(x); } default: return(close[bar]); } } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Calculate minimum bars needed int ATR_Period=10; min_rates_total = int(iAverage) + int(iPeriod) + int(iLength) * 2 + ATR_Period; //--- Get ATR indicator handle ATR_Handle = iATR(NULL, 0, ATR_Period); if(ATR_Handle == INVALID_HANDLE) { Print("Failed to create ATR indicator handle"); return(INIT_FAILED); } //--- Set indicator buffers SetIndexBuffer(0, SellBuffer, INDICATOR_DATA); SetIndexBuffer(1, BuyBuffer, INDICATOR_DATA); SetIndexBuffer(2, RSVBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(3, XMA1Buffer, INDICATOR_CALCULATIONS); SetIndexBuffer(4, XMA2Buffer, INDICATOR_CALCULATIONS); //--- Set arrays as series ArraySetAsSeries(SellBuffer, true); ArraySetAsSeries(BuyBuffer, true); ArraySetAsSeries(RSVBuffer, true); ArraySetAsSeries(XMA1Buffer, true); ArraySetAsSeries(XMA2Buffer, true); //--- Set drawing parameters PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, min_rates_total); PlotIndexSetInteger(0, PLOT_ARROW, 234); PlotIndexSetInteger(0, PLOT_SHIFT, Shift); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, min_rates_total); PlotIndexSetInteger(1, PLOT_ARROW, 233); PlotIndexSetInteger(1, PLOT_SHIFT, Shift); //--- Set indicator name string shortname = "AFL_WinnerSign"; IndicatorSetString(INDICATOR_SHORTNAME, shortname); IndicatorSetInteger(INDICATOR_DIGITS, _Digits); Print("=== AFL_WinnerSign Initialized ==="); Print("Min bars required: ", min_rates_total); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) { if(ATR_Handle != INVALID_HANDLE) IndicatorRelease(ATR_Handle); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- Check if enough bars if(rates_total < min_rates_total) { return(0); } //--- Set arrays as series ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(tick_volume, true); ArraySetAsSeries(volume, true); ArraySetAsSeries(time, true); //--- Check ATR if(BarsCalculated(ATR_Handle) < rates_total) { return(0); } //--- Determine calculation range int start_pos; static int last_trend = 0; if(prev_calculated == 0) { start_pos = rates_total - min_rates_total; last_trend = 0; ArrayInitialize(SellBuffer, 0.0); ArrayInitialize(BuyBuffer, 0.0); ArrayInitialize(RSVBuffer, 0.0); ArrayInitialize(XMA1Buffer, 0.0); ArrayInitialize(XMA2Buffer, 0.0); } else { start_pos = rates_total - prev_calculated; } //--- Step 1: Calculate weighted average price (Value buffer) double ValueBuffer[]; ArrayResize(ValueBuffer, rates_total); ArraySetAsSeries(ValueBuffer, true); for(int i = start_pos; i >= 0; i--) { double scost = 0.0; long svol = 0; for(int j = 0; j < (int)iAverage; j++) { if(i + j >= rates_total) break; long vol_value = (VolumeType == VOLUME_TICK) ? tick_volume[i + j] : volume[i + j]; double price_value = PriceSeries(IPC, i + j, open, low, high, close); scost += vol_value * price_value; svol += vol_value; } ValueBuffer[i] = (svol > 0) ? (scost / svol) : close[i]; } //--- Step 2: Calculate RSV for(int i = start_pos; i >= 0; i--) { if(i + (int)iPeriod >= rates_total) { RSVBuffer[i] = 0.0; continue; } //--- Find highest and lowest values double highest = ValueBuffer[i]; double lowest = ValueBuffer[i]; for(int j = 1; j < (int)iPeriod; j++) { if(ValueBuffer[i + j] > highest) highest = ValueBuffer[i + j]; if(ValueBuffer[i + j] < lowest) lowest = ValueBuffer[i + j]; } //--- Calculate RSV double range = highest - lowest; if(range < _Point * 10) range = _Point * 10; RSVBuffer[i] = ((ValueBuffer[i] - lowest) / range) * 100.0 - 50.0; } //--- Step 3: First smoothing (MA of RSV) for(int i = start_pos; i >= 0; i--) { if(i + (int)iLength >= rates_total) { XMA1Buffer[i] = RSVBuffer[i]; continue; } double sum = 0.0; for(int j = 0; j < (int)iLength; j++) { sum += RSVBuffer[i + j]; } XMA1Buffer[i] = sum / iLength; } //--- Step 4: Second smoothing (MA of XMA1) for(int i = start_pos; i >= 0; i--) { if(i + (int)iLength >= rates_total) { XMA2Buffer[i] = XMA1Buffer[i]; continue; } double sum = 0.0; for(int j = 0; j < (int)iLength; j++) { sum += XMA1Buffer[i + j]; } XMA2Buffer[i] = sum / iLength; } //--- Step 5: Generate trading signals (only on crossover) for(int i = start_pos; i >= 0; i--) { BuyBuffer[i] = 0.0; SellBuffer[i] = 0.0; //--- Skip if not enough data if(i + (int)iLength >= rates_total) continue; if(i + 1 >= rates_total) continue; // Need previous bar //--- Get ATR double ATR[]; if(CopyBuffer(ATR_Handle, 0, i, 1, ATR) <= 0) continue; //--- Determine current trend int current_trend = 0; if(XMA1Buffer[i] > XMA2Buffer[i]) current_trend = 1; else if(XMA1Buffer[i] < XMA2Buffer[i]) current_trend = -1; //--- Determine previous trend int prev_trend = 0; if(XMA1Buffer[i + 1] > XMA2Buffer[i + 1]) prev_trend = 1; else if(XMA1Buffer[i + 1] < XMA2Buffer[i + 1]) prev_trend = -1; //--- Detect crossover (trend change) if(current_trend == 1 && prev_trend <= 0) { // Bullish crossover BuyBuffer[i] = low[i] - ATR[0] * 0.5; static int buy_signals = 0; if(buy_signals < 5) { Print("====== BUY SIGNAL ======"); Print("Time: ", TimeToString(time[i]), " Bar: ", i); Print("XMA1: ", DoubleToString(XMA1Buffer[i], 2)); Print("XMA2: ", DoubleToString(XMA2Buffer[i], 2)); Print("Prev XMA1: ", DoubleToString(XMA1Buffer[i + 1], 2)); Print("Prev XMA2: ", DoubleToString(XMA2Buffer[i + 1], 2)); Print("Arrow at: ", DoubleToString(BuyBuffer[i], _Digits)); buy_signals++; } } else if(current_trend == -1 && prev_trend >= 0) { // Bearish crossover SellBuffer[i] = high[i] + ATR[0] * 0.5; static int sell_signals = 0; if(sell_signals < 5) { Print("====== SELL SIGNAL ======"); Print("Time: ", TimeToString(time[i]), " Bar: ", i); Print("XMA1: ", DoubleToString(XMA1Buffer[i], 2)); Print("XMA2: ", DoubleToString(XMA2Buffer[i], 2)); Print("Prev XMA1: ", DoubleToString(XMA1Buffer[i + 1], 2)); Print("Prev XMA2: ", DoubleToString(XMA2Buffer[i + 1], 2)); Print("Arrow at: ", DoubleToString(SellBuffer[i], _Digits)); sell_signals++; } } //--- Update last trend only for current bar if(i == 0) last_trend = current_trend; } return(rates_total); }
//+------------------------------------------------------------------+
取引の機会を逃しています。
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
AFL_WinnerSign:
AFL_Winner インディケータに基づくセマフォシグナルインディケータ
作者: Nikolay Kositsin