English Русский 中文 Deutsch 日本語 Português
preview
Teoría de categorías en MQL5 (Parte 2)

Teoría de categorías en MQL5 (Parte 2)

MetaTrader 5Integración | 12 mayo 2023, 09:33
261 0
Stephen Njuki
Stephen Njuki

Introducción

Hoy continuaremos la discusión sobre el uso de la teoría de categorías en MQL5 iniciada en el artículo anterior. Como recordará, presentamos la teoría de categorías como una rama de las matemáticas especialmente útil para organizar y clasificar información. En este contexto, hemos discutido algunos de los conceptos básicos de la teoría de categorías y cómo podemos aplicar estos al análisis de datos de series temporales financieras. En particular, analizamos elementos, dominios y morfismos. Los elementos son las unidades básicas de información en el sistema de teoría de categorías. Por lo general, se los trata como miembros de un conjunto, llamado en estas series un dominio. Un dominio puede tener relaciones con otros dominios a través de un proceso llamado morfismo. En este artículo, empezaremos analizando lo que constituye una categoría al observar los axiomas de identidad y asociación, así como el diagrama conmutativo. Al mismo tiempo, a lo largo del artículo analizaremos varios ejemplos de lo que no es una categoría. Por último, introduciremos los registros ontológicos.

Antes de profundizar en la definición de los axiomas de una categoría, puede ser útil ver algunos ejemplos cotidianos de categorías "en acción". Ya hemos definido los dominios y los elementos que estos contienen. Los siguientes ejemplos mostrarán el uso de una categoría como un conjunto de dominios relacionados.

    • Una categoría de medios de transporte, con dominios que representan diferentes medios de transporte (automóviles, aviones, trenes, etc.). Los elementos de cada dominio serán los tipos de vehículos correspondientes. En el caso de los coches, podremos tener, por ejemplo, viajes conjuntos, alquileres, coches privados, taxis. Las aeronaves pueden ser privadas, o comerciales o arrendadas. Los trenes pueden incluir tranvías, trenes bala, locomotoras de vapor, etc. El morfismo entre estos puede servir para determinar el itinerario completo del viaje. Por ejemplo, si hemos tomado un taxi al aeropuerto, un vuelo comercial y luego un tren bala desde el aeropuerto hasta nuestro destino, cada una de estas opciones podría encajar fácilmente en esta categoría.  
    • Una categoría alimentos, con dominios que representan el menú para cada plato. Digamos que tenemos cinco platos, a saber, entrantes, sopa, plato principal, postre y queso. En este caso, los elementos de cada dominio serán los alimentos del menú del plato correspondiente. Por ejemplo, los entrantes pueden tener opciones de selección en su área (menú): zanahorias confitadas con miel, comino y paprika; o champiñones rellenos de pecorino romano, ajo y pan rallado; o brócoli frito con pimientos shishito y cebollas en escabeche. Del mismo modo, la sopa puede incluir varias opciones: sopa toscana de frijoles blancos y ajo asado; o sopa de calabaza y salvia; o sopa fría de melón y albahaca. Cada uno de estos elementos del menú representa un elemento en su propio dominio. De la misma manera, el morfismo entre ellos servirá para definir toda la comida elegida por el comensal del restaurante. Por ejemplo, si un cliente ha pedido zanahorias confitadas, luego calabaza, etc., para todos los demás platos, cada una de estas opciones, como las anteriores, se podrá asignar fácilmente a una categoría.
    • Otro ejemplo de una categoría serían los tipos de entretenimiento semanal. Aquí, nuestros dominios pueden ser los deportes, la retransmisión de TV y las visitas a los parques. Los elementos de cada dominio podrían ser: NFL, MLB o NBA para el dominio deportivo; Netflix, HBO o AMC para el dominio de retransmisión de TV; Disneyland, o un zoológico, o un parque natural para las visitas a los parques. Nuevamente, el público puede elegir de cada dominio un juego deportivo, un programa de televisión y un parque. Y la fila de selecciones en estos dominios (morfismos) le permitirá mostrar fácilmente esta información.

    Todo esto y, obviamente, mucho más se puede arreglar usando la teoría de categorías. Pero ¿con qué propósito?  Hay un dicho muy interesante: "un mal artesano siempre culpa a sus herramientas". También se aplica a este caso. El objetivo lo definirá el usuario. En mi opinión, la teoría de categorías resulta adecuada para la cuantificación de la equivalencia. Este tema lo cubriremos en futuros artículos, tras aprender los conceptos básicos. Baste decir que por esta razón se observan dos categorías aparte sobre diferentes temas que pueden parecer no relacionados a primera vista, pero que en un examen más detenido resultan ser idénticos u opuestos. Estos conocimientos resultan vitales a la hora de tomar decisiones porque rara vez tenemos suficiente información en el momento de las mismas. Sin embargo, si tenemos categorías correlacionadas, entonces podemos llenar el vacío de información. 


    Identidad

    El isomorfismo es una propiedad importante de los homomorfismos en la teoría de categorías porque garantiza que la estructura de los dominios en la categoría de destino se conserve durante la conversión. También garantiza que se conserven las operaciones algebraicas de los dominios en la categoría original. Por ejemplo, vamos a analizar una categoría de ropa cuyos dominios son camisas y pantalones, y cuyos morfismos son funciones que convierten una talla de camisa en una talla de pantalón. En esta categoría, el homomorfismo sería la función que mantiene las tallas de camisa consistentes con las tallas de pantalones correspondientes. En esta categoría, el isomorfismo sería la función que no solo conserva la paridad algebraica de las tallas, sino que establece una correspondencia unívoca mutua entre las tallas de camisa y pantalón. Esto significa que para cualquier talla de camisa, habrá exactamente una talla de pantalón correspondiente, y viceversa. Por ejemplo, vamos a considerar una función que haga coincidir una talla de camisa ("pequeña", "mediana", "grande") con una talla de pantalón ("26", "28", "30", "32"). Esta función será un homomorfismo porque conserva y define un par de tamaños (por ejemplo, "pequeño" se puede asignar a "26"). Pero esto no es un isomorfismo, porque no establece una correspondencia unívoca mutua entre las tallas de camisa y pantalón, ya que la talla "pequeña" también puede llevarse con "28" o "26". En este caso, no hay reversibilidad.


    non_iso


    Por otro lado, vamos a considerar una función que empareja una talla de camisa ("pequeña", "mediana", "grande") solo con una talla de pantalón ("28", "30", "32"). Esta función no es solo un homomorfismo, sino también un isomorfismo, pues admite la reversibilidad.


    iso


    En el ejemplo de la categoría de ropa, donde los dominios son camisas y pantalones, mientras que los morfismos son funciones que convierten una talla de camisa en una talla de pantalón, un único morfismo no puede ser isomorfo, ya que todos los morfismos únicos son inherentemente reversibles y, por lo tanto, "isomorfos". La propiedad de isomorfismo se refiere a un grupo de morfismos (también conocido como conjunto de homomorfismos) de un dominio a un codominio, y solo se puede considerar que está presente si todos esos morfismos como grupo son reversibles, conservando al mismo tiempo las propiedades de emparejamiento algebraico del homomorfismo. Por eso resulta importante enumerar todos los morfismos de un dominio antes de confirmar un isomorfismo. Sin considerar todos los morfismos posibles, podría parecer que dos objetos son isomorfos, aunque en realidad no sea así. El predecesor del isomorfismo es la cardinalidad de los dominios. Este valor debe ser el mismo para ambos dominios. Si los dominios tienen cardinalidad no coincidente, el homomorfismo entre ellos no podrá ser reversible, ya que de un mismo dominio tendremos más de un elemento convertible en el mismo coelemento. Por lo tanto, necesitaremos un grupo de morfismos entre dominios para definir un isomorfismo. Normalmente necesitamos dos morfismos, uno de camisa a pantalón y otro de pantalón a camisa, que establezcan una correspondencia unívoca mutua entre las tallas de camisa y pantalón. Estos morfismos deberán ser inversos entre sí, lo cual significa que si un morfismo asigna una camisa de talla "pequeña" a un pantalón de talla "28", entonces el otro morfismo deberá asignar un pantalón de talla "28" a una camisa de talla "pequeña". Y cuando componemos estos dos morfismos, debería darnos el morfismo de identidad para el dominio que hemos comenzado.

    Este requisito de axiomas en la teoría de categorías ha redundado en la necesidad de morfismos auto-mapeantes. Todavía se debate si son importantes a la hora de definir una categoría. 

    Vamos a ilustrar un isomorfismo en MQL5. Hemos reescrito la mayor parte del script del primer artículo para incluir plantillas. Todas las clases, desde la clase de elemento hasta la clase de categoría, incluyen el uso de tipos de datos de plantilla para ofrecer flexibilidad. No obstante, he "enumerado" los tipos disponibles en la clase de categoría. Son datetime, string, double e int. El tipo int se usa por defecto y se utilizará si, por ejemplo, usamos el tipo de datos color. El código completo se adjunta al final del artículo. A continuación, le mostramos nuestra nueva clase de homomorfismos.

    //+------------------------------------------------------------------+
    //| HOMO-MORPHISM CLASS                                              |
    //+------------------------------------------------------------------+
    template <typename TD,typename TC>
    class CHomomorphism                 : public CObject
       {
          protected:
          
          int                           morphisms;
          
          public:
          
          CDomain<TD>                   domain;
          CDomain<TC>                   codomain;
          
          CMorphism<TD,TC>              morphism[];
          
          int                           Morphisms() { return(morphisms); }
          bool                          Morphisms(int Value) { if(Value>=0 && Value<INT_MAX) { morphisms=Value; ArrayResize(morphism,morphisms); return(true); } return(false); }
          
          bool                          Get(int MorphismIndex,CMorphism<TD,TC> &Morphism) { if(MorphismIndex>=0 && MorphismIndex<Morphisms()) { Morphism=morphism[MorphismIndex]; Morphism.domain=domain; Morphism.codomain=codomain; return(true); } return(false); }
          
                                        template <typename TDD,typename TDC>
          bool                          Set(int ValueIndex,CMorphism<TDD,TDC> &Value)
                                        {
                                           if
                                           (
                                           (string(typename(TD))!=string(typename(TDD)))
                                           ||
                                           (string(typename(TC))!=string(typename(TDC)))
                                           ||
                                           )
                                           {
                                              return(false);
                                           }
                                           // 
                                           if(ValueIndex>=0 && ValueIndex<Morphisms())
                                           {
                                              Value.domain=domain;
                                              Value.codomain=codomain;
                                           
                                              if(Index(Value)==-1)
                                              {
                                                 morphism[ValueIndex]=Value;
                                                 
                                                 return(true);
                                              } 
                                           }
                                           
                                           return(false); 
                                        };
          
          
                                        template <typename TDD,typename TDC>
          int                           Index(CMorphism<TDD,TDC> &Value)
                                        {
                                           int _index=-1;
                                           //
                                           if
                                           (
                                           (string(typename(TD))!=string(typename(TDD)))
                                           ||
                                           (string(typename(TC))!=string(typename(TDC)))
                                           ||
                                           )
                                           {
                                              return(_index);
                                           }
                                           // 
                                           for(int m=0; m<morphisms; m++)
                                           {
                                              if(MorphismMatch(Value,morphism[m]))
                                              {
                                                 _index=m; break;
                                              }
                                           }
                                           
                                           return(_index);
                                        }
          
                                        CHomomorphism(void){  Morphisms(0); };
                                        ~CHomomorphism(void){};
       };

    Para probar el isomorfismo, utilizaremos los mismos dominios que en el artículo anterior y los ejecutaremos a través de la función IsIsomorphic. Esta función retorna un valor booleano donde true indica el éxito y false indica el fallo.

    //+------------------------------------------------------------------+
    //| Get Isomorphisms function                                        |
    //+------------------------------------------------------------------+
    template <typename TD,typename TC>
    bool IsIsomorphic(CDomain<TD> &A,CDomain<TC> &B,CHomomorphism<TD,TC> &Output[])
       {
          if(A.Cardinality()!=B.Cardinality())
          {
             return(false);
          }
          
          int _cardinal=A.Cardinality();
          
          uint _factorial=MathFactorial(_cardinal);
          
          ArrayResize(Output,_factorial);
          
          for(uint f=0;f<_factorial;f++)
          {
             ArrayResize(Output[f].morphism,_cardinal);
             //
             for(int c=0;c<_cardinal;c++)
             {
                Output[f].morphism[c].domain=A;
                Output[f].morphism[c].codomain=B;
             }
          }
          
          int _index=0;
          CDomain<TC> _output[];ArrayResize(_output,_factorial);
          GetIsomorphisms(B, 0, _cardinal-1, _cardinal, _index, _output);
          
          for(uint f=0;f<_factorial;f++)
          {
             for(int c=0;c<_cardinal;c++)
             {
                CElement<TC> _ec;
                if(_output[f].Get(c,_ec))
                {
                   for(int cc=0;cc<_cardinal;cc++)
                   {
                      CElement<TC> _ecc;
                      if(B.Get(cc,_ecc))
                      {
                         if(ElementMatch(_ec,_ecc))
                         {
                            if(Output[f].morphism[c].Codomain(cc))
                            {
                               break;
                            }
                         }
                      }
                   }
                }
                
                if(Output[f].morphism[c].Domain(c))
                {
                }
             }
          }
             
          return(true);
       }

    Sin embargo, el homomorfismo de salida deberá especificarse directamente, y en nuestro caso usaremos la variable "_h_i". Este valor de salida, que supone un array de clases de homomorfismo, incluirá una enumeración de todos los homomorfismos de isomorfismo posibles entre los dos dominios de entrada.

          //IDENTITY
          CHomomorphism<int,int> _h_i[];
          //is evens isomorphic to odds?
          if(IsIsomorphic(_evens,_odds,_h_i))
          {
             printf(__FUNCSIG__+" evens can be isomorphic to odds by up to: "+IntegerToString(ArraySize(_h_i))+" homomorphisms. These could be... ");
             for(int s=0; s<ArraySize(_h_i); s++)
             {
                printf(__FUNCSIG__);
                
                string _print="";
                for(int ss=0; ss<ArraySize(_h_i[s].morphism); ss++)
                {
                   _print+=PrintMorphism(_h_i[s].morphism[ss],0);
                }
                
                printf(_print+" at: "+IntegerToString(s));
             }
          }

    Si ejecutamos este código, veremos las siguientes entradas en el registro:

    2023.01.26 10:42:56.909 ct_2 (EURGBP.ln,H1)     void OnStart() evens can be isomorphic to odds by up to: 6 homomorphisms. These could be...
    2023.01.26 10:42:56.909 ct_2 (EURGBP.ln,H1)     void OnStart()
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (0)|----->(1)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (2)|----->(3)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (4)|----->(5)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)      at: 0
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     void OnStart()
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (0)|----->(1)
    
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (2)|----->(5)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (4)|----->(3)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)      at: 1
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     void OnStart()
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (0)|----->(3)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (2)|----->(1)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (4)|----->(5)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)      at: 2
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     void OnStart()
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (0)|----->(3)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (2)|----->(5)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (4)|----->(1)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)      at: 3
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     void OnStart()
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (0)|----->(5)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (2)|----->(3)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (4)|----->(1)
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)      at: 4
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     void OnStart()
    2023.01.26 10:42:56.910 ct_2 (EURGBP.ln,H1)     (0)|----->(5)
    2023.01.26 10:42:56.911 ct_2 (EURGBP.ln,H1)     (2)|----->(1)
    2023.01.26 10:42:56.911 ct_2 (EURGBP.ln,H1)     (4)|----->(3)
    2023.01.26 10:42:56.911 ct_2 (EURGBP.ln,H1)      at: 5
    
    

    Dominio par:

    2023.01.26 10:42:56.899 ct_2 (EURGBP.ln,H1)     void OnStart() evens are... {(0),(2),(4)}
    

    Dominio impar:

    2023.01.26 10:42:56.899 ct_2 (EURGBP.ln,H1)     void OnStart() odds are... {(1),(3),(5)}
    


    Asociatividad

    En teoría de categorías, el axioma de asociatividad es una de las principales propiedades que debe cumplir una categoría. Volviendo al ejemplo de la categoría de ropa, los dominios son artículos de ropa específicos, como camisas, pantalones y zapatos, mientras que los morfismos serán funciones que emparejan la ropa según la forma física. El axioma de asociatividad, también conocido como "ley de asociatividad", establece que la composición de los morfismos es asociativa. Esto significa que al componer múltiples morfismos, el orden en que se aplican no afectará el resultado final.

    Por ejemplo, vamos a analizar el morfismo "se lleva con" en los tres dominios de ropa (camisas, pantalones y zapatos). Digamos que tenemos un morfismo f: camiseta -> camisa con botones, g: camisa con botones -> vaqueros y h: vaqueros -> zapatillas. Usando el axioma de asociación, podemos definir la composición de estos morfismos como h o (g o f) = (h o g) o f. Esto significa que el orden de los morfismos no importa, y podemos agruparlos como deseemos, lo cual simplifica la definición de la categoría, ya que evita calcular los paréntesis de múltiples morfismos. En su lugar, podemos agrupar los morfismos, independientemente de su orden, y el resultado final será el mismo.

    Vamos a ver esto en acción en MQL5. Tendremos que recomponer la clase de categoría que ofrecimos en el artículo anterior.

    //+------------------------------------------------------------------+
    //| CATEGORY CLASS                                                   |
    //+------------------------------------------------------------------+
    class CCategory
       {
          protected:
          
          int                           domains_datetime;
          int                           domains_string;
          int                           domains_double;
          int                           domains_int;
          
          int                           ontologies;
          
          CDomain<datetime>             domain_datetime[];
          CDomain<string>               domain_string[];
          CDomain<double>               domain_double[];
          CDomain<int>                  domain_int[];
          
          COntology                     ontology[];
          
          public:
          
          int                           Domain(string T)
                                        { 
                                           if(T=="datetime"){ return(domains_datetime); }
                                           else if(T=="string"){ return(domains_string); }
                                           else if(T=="double"){ return(domains_double); }
                                           
                                           return(domains_int);
                                        };
          
          bool                          Domain(string T,int Value)
                                        { 
                                           if(Value>=0 && Value<INT_MAX)
                                           { 
                                              if(T=="datetime")
                                              { 
                                                 if(ArrayResize(domain_datetime,Value)>=Value)
                                                 {
                                                    domains_datetime=Value;  
                                                    return(true); 
                                                 } 
                                              }
                                              else if(T=="string")
                                              { 
                                                 if(ArrayResize(domain_string,Value)>=Value)
                                                 {
                                                    domains_string=Value;  
                                                    return(true); 
                                                 } 
                                              }
                                              else if(T=="double")
                                              { 
                                                 if(ArrayResize(domain_double,Value)>=Value)
                                                 {
                                                    domains_double=Value;  
                                                    return(true); 
                                                 } 
                                              }
                                              else //if(T=="int")
                                              { 
                                                 if(ArrayResize(domain_int,Value)>=Value)
                                                 {
                                                    domains_int=Value;  
                                                    return(true);
                                                 }  
                                              }
                                           } 
                                           
                                           return(false); 
                                        };
                                        
                                        
          int                           Ontology(){ return(ontologies); };
          bool                          Ontology(int Value){ if(Value>=0 && Value<INT_MAX){ ontologies=Value; ArrayResize(ontology,ontologies); return(true); } return(false); };
          
          
                                        template <typename T>
          bool                          Set(int ValueIndex,CDomain<T> &Value)
                                        {
                                           if(Index(Value)==-1 && ValueIndex>=0)
                                           {
                                              if
                                              (
                                              ValueIndex<Domain(string(typename(T)))
                                              ||
                                              (ValueIndex>=Domain(string(typename(T))) && Domain(string(typename(T)),ValueIndex+1))
                                              )
                                              {
                                                 if(string(typename(T))=="datetime")
                                                 {
                                                    domain_datetime[ValueIndex]=Value;
                                                    return(true);
                                                 }
                                                 else if(string(typename(T))=="string")
                                                 {
                                                    domain_string[ValueIndex]=Value;
                                                    
                                                    return(true);
                                                 }
                                                 else if(string(typename(T))=="double")
                                                 {
                                                    domain_double[ValueIndex]=Value;
                                                    return(true);
                                                 }
                                                 else //if(string(typename(T))=="int")
                                                 {
                                                    domain_int[ValueIndex]=Value;
                                                    return(true);
                                                 }
                                              }
                                           }
                                           //
                                           return(false);
                                        };
                                        
                                        template <typename T>
          bool                          Get(int DomainIndex,CDomain<T> &D)
                                        {
                                           if(DomainIndex>=0 && DomainIndex<Domain(string(typename(T))))
                                           {
                                              if(string(typename(T))=="datetime")
                                              {
                                                 D=domain_datetime[DomainIndex];
                                                 
                                                 return(true);
                                              }
                                              else if(string(typename(T))=="string")
                                              {
                                                 D=domain_string[DomainIndex];
                                                 
                                                 return(true);
                                              }
                                              else if(string(typename(T))=="double")
                                              {
                                                 D=domain_double[DomainIndex];
                                                 
                                                 return(true);
                                              }
                                              else //if(string(typename(T))=="int")
                                              {
                                                 D=domain_int[DomainIndex];
                                                 
                                                 return(true);
                                              }
                                           }
                                           
                                           return(false);
                                        };
                                        
          bool                          Set(int ValueIndex,COntology &Value)
                                        {
                                           if
                                           (
                                           ValueIndex>=0 && ValueIndex<Ontology()
                                           )
                                           {
                                              ontology[ValueIndex]=Value;
                                              return(true);
                                           }
                                           else if(ValueIndex>=Ontology())
                                           {
                                              if(Ontology(Ontology()+1))
                                              {
                                                 ontology[Ontology()-1]=Value;
                                                 return(true);
                                              }
                                           }
                                           //
                                           return(false);
                                        };
                                        
          bool                          Get(int OntologyIndex,COntology &O)
                                        {
                                           if(OntologyIndex>=0 && OntologyIndex<Ontology())
                                           {
                                              O=ontology[OntologyIndex];
                                              
                                              return(true);
                                           }
                                           
                                           return(false);
                                        };
          
          
                                        template <typename T>
          int                           Index(CDomain<T> &Value)
                                        {
                                           int _index=-1;
                                           //
                                           for(int d=0; d<Domain(string(typename(T))); d++)
                                           {
                                              if(string(typename(T))=="string")
                                              {
                                                 if(DomainMatch(Value,domain_string[d]))
                                                 {
                                                    _index=d; break;
                                                 }
                                              }
                                              else if(string(typename(T))=="datetime")
                                              {
                                                 if(DomainMatch(Value,domain_int[d]))
                                                 {
                                                    _index=d; break;
                                                 }
                                              }
                                              else if(string(typename(T))=="double")
                                              {
                                                 if(DomainMatch(Value,domain_double[d]))
                                                 {
                                                    _index=d; break;
                                                 }
                                              }
                                              else if(string(typename(T))=="int")
                                              {
                                                 if(DomainMatch(Value,domain_int[d]))
                                                 {
                                                    _index=d; break;
                                                 }
                                              }
                                           }
                                           
                                           return(_index);
                                        }
          
          
          int                           Index(COntology &Value)
                                        {
                                           int _index=-1;
                                           //
                                           for(int o=0; o<Ontology(); o++)
                                           {
                                              if(!OntologyMatch(Value,ontology[o]))
                                              {
                                                 _index=o; break;
                                              }
                                           }
                                           
                                           return(_index);
                                        }
          
                                        CCategory()
                                        { 
                                           domains_datetime=0; 
                                           domains_string=0; 
                                           domains_double=0; 
                                           domains_int=0; 
                                           
                                           ontologies=0; 
                                        };
                                        ~CCategory()
                                        { 
                                        };
       };

    Preste atención a los tipos de datos "enumerados" válidos. Intentaremos hacerlos más visibles en futuros artículos combinándolos como un objeto en un solo array. Además, aparte de la función que llenaba el dominio con números naturales, hemos añadido la función FillDomain.

    //+------------------------------------------------------------------+
    //| Fill Domain(Set) with one-cardinal elements from input E array.  |
    //+------------------------------------------------------------------+
    template <typename TD,typename TE>
    void FillDomain(CDomain<TD> &D,CElement<TE> &E[])
       {
          if(string(typename(TD))!=string(typename(TE)))
          {
             return;
          }
          
          int _cardinal=ArraySize(E);
          //
          if(_cardinal<0||INT_MAX<=_cardinal)
          {
             return;
          }
          
          //Set its cardinal to input array size
          if(D.Cardinality(_cardinal))
          {
             for(int c=0;c<_cardinal;c++)
             {
                D.Set(c,E[c],true);
             }
          }
       }

    Para probar la asociatividad, crearemos la categoría '_ca'. Luego declararemos tres conjuntos sencillos de tipo string, cada uno rellenado con un tipo de ropa. Después copiaremos estos conjuntos (arrays) en los nuevos arrays de elementos ('_et', '_ep', '_es') y añadiremos cada uno de estos elementos a su propio dominio ('_dt', '_dp', '_ds'). Una vez hecho esto, estableceremos la cantidad de dominios en nuestra categoría en tres y procederemos a configurar un dominio en cada índice con los dominios recién creados que se hayan poblado con elementos de tipo ropa.

          //ASSOCIATION
          CCategory _ca;
          
          string _tops[__EA]={"T-shirt","button-up","polo","sweatshirt","tank top"};          //domain 0
          string _pants[__EA]={"jeans","slacks","khakis","sweatpants","shorts"};              //domain 1
    
          string _shoes[__EA]={"sneakers","dress shoes","loafers","running shoes","sandals"}; //domain 2
          
          CElement<string> _et[];ArrayResize(_et,__EA);
          CElement<string> _ep[];ArrayResize(_ep,__EA);
          CElement<string> _es[];ArrayResize(_es,__EA);
          
          for(int e=0;e<__EA;e++)
          { 
             _et[e].Cardinality(1); _et[e].Set(0,_tops[e]);
             _ep[e].Cardinality(1); _ep[e].Set(0,_pants[e]);
             _es[e].Cardinality(1); _es[e].Set(0,_shoes[e]); 
          }
          
          CDomain<string> _dt,_dp,_ds;
          FillDomain(_dt,_et);FillDomain(_dp,_ep);FillDomain(_ds,_es);
          
          //
          if(_ca.Domain("string",__DA))//resize domains array to 3
          {
             if(_ca.Set(0,_dt) && _ca.Set(1,_dp) && _ca.Set(2,_ds))//assign each filled domain above to a spot (index) within the category
             {
                if(_ca.Domain("string")==__DA)//check domains count 
                {
                   for(int e=0;e<__EA;e++)
                   {
                      COntology _o_01_2;
                      CMorphism<string,string> _m1_01_2,_m2_01_2;
                      SetCategory(_ca,0,1,e,e,_o_01_2," is worn with ",_m1_01_2);
                      SetCategory(_ca,1,2,e,e,_o_01_2," is worn with ",_m2_01_2,ONTOLOGY_POST);printf(__FUNCSIG__+" (0 & 1) followed by 2 Log is: "+_o_01_2.ontology);
                      
                      COntology _o_0_12;
                      CMorphism<string,string> _m1_0_12,_m2_0_12;
                      SetCategory(_ca,1,2,e,e,_o_0_12," is worn with ",_m1_0_12);
                      SetCategory(_ca,0,2,e,e,_o_0_12," is worn with ",_m2_0_12,ONTOLOGY_PRE);printf(__FUNCSIG__+" 0 following (1 & 2) Log is: "+_o_0_12.ontology);
                   }
                }
             }
          }

    Para probar la asociatividad, mostraremos los resultados de los morfismos en los registros ontológicos. Para hacer esto, crearemos la clase COntology, que se describe a continuación con una enumeración y una estructura con el mismo nombre.

    //+------------------------------------------------------------------+
    //| ONTOLOGY ENUM                                                    |
    //+------------------------------------------------------------------+
    enum EOntology
      {
          ONTOLOGY_PRE=-1,
          ONTOLOGY_NEW=0,
          ONTOLOGY_POST=1
      };
    //+------------------------------------------------------------------+
    //| ONTOLOGY STRUCT                                                  |
    //+------------------------------------------------------------------+
    struct SOntology
      {
          int                           in;
          int                           out;
          
                                        SOntology()
                                        {
                                           in=-1;
                                           out=-1;
                                        };
                                        ~SOntology(){};
      };
    //+------------------------------------------------------------------+
    //| ONTOLOGY CLASS                                                   |
    //+------------------------------------------------------------------+
    class COntology
      {
          protected:
          
          int                           facts;
          
          SOntology                     types[];
          SOntology                     universe[];
          
          public:
          
          string                        ontology;
          
          int                           Facts() { return(facts); }
          bool                          Facts(int Value) { if(Value>=0 && Value<INT_MAX) { facts=Value; ArrayResize(types,facts); ArrayResize(universe,facts); return(true); } return(false); }
          
          bool                          GetType(int TypeIndex,int &TypeIn,int &TypeOut) { if(TypeIndex>=0 && TypeIndex<Facts()) { TypeIn=types[TypeIndex].in; TypeOut=types[TypeIndex].out; return(true); } return(false); }
          bool                          SetType(int ValueIndex,int ValueIn,int ValueOut) 
                                        { 
                                           if(ValueIndex>=0 && ValueIndex<Facts()) 
                                           { 
                                              types[ValueIndex].in=ValueIn; types[ValueIndex].out=ValueOut; 
                                              return(true); 
                                           } 
                                           else if(ValueIndex>=0 && ValueIndex>=Facts() && ValueIndex<INT_MAX-1) 
                                           { 
                                              if(Facts(ValueIndex+1))
                                              {
                                                 types[ValueIndex].in=ValueIn; types[ValueIndex].out=ValueOut; 
                                                 return(true); 
                                              }
                                           } 
                                           
                                           return(false); 
                                        }
          
          bool                          GetUniverse(int UniverseIndex,int &UniverseIn,int &UniverseOut) { if(UniverseIndex>=0 && UniverseIndex<Facts()) { UniverseIn=universe[UniverseIndex].in; UniverseOut=universe[UniverseIndex].out; return(true); } return(false); }
          bool                          SetUniverse(int ValueIndex,int ValueIn,int ValueOut) 
                                        { 
                                           if(ValueIndex>=0 && ValueIndex<Facts()) 
                                           { 
                                              universe[ValueIndex].in=ValueIn; universe[ValueIndex].out=ValueOut; 
                                              return(true); 
                                           } 
                                           else if(ValueIndex>=0 && ValueIndex>=Facts() && ValueIndex<INT_MAX-1) 
                                           { 
                                              if(Facts(ValueIndex+1))
                                              {
                                                 universe[ValueIndex].in=ValueIn; universe[ValueIndex].out=ValueOut; 
                                                 return(true); 
                                              }
                                           } 
                                           
                                           return(false); 
                                        }
          
          string                        old_hash;
          string                        new_hash;
          
                                        COntology()
                                        {
                                           ontology="";
                                           
                                           facts=0;
                                           
                                           ArrayResize(types,facts);
                                           ArrayResize(universe,facts);
                                           
                                           old_hash="";
                                           new_hash="";
                                        };
                                        ~COntology(){};
      };

    La ejecución del script debería crear las siguientes entradas en el registro.

    2023.01.26 10:42:56.911 ct_2 (EURGBP.ln,H1)     void OnStart() (0 & 1) followed by 2 Log is: T-shirt is worn with jeans is worn with sneakers
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() 0 following (1 & 2) Log is: T-shirt is worn with jeans is worn with sneakers
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() (0 & 1) followed by 2 Log is: button-up is worn with slacks is worn with dress shoes
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() 0 following (1 & 2) Log is: button-up is worn with slacks is worn with dress shoes
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() (0 & 1) followed by 2 Log is: polo is worn with khakis is worn with loafers
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() 0 following (1 & 2) Log is: polo is worn with khakis is worn with loafers
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() (0 & 1) followed by 2 Log is: sweatshirt is worn with sweatpants is worn with running shoes
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() 0 following (1 & 2) Log is: sweatshirt is worn with sweatpants is worn with running shoes
    2023.01.26 10:42:56.912 ct_2 (EURGBP.ln,H1)     void OnStart() (0 & 1) followed by 2 Log is: tank top is worn with shorts is worn with sandals
    2023.01.26 10:42:56.913 ct_2 (EURGBP.ln,H1)     void OnStart() 0 following (1 & 2) Log is: tank top is worn with shorts is worn with sandals
    


     

    Por lo tanto, el axioma de asociatividad facilita la definición de una categoría al permitir que la composición de los morfismos sea asociativa, eliminando así la necesidad de calcular los paréntesis al definir múltiples morfismos. Esto facilita la comprensión de las relaciones entre los objetos de una categoría, en este caso, las prendas de vestir en los tres dominios (camisas, pantalones y zapatos). 


    Diagramas conmutativos

    Un diagrama conmutativo es un diagrama que representa la relación entre dos morfismos en una categoría. Consiste en un conjunto de dominios, morfismos y sus composiciones, organizados de cierta forma para mostrar que los morfismos conmutan, y esto significa que no importa el orden en que se compongan. Asimismo, significa que para cualesquiera tres dominios A, B y C en la categoría y para sus morfismos f: A -> B, g: B -> C y h: A->C; la composición de estos morfismos deberá satisfacer la igualdad:

    f o g = h

    Un ejemplo de conmutación usando precios de monedas sería el arbitraje: la relación entre el precio de, digamos, EURUSD, EURJPY y USDJPY. En este ejemplo, los dominios podrían ser las propias monedas (EUR, USD, JPY), mientras que los morfismos podrían representar el proceso de conversión de una moneda a otra al tipo de cambio. Por ejemplo, digamos que f: EUR -> USD es un morfismo que representa el proceso de conversión de EUR a USD al tipo de cambio EURUSD; y digamos que g: USD -> JPY: es un morfismo que representa el proceso de conversión de USD a JPY al tipo de cambio USDJPY; y que h: EUR -> JPY es un morfismo que representa la conversión de EUR a JPY. Dada la regla de conmutación anterior (fog = h), esto implicaría:

    la conversión de EUR a USD al tipo EURUSD, luego la conversión de USD a JPY al tipo USDJPY = la conversión de EUR a JPY al tipo EURJPY.

    Ilustraremos esto usando MQL5. Vamos a declarar la categoría '_cc' y rellenarla con tres dominios con dos monedas cada uno. Los dominios se pueden ver como portafolios en una distribución de activos. Al igual que con el axioma de asociatividad, completaremos y validaremos los valores de nuestras categorías usando registros ontológicos como se muestra más abajo.

          //COMMUTATION
          CCategory _cc;
          
          string _a[__EC]={"EUR","GBP"};       //domain 0
          string _b[__EC]={"USD","CAD"};       //domain 1
          string _c[__EC]={"CHF","JPY"};       //domain 2
          
          CElement<string> _e_a[];ArrayResize(_e_a,__EC);
          CElement<string> _e_b[];ArrayResize(_e_b,__EC);
          CElement<string> _e_c[];ArrayResize(_e_c,__EC);
          
          for(int e=0;e<__EC;e++)
          { 
             _e_a[e].Cardinality(1); _e_a[e].Set(0,_a[e]);
             _e_b[e].Cardinality(1); _e_b[e].Set(0,_b[e]);
             _e_c[e].Cardinality(1); _e_c[e].Set(0,_c[e]); 
          }
          
          CDomain<string> _d_a,_d_b,_d_c;
          FillDomain(_d_a,_e_a);FillDomain(_d_b,_e_b);FillDomain(_d_c,_e_c);
          
          //
          if(_cc.Domain("string",__DC))//resize domains array to 3
          {
             if(_cc.Set(0,_d_a) && _cc.Set(1,_d_b) && _cc.Set(2,_d_c))//assign each filled domain above to a spot (index) within the category
             {
                if(_cc.Domain("string")==__DC)//check domains count 
                {
                   for(int e=0;e<__EC;e++)
                   {
                      COntology _o_ab_bc;
                      string _ab=_a[e]+_b[e],_bc=_b[e]+_c[e];
                      double _ab_bid=SymbolInfoDouble(_ab,SYMBOL_BID),_bc_bid=SymbolInfoDouble(_bc,SYMBOL_BID);
                      string _aspect_ab=" is exchanged at: "+DoubleToString(_ab_bid,(int)SymbolInfoInteger(_ab,SYMBOL_DIGITS))+", for: ";
                      string _aspect_bc=" is exchanged at: "+DoubleToString(_bc_bid,(int)SymbolInfoInteger(_bc,SYMBOL_DIGITS))+", for: ";
                      CMorphism<string,string> _m_ab,_m_bc;
                      SetCategory(_cc,0,1,e,e,_o_ab_bc,_aspect_ab,_m_ab);
                      SetCategory(_cc,1,2,e,e,_o_ab_bc,_aspect_bc,_m_bc,ONTOLOGY_POST);printf(__FUNCSIG__+" a to b then b to c logs: "+_o_ab_bc.ontology);
                      
                      COntology _o_ac;
                      string _ac=_a[e]+_c[e];
                      string _aspect_ac=" is exchanged at: "+DoubleToString(SymbolInfoDouble(_ac,SYMBOL_BID),(int)SymbolInfoInteger(_ac,SYMBOL_DIGITS))+", for: ";
                      CMorphism<string,string> _m_ac;
                      SetCategory(_cc,0,2,e,e,_o_ac,_aspect_ac,_m_ac);printf(__FUNCSIG__+" a to c logs: "+_o_ac.ontology+" vs product of bid rate for ab and bc of: "+DoubleToString(_ab_bid*_bc_bid,(int)SymbolInfoInteger(_ac,SYMBOL_DIGITS)));//ontology
                   }
                }
             }
          }

    Luego verificaremos la conmutación comparando el tipo de cambio del morfismo de conmutación '_m_ac' con el producto de los dos tipos del morfismo '_m_ab' y '_m_bc'. Existen discrepancias, pero se deben principalmente a la calidad de los datos históricos del bróker y la consideración del spread (solo se utiliza Bid). Ejecutar este script debería darnos las siguientes entradas en el registro.

    2023.01.26 17:27:19.093 ct_2 (EURGBP.ln,H1)     void OnStart() a to b then b to c logs: EUR is exchanged at: 1.08966, for: USD is exchanged at: 0.91723, for: CHF
    2023.01.26 17:27:19.093 ct_2 (EURGBP.ln,H1)     void OnStart() a to c logs: EUR is exchanged at: 0.99945, for: CHF vs product of bid rate for ab and bc of: 0.99947
    2023.01.26 17:27:19.093 ct_2 (EURGBP.ln,H1)     void OnStart() a to b then b to c logs: GBP is exchanged at: 1.65097, for: CAD is exchanged at: 97.663, for: JPY
    2023.01.26 17:27:19.093 ct_2 (EURGBP.ln,H1)     void OnStart() a to c logs: GBP is exchanged at: 161.250, for: JPY vs product of bid rate for ab and bc of: 161.239
    



    Registros ontológicos

    Las ontologías son visiones generales subjetivas de las categorías. Sirven como una herramienta importante en la teoría de categorías porque hacen posible interpretar la estructura y las relaciones de los dominios en cuanto a los morfismos en una categoría dada. En otras palabras, son una estructura matemática (o un modelo de datos equivalente a un esquema de base de datos) que describe los tipos de dominio y sus morfismos en el mismo. Existen varios tipos de ontologías:
    • Las ontologías taxonómicas describen un conjunto de objetos y sus subclases y definen las relaciones entre ellos en términos de relaciones IS-A.
    • Las ontologías jerárquicas describen un conjunto de objetos y sus propiedades y definen las relaciones entre ellos en términos de relaciones PART-OF.
    • Las ontologías relacionales describen un conjunto de objetos y sus relaciones y definen las relaciones entre ellos en términos de relaciones binarias arbitrarias.

    Si hablamos de los sistemas comerciales de Fórex, las ontologías relacionales pueden ser las más apropiadas, pues permiten modelar diferentes tipos de estrategias comerciales y la relación entre ellas, por ejemplo, qué estrategias funcionan mejor bajo ciertas condiciones de mercado. Además, las ontologías relacionales se pueden ampliar fácilmente para incluir información adicional, como datos históricos, que pueden resultar útiles al desarrollar un sistema comercial.

    Las ontologías relacionales pueden demostrarse en acción cuando se usan en distintas áreas de la teoría de categorías utilizando varios ejemplos del ámbito de los mercados financieros. A continuación, mostramos cinco ejemplos:

    1. Pares de divisas: el mercado Fórex se compone de pares de divisas. Las divisas incluidas en el par se negocian una contra otra. Las relaciones entre estas divisas se pueden modelar utilizando ontologías relacionales, donde los pares de divisas se consideran como dominios y el tipo de cambio se considera como un morfismo que los conecta. Más arriba hemos visto un ejemplo de un diagrama conmutativo.
    2. Datos de series temporales: los precios de Fórex a menudo se representan como datos de series temporales que se pueden modelar utilizando ontologías relacionales donde los datos de las series temporales se tratan como un dominio, mientras que los cambios de precio a lo largo del tiempo se tratan como morfismos.
    3. Los indicadores técnicos, como las medias móviles o los índices de fuerza relativa, se pueden utilizar para analizar los precios de las divisas. Estos indicadores se pueden modelar usando ontologías relacionales donde el indicador se considera como un dominio, mientras que los valores del indicador se consideran como morfismos.
    4. Estrategias comerciales: los tráders a menudo usan varias estrategias comerciales, como el seguimiento de tendencias o las estrategias basadas en el impulso (momentum). Estas estrategias se pueden modelar usando ontologías relacionales donde la estrategia comercial se trata como un dominio, mientras que las operaciones ejecutadas según la estrategia se tratan como morfismos.
    5. La profundidad de mercado supone un registro de todas las órdenes de compra y venta que se han realizado en Fórex. Este sistema se puede modelar (si lo proporciona el bróker) usando ontologías relacionales donde la profundidad de mercado se considera un dominio y las órdenes colocadas se consideran morfismos.

    En general, las ontologías relacionales resultan útiles en la teoría de categorías cuando se usan en el comercio porque permiten modelar y analizar sistemas y relaciones complejos de una forma clara y estructurada. Las ontologías usan "tipos" y "aspectos" para representar una visión subjetiva de una categoría. El tipo se puede estudiar como un grupo de dominios dentro de una categoría particular. Puede ser simple o compuesto. Uno simple contiene solo un dominio, mientras que uno compuesto contiene varios. Los aspectos se relacionan con los tipos de la misma forma que los morfismos se relacionan con los dominios dentro de una categoría. Las ontologías relacionales basadas en pares de divisas se ven así:

    Tipos:

    1. Un par de divisas es un tipo básico que representa dos divisas que se negocian una contra otra. Por ejemplo, el par de divisas EURUSD presenta el tipo de cambio entre el euro y el dólar estadounidense.
    2. Un tipo de cambio es la tasa a la que se puede cambiar una divisa por otra. Supone un morfismo entre los objetos del par de divisas. Por ejemplo, el tipo de cambio del par de divisas EURUSD puede ser de 1,20, es decir, se puede cambiar 1 euro por 1,20 dólares estadounidenses.
    3. El tiempo es un tipo que se puede usar para representar el momento en el que se aplica el tipo de cambio. Se puede utilizar para relacionar el morfismo del tipo de cambio con los datos de las series temporales.

    Aspectos:

    1. Los tipos de cambio históricos son los tipos de cambio registrados en diferentes momentos. Se pueden utilizar para analizar tendencias y patrones en el mercado Fórex.
    2. La volatilidad supone una medida de cuánto cambia el tipo de cambio a lo largo del tiempo. Se puede utilizar para evaluar el riesgo vinculado con un par de divisas en particular.
    3. La correlación supone una medida de la relación entre dos pares de divisas. Se puede utilizar para identificar oportunidades de diversificación o cobertura en el mercado Fórex.

    En general, las ontologías relacionales ofrecen una visión clara y estructurada de las relaciones entre los pares de divisas, los tipos de cambio, el tiempo y otros aspectos del mercado de divisas. Se pueden usar para analizar el mercado y tomar decisiones bien informadas. Los universos de Grothendieck se utilizan para definir el concepto de un universo de tipos, que es clave en las ontologías de la teoría de categorías. El universo de tipos es el conjunto de tipos en una categoría dada. Permite ordenar los tipos y resuelve el problema del "conjunto de conjuntos".

    Para ver las ontologías en acción, analizaremos un ejemplo del campo de las finanzas. Diferentes organizaciones, como la Comisión de Bolsa y Valores (SEC) y los fondos de cobertura, pueden usar ontologías para distribuir y clasificar datos financieros en la misma categoría de diferentes maneras. Esto puede dar lugar a diferentes tipos y aspectos de los datos representados en las ontologías usadas por cada objeto. Desde el punto de vista de la SEC, las ontologías se pueden usar para organizar datos relacionados con los valores y la actividad comercial, haciendo hincapié en cuestiones de cumplimiento y regulación. Esto puede incluir tipos tales como "valores", "actividades comerciales", "uso de información privilegiada" y "violaciones de las leyes de valores". Las ontologías también pueden incluir aspectos relacionados con la aplicación de la ley y la legislación comercial, como "investigaciones" y "castigos". Desde la perspectiva de un fondo de cobertura, la misma categoría de datos de objetos se puede usar para organizar datos relacionados con estrategias de inversión, gestión de portafolios y medidas de rendimiento. Esto puede incluir tipos como "estrategias de inversión", "gestión de portafolios", "medidas de rendimiento" y "gestión de riesgos". Las ontologías también pueden incluir aspectos relacionados con las operaciones y la gestión de fondos, como "activos bajo gestión" y "gestores de fondos". Como podemos ver, si bien ambas organizaciones pueden utilizar ontologías para organizar los datos financieros, los tipos y aspectos presentados en sus modelos difieren, lo cual refleja los diferentes objetivos, perspectivas y problemas de la SEC en comparación con un fondo de cobertura. Por lo tanto, las ontologías de la SEC se centrarán en el cumplimiento, las reglas y las infracciones en el comercio de valores, mientras que las ontologías de los fondos de cobertura se centrarán en la inversión, la gestión de riesgos y la gestión de portafolios.

     

    En el contexto de Fórex, los tipos simples y compuestos se refieren a tipos de datos que se pueden usar para representar varios aspectos del mercado. Los tipos simples son tipos de datos básicos que se pueden representar usando un solo valor. Por ejemplo, en Fórex, el tipo de cambio entre dos divisas se puede considerar como un tipo simple representado por un valor único como 1,20 (lo cual significa que 1 unidad de la divisa básica se puede cambiar por 1,20 unidades de la divisa de cotización). Los tipos compuestos son tipos de datos que constan de múltiples valores u otros tipos de datos. Por ejemplo, podemos pensar en un gráfico de velas como un tipo compuesto porque consta de múltiples valores, como el precio de apertura, el precio de cierre, el precio más alto y el precio más bajo para un periodo de tiempo determinado. Desde el punto de vista de los aspectos, los aspectos simples son aquellos que relacionan dos tipos simples. Por ejemplo, el tipo de cambio entre dos divisas puede considerarse un aspecto simple. Los aspectos compuestos son aquellos que conectan dos tipos compuestos, o un tipo compuesto y un tipo simple, por ejemplo, una estrategia comercial puede considerarse un aspecto compuesto porque relaciona una estrategia a las transacciones ejecutadas en base a ella. En general, los tipos y aspectos simples son los bloques de construcción básicos que se pueden usar para representar piezas básicas de información en ontologías, mientras que los tipos y aspectos compuestos son tipos de datos más complejos que constan de múltiples valores u otros tipos de datos que se pueden usar para representar aspectos más complejos del sistema que estamos modelando.

    Los registros ontológicos son una forma de organizar y representar el conocimiento ofreciendo una estructura lógica del dominio de interés, además, ayudan a definir conceptos, propiedades y relaciones dentro de un dominio, subdominio, tarea, instancia o proceso en particular. Un registro ontológico es una representación formal de un conjunto de conceptos, propiedades y relaciones existentes en un dominio determinado. Se utiliza para definir la estructura del conocimiento en un área determinada y para ofrecer una presentación coherente y lógica del conocimiento. Esto facilita que las máquinas y los humanos comprendan y usen la información del dominio. Los registros ontológicos se pueden utilizar en varios campos, tales como la inteligencia artificial, el procesamiento del lenguaje natural, la representación del conocimiento y la informática. Suelen usarse junto con otros tipos de ontologías, como ontologías de nivel superior y ontologías de dominio, para proporcionar una representación completa del dominio. Los registros ontológicos generalmente se presentan en un formato legible por la máquina, como OWL (Web Ontology Language, lenguaje de ontología web) o RDF (Resource Description Framework, marco de descripción de recursos), lo cual permite que las máquinas los procesen y utilicen fácilmente. También son legibles por humanos, lo que facilita que las personas comprendan y usen la información ofrecida en el registro ontológico.

    En el contexto de la teoría de categorías, los registros ontológicos ofrecen una forma de organizar y representar el conocimiento dentro de un dominio de manera estructurada y lógica. ayudan a definir conceptos, propiedades y relaciones dentro de un dominio, subdominio, tarea, instancia o proceso en particular. La teoría de categorías es una rama de las matemáticas que estudia la estructura de los sistemas matemáticos y ofrece un marco para modelar las relaciones entre objetos y morfismos. En el contexto de la teoría de categorías, los registros ontológicos proporcionan una forma de organizar y representar el conocimiento del dominio de una forma estructurada y lógica.

    Existen varios tipos de registros ontológicos usados comúnmente en la teoría de categorías, por ejemplo:

    1. Ontología de nivel superior: ontología general que proporciona una vista de alto nivel de un dominio y define los conceptos y relaciones más generales aplicados a través de múltiples subdominios. Esta es una forma común de ofrecer una estructura unificadora para diferentes ontologías.
    2. Ontología de dominio: ontología que se enfoca en un dominio particular (subdominio) dentro de un dominio más grande (dominio). Define los conceptos y las relaciones concretas de este subdominio.
    3. Ontología de tareas: ontología que se enfoca en una tarea o problema específico en un dominio. Define los conceptos y las relaciones concretas de esa tarea o problema.
    4. Ontología de instancia: ontología que se enfoca en las instancias de un concepto o clase en particular. Define las propiedades y relaciones concretas de estas instancias.
    5. Ontología de procesos: ontología que se enfoca en los procesos o actividades que ocurren dentro de un dominio. Define los conceptos y relaciones concretas de estos procesos o actividades.

    Estos tipos de registros ontológicos se usan para estructurar el conocimiento y las relaciones dentro de un dominio y para facilitar la comprensión, presentación y procesamiento de la información. Ayudan a proporcionar una representación coherente y lógica del conocimiento dentro de un dominio y se pueden usar junto con ontologías relacionales para ofrecer una representación integral de un dominio.

    Un registro de ontología de procesos es un tipo especial de registro de ontología centrado en los procesos o actividades que ocurren dentro de un dominio. Define los conceptos y relaciones concretas de estos procesos o actividades. Por lo tanto, los tipos de aspectos que se pueden usar en un registro de ontología de procesos dependerán del dominio particular y de los procesos o actividades que se modelen. Estos son algunos ejemplos de aspectos que se pueden utilizar en un registro de ontología de procesos:

    1. Datos de entrada y salida: las entradas y salidas de un proceso se pueden usar para definir los recursos, los materiales o la información necesarios para ejecutar el proceso y los productos finales, los servicios o la información generada por el proceso.
    2. Pasos o etapas: un proceso se puede dividir en pasos o etapas más pequeños. Cada etapa se puede definir como un concepto que representa las actividades y objetivos de esa etapa. Las relaciones entre los pasos también se pueden modelar.
    3. Actores: entidades o agentes involucrados en un proceso, como personas, máquinas u organizaciones. Las relaciones entre los actores y sus roles en un proceso se pueden definir.
    4. Restricciones: reglas, regulaciones o restricciones que debe cumplir un proceso. Este aspecto se puede usar para definir las condiciones y requisitos a cumplir para que el proceso se complete con éxito.
    5. Métricas: medidas o indicadores utilizados para medir el rendimiento de un proceso, como la eficiencia, la calidad o el coste. Este aspecto se puede usar para definir las dimensiones y métricas utilizadas para evaluar el proceso y cómo se calculan.
    6. Aspectos temporales: se refiere a los parámetros temporales del proceso, tales como la hora de inicio y finalización, la duración y la frecuencia del proceso. Este aspecto se puede usar para modelar los aspectos temporales del proceso.

    En general, un registro de ontología de procesos se puede utilizar para modelar varios aspectos de un proceso, incluidas entradas y salidas, pasos o etapas, actores, restricciones, métricas y aspectos temporales, así como las relaciones entre ellos de una forma estructurada y lógica, lo cual facilita la comprensión, la representación y el procesamiento de la información. Un ejemplo de una ontología de procesos en la categoría del mercado de divisas (Fórex) puede ser el proceso de ejecución de una transacción. La ontología de procesos definirá los conceptos y las relaciones específicas del proceso de ejecución de una transacción. Aquí tenemos un ejemplo sobre cómo se pueden modelar los aspectos de esta ontología de procesos:

    1. Datos de entrada y salida: los datos de entrada del proceso incluyen la estrategia comercial, el par de divisas para negociar y el balance de la cuenta comercial. Los datos de salida serán la transacción completada.
    2. Pasos o etapas: el proceso se puede dividir en pasos o etapas más pequeños, como la selección de un par de divisas, el establecimiento de los parámetros comerciales, la colocación de una orden y el monitoreo de la transacción.
    3. Actores: en el proceso intervienen el tráder, la plataforma comercial y el mercado. El tráder es el actor principal que inicia el proceso, la plataforma comercial es el instrumento utilizado para realizar la transacción y el mercado es el entorno en el que se lleva a cabo la transacción.
    4. Restricciones: las restricciones incluyen las disposiciones sobre márgenes, apalancamiento y gestión de riesgos. Estas restricciones deben cumplirse para que la transacción se complete con éxito.
    5. Métricas: Las métricas usadas para evaluar el rendimiento del proceso incluyen el beneficio o las pérdidas por operación, la relación riesgo/recompensa y el porcentaje de operaciones exitosas.
    6. Aspectos temporales: los aspectos temporales se refieren al tiempo del proceso, como la hora de inicio y finalización de la transacción, la duración de la misma y la frecuencia de las transacciones.

    Este registro de ontología de procesos se puede utilizar para estructurar y modelar lógicamente varios aspectos del proceso de transacción de divisas. Se puede usar para facilitar la comprensión, la representación y la manipulación de la información relacionada con el proceso de ejecución de las transacciones, así como combinado con otros tipos de ontologías para ofrecer una visión integral de los mercados financieros.


    Conclusión

    La teoría de categorías ofrece un marco poderoso para modelar y analizar sistemas complejos como los mercados financieros. La implementación de la teoría de categorías en MQL5 puede ayudar a los tráders a comprender mejor el mercado y a orientarse en el mismo, proporcionando una vista estructurada y lógica de las relaciones entre dominios y morfismos. El artículo destaca la importancia de las definiciones de axiomas de categoría en la teoría de categorías y cómo proporcionan un marco para modelar las relaciones entre los dominios y los morfismos. En el presente artículo también se ha discutido el concepto de registros ontológicos y cómo se pueden utilizar para ofrecer un marco lógico para el área de interés, en este caso, los mercados financieros. En general, la teoría de categorías en MQL5 puede ser una herramienta valiosa para los tráders que buscan alcanzar una comprensión más profunda del mercado y tomar decisiones comerciales más informadas, ya que proporciona un enfoque estructurado y lógico para el análisis de mercado que puede ayudar a los tráders a detectar patrones y oportunidades que, de otra forma, resultarían difíciles de percibir.

    Traducción del inglés realizada por MetaQuotes Ltd.
    Artículo original: https://www.mql5.com/en/articles/11958

    Archivos adjuntos |
    ct_2.mq5 (62.16 KB)
    Probando y optimizando estrategias de opciones binarias en MetaTrader 5 Probando y optimizando estrategias de opciones binarias en MetaTrader 5
    Probando y optimizando estrategias de opciones binarias en MetaTrader 5
    Recetas MQL5 - Base de datos de eventos macroeconómicos Recetas MQL5 - Base de datos de eventos macroeconómicos
    El presente artículo analiza las posibilidades de trabajar con bases de datos que utilizan el motor SQLite como base. Hemos creado una clase CDatabase para usar de forma cómoda y eficaz los principios de la programación orientada a objetos. Posteriormente se utilizará para crear y gestionar una base de datos de eventos macroeconómicos. Asimismo, ofreceremos ejemplos de muchos métodos de la clase CDatabase.
    Cómo construir un EA que opere automáticamente (Parte 13): Automatización (V) Cómo construir un EA que opere automáticamente (Parte 13): Automatización (V)
    ¿Sabes lo que es un diagrama de flujo? ¿Sabes cómo utilizarlo? ¿Cree que los diagramas de flujo son sólo cosas de aprendiz de programador? Pues echa un vistazo a este artículo y aprende a trabajar con diagramas de flujo.
    Desarrollando una DLL experimental con soporte multihilo en C++ para MetaTrader 5 en Linux Desarrollando una DLL experimental con soporte multihilo en C++ para MetaTrader 5 en Linux
    En este artículo, describiremos el proceso de desarrollo de la plataforma MetaTrader 5 exclusivamente en Linux. El producto final funcionará a la perfección tanto en Windows como en Linux. Asimismo, aprenderemos sobre Wine y Mingw, herramientas importantes para el desarrollo multiplataforma. Mingw ofrece transmisión de flujo (POSIX y Win32), lo que debe tenerse en cuenta a la hora de elegir la herramienta adecuada. A continuación crearemos una DLL para probar el concepto; luego la usaremos en el código MQL5 y compararemos el rendimiento de ambas implementaciones de los hilos. Este artículo pretende ser un punto de partida para experimentos propios. Después de leer este artículo, el lector será capaz de crear herramientas para MetaTrader en Linux.