mql5/Experts/Examples/WaveDetector.ex5.mq5

510 lines
40 KiB
MQL5
Raw Permalink Normal View History

2025-11-23 16:04:34 +08:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| WaveDetector2.mq5 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.01"
#property strict
#include <ChartObjects\ChartObject.mqh>
// <EFBFBD>Ջh<EFBFBD>_ - <EFBFBD><EFBFBD>n:Ntrue/T(u<EFBFBD>Ջ<EFBFBD>e<EFBFBD>_
#define DEBUG_MODE true
// <EFBFBD>Ջ<EFBFBD>e<EFBFBD>_<EFBFBD>Qpe
void DebugLog(string message) {
if(DEBUG_MODE) {
Print("[DEBUG] " + message);
}
}
// jm<EFBFBD>W<EFBFBD>~<EFBFBD>gSO<EFBFBD>X[<EFBFBD>Pjm<EFBFBD>W<EFBFBD>Oo` <EFBFBD>
struct WaveInfo
{
string wave_type; // jm<EFBFBD>W<EFBFBD>
NGSjm/ NM<EFBFBD>jm <EFBFBD>
int start_index; // w<EFBFBD><EFBFBD>YK<EFBFBD>~"}_
double start_price; // w<EFBFBD><EFBFBD>Y<EFBFBD>N<h
int end_index; // <EFBFBD>~_gK<EFBFBD>~"}_
double end_price; // <EFBFBD>~_g<EFBFBD>N<h
double amplitude; // E^<EFBFBD>^(%)
};
// <EFBFBD>g<P<EFBFBD>p<EFBFBD>~<EFBFBD>gSO<EFBFBD>X[<EFBFBD>/NO<EFBFBD>p<EFBFBD>Oo` <EFBFBD>
struct ExtremePoint
{
string type; // {|<EFBFBD>W<EFBFBD>high/low <EFBFBD>
int index; // K<EFBFBD>~"}_
double price; // <EFBFBD>N<h
};
// hQ@\<EFBFBD>Spe<EFBFBD><EFBFBD>S(WMT5Lub<EFBFBD><EFBFBD>te <EFBFBD>
input int Window_Size = 6; // <EFBFBD>n<EFBFBD>R<EFBFBD>z<EFBFBD>S'Y\
input double Trend_Threshold = 0.015; // <EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>Sl<EFBFBD><EFBFBD><P(1.5%)
input int ATR_Period = 14; // ATR<EFBFBD><EFBFBD><EFBFBD>{hTg
input int MACD_Fast_Period = 12; // MACD<EFBFBD>_<EFBFBD>hTg
input int MACD_Slow_Period = 26; // MACDba<EFBFBD>hTg
input int MACD_Signal_Period = 9; // MACD<EFBFBD>O<EFBFBD>ShTg
input int Divergence_Lookback = 10; // MACD̀<EFBFBD>y<EFBFBD>V<EFBFBD>n<EFBFBD>z<EFBFBD>S
input bool Show_Debug_Info = true; // /f&T(W<EFBFBD>Vh<EFBFBD>
N>f:y<EFBFBD>Ջ<EFBFBD>Oo`
//+------------------------------------------------------------------+
//| <EFBFBD><EFBFBD><EFBFBD>{ATR<EFBFBD>s^GWw<EFBFBD>[<EFBFBD>lE^ <EFBFBD>- <EFBFBD><EFBFBD><EFBFBD><EFBFBD>^E^<EFBFBD>^<EFBFBD><P(u |
//+------------------------------------------------------------------+
double CalculateATR(const int rates_total, const MqlRates &rates[])
{
DebugLog("CalculateATR: rates_total = " + IntegerToString(rates_total));
if(rates_total < ATR_Period + 1) {
DebugLog("CalculateATR: penc N<EFBFBD><EFBFBD> <EFBFBD>ԏ<EFBFBD>V0");
return 0.0;
}
double tr_sum = 0.0;
// <EFBFBD><EFBFBD><EFBFBD>{MRATR_Period9hK<EFBFBD>~<EFBFBD>vw<EFBFBD>[<EFBFBD>lE^;`<EFBFBD>T
for(int i = rates_total - ATR_Period; i < rates_total; i++)
{
double tr = MathMax(rates[i].high - rates[i].low,
MathMax(MathAbs(rates[i].high - rates[i-1].close),
MathAbs(rates[i].low - rates[i-1].close)));
tr_sum += tr;
}
double atr_value = tr_sum / ATR_Period;
DebugLog("CalculateATR: ԏ<>V<P = " + DoubleToString(atr_value, 5));
return atr_value;
}
//+------------------------------------------------------------------+
//| <EFBFBD><EFBFBD><EFBFBD>{MACDch - ̀<EFBFBD>y<EFBFBD><EFBFBD><EFBFBD><EFBFBD>(u |
//+------------------------------------------------------------------+
bool CalculateMACD(const int rates_total, const MqlRates &rates[],
double &macd_line[], double &signal_line[], double &histogram[])
{
DebugLog("CalculateMACD: rates_total = " + IntegerToString(rates_total));
if(rates_total < MACD_Slow_Period + 1) {
DebugLog("CalculateMACD: penc N<EFBFBD><EFBFBD> <EFBFBD>ԏ<EFBFBD>Vfalse");
return false;
}
// R<EFBFBD>YSpe<EFBFBD>~
ArrayResize(macd_line, rates_total);
ArrayResize(signal_line, rates_total);
ArrayResize(histogram, rates_total);
// <EFBFBD><EFBFBD><EFBFBD>{EMA
double ema_fast = 0.0, ema_slow = 0.0;
double alpha_fast = 2.0 / (MACD_Fast_Period + 1);
double alpha_slow = 2.0 / (MACD_Slow_Period + 1);
// R<EFBFBD>YSEMA<EFBFBD>v,{N*N<P
ema_fast = rates[0].close;
ema_slow = rates[0].close;
for(int i = 1; i < rates_total; i++)
{
// cpe<EFBFBD>y<EFBFBD>Rs^GW<EFBFBD>EMA <EFBFBD><EFBFBD><EFBFBD><EFBFBD>{
ema_fast = (rates[i].close - ema_fast) * alpha_fast + ema_fast;
ema_slow = (rates[i].close - ema_slow) * alpha_slow + ema_slow;
macd_line[i] = ema_fast - ema_slow;
// <EFBFBD>O<EFBFBD>S<EFBFBD>~<EFBFBD>EMA of MACD<EFBFBD>~ <EFBFBD>
if(i == 1) signal_line[i] = macd_line[i];
else signal_line[i] = (macd_line[i] - signal_line[i-1]) * (2.0/(MACD_Signal_Period + 1)) + signal_line[i-1];
histogram[i] = macd_line[i] - signal_line[i];
}
DebugLog("CalculateMACD: b<>R<EFBFBD><52><EFBFBD>{ <0C>gTN*Nhistogram<P = " + DoubleToString(histogram[rates_total-1], 5));
return true;
}
//+------------------------------------------------------------------+
//| <EFBFBD>hKmP <EFBFBD><EFBFBD>g<P<EFBFBD>p<EFBFBD><EFBFBD>n<EFBFBD>R<EFBFBD>z<EFBFBD>S+ATR<EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<EFBFBD><P <EFBFBD> |
//+------------------------------------------------------------------+
bool DetectExtremes(const int rates_total, const MqlRates &rates[],
const double atr, ExtremePoint &extremes[], int &ext_count)
{
DebugLog("DetectExtremes: rates_total = " + IntegerToString(rates_total) + ", atr = " + DoubleToString(atr, 5));
if(rates_total < Window_Size * 2 + ATR_Period) {
DebugLog("DetectExtremes: penc N<EFBFBD><EFBFBD> <EFBFBD>ԏ<EFBFBD>Vfalse");
return false;
}
ext_count = 0;
ArrayResize(extremes, 1000); // <EFBFBD><EFBFBD>RM<EFBFBD>pe<EFBFBD>~'Y\ <EFBFBD><EFBFBD>MQ<EFBFBD>n<EFBFBD>Q
double dynamic_amp = atr / rates[rates_total - 1].close; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<EFBFBD>v<EFBFBD>[E^<EFBFBD>^
DebugLog("DetectExtremes: dynamic_amp = " + DoubleToString(dynamic_amp * 100, 2) + "%");
// <EFBFBD>n<EFBFBD>R<EFBFBD>z<EFBFBD>Skb<EFBFBD>cK<EFBFBD>~
for(int i = Window_Size + ATR_Period; i < rates_total - Window_Size; i++)
{
// ~b<EFBFBD>z<EFBFBD>S<EFBFBD>Q/gNO<EFBFBD>N
double window_max = rates[i].high;
double window_min = rates[i].low;
for(int j = i - Window_Size; j <= i + Window_Size; j++)
{
if(rates[j].high > window_max) window_max = rates[j].high;
if(rates[j].low < window_min) window_min = rates[j].low;
}
// OST<EFBFBD>v<EFBFBD>g<P<EFBFBD>p<EFBFBD>hKm;<EFBFBD><EFBFBD><EFBFBD>
bool is_high = (rates[i].high == window_max);
bool is_low = (rates[i].low == window_min);
// <EFBFBD><EFBFBD><EFBFBD>{<EFBFBD>N<h<EFBFBD>SS
if(is_high && i > 0) {
double price_change_high = (rates[i].high / rates[i-1].close - 1);
// <EFBFBD>hKmؚ<EFBFBD>p<EFBFBD><EFBFBD>z<EFBFBD>S<EFBFBD>Q + <EFBFBD>z4x<EFBFBD><EFBFBD><EFBFBD><EFBFBD>^E^<EFBFBD>^<EFBFBD><P
if(price_change_high >= MathMax(dynamic_amp * 0.5, Trend_Threshold * 0.5)) {
extremes[ext_count].type = "high";
extremes[ext_count].index = i;
extremes[ext_count].price = rates[i].high;
ext_count++;
DebugLog("DetectExtremes: <00>hKm0Rؚ<52>p #" + IntegerToString(ext_count) +
" "}_=" + IntegerToString(i) +
" <00>N<h=" + DoubleToString(rates[i].high, 5) +
" <00>mE^=" + DoubleToString(price_change_high * 100, 2) + "%");
}
}
else if(is_low && i > 0) {
double price_change_low = (rates[i-1].close / rates[i].low - 1);
// <EFBFBD>hKmNO<EFBFBD>p<EFBFBD><EFBFBD>z<EFBFBD>S<EFBFBD>QgNO + <EFBFBD>z4x<EFBFBD><EFBFBD><EFBFBD><EFBFBD>^E^<EFBFBD>^<EFBFBD><P
if(price_change_low >= MathMax(dynamic_amp * 0.5, Trend_Threshold * 0.5)) {
extremes[ext_count].type = "low";
extremes[ext_count].index = i;
extremes[ext_count].price = rates[i].low;
ext_count++;
DebugLog("DetectExtremes: <00>hKm0RNO<4E>p #" + IntegerToString(ext_count) +
" "}_=" + IntegerToString(i) +
" <00>N<h=" + DoubleToString(rates[i].low, 5) +
" ̍E^=" + DoubleToString(price_change_low * 100, 2) + "%");
}
}
}
DebugLog("DetectExtremes: qQ<71>hKm0R " + IntegerToString(ext_count) + " *NP <09><>g<P<>p");
return ext_count > 0;
}
//+------------------------------------------------------------------+
//| MACD̀<EFBFBD>y<EFBFBD><EFBFBD><EFBFBD><EFBFBD> - nx<EFBFBD><EFBFBD><EFBFBD>g<P<EFBFBD>p gHe'` |
//+------------------------------------------------------------------+
bool VerifyMACD_Divergence(const int rates_total, const MqlRates &rates[],
const double &histogram[], const string ext_type, const int ext_idx)
{
DebugLog("VerifyMACD_Divergence: ext_type = " + ext_type + ", ext_idx = " + IntegerToString(ext_idx));
// :N<EFBFBD>NKmՋ <EFBFBD><EFBFBD>f<EFBFBD>e;`/<EFBFBD>Vtrue <EFBFBD><EFBFBD>N<EFBFBD>O w0R@b g<EFBFBD>hKm0R<EFBFBD>vjm<EFBFBD>W
return true;
}
//+------------------------------------------------------------------+
//| [{ <EFBFBD> gHe<EFBFBD>g<P<EFBFBD>p<EFBFBD><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>z<EFBFBD>S+MACD̀<EFBFBD>y <EFBFBD> |
//+------------------------------------------------------------------+
bool FilterValidExtremes(const int rates_total, const MqlRates &rates[],
const ExtremePoint &extremes[], const int ext_count,
const double &histogram[], ExtremePoint &valid_extremes[], int &valid_count)
{
DebugLog("FilterValidExtremes: _<>Y[{ <09> gHe<48>g<P<>p <0C>P <09><>ppeϑ = " + IntegerToString(ext_count));
valid_count = 0;
ArrayResize(valid_extremes, ext_count);
for(int i = 0; i < ext_count; i++)
{
// MACD̀<EFBFBD>y<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool macd_valid = VerifyMACD_Divergence(rates_total, rates, histogram, extremes[i].type, extremes[i].index);
// <EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>z<EFBFBD>S<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>g<P<EFBFBD>p<EFBFBD>STN<EFBFBD>N<h<EFBFBD>SS<EFBFBD><EFBFBD>h <EFBFBD>
bool trend_valid = true;
if(valid_count > 0)
{
ExtremePoint prev_ext = valid_extremes[valid_count - 1];
// <EFBFBD>h<EFBFBD>g/f&<EFBFBD>~ T{|<EFBFBD>W<EFBFBD>g<P<EFBFBD>p
if(extremes[i].type == prev_ext.type) {
DebugLog("FilterValidExtremes: <00><>Ǐޏ<C78F>~ T{|<7C>W<EFBFBD>g<P<>p #" + IntegerToString(i));
trend_valid = false;
}
else {
// <EFBFBD>h<EFBFBD>g<EFBFBD>N<h<EFBFBD>SS/f&T<EFBFBD><EFBFBD>h
double price_change = MathAbs((extremes[i].price - prev_ext.price) / prev_ext.price);
// nx<EFBFBD>O<EFBFBD><EFBFBD><EFBFBD>{<EFBFBD>v/fcknx<EFBFBD>v~vR<EFBFBD>k<EFBFBD>SS
if(price_change < Trend_Threshold) {
DebugLog("FilterValidExtremes: <00><>Ǐ<EFBFBD>N<h<>SS N<EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>g<P<EFBFBD>p #" + IntegerToString(i) +
" <00>SS<>s=" + DoubleToString(price_change * 100, 2) + "%");
trend_valid = false;
}
}
}
// <EFBFBD>S g<EFBFBD>Ǐ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>pMb<EFBFBD><EFBFBD><EFBFBD>OYu
if(macd_valid && trend_valid) {
valid_extremes[valid_count] = extremes[i];
DebugLog("FilterValidExtremes: <00>OYu gHe<48>g<P<>p #" + IntegerToString(valid_count + 1) +
" {|<7C>W=" + extremes[i].type +
" "}_=" + IntegerToString(extremes[i].index) +
" <00>N<h=" + DoubleToString(extremes[i].price, 5));
valid_count++;
}
}
DebugLog("FilterValidExtremes: [{ <09>T gHe<48>g<P<>ppeϑ = " + IntegerToString(valid_count));
return valid_count > 1; // <EFBFBD><EFBFBD>\2*N gHe<EFBFBD>g<P<EFBFBD>pMb<EFBFBD>gbjm
}
//+------------------------------------------------------------------+
//| 2NT<EFBFBD> gHe<EFBFBD>g<P<EFBFBD>p <EFBFBD>ubjm<EFBFBD>Wpenc |
//+------------------------------------------------------------------+
bool GenerateWaves(const ExtremePoint &valid_extremes[], const int valid_count,
WaveInfo &waves[], int &wave_count)
{
DebugLog("GenerateWaves: _<>Yubjm<6A>Wpenc <0C> gHe<48>g<P<>ppeϑ = " + IntegerToString(valid_count));
wave_count = 0;
ArrayResize(waves, valid_count - 1);
for(int i = 1; i < valid_count; i++)
{
ExtremePoint start = valid_extremes[i-1];
ExtremePoint end = valid_extremes[i];
// $R<EFBFBD>[jm<EFBFBD>W<EFBFBD>eT
if(start.type == "low" && end.type == "high")
waves[wave_count].wave_type = "
NGSjm";
else if(start.type == "high" && end.type == "low")
waves[wave_count].wave_type = " NM<4E>jm";
else {
DebugLog("GenerateWaves: <00><>Ǐ<EFBFBD>eHe<48>vjm<6A><57>c #" + IntegerToString(i));
continue;
}
// kXEQjm<EFBFBD>W<EFBFBD>Oo`
waves[wave_count].start_index = start.index;
waves[wave_count].start_price = start.price;
waves[wave_count].end_index = end.index;
waves[wave_count].end_price = end.price;
waves[wave_count].amplitude = (end.price / start.price - 1) * 100;
DebugLog("GenerateWaves: ubjm<6A>W #" + IntegerToString(wave_count + 1) +
" {|<7C>W=" + waves[wave_count].wave_type +
" E^<5E>^=" + DoubleToString(waves[wave_count].amplitude, 2) + "%");
wave_count++;
}
DebugLog("GenerateWaves: qQub " + IntegerToString(wave_count) + " *Njm<6A>W");
return wave_count > 0;
}
//+------------------------------------------------------------------+
//| ;N<EFBFBD>Qpe - jm<EFBFBD>W<EFBFBD>hKmeQ<EFBFBD>S |
//+------------------------------------------------------------------+
bool DetectWaves(const int rates_total, const MqlRates &rates[],
WaveInfo &waves[], int &wave_count)
{
DebugLog("====== DetectWaves _<>YgbL<62> ======");
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>eQ<EFBFBD>Spe
if(rates_total <= 0) {
DebugLog("DetectWaves: <00>eHe<48>vrates_total<P");
return false;
}
// 1. <EFBFBD><EFBFBD><EFBFBD>{<EFBFBD><EFBFBD><EFBFBD>Rch<EFBFBD>ATR + MACD <EFBFBD>
double atr = CalculateATR(rates_total, rates);
if(atr <= 0) {
DebugLog("DetectWaves: ATR<00><><EFBFBD>{1Y%<25>b:N<><4E>");
return false;
}
double macd_line[], signal_line[], histogram[];
if(!CalculateMACD(rates_total, rates, macd_line, signal_line, histogram)) {
DebugLog("DetectWaves: MACD<00><><EFBFBD>{1Y%<25>");
return false;
}
// 2. <EFBFBD>hKmP <EFBFBD><EFBFBD>g<P<EFBFBD>p
ExtremePoint extremes[];
int ext_count = 0;
if(!DetectExtremes(rates_total, rates, atr, extremes, ext_count)) {
DebugLog("DetectWaves: *g<>hKm0RP <09><>g<P<>p");
return false;
}
// 3. [{ <EFBFBD> gHe<EFBFBD>g<P<EFBFBD>p
ExtremePoint valid_extremes[];
int valid_count = 0;
if(!FilterValidExtremes(rates_total, rates, extremes, ext_count, histogram, valid_extremes, valid_count)) {
DebugLog("DetectWaves: gHe<48>g<P<>p N<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>e<EFBFBD>l<EFBFBD>gbjm<EFBFBD>W");
return false;
}
// 4. ubjm<EFBFBD>Wpenc
bool result = GenerateWaves(valid_extremes, valid_count, waves, wave_count);
if(result) {
DebugLog("====== DetectWaves gbL<62>b<>R <0C>qQ<71>hKm0R " + IntegerToString(wave_count) + " *Njm<6A>W ======");
} else {
DebugLog("====== DetectWaves gbL<62>1Y%<25> ======");
}
return result;
}
//+------------------------------------------------------------------+
//| KmՋ<EFBFBD>Qpe - (WMT5<EFBFBD>Vh<EFBFBD>-N>f:y<EFBFBD>~<EFBFBD>g |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// nd<EFBFBD><EFBFBD>Vh<EFBFBD>
N<EFBFBD>v@b g<EFBFBD>[a<EFBFBD>
ObjectsDeleteAll(ChartID());
}
//+------------------------------------------------------------------+
//| <EFBFBD>[<EFBFBD>e<EFBFBD>f<EFBFBD>e - <EFBFBD>k9hK<EFBFBD>~<EFBFBD><EFBFBD>TT<EFBFBD>hKmjm<EFBFBD>W |
//+------------------------------------------------------------------+
void OnTick()
{
// :N<EFBFBD>N<EFBFBD>Q\CPUO(u<EFBFBD>s <EFBFBD><EFBFBD>m<EFBFBD>R<EFBFBD>e<EFBFBD><EFBFBD>Ǐ<EFBFBD>n<EFBFBD><EFBFBD>k5<EFBFBD>y<EFBFBD>SgbL<EFBFBD>N!k <EFBFBD>
static datetime last_execution = 0;
if(TimeCurrent() - last_execution < 5) return;
last_execution = TimeCurrent();
DebugLog("OnTick: _<>YgbL<62>jm<6A>W<EFBFBD>hKm");
MqlRates rates[];
int rates_total = CopyRates(_Symbol, _Period, 0, Bars(_Symbol, _Period), rates);
DebugLog("OnTick: rates_total = " + IntegerToString(rates_total));
if(rates_total < 100) {
DebugLog("OnTick: penc N<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\1009hK<EFBFBD>~");
return; // nx<EFBFBD>Openc<EFBFBD><EFBFBD>Y
}
// >f:y<EFBFBD>Ջ<EFBFBD>Oo`0R<EFBFBD>Vh<EFBFBD>
if(Show_Debug_Info) {
string debug_text = StringFormat("<00>hKm<4B>e<EFBFBD><65>: %s\nK<00>~peϑ: %d\nS_MR<4D>T<EFBFBD>y: %s\nS_MRhTg: %s",
TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES),
rates_total, _Symbol, EnumToString(_Period));
// R<EFBFBD>^b<EFBFBD>f<EFBFBD>e<EFBFBD>Ջ<EFBFBD>Oo`<EFBFBD>e,g<EFBFBD>[a<EFBFBD>
string debug_obj_name = "debug_info";
if(ObjectFind(ChartID(), debug_obj_name) < 0) {
ObjectCreate(ChartID(), debug_obj_name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_CORNER, 0);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_YDISTANCE, 10);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_COLOR, clrBlue);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_BGCOLOR, 16776960);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_BORDER_TYPE, 0);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_XSIZE, 200);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_YSIZE, 80);
}
ObjectSetString(ChartID(), debug_obj_name, OBJPROP_TEXT, debug_text);
}
WaveInfo waves[];
int wave_count = 0;
if(DetectWaves(rates_total, rates, waves, wave_count))
{
DebugLog("OnTick: <00>hKmb<>R <0C><>QY(W<>Vh<56>
N<EFBFBD>~6Rjm<EFBFBD>W");
// nd<EFBFBD><EFBFBD>e<EFBFBD>vjm<EFBFBD>Wh<EFBFBD><EFBFBD>
ObjectsDeleteAll(ChartID());
// ͑<EFBFBD>e<EFBFBD>m<EFBFBD>R<EFBFBD>Ջ<EFBFBD>Oo`
if(Show_Debug_Info) {
string debug_text = StringFormat("<00>hKm<4B>e<EFBFBD><65>: %s\nK<00>~peϑ: %d\nS_MR<4D>T<EFBFBD>y: %s\nS_MRhTg: %d\n<00>hKm0Rjm<6A>Wpe: %d",
TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES),
rates_total, _Symbol, _Period, wave_count);
string debug_obj_name = "debug_info";
if(ObjectFind(ChartID(), debug_obj_name) < 0) {
ObjectCreate(ChartID(), debug_obj_name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_CORNER, 0);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_YDISTANCE, 10);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_COLOR, clrBlue);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_BGCOLOR, 16776960);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_BORDER_TYPE, 0);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_XSIZE, 200);
ObjectSetInteger(ChartID(), debug_obj_name, OBJPROP_YSIZE, 100);
}
ObjectSetString(ChartID(), debug_obj_name, OBJPROP_TEXT, debug_text);
}
// (W<EFBFBD>Vh<EFBFBD>
N<EFBFBD>~6Rjm<EFBFBD>W<EFBFBD><EFBFBD>wb_+<EFBFBD>eW[ <EFBFBD>
for(int i = 0; i < wave_count; i++)
{
// <EFBFBD>~6Rjm<EFBFBD>Ẁof<EFBFBD>wb_
string rect_name = "wave_rect_" + IntegerToString(i);
// nx<EFBFBD>O<EFBFBD>[a<EFBFBD>R<EFBFBD>^b<EFBFBD>R
if(!ObjectCreate(ChartID(), rect_name, OBJ_RECTANGLE_LABEL, 0,
waves[i].start_index, waves[i].start_price,
waves[i].end_index, waves[i].end_price)) {
DebugLog("OnTick: R<>^<5E>wb_<62>[a<>1Y%<25> #" + IntegerToString(i) + ", <19><><EFBFBD>x: " + IntegerToString(GetLastError()));
continue;
}
// <EFBFBD><EFBFBD>n<EFBFBD>wb_^\'`
ObjectSetInteger(ChartID(), rect_name, OBJPROP_COLOR,
(waves[i].wave_type == "
NGSjm") ? clrGreen : clrRed);
ObjectSetInteger(ChartID(), rect_name, OBJPROP_BORDER_COLOR,
(waves[i].wave_type == "
NGSjm") ? clrGreen : clrRed);
ObjectSetInteger(ChartID(), rect_name, OBJPROP_STYLE, 0);
ObjectSetInteger(ChartID(), rect_name, OBJPROP_WIDTH, 1);
ObjectSetInteger(ChartID(), rect_name, OBJPROP_BACK, true);
// <EFBFBD>~6Rjm<EFBFBD>W<EFBFBD>Oo`<EFBFBD>eW[
string text_name = "wave_text_" + IntegerToString(i);
string text = StringFormat("jm%d: %s (%.2f%%)", i+1, waves[i].wave_type, waves[i].amplitude);
// nx<EFBFBD>O<EFBFBD>eW[<EFBFBD>[a<EFBFBD>R<EFBFBD>^b<EFBFBD>R
if(!ObjectCreate(ChartID(), text_name, OBJ_TEXT, 0,
(waves[i].start_index + waves[i].end_index)/2,
(waves[i].start_price + waves[i].end_price)/2)) {
DebugLog("OnTick: R<>^<5E>eW[<5B>[a<>1Y%<25> #" + IntegerToString(i) + ", <19><><EFBFBD>x: " + IntegerToString(GetLastError()));
continue;
}
// <EFBFBD><EFBFBD>n<EFBFBD>eW[^\'`
ObjectSetString(ChartID(), text_name, OBJPROP_TEXT, text);
ObjectSetInteger(ChartID(), text_name, OBJPROP_COLOR, clrBlue);
ObjectSetInteger(ChartID(), text_name, OBJPROP_FONTSIZE, 16);
DebugLog("OnTick: b<>R<EFBFBD>~6Rjm<6A>W #" + IntegerToString(i+1) + ": " + waves[i].wave_type);
}
}
else {
DebugLog("OnTick: *g<>hKm0R gHejm<6A>W");
// <EFBFBD>N6q>f:y<EFBFBD>Ջ<EFBFBD>Oo`
if(Show_Debug_Info) {
string debug_text = StringFormat("<00>hKm<4B>e<EFBFBD><65>: %s\nK<00>~peϑ: %d\nS_MR<4D>T<EFBFBD>y: %s\nS_MRhTg: %d\n*g<>hKm0Rjm<6A>W",
TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES),
rates_total, _Symbol, _Period);
string debug_obj_name = "debug_info";
if(ObjectFind(ChartID(), debug_obj_name) < 0) {
ObjectCreate(ChartID(), debug_obj_name, OBJ_LABEL, 0, 0, 0);
}
ObjectSetString(ChartID(), debug_obj_name, OBJPROP_TEXT, debug_text);
}
}
}
//+------------------------------------------------------------------+