ICTLibraryExamples/Sensei/Est2024/Main.mqh
227 lines
9.4 KiB
MQL5
Nique_372
2025-11-26 07:19:36 -05:00
//+------------------------------------------------------------------+
//| Main.mqh |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372/news |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372/news"
#property strict
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Defines.mqh"
Nique_372
2026-10-23 21:51:38 -05:00
#include <TSN\\MQLArticles\\Utils\\Fibonacci.mqh>
Nique_372
2025-11-26 07:19:36 -05:00
// Source: https://www.youtube.com/watch?v=msQCfwfjEvU&t=7s
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Nique_372
2026-10-23 21:51:38 -05:00
class CEstrategia : public TSN::CStrategyBase
Nique_372
2025-11-26 07:19:36 -05:00
{
private:
Nique_372
2026-11-06 13:21:07 -05:00
TSN::CFibbo m_fibbo;
Nique_372
2026-11-06 15:35:47 -05:00
ENUM_EST2024_STATE m_state;
Nique_372
2025-11-26 07:19:36 -05:00
double m_price_ds;
Nique_372
2026-11-06 13:21:07 -05:00
int m_fibbo_level_idx;
Nique_372
2025-11-26 07:19:36 -05:00
//---
void OpenOrder(ENUM_POSITION_TYPE type);
void Clean();
public:
Nique_372
2026-11-06 13:21:07 -05:00
CEstrategia(ulong magic_number_, string symbol_, bool draw_fibbo, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0,
Nique_372
2025-11-26 07:19:36 -05:00
int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED);
~CEstrategia(void);
Nique_372
2026-01-02 10:21:37 -05:00
//---
Nique_372
2026-11-06 15:35:47 -05:00
bool Init(color clr_fibbo, double level_elegido, const string& levels, const string& clrs);
Nique_372
2026-11-06 13:21:07 -05:00
void OnNewBar(const datetime curr_time) override final;
void OnTick(const datetime curr_time) override final { }
Nique_372
2026-11-06 15:35:47 -05:00
//--- Error
static void FormatTrace(const TSN::TSNErrorFrame &trace[], int &trace_idx, string &out);
Nique_372
2025-11-26 07:19:36 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Nique_372
2026-11-06 13:21:07 -05:00
CEstrategia::CEstrategia(ulong magic_number_, string symbol_, bool draw_fibbo, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0,
Nique_372
2025-11-26 07:19:36 -05:00
int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED)
Nique_372
2026-11-06 15:35:47 -05:00
: CStrategyBase(magic_number_, symbol_, timeframe_, chart_id_, subwindow_, max_deviation_, "Estrategia del sensei"), m_fibbo(draw_fibbo),
m_state(EST2024_STATE_BUSCAR_MITIGACION), m_price_ds(0.00), m_fibbo_level_idx(-1) // no se llama Clean() aqui: los conceptos globales aun no estan creados
Nique_372
2025-11-26 07:19:36 -05:00
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CEstrategia::~CEstrategia(void)
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Nique_372
2026-11-06 13:21:07 -05:00
bool CEstrategia::Init(color clr_fibbo, double level_elegido, const string& levels, const string& clrs)
Nique_372
2025-11-26 07:19:36 -05:00
{
Nique_372
2026-11-06 13:21:07 -05:00
// estos ya tiran su "trow"
if(!m_fibbo.Create(m_chart_id, "FibboStrategySensei", m_subwindow, clr_fibbo, STYLE_SOLID, 1, "Fibbo", true))
return false;
if(!m_fibbo.InitFibbo(levels, clrs, STYLE_SOLID, 1, ','))
return false;
// este no tira "trow" simpelte callea hashmap y ese a su vez como es de bajo nivel tampoco
// debido a eso hace falta uqe nosotros lo hagemos
if(!m_fibbo.GetLevelIndex(level_elegido, m_fibbo_level_idx))
Nique_372
2026-11-06 15:35:47 -05:00
return TSN::CErrorTrace::FailInit<CEstrategia>(ESTRATEGIA_ERR_FAILED_CALC_LEVEL_IDX, TSN::CBitsReinterprete::ToBasic<ulong, double>(level_elegido));
Nique_372
2026-11-06 13:21:07 -05:00
return true;
Nique_372
2025-11-26 07:19:36 -05:00
}
Nique_372
2026-11-06 15:35:47 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CEstrategia::FormatTrace(const TSN::TSNErrorFrame &trace[], int &trace_idx, string &out)
{
TSNSTD_ERRMAN_PUSHINI(out, trace_idx)
switch(trace[trace_idx].code)
{
case ESTRATEGIA_ERR_NOT:
TSNSTD_ERRMAN_PUSHOUT(out, "Not error", trace_idx)
break;
case ESTRATEGIA_ERR_FAILED_CALC_LEVEL_IDX:
TSNSTD_ERRMAN_PUSHOUT(out, StringFormat("The chosen fibbo level [%.4f] is not one of the fibbo levels (InpStrategyFibboLevels)",
TSN::CBitsReinterprete::ToBasic<double, ulong>(trace[trace_idx].info)), trace_idx)
break;
default:
TSNSTD_ERRMAN_PUSHOUT(out, "Unknow error", trace_idx)
break;
}
}
Nique_372
2025-11-26 07:19:36 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CEstrategia::Clean(void)
{
g_support_resistence.DeleteAll();
g_zz.SetParo(); // Nuevo hay que mteer el set paro dado que zz se interumpe
Nique_372
2026-11-06 15:35:47 -05:00
m_state = EST2024_STATE_BUSCAR_MITIGACION;
Nique_372
2025-11-26 07:19:36 -05:00
m_price_ds = 0.00;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
Nique_372
2026-02-14 17:50:28 -05:00
void CEstrategia::OnNewBar(const datetime curr_time)
Nique_372
2025-11-26 07:19:36 -05:00
{
if(risk.GetPositionsTotal() > 0)
return;
if(g_session.EnSesion())
{
g_support_resistence.OnNewBar();
g_zz.OnNewBar();
//---
Nique_372
2026-11-06 15:35:47 -05:00
do
Nique_372
2025-11-26 07:19:36 -05:00
{
Nique_372
2026-11-06 15:35:47 -05:00
switch(m_state)
Nique_372
2025-11-26 07:19:36 -05:00
{
Nique_372
2026-11-06 15:35:47 -05:00
//--- Esperando la mitigacion de un soporte/resistencia, al ocurrir se dibuja el fibbo y se decide la direccion
case EST2024_STATE_BUSCAR_MITIGACION:
Nique_372
2025-11-26 07:19:36 -05:00
{
Nique_372
2026-11-06 15:35:47 -05:00
if(g_support_resistence.SizeResistenciasMitigadas() > 0 && g_support_resistence.GetResisteciaMitigada(0).initial_type == SOPORTE)
{
::SymbolInfoTick(m_symbol, m_tick);
const Swings swing = g_zz.GetSwingHighMasCeracanoPorPrecioYTime(m_tick.bid, SWING_MAYOR_A_TARGET_PRICE);
double minimo = ::iLow(m_symbol, m_timeframe, ::iLowest(m_symbol, m_timeframe, MODE_LOW, ::iBarShift(m_symbol, m_timeframe, swing.time), 0));
m_fibbo.Move(swing.time, m_tick.time, swing.price, minimo);
m_price_ds = m_fibbo.GetLevelPrice(m_fibbo_level_idx);
m_state = EST2024_STATE_BUSCAR_VENTAS;
continue; // de una al siguiente
}
else
if(g_support_resistence.SizeSoportesMitigados() > 0 && g_support_resistence.GetSoporteMitigado(0).initial_type == RESISTENCIA)
{
::SymbolInfoTick(m_symbol, m_tick);
const Swings swing = g_zz.GetSwingLowMasCeracanoPorPrecioYTime(m_tick.bid, SWING_MENOR_A_TARGET_PRICE);
double maximo = ::iHigh(m_symbol, m_timeframe, ::iHighest(m_symbol, m_timeframe, MODE_HIGH, ::iBarShift(m_symbol, m_timeframe, swing.time), 0));
m_fibbo.Move(swing.time, m_tick.time, swing.price, maximo);
m_price_ds = m_fibbo.GetLevelPrice(m_fibbo_level_idx);
m_state = EST2024_STATE_BUSCAR_COMPRAS;
continue; // de una al siguiente
}
break;
Nique_372
2025-11-26 07:19:36 -05:00
}
Nique_372
2026-11-06 15:35:47 -05:00
//--- Entrada de venta: la vela previa reacciona al nivel del fibbo
case EST2024_STATE_BUSCAR_VENTAS:
Nique_372
2025-11-26 07:19:36 -05:00
{
Nique_372
2026-11-06 15:35:47 -05:00
const double prev_close = ::iClose(m_symbol, m_timeframe, 1);
const double prev_high = ::iHigh(m_symbol, m_timeframe, 1);
if(prev_high > m_price_ds && m_price_ds > prev_close) // Reacciona al 50%
OpenOrder(POSITION_TYPE_SELL);
break;
Nique_372
2025-11-26 07:19:36 -05:00
}
Nique_372
2026-11-06 15:35:47 -05:00
//--- Entrada de compra
case EST2024_STATE_BUSCAR_COMPRAS:
Nique_372
2025-11-26 07:19:36 -05:00
{
Nique_372
2026-11-06 15:35:47 -05:00
const double prev_close = ::iClose(m_symbol, m_timeframe, 1);
Nique_372
2025-11-26 07:19:36 -05:00
const double prev_low = ::iLow(m_symbol, m_timeframe, 1);
if(m_price_ds > prev_low && prev_close > m_price_ds) // Reacciona al 50%
OpenOrder(POSITION_TYPE_BUY);
Nique_372
2026-11-06 15:35:47 -05:00
break;
Nique_372
2025-11-26 07:19:36 -05:00
}
Nique_372
2026-11-06 15:35:47 -05:00
default:
break;
}
//---
break;
Nique_372
2025-11-26 07:19:36 -05:00
}
Nique_372
2026-11-06 15:35:47 -05:00
while(true);
Nique_372
2025-11-26 07:19:36 -05:00
}
else
if(g_session.IsEndSession())
{
Clean(); // Finalizacion de sesion
}
}
//+------------------------------------------------------------------+
//| Open Order Default |
//+------------------------------------------------------------------+
void CEstrategia::OpenOrder(ENUM_POSITION_TYPE type)
{
::SymbolInfoTick(m_symbol, m_tick);
if(type == POSITION_TYPE_BUY)
{
double entry = m_tick.ask;
double sl = GetSL(entry, type, m_tick.time);
double tp = GetTP(entry, type, m_tick.time);
Nique_372
2026-11-01 22:12:14 -05:00
risk.SetStopLoss(m_symbol, entry - sl);
Nique_372
2025-11-26 07:19:36 -05:00
double l = m_LOT_SIZE > 0.00 ? m_LOT_SIZE : risk.GetLote(ORDER_TYPE_BUY, entry, m_max_deviation, 0);
m_trade.Buy(l, m_symbol, entry, sl, tp, "Ea buy");
}
else
if(type == POSITION_TYPE_SELL)
{
double entry = m_tick.bid;
double sl = GetSL(entry, type, m_tick.time);
double tp = GetTP(entry, type, m_tick.time);
Nique_372
2026-11-01 22:12:14 -05:00
risk.SetStopLoss(m_symbol, sl - entry);
Nique_372
2025-11-26 07:19:36 -05:00
double l = m_LOT_SIZE > 0.00 ? m_LOT_SIZE : risk.GetLote(ORDER_TYPE_SELL, entry, m_max_deviation, 0);
m_trade.Sell(l, m_symbol, entry, sl, tp, "Ea sell");
}
Clean();
}
//+------------------------------------------------------------------+