| //+------------------------------------------------------------------+
|
| //| 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"
|
| #include <TSN\\MQLArticles\\Utils\\Fibonacci.mqh>
|
|
|
| // Source: https://www.youtube.com/watch?v=msQCfwfjEvU&t=7s
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| class CEstrategia : public TSN::CStrategyBase
|
| {
|
| private:
|
| TSN::CFibbo m_fibbo;
|
| ENUM_EST2024_STATE m_state;
|
| double m_price_ds;
|
| int m_fibbo_level_idx;
|
|
|
| //---
|
| void OpenOrder(ENUM_POSITION_TYPE type);
|
| void Clean();
|
|
|
| public:
|
| CEstrategia(ulong magic_number_, string symbol_, bool draw_fibbo, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0,
|
| int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED);
|
| ~CEstrategia(void);
|
|
|
| //---
|
| bool Init(color clr_fibbo, double level_elegido, const string& levels, const string& clrs);
|
| void OnNewBar(const datetime curr_time) override final;
|
| void OnTick(const datetime curr_time) override final { }
|
|
|
| //--- Error
|
| static void FormatTrace(const TSN::TSNErrorFrame &trace[], int &trace_idx, string &out);
|
| };
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| CEstrategia::CEstrategia(ulong magic_number_, string symbol_, bool draw_fibbo, ENUM_TIMEFRAMES timeframe_ = PERIOD_CURRENT, long chart_id_ = 0,
|
| int subwindow_ = 0, ulong max_deviation_ = NO_MAX_DEVIATION_DEFINED)
|
| : 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
|
| {
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| CEstrategia::~CEstrategia(void)
|
| {
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| bool CEstrategia::Init(color clr_fibbo, double level_elegido, const string& levels, const string& clrs)
|
| {
|
| // 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))
|
| return TSN::CErrorTrace::FailInit<CEstrategia>(ESTRATEGIA_ERR_FAILED_CALC_LEVEL_IDX, TSN::CBitsReinterprete::ToBasic<ulong, double>(level_elegido));
|
| return true;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| 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;
|
| }
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CEstrategia::Clean(void)
|
| {
|
| g_support_resistence.DeleteAll();
|
| g_zz.SetParo(); // Nuevo hay que mteer el set paro dado que zz se interumpe
|
| m_state = EST2024_STATE_BUSCAR_MITIGACION;
|
| m_price_ds = 0.00;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CEstrategia::OnNewBar(const datetime curr_time)
|
| {
|
| if(risk.GetPositionsTotal() > 0)
|
| return;
|
|
|
| if(g_session.EnSesion())
|
| {
|
| g_support_resistence.OnNewBar();
|
| g_zz.OnNewBar();
|
|
|
| //---
|
| do
|
| {
|
| switch(m_state)
|
| {
|
| //--- Esperando la mitigacion de un soporte/resistencia, al ocurrir se dibuja el fibbo y se decide la direccion
|
| case EST2024_STATE_BUSCAR_MITIGACION:
|
| {
|
| 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;
|
| }
|
|
|
| //--- Entrada de venta: la vela previa reacciona al nivel del fibbo
|
| case EST2024_STATE_BUSCAR_VENTAS:
|
| {
|
| 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;
|
| }
|
|
|
| //--- Entrada de compra
|
| case EST2024_STATE_BUSCAR_COMPRAS:
|
| {
|
| const double prev_close = ::iClose(m_symbol, m_timeframe, 1);
|
| 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);
|
| break;
|
| }
|
| default:
|
| break;
|
| }
|
|
|
| //---
|
| break;
|
| }
|
| while(true);
|
| }
|
| 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);
|
|
|
| risk.SetStopLoss(m_symbol, entry - sl);
|
| 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);
|
|
|
| risk.SetStopLoss(m_symbol, sl - entry);
|
| 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();
|
| }
|
| //+------------------------------------------------------------------+
|