mình mới học lập trình mql4, đang viết 1 con ea để tìm nến a hoặc nến d theo logic, mà con ea mình viết, nó luôn tìm sai nến a và nến d. mình không biết lỗi ở đâu, mong những bạn có nhiều kinh nghiệm hơn giúp mình sửa lỗi.
Hình 1: Hình ảnh về việc nến a bị đánh dấu sai
Logic của đoạn code :
Ban đầu, khi khởi chạy ea , trong cửa số properties sẽ hiện nút sổ để lựa chọn đỉnh cao nhất hoặc đáy thấp nhất, và 1 khung nhập dữ liệu cho phép người dùng nhập vào 1 giá trị số. (chỉ hiển thị 1 lần lúc khởi động)
//+------------------------------------------------------------------+
//| Sample.mq4 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property strict
// khung nhập dữ liệu trong cửa số propertiles, để tìm nến x xanh hoặc x đỏ
extern double InputPrice = 0.0;
extern bool FindHighest = true; // true để tìm đỉnh cao nhất có giá bằng giá đã nhập , false để tìm đáy thấp nhất có giá bằng giá đã nhập
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
FindAndMarkCandle();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete("MarkArrow");
ObjectDelete("MarkArrowA");
ObjectDelete("MarkArrowD");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
//| tìm và đánh dấu nến x xanh hoặc x đỏ |
//+------------------------------------------------------------------+
void FindAndMarkCandle()
{
int limit = 500; // tìm trong 500 cây nến
int xCandleIndex = -1;
// tìm nến x
for (int i = 0; i < limit; i++)
{
int index = i + 1; // bắt đầu tìm từ nến số 0
if (FindHighest && High[index] == InputPrice)
{
// đánh dấu nến x xanh với mũi tên xanh
DrawArrow(index, High[index], clrRed, "MarkArrow");
xCandleIndex = index;
break;
}
else if (!FindHighest && Low[index] == InputPrice)
{
// đánh dấu nến x đỏ với mũi tên đỏ
DrawArrow(index, Low[index], clrBlue , "MarkArrow");
xCandleIndex = index;
break;
}
}
// tìm và đánh dấu nến a hoặc d
if (FindHighest)
{
FindAndMarkACandle(xCandleIndex);
}
else
{
FindAndMarkDCandle(xCandleIndex);
}
}
//+------------------------------------------------------------------+
//| tìm và đánh dấu nến a sau nến x đỏ |
//+------------------------------------------------------------------+
void FindAndMarkACandle(int xCandleIndex)
{
for (int i = xCandleIndex - 1; i >= 1; i--)
{
if (High > High[i + 1] && !namtrongdinhdaynenphiatruoc(xCandleIndex, i, High, Low) && daybiphaboicaynenphiasau(i))
{
// đánh dấu nến a bằng mũi tên vàng
DrawArrow(i, High, clrYellow, "MarkArrowA");
return;
}
}
}
//+------------------------------------------------------------------+
//| tìm và đánh dấu nến d sau nến x xanh |
//+------------------------------------------------------------------+
void FindAndMarkDCandle(int xCandleIndex)
{
for (int i = xCandleIndex - 1; i >= 1; i--)
{
if (Low < Low[i + 1] && !namtrongdinhdaynenphiatruoc(xCandleIndex, i, High, Low) && dinhbiphaboicaynenphiasau(i))
{
// đánh dấu nến d bằng mũi tên vàng
DrawArrow(i, Low, clrYellow, "MarkArrowD");
return;
}
}
}
//+------------------------------------------------------------------+
//| kiểm tra nến a có nằm trong đỉnh đáy cây nến nào trước đó tính từ nến x đỏ / kiểm tra nến d có nằm trong đỉnh đáy cây nến nào trước đó tính từ nến x xanh |
//+------------------------------------------------------------------+
bool namtrongdinhdaynenphiatruoc(int xIndex, int targetIndex, double targetHigh, double targetLow)
{
for (int i = targetIndex + 1; i < xIndex; i++)
{
if (High >= targetHigh && Low <= targetLow)
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| kiểm tra đáy nến a bị phá bằng 1 cây nến phía sau không |
//+------------------------------------------------------------------+
bool daybiphaboicaynenphiasau(int index)
{
for (int i = index - 1; i >= 1; i--)
{
if (Low < Low[index])
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| kiểm tra đỉnh nến d bị phá bằng 1 cây nến phía sau không|
//+------------------------------------------------------------------+
bool dinhbiphaboicaynenphiasau(int index)
{
for (int i = index - 1; i >= 1; i--)
{
if (High > High[index])
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| định dạng mũi tên trên biểu đồ |
//+------------------------------------------------------------------+
void DrawArrow(int index, double price, color arrowColor, string arrowName)
{
if (ObjectFind(arrowName) != -1)
{
ObjectDelete(arrowName);
}
ObjectCreate(0, arrowName, OBJ_ARROW, 0, Time[index], price);
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 6);
ObjectSetInteger(0, arrowName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
}
Hình 1: Hình ảnh về việc nến a bị đánh dấu sai
Logic của đoạn code :
Ban đầu, khi khởi chạy ea , trong cửa số properties sẽ hiện nút sổ để lựa chọn đỉnh cao nhất hoặc đáy thấp nhất, và 1 khung nhập dữ liệu cho phép người dùng nhập vào 1 giá trị số. (chỉ hiển thị 1 lần lúc khởi động)
- Nếu người dùng nhập giá trị và chọn đỉnh cao nhất, hệ thống sẽ tìm từ cây nến hiện tại ngược về cây nến gần nhất có đỉnh cao nhất bằng với giá trị đã nhập, và đánh dấu cây nến đó bằng mũi tên đỏ (gọi là nến x đỏ).
- tìm từ nến x đỏ đến nến hiện tại cây nến a thỏa mãn cả 3 điều kiện sau:
- nến a có đáy thấp hơn đáy của nến đằng trước,
- nến a không nằm trong đỉnh và đáy của bất kỳ cây nến nào trong số những cây nến tính từ nến x đỏ đến nến a
- nến a có đỉnh bị 1 cây nến khác phía sau phá qua ,
- đánh dấu cây nến thỏa mãn 3 điều kiện trên bằng mũi tên vàng
- Nếu người dùng nhập giá trị và chọn đáy thấp nhất, hệ thống sẽ tìm từ cây nến hiện tại ngược về cây nến gần nhất có đáy thấp nhất bằng với giá trị đã nhập, và đánh dấu cây nến đó bằng mũi tên xanh (gọi là nến x xanh).
- Tìm từ nến x xanh đến nến hiện tại cây nến d thỏa mãn cả 3 điều kiện sau:
- Nến d có đỉnh cao hơn đỉnh của nến đằng trước,
- Nến d không nằm trong đỉnh và đáy của bất kỳ cây nến nào trong số những cây nến tính từ nến x xanh đến nến d
- Nến d có đáy bị 1 cây nến khác phía sau phá qua ,
- đánh dấu cây nến thỏa mãn 3 điều kiện trên bằng mũi tên vàng ( vd hình 1)
đoạn code cần sửa
//+------------------------------------------------------------------+
//| Sample.mq4 |
//| Copyright 2024, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property strict
// khung nhập dữ liệu trong cửa số propertiles, để tìm nến x xanh hoặc x đỏ
extern double InputPrice = 0.0;
extern bool FindHighest = true; // true để tìm đỉnh cao nhất có giá bằng giá đã nhập , false để tìm đáy thấp nhất có giá bằng giá đã nhập
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
FindAndMarkCandle();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete("MarkArrow");
ObjectDelete("MarkArrowA");
ObjectDelete("MarkArrowD");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
//| tìm và đánh dấu nến x xanh hoặc x đỏ |
//+------------------------------------------------------------------+
void FindAndMarkCandle()
{
int limit = 500; // tìm trong 500 cây nến
int xCandleIndex = -1;
// tìm nến x
for (int i = 0; i < limit; i++)
{
int index = i + 1; // bắt đầu tìm từ nến số 0
if (FindHighest && High[index] == InputPrice)
{
// đánh dấu nến x xanh với mũi tên xanh
DrawArrow(index, High[index], clrRed, "MarkArrow");
xCandleIndex = index;
break;
}
else if (!FindHighest && Low[index] == InputPrice)
{
// đánh dấu nến x đỏ với mũi tên đỏ
DrawArrow(index, Low[index], clrBlue , "MarkArrow");
xCandleIndex = index;
break;
}
}
// tìm và đánh dấu nến a hoặc d
if (FindHighest)
{
FindAndMarkACandle(xCandleIndex);
}
else
{
FindAndMarkDCandle(xCandleIndex);
}
}
//+------------------------------------------------------------------+
//| tìm và đánh dấu nến a sau nến x đỏ |
//+------------------------------------------------------------------+
void FindAndMarkACandle(int xCandleIndex)
{
for (int i = xCandleIndex - 1; i >= 1; i--)
{
if (High > High[i + 1] && !namtrongdinhdaynenphiatruoc(xCandleIndex, i, High, Low) && daybiphaboicaynenphiasau(i))
{
// đánh dấu nến a bằng mũi tên vàng
DrawArrow(i, High, clrYellow, "MarkArrowA");
return;
}
}
}
//+------------------------------------------------------------------+
//| tìm và đánh dấu nến d sau nến x xanh |
//+------------------------------------------------------------------+
void FindAndMarkDCandle(int xCandleIndex)
{
for (int i = xCandleIndex - 1; i >= 1; i--)
{
if (Low < Low[i + 1] && !namtrongdinhdaynenphiatruoc(xCandleIndex, i, High, Low) && dinhbiphaboicaynenphiasau(i))
{
// đánh dấu nến d bằng mũi tên vàng
DrawArrow(i, Low, clrYellow, "MarkArrowD");
return;
}
}
}
//+------------------------------------------------------------------+
//| kiểm tra nến a có nằm trong đỉnh đáy cây nến nào trước đó tính từ nến x đỏ / kiểm tra nến d có nằm trong đỉnh đáy cây nến nào trước đó tính từ nến x xanh |
//+------------------------------------------------------------------+
bool namtrongdinhdaynenphiatruoc(int xIndex, int targetIndex, double targetHigh, double targetLow)
{
for (int i = targetIndex + 1; i < xIndex; i++)
{
if (High >= targetHigh && Low <= targetLow)
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| kiểm tra đáy nến a bị phá bằng 1 cây nến phía sau không |
//+------------------------------------------------------------------+
bool daybiphaboicaynenphiasau(int index)
{
for (int i = index - 1; i >= 1; i--)
{
if (Low < Low[index])
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| kiểm tra đỉnh nến d bị phá bằng 1 cây nến phía sau không|
//+------------------------------------------------------------------+
bool dinhbiphaboicaynenphiasau(int index)
{
for (int i = index - 1; i >= 1; i--)
{
if (High > High[index])
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| định dạng mũi tên trên biểu đồ |
//+------------------------------------------------------------------+
void DrawArrow(int index, double price, color arrowColor, string arrowName)
{
if (ObjectFind(arrowName) != -1)
{
ObjectDelete(arrowName);
}
ObjectCreate(0, arrowName, OBJ_ARROW, 0, Time[index], price);
ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, 6);
ObjectSetInteger(0, arrowName, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
}
Giới thiệu sách Trading hay
Nhật Ký Giao Dịch Thực Chiến của Phù Thủy Thị trường Tài Chính
Sách chia sẻ 05 tháng giao dịch thực tế trên thị trường tài chính, sử dụng Price Action và Mô hình Biểu đồ của Phù thủy trader Peter Brandt, người có gần 50 năm kinh nghiệm trading và đạt lợi nhuận bình quân 68% lợi nhuận mỗi năm
Bài viết liên quan