//+------------------------------------------------------------------+ //| 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 // 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(ESTRATEGIA_ERR_FAILED_CALC_LEVEL_IDX, TSN::CBitsReinterprete::ToBasic(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(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(); } //+------------------------------------------------------------------+