forked from nique_372/MQLArticles
		
	
		
			
				
	
	
		
			535 lines
		
	
	
	
		
			36 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			535 lines
		
	
	
	
		
			36 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
//+------------------------------------------------------------------+
 | 
						|
//|                                                    Fibonacci.mqh |
 | 
						|
//|                                  Copyright 2025, Niquel Mendoza. |
 | 
						|
//|                                             https://www.mql5.com |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#property copyright "Copyright 2025, Niquel Mendoza."
 | 
						|
#property link      "https://www.mql5.com"
 | 
						|
#property strict
 | 
						|
 | 
						|
#ifndef MQH_FIBBO
 | 
						|
#define MQH_FIBBO
 | 
						|
 | 
						|
#include "..\\Utils\\GraphicObjects.mqh"
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
struct FibboLevel
 | 
						|
 {
 | 
						|
  double             level_price;
 | 
						|
  double             level_value;
 | 
						|
  color              level_color;
 | 
						|
 | 
						|
                     FibboLevel()
 | 
						|
    :                level_color(clrBlack), level_price(0.00), level_value(0.00)
 | 
						|
   {
 | 
						|
 | 
						|
   }
 | 
						|
                     FibboLevel(const FibboLevel& other)
 | 
						|
   {
 | 
						|
    this = other;
 | 
						|
   }
 | 
						|
 | 
						|
 | 
						|
 };
 | 
						|
 | 
						|
enum ENUM_MODE_NEAREST_LEVEL_FIBBO
 | 
						|
 {
 | 
						|
  FIBBO_LEVEL_MAYOR_A_TARGE_PRICE,
 | 
						|
  FIBBO_LEVEL_MENOR_A_TARGE_PRICE,
 | 
						|
 };
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#define GEN_SORT(TYPE, FIELD_ACCESS) \
 | 
						|
void SortArrayBy##FIELD_ACCESS(TYPE &array[], int left, int right) \
 | 
						|
{ \
 | 
						|
    if(left >= right) \
 | 
						|
        return; \
 | 
						|
    \
 | 
						|
    int pivotIndex = (left + right) >> 1; \
 | 
						|
    double pivotValue = array[pivotIndex].FIELD_ACCESS; \
 | 
						|
    int i = left, j = right; \
 | 
						|
    \
 | 
						|
    while(i <= j) \
 | 
						|
    { \
 | 
						|
        while(array[i].FIELD_ACCESS < pivotValue) \
 | 
						|
            i++; \
 | 
						|
        \
 | 
						|
        while(array[j].FIELD_ACCESS > pivotValue) \
 | 
						|
            j--; \
 | 
						|
        \
 | 
						|
        if(i <= j) \
 | 
						|
        { \
 | 
						|
            TYPE temp = array[i]; \
 | 
						|
            array[i] = array[j]; \
 | 
						|
            array[j] = temp; \
 | 
						|
            i++; \
 | 
						|
            j--; \
 | 
						|
        } \
 | 
						|
    } \
 | 
						|
    \
 | 
						|
 SortArrayBy##FIELD_ACCESS(array, left, j); \
 | 
						|
 SortArrayBy##FIELD_ACCESS(array, i, right); \
 | 
						|
}
 | 
						|
 | 
						|
#define GEN_SORT_HELPER(TYPE, FIELD_ACCESS) \
 | 
						|
void SortArrayBy##FIELD_ACCESS(TYPE &array[]) \
 | 
						|
{ \
 | 
						|
    int size = ArraySize(array); \
 | 
						|
    if(size > 1) \
 | 
						|
        SortArrayBy##FIELD_ACCESS(array, 0, size - 1); \
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
GEN_SORT(FibboLevel, level_value)
 | 
						|
GEN_SORT_HELPER(FibboLevel, level_value)
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
GEN_SORT(FibboLevel, level_price)
 | 
						|
GEN_SORT_HELPER(FibboLevel, level_price)
 | 
						|
 | 
						|
#undef GEN_SORT
 | 
						|
#undef GEN_SORT_HELPER
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CFibbo : public CLoggerBase
 | 
						|
 {
 | 
						|
private:
 | 
						|
  //--- Caracteristicas principales
 | 
						|
  long               chart_id;
 | 
						|
  int                subwin;
 | 
						|
  bool               create; //Indica si el fibbo ha sido creado
 | 
						|
 | 
						|
  //--- Caracteristicas del fibbo
 | 
						|
  string             obj_name;
 | 
						|
  double             price_2;
 | 
						|
  double             price_1;
 | 
						|
  datetime           init_fibbo;
 | 
						|
 | 
						|
  //---
 | 
						|
  double             max_level;
 | 
						|
  double             min_level;
 | 
						|
 | 
						|
  //---
 | 
						|
  int                total_fibbo;
 | 
						|
  FibboLevel         fibbo_levels[];
 | 
						|
 | 
						|
  //---
 | 
						|
  int8_t             digits;
 | 
						|
 | 
						|
 | 
						|
  //--- Find
 | 
						|
  bool               CheckIndex(const int index) const;
 | 
						|
 | 
						|
  //--- Add
 | 
						|
  bool               AddLevel(const FibboLevel &new_level);
 | 
						|
 | 
						|
  //---
 | 
						|
  void               CalculatePriceLevelsFibbo();
 | 
						|
 | 
						|
public:
 | 
						|
                     CFibbo();
 | 
						|
                    ~CFibbo(void);
 | 
						|
  //--- Creacion
 | 
						|
  bool               Create(const long      chart_ID,      // ID del gráfico
 | 
						|
                            const string          name, // nombre del objeto
 | 
						|
                            const int             sub_window,    // número de subventana
 | 
						|
                            const color           clr,      // color del objeto
 | 
						|
                            const ENUM_LINE_STYLE style, // estilo de las líneas del objeto
 | 
						|
                            const int             width,
 | 
						|
                            const string      tooltip,         // grosor de las líneas del objeto
 | 
						|
                            const bool            back = false,      // al fondo
 | 
						|
                            const bool            selection = false,  // seleccionar para mover
 | 
						|
                            const long            z_order = 0);
 | 
						|
 | 
						|
 | 
						|
  //--- Objetos Graficos\Niveles
 | 
						|
  bool               SetLevels(string vals,         // valores de las líneas del nivel
 | 
						|
                               string clrs,         // color de las líneas del nivel
 | 
						|
                               ENUM_LINE_STYLE styles,         // estilo de las líneas del nivel
 | 
						|
                               int             widths,
 | 
						|
                               ushort separator_str
 | 
						|
                              );         // grosor de las líneas del nivel
 | 
						|
 | 
						|
  void               ModifyLevel(double level, color new_color = clrNONE, ENUM_LINE_STYLE new_style  = WRONG_VALUE, int new_widt = -1); //Cambiar un nivel
 | 
						|
  void               ModifyLevel(int level_index, color new_color = clrNONE, ENUM_LINE_STYLE new_style  = WRONG_VALUE, int new_widt = -1); //Cambiar un nivel
 | 
						|
 | 
						|
  //--- Modificar el donde se ubica el fibbo
 | 
						|
  void               Move(datetime new_init, datetime new_end, double price1, double price2); //Momer el fibbo completamente
 | 
						|
  void               UpdateTime2(datetime new_end); //Solo actulizar el fibbo a un nuevo time2
 | 
						|
 | 
						|
  //--- Funciones para trabajar con niveles
 | 
						|
  inline double      GetLevelPrice(const double level_val) const; //Obtener el precio actual de un nivel(double)
 | 
						|
  int                GetLevelIndex(const double level_val) const; //Obtener el indice en el array de un nivel(double)
 | 
						|
  void               GetArrayLevel(double &levels[], bool contains_lebel_0_100 = false) const;
 | 
						|
  double             GetNearestLevel(double target_price, ENUM_MODE_NEAREST_LEVEL_FIBBO mode) const;
 | 
						|
 | 
						|
  //--- Getter - Max\Min Level
 | 
						|
  inline double      MaxLevel() const { return this.max_level; }
 | 
						|
  inline double      MinLevel() const { return this.min_level; }
 | 
						|
 | 
						|
  //---
 | 
						|
  void               PrintInfo();
 | 
						|
 };
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CFibbo::~CFibbo()
 | 
						|
 {
 | 
						|
  ArrayFree(fibbo_levels);
 | 
						|
  ObjectDelete(this.chart_id, this.obj_name);
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
CFibbo::CFibbo()
 | 
						|
  : init_fibbo(wrong_datetime), price_1(0), price_2(0), subwin(0), chart_id(0), max_level(0), min_level(0)
 | 
						|
 {
 | 
						|
  ArrayResize(fibbo_levels, 0);
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//|                                                                  |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::PrintInfo(void)
 | 
						|
 {
 | 
						|
  int d = fmax(3, digits);
 | 
						|
  ArrayPrint(this.fibbo_levels, d, " | ");
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
bool CFibbo::AddLevel(const FibboLevel &new_level)
 | 
						|
 {
 | 
						|
  const static double fibbo_min_value = 0.00040; //Considerar esto, de pormedio un fibbo level como maximo tiene 3 decimales
 | 
						|
 | 
						|
  for(int i = 0; i < total_fibbo; i++)
 | 
						|
   {
 | 
						|
    if(fabs(fibbo_levels[i].level_value - new_level.level_value) <= fibbo_min_value)
 | 
						|
     {
 | 
						|
      LogWarning(StringFormat("No se agregara el fibbo level %f dado que ya existe", new_level.level_value), FUNCION_ACTUAL);
 | 
						|
      return false;
 | 
						|
     }
 | 
						|
   }
 | 
						|
 | 
						|
  total_fibbo++;
 | 
						|
  AddArrayNoVerification(fibbo_levels, new_level, 0);
 | 
						|
  return true;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
double CFibbo::GetNearestLevel(double target_price, ENUM_MODE_NEAREST_LEVEL_FIBBO mode) const
 | 
						|
 {
 | 
						|
  if(total_fibbo == 0)
 | 
						|
    return 0.00;
 | 
						|
 | 
						|
//---
 | 
						|
  FibboLevel temp_levels[];
 | 
						|
  ArrayResize(temp_levels, total_fibbo);
 | 
						|
  ArrayCopyCts(temp_levels, fibbo_levels);
 | 
						|
 | 
						|
//---
 | 
						|
  SortArrayBylevel_price(temp_levels);
 | 
						|
 | 
						|
  if(mode == FIBBO_LEVEL_MAYOR_A_TARGE_PRICE)
 | 
						|
   {
 | 
						|
    for(int i = 0; i < total_fibbo; i++)
 | 
						|
     {
 | 
						|
      if(temp_levels[i].level_price > target_price)
 | 
						|
       {
 | 
						|
        return temp_levels[i].level_price;
 | 
						|
       }
 | 
						|
     }
 | 
						|
   }
 | 
						|
  else
 | 
						|
    if(mode == FIBBO_LEVEL_MENOR_A_TARGE_PRICE)
 | 
						|
     {
 | 
						|
      double nivel_menor = 0.00;
 | 
						|
      bool encontrado = false;
 | 
						|
 | 
						|
      for(int i = 0; i < total_fibbo; i++)
 | 
						|
       {
 | 
						|
        if(temp_levels[i].level_price < target_price)
 | 
						|
         {
 | 
						|
          nivel_menor = temp_levels[i].level_price;
 | 
						|
          encontrado = true;
 | 
						|
         }
 | 
						|
       }
 | 
						|
 | 
						|
      if(encontrado)
 | 
						|
        return nivel_menor;
 | 
						|
     }
 | 
						|
 | 
						|
  LogWarning(StringFormat("No se ha encontrado un nivel cercano al target price = %.*f >> modo = %s", digits, target_price, EnumToString(mode)), FUNCION_ACTUAL);
 | 
						|
  return 0.00;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
bool CFibbo::Create(const long      chart_ID,      // ID del gráfico
 | 
						|
                    const string          name, // nombre del objeto
 | 
						|
                    const int             sub_window,    // número de subventana
 | 
						|
                    const color           clr,      // color del objeto
 | 
						|
                    const ENUM_LINE_STYLE style, // estilo de las líneas del objeto
 | 
						|
                    const int             width,
 | 
						|
                    const string      tooltip,         // grosor de las líneas del objeto
 | 
						|
                    const bool            back = false,      // al fondo
 | 
						|
                    const bool            selection = false,  // seleccionar para mover
 | 
						|
                    const long            z_order = 0)
 | 
						|
 {
 | 
						|
  if(create)
 | 
						|
   {
 | 
						|
    LogWarning("Se esta volviendo a redibujar el objeto fibbo..", FUNCION_ACTUAL);
 | 
						|
   }
 | 
						|
 | 
						|
  this.chart_id = chart_ID;
 | 
						|
  this.subwin = sub_window;
 | 
						|
  string s = ChartSymbol(chart_ID);
 | 
						|
  this.digits = (int8_t)SymbolInfoInteger(s, SYMBOL_DIGITS);
 | 
						|
  bool res = FiboLevelsCreate(chart_ID, name, sub_window, 0, 0, 0, 0, clr, style, width, back, selection, false, false, z_order);
 | 
						|
  this.obj_name = name;
 | 
						|
 | 
						|
  if(!res)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("No se pudo crear el fibbo[ %s ], ultimo error = %d", name, GetLastError()), FUNCION_ACTUAL);
 | 
						|
   }
 | 
						|
  else
 | 
						|
   {
 | 
						|
    ObjectSetString(chart_ID, name, OBJPROP_TOOLTIP, tooltip);
 | 
						|
    create = true;
 | 
						|
   }
 | 
						|
 | 
						|
  return res;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::GetArrayLevel(double &levels[], bool contains_lebel_0_100 = false) const
 | 
						|
 {
 | 
						|
  for(int i = 0; i < ArraySize(fibbo_levels) ; i++)
 | 
						|
   {
 | 
						|
    if((fibbo_levels[i].level_value == 0.00 || fibbo_levels[i].level_value == 1.00) && contains_lebel_0_100 == false)
 | 
						|
      continue;
 | 
						|
    AddArrayNoVerification(levels, fibbo_levels[i].level_value, 0);
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
bool CFibbo::CheckIndex(const int index) const
 | 
						|
 {
 | 
						|
  if(index < 0 || index >= total_fibbo)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("El indice %d esta fuera de rango, rango diponible: [ %d - %d ]", 0, total_fibbo), FUNCION_ACTUAL);
 | 
						|
    Remover();
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 | 
						|
  return true;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
int CFibbo::GetLevelIndex(const double level_val) const
 | 
						|
 {
 | 
						|
  int left = 0;
 | 
						|
  int right = total_fibbo - 1;
 | 
						|
  const static double fibbo_min_value = 0.000040;
 | 
						|
 | 
						|
  while(left <= right)
 | 
						|
   {
 | 
						|
    int mid = left + ((right - left) >> 1);
 | 
						|
 | 
						|
    if(fabs(fibbo_levels[mid].level_value - level_val) <= fibbo_min_value) //no es seguro comparar double
 | 
						|
      return mid; // Encontrado
 | 
						|
    else
 | 
						|
      if(fibbo_levels[mid].level_value < level_val)
 | 
						|
        left = mid + 1;
 | 
						|
      else
 | 
						|
        right = mid - 1;
 | 
						|
   }
 | 
						|
 | 
						|
  LogWarning(StringFormat("No se ha encontrado el indice del level_value = %.3f", level_val), FUNCION_ACTUAL);
 | 
						|
  return -1;
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::ModifyLevel(double level, color new_color = clrNONE, ENUM_LINE_STYLE new_style = -1, int new_widt = -1)
 | 
						|
 {
 | 
						|
  int idx;
 | 
						|
  if((idx = GetLevelIndex(level)) == -1)
 | 
						|
    return;
 | 
						|
 | 
						|
//---
 | 
						|
  if(new_color != clrNONE)
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELCOLOR, idx, new_color);
 | 
						|
 | 
						|
//---
 | 
						|
  if(new_style != WRONG_VALUE)
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELSTYLE, idx, new_style);
 | 
						|
 | 
						|
//---
 | 
						|
  if(new_widt >= 1)
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELWIDTH, idx,  new_widt);
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::ModifyLevel(int level_index, color new_color = clrNONE, ENUM_LINE_STYLE new_style = -1, int new_widt = -1)
 | 
						|
 {
 | 
						|
  if(!CheckIndex(level_index))
 | 
						|
    return;
 | 
						|
//---
 | 
						|
  if(new_color != clrNONE)
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELCOLOR, level_index, new_color);
 | 
						|
 | 
						|
//---
 | 
						|
  if(new_style != WRONG_VALUE)
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELSTYLE, level_index, new_style);
 | 
						|
 | 
						|
//---
 | 
						|
  if(new_widt >= 1)
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELWIDTH, level_index,  new_widt);
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::UpdateTime2(datetime new_end)
 | 
						|
 {
 | 
						|
  ObjectSetInteger(this.chart_id, this.obj_name, OBJPROP_TIME, 1, new_end);
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
inline double CFibbo::GetLevelPrice(const double level_val) const
 | 
						|
 {
 | 
						|
  int idx;
 | 
						|
  if((idx = GetLevelIndex(level_val)) == -1)
 | 
						|
    return 0.00;
 | 
						|
  return fibbo_levels[idx].level_price;
 | 
						|
 }
 | 
						|
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::CalculatePriceLevelsFibbo(void)
 | 
						|
 {
 | 
						|
  for(int i = 0; i < total_fibbo; i++)
 | 
						|
   {
 | 
						|
    double val = ObjectGetDouble(this.chart_id, obj_name, OBJPROP_LEVELVALUE, i);
 | 
						|
    double diff = MathAbs(price_1 - price_2);
 | 
						|
 | 
						|
    if(price_1 > price_2)
 | 
						|
      this.fibbo_levels[i].level_price = NormalizeDouble((price_2 + (val * diff)), digits);
 | 
						|
    else
 | 
						|
      if(price_2 > price_1)
 | 
						|
        this.fibbo_levels[i].level_price = NormalizeDouble((price_2 - (val * diff)), digits);
 | 
						|
      else //Si son iguales error
 | 
						|
       {
 | 
						|
        LogError(StringFormat("No se pudo obtener un valor para el level fibbo = %.3f", fibbo_levels[i].level_value), FUNCION_ACTUAL);
 | 
						|
       }
 | 
						|
   }
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void CFibbo::Move(datetime new_init, datetime new_end, double price1, double price2)
 | 
						|
 {
 | 
						|
  ResetLastError();
 | 
						|
  if(!ObjectMove(this.chart_id, obj_name, 0, new_init, price1))
 | 
						|
   {
 | 
						|
    LogError(StringFormat("No se pudo movel el anclaje 0, new_init = %s >> price1 = %.*f, ultimo error = %d", TimeToString(new_init), digits, price1, GetLastError()), FUNCION_ACTUAL);
 | 
						|
   }
 | 
						|
 | 
						|
  ResetLastError();
 | 
						|
  if(!ObjectMove(this.chart_id, obj_name, 1, new_end, price2))
 | 
						|
   {
 | 
						|
    LogError(StringFormat("No se pudo movel el anclaje 1, time2 = %s >> price2 = %.*f, ultimo error = %d", TimeToString(new_end), digits, price2, GetLastError()), FUNCION_ACTUAL);
 | 
						|
   }
 | 
						|
 | 
						|
  this.price_1 = price1;
 | 
						|
  this.price_2 = price2;
 | 
						|
  this.init_fibbo = new_init;
 | 
						|
  CalculatePriceLevelsFibbo();
 | 
						|
 }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
bool CFibbo::SetLevels(string vals, string clrs, ENUM_LINE_STYLE styles, int widths, ushort separator_str)
 | 
						|
 {
 | 
						|
//---
 | 
						|
  string res_vals[];
 | 
						|
  int num_vals;
 | 
						|
  string res_clrs[];
 | 
						|
  int num_clrs;
 | 
						|
 | 
						|
//---
 | 
						|
  if((num_vals = StringSplit(vals, separator_str, res_vals)) == -1)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("La cadena de valores %s no contiene el separador %s o esta vacia", vals, ShortToString(separator_str)), FUNCION_ACTUAL);
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 | 
						|
  if((num_clrs = StringSplit(clrs, separator_str, res_clrs)) == -1)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("La cadena de colores %s no contiene el separador %s o esta vacia", vals, ShortToString(separator_str)), FUNCION_ACTUAL);
 | 
						|
    return false;
 | 
						|
   }
 | 
						|
 | 
						|
//---
 | 
						|
  if(num_vals != num_clrs)
 | 
						|
   {
 | 
						|
    LogError(StringFormat("El tamaño del array de niveles %d y colores %d no son iguales", num_vals, num_clrs), FUNCION_ACTUAL);
 | 
						|
    return(false);
 | 
						|
   }
 | 
						|
 | 
						|
//---
 | 
						|
  ArrayFree(this.fibbo_levels);
 | 
						|
  this.total_fibbo = 0;
 | 
						|
 | 
						|
//---
 | 
						|
  for(int i = 0; i < num_clrs; i++)
 | 
						|
   {
 | 
						|
    FibboLevel new_level;
 | 
						|
 | 
						|
    //--- para color trim, mql5 confunde con espacion asuem black
 | 
						|
    string res_color = StringTrimChar(res_clrs[i]);
 | 
						|
    new_level.level_color = StringToColor(res_color);
 | 
						|
 | 
						|
    //--- para oduble si, si hay eopacions no importa
 | 
						|
    new_level.level_value = StringToDouble(res_vals[i]);
 | 
						|
    new_level.level_price = 0.00;
 | 
						|
    AddLevel(new_level);
 | 
						|
   }
 | 
						|
 | 
						|
  SortArrayBylevel_value(this.fibbo_levels);
 | 
						|
 | 
						|
//---
 | 
						|
  if(IsInfoLogEnabled())
 | 
						|
   {
 | 
						|
    FastLog(FUNCION_ACTUAL, INFO_TEXT, "Niveles de fibbos listos: ");
 | 
						|
    ArrayPrint(this.fibbo_levels, 3, " | ");
 | 
						|
   }
 | 
						|
 | 
						|
//--- establecemos el número de los niveles
 | 
						|
  ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELS, total_fibbo);
 | 
						|
 | 
						|
//--- establecemos las propiedades de los niveles en el ciclo
 | 
						|
  for(int i = 0; i < total_fibbo; i++)
 | 
						|
   {
 | 
						|
    //--- valor del nivel
 | 
						|
    ObjectSetDouble(chart_id, obj_name, OBJPROP_LEVELVALUE, i, fibbo_levels[i].level_value);
 | 
						|
    //--- color del nivel
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELCOLOR, i, fibbo_levels[i].level_color);
 | 
						|
    //--- estilo del nivel
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELSTYLE, i, styles);
 | 
						|
    //--- grosor del nivel
 | 
						|
    ObjectSetInteger(chart_id, obj_name, OBJPROP_LEVELWIDTH, i, widths);
 | 
						|
    //--- descripción del nivel
 | 
						|
    ObjectSetString(chart_id, obj_name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * fibbo_levels[i].level_value, 1));
 | 
						|
   }
 | 
						|
 | 
						|
  this.max_level = this.fibbo_levels[total_fibbo - 1].level_value;
 | 
						|
  this.min_level = this.fibbo_levels[0].level_value;
 | 
						|
 | 
						|
//--- ejecución con éxito
 | 
						|
  return(true);
 | 
						|
 }
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#endif
 | 
						|
//+------------------------------------------------------------------+
 |