English 中文 Español Deutsch 日本語 Português
preview
Теория категорий в MQL5 (Часть 2)

Теория категорий в MQL5 (Часть 2)

MetaTrader 5Интеграция | 20 марта 2023, 15:36
1 185 0
Stephen Njuki
Stephen Njuki

Введение

Продолжаем обсуждение использования теории категорий в MQL5, начатое в предыдущей статье. Как вы помните, мы представили теорию категорий как раздел математики, особенно полезный для организации и классификации информации. В этом контексте мы обсудили некоторые основные концепции теории категорий и то, как ее можно применить к анализу данных финансовых временных рядов. В частности, мы рассмотрели элементы, домены и морфизмы. Элементы являются основными единицами информации в системе теории категорий. Обычно они рассматриваются как члены множества, называемого в этих сериях доменом. Домен может иметь отношения с другими доменами посредством процесса, называемого морфизмом. В этой статье мы начнем с рассмотрения того, что составляет категорию, рассмотрев аксиомы тождества и ассоциации, а также коммутативную диаграмму. При этом на протяжении всей статьи мы будем рассматривать примеры того, что не является категорией. Наконец, мы закончим введением онтологических записей.

Прежде чем мы углубимся в определения аксиом категории, взглянем на несколько повседневных примеров категорий "в действии". Мы уже определили домены и содержащиеся в них элементы. Следующие примеры показывают использование категории как набора связанных доменов.

    • Категория виды транспорта с доменами, представляющими разные виды транспорта (автомобили, самолеты, поезда и т.д.). Элементами каждого домена будут соответствующие виды транспортных средств. В случае с автомобилями у нас могут быть, например, совместные поездки, прокат, личное авто, такси. Самолеты могут быть частными, коммерческими, арендованными. Поезда могут включать в себя трамваи, сверхскоростные поезда, паровозы и т.д. Морфизм между ними может служить для определения полного маршрута путешествия. Например, если вы добирались до аэропорта на такси, летели коммерческим рейсом, а затем ехали на сверхскоростном поезде из аэропорта до пункта назначения, каждый из этих вариантов можно легко сопоставить с этой категорией.  
    • Категория блюд с доменами, представляющими меню для каждого курса. Допустим, у нас есть пять блюд, а именно: закуска, суп, основное блюдо, десерт и сыр. В этом случае элементами каждого домена будут продукты питания в меню соответствующего блюда. Например, закуска может иметь в своей области (меню) варианты выбора: засахаренная морковь с медом, тмином и паприкой; ИЛИ грибы, фаршированные пекорино романо, чесноком и панировочными сухарями; ИЛИ обжаренная брокколи с перцем шишито и маринованным луком. Точно так же суп может включать в себя варианты: тосканский суп из белой фасоли и жареного чеснока; ИЛИ суп из тыквы и шалфея; ИЛИ холодный суп из дыни и базилика. Каждый из этих пунктов меню представляет элемент в своем домене. Точно так же морфизм между ними будет служить для определения всей еды, выбранной посетителем ресторана. Например, если клиент заказал засахаренную морковь, затем тыкву и т. д. для всех остальных блюд, каждый из этих вариантов, подобных приведенным выше, можно легко сопоставить с категорией.
    • Другим примером категории могут быть типы еженедельных развлечений. Здесь нашими доменами могут быть спортивные соревнования, просмотр потокового ТВ и посещения парков. Элементами каждого домена могут быть: NFL, или MLB, или NBA для спортивного домена; Netflix, или HBO, или AMC для домена потокового ТВ; Диснейленд, или зоопарк, или природный парк для посещений парков. И снова аудитория может выбрать из каждого домена спортивную игру, телепередачу и парк. И строка выборок в этих доменах (морфизмах) легко позволяет отображать эту информацию.

    Всё это и, очевидно, многое другое можно зафиксировать с помощью теории категорий. Но с какой целью?  Есть поговорка "у плохого мастера всегда инструмент виноват". Она применима и к этому случаю. Цель определяется пользователем. По моему мнению, теория категорий хорошо подходит для количественной оценки эквивалентности. Это тема, которую мы рассмотрим в следующих статьях после того, как изучим основные понятия. Достаточно сказать, что именно по этой причине обнаруживаются две отдельные категории по разным темам, которые могут показаться несвязанными на первый взгляд, но при более глубоком рассмотрении оказываются идентичными или зеркально противоположными. Эти идеи жизненно важны для принятия решений, потому что у нас редко бывает достаточно информации во время принятия решений. Однако если у нас есть коррелируемые категории, то информационный пробел можно восполнить. 


    Тождество

    Изоморфизм является важным свойством гомоморфизмов в теории категорий, поскольку он гарантирует, что структура доменов в целевой категории сохраняется при конвертации. Он также гарантирует сохранение алгебраических операций доменов в исходной категории. Например, давайте рассмотрим категорию одежды, доменами которой являются рубашки и брюки, а морфизмы — это функции, которые конвертируют размер рубашки в размер брюк. Гомоморфизмом в этой категории была бы функция, сохраняющая соответствие размеров рубашек соответствующим размерам брюк. Изоморфизмом в этой категории была бы функция, не только сохраняющая алгебраическую парность размеров, но и устанавливающая взаимно однозначное соответствие между размерами рубашек и брюк. Это означает, что для любого размера рубашки существует ровно один соответствующий размер брюк, и наоборот. Например, рассмотрим функцию, которая сопоставляет размер рубашки ("маленький", "средний", "большой") с размером брюк ("26", "28", "30", "32"). Эта функция является гомоморфизмом, потому что она сохраняет и определяет пару размеров (например, "маленький" может быть сопоставлен с "26"). Но это не изоморфизм, потому что он не устанавливает однозначного соответствия между размерами рубашки и брюк, учитывая, что "маленький" размер также можно носить с "28" или "26". Обратимости в этом случае нет.


    non_iso


    С другой стороны, рассмотрим функцию, которая сопоставляет размер рубашки ("маленький", "средний", "большой") только с размером брюк ("28", "30", "32"). Эта функция является не только гомоморфизмом, но и изоморфизмом, поскольку она допускает обратимость.


    iso


    В примере с категорией одежды, где доменами являются рубашки и брюки, а морфизмы — это функции, конвертирующие размер рубашки в размер брюк, отдельный морфизм не может быть изоморфным, поскольку все отдельные морфизмы по своей природе обратимы и таким образом "изоморфны". Свойство изоморфизма касается группы морфизмов (также называемых набором гомоморфизмов) одного домена в кодомен, и его можно считать присутствующим только в том случае, если все эти морфизмы как группа являются обратимыми, сохраняя при этом свойства алгебраического сопоставления гомоморфизма. Вот почему важно перечислить все морфизмы из домена, прежде чем подтверждать изоморфизм. Без рассмотрения всех возможных морфизмов может показаться, что два объекта изоморфны, хотя на самом деле это не так. Предшественником изоморфизма является кардинальность доменов. Это значение должно быть одинаковым для обоих доменов. Если домены имеют несовпадающую кардинальность, то гомоморфизм между ними не может быть обратимым, потому что из одного домена у нас будет более одного элемента, конвертируемого в один и тот же коэлемент. Следовательно, нам нужна группа морфизмов между областями для определения изоморфизма. Обычно нам нужны два морфизма, один из рубашек в штаны, а другой из штанов в рубашки, которые устанавливают однозначное соответствие между размерами рубашек и штанов. Эти морфизмы должны быть обратными друг другу, а это означает, что если один морфизм переводит рубашку размера "маленький" в брюки размера "28", то другой морфизм должен переводить брюки размера "28" в рубашку размера "маленький". И когда мы составим эти два морфизма, это должно дать нам тождественный морфизм для начатого нами домена.

    Это требование аксиом в теории категорий привело к необходимости самоотображающихся морфизмов. Споры о том, имеют ли они значение в определении категории, ведутся до сих пор. 

    Давайте проиллюстрируем изоморфизм в MQL5. Я переписал большую часть скрипта из первой статьи, включив в него шаблоны. Все классы от класса элемента до класса категории включают использование шаблонных типов данных для обеспечения гибкости. Однако я "перечислил" типы, доступные в классе категории. Это datetime, string, double и int. Тип int используется по умолчанию и будет использоваться, если, например, используется такой тип данных как color. Весь код прикреплен в конце статьи. Ниже представлен наш новый класс гомоморфизмов.

    //+------------------------------------------------------------------+
    //| 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){};
       };

    Для проверки изоморфизма мы будем использовать те же домены, что и в предыдущей статье, и пропустим их через функцию IsIsomorphic. Эта функция возвращает логическое значение, где true указывает на успех, а false — на неудачу.

    //+------------------------------------------------------------------+
    //| 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);
       }

    Однако выходной гомоморфизм необходимо указать сразу, и в нашем случае мы используем переменную "_h_i". Это выходное значение, которое представляет собой массив классов гомоморфизмов, будет включать перечисление всех возможных изоморфных гомоморфизмов между двумя входными доменами.

          //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));
             }
          }

    Если мы запустим этот код, то увидим следующие записи в журнале:

    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
    
    

    Четный домен:

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

    Нечетный домен:

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


    Ассоциативность

    В теории категорий аксиома ассоциативности — одно из основных свойств, которым должна удовлетворять категория. Возвращаясь к примеру с категорией одежды, доменами являются определенные предметы одежды, такие как рубашки, брюки и обувь, а морфизмы будут функциями, которые сопоставляют одежду в зависимости от пригодности. Аксиома ассоциативности, также известная как "закон ассоциативности", утверждает, что композиция морфизмов ассоциативна. Это означает, что при составлении нескольких морфизмов порядок их применения не влияет на конечный результат.

    Например, рассмотрим морфизм "надевается с" во всех трех областях одежды (рубашки, брюки и обувь). Допустим, у нас есть морфизм f: футболка -> рубашка на пуговицах, g: рубашка на пуговицах -> джинсы и h: джинсы -> кроссовки. Используя аксиому ассоциации, мы можем определить композицию этих морфизмов как h o (g o f) = (h o g) o f. Это означает, что порядок морфизмов не имеет значения, и мы можем группировать их как угодно. Это упрощает определение категории, поскольку позволяет избежать вычисления скобок нескольких морфизмов. Вместо этого мы можем сгруппировать морфизмы вместе, независимо от их порядка, и конечный результат будет одним и тем же.

    Давайте посмотрим на это в действии в MQL5. Нам нужно будет перекомпоновать класс категорий, который я приводил в предыдущей статье.

    //+------------------------------------------------------------------+
    //| 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()
                                        { 
                                        };
       };

    Обратите внимание на допустимые "перечисленные" типы данных. Я постараюсь сделать их заметнее в будущих статьях, объединив их как объект в единый массив. Также, помимо функции, заполнявшей домен натуральными числами, была добавлена функция 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);
             }
          }
       }

    Чтобы проверить ассоциативность, создадим категорию '_ca'. Затем объявим три простых набора строкового типа, каждый из которых заполнен типом одежды. Скопируем эти наборы (массивы) в новые массивы элементов ('_et', '_ep', '_es'), а затем добавим каждый из этих элементов в его собственный домен ('_dt', '_dp', '_ds'). Сделав это, мы устанавливаем количество доменов в нашей категории равным трем, а затем приступаем к установке домена в каждом индексе с вновь созданными доменами, которые были заполнены элементами типа одежды.

          //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);
                   }
                }
             }
          }

    Для проверки на ассоциативность будем выводить результаты морфизмов в онтологоческих записях. Для этого создадим класс COntology. Это описано ниже с перечислением и структурой, имеющей то же имя.

    //+------------------------------------------------------------------+
    //| 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(){};
      };

    Запуск скрипта должен дать нам следующие записи в логах.

    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
    


     

    Таким образом, аксиома ассоциативности позволяет легко определить категорию, позволяя композиции морфизмов быть ассоциативной, что устраняет необходимость вычислять круглые скобки при определении нескольких морфизмов. Это упрощает понимание взаимосвязей между объектами в категории, в данном случае предметами одежды во всех трех доменах (рубашки, брюки и обувь). 


    Коммутативные диаграммы

    Коммутативная диаграмма - это диаграмма, которая представляет отношения между двумя морфизмами в категории. Она состоит из набора областей, морфизмов и их композиций, организованных определенным образом, чтобы показать, что морфизмы коммутируют, а это означает, что порядок, в котором они составлены, не имеет значения. Это означает, что для любых трех областей A, B и С в категории и для их морфизмов f: A -> B, g: B -> C и h: A -> C; композиция этих морфизмов должна удовлетворять равенству:

    f o g = h

    Примером коммутации с использованием форекс-цен может быть арбитраж - соотношение между ценой, скажем, EURUSD, EURJPY и USDJPY. В этом примере доменами могут быть сами валюты (EUR, USD, JPY), а морфизмы могут представлять процесс конвертации одной валюты в другую по обменному курсу. Например, пусть f: EUR -> USD будет морфизмом, представляющим процесс конвертации EUR в USD по обменному курсу EURUSD; пусть g: USD -> JPY — морфизм, представляющий процесс конвертации USD в JPY по обменному курсу USDJPY; а h: EUR -> JPY будет морфизмом, представляющим конвертацию EUR в JPY. С учетом вышеприведенного правила коммутации (f o g = h), это будет означать:

    конвертация EUR в USD по курсу EURUSD, затем конвертация USD в JPY по курсу USDJPY = конвертация EUR в JPY по курсу EURJPY.

    Проиллюстрируем это средствами MQL5. Объявим категорию '_cc' и заполним ее тремя доменами с двумя валютами в каждом. Домены можно рассматривать как портфели в распределении активов. Как и в случае с аксиомой ассоциативности, мы будем заполнять и проверять значения наших категорий, используя онтологические записи, как показано ниже.

          //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
                   }
                }
             }
          }

    Мы проверяем коммутацию, сравнивая курс коммутирующего морфизма '_m_ac' с произведением двух курсов морфизмов '_m_ab' и '_m_bc'. Есть расхождения, но они в основном из-за качества исторических данных брокера и учета спреда (используются только биды). Запуск этого скрипта должен дать нам следующие записи в логах.

    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
    



    Онтологические записи

    Онтологии - это субъективные обзоры категорий. Они служат важным инструментом теории категорий, поскольку дают возможность интерпретировать структуру и отношения доменов через морфизмы в данной категории. Иными словами, они представляют собой математическую структуру (или модель данных, эквивалентную схеме базы данных), которая описывает типы доменов и их морфизмы в домене. Существуют несколько типов онтологий:
    • Таксономические онтологии описывают набор объектов и их подклассов и определяют отношения между ними в терминах отношений IS-A.
    • Иерархические онтологии описывают набор объектов и их свойств и определяют отношения между ними в терминах отношений PART-OF.
    • Реляционные онтологии описывают множество объектов и их отношений и определяют отношения между ними в терминах произвольных бинарных отношений.

    Применительно к торговой системе для форекса наиболее подходящими могут быть реляционные онтологии. Они позволяют моделировать различные типы торговых стратегий и отношения между ними, например, какие стратегии наиболее эффективны в определенных рыночных условиях. Кроме того, реляционные онтологии можно легко расширить, включив в них дополнительную информацию, такую как исторические данные, которые могут быть полезны при разработке торговой системы.

    Реляционные онтологии можно продемонстрировать в действии при использовании в разных областях теории категорий на различных примерах из области финансовых рынков. Ниже приведены пять примеров:

    1. Валютные пары: рынок форекс состоит из валютных пар. Валюты, входящие в пару, торгуются друг против друга. Отношения между этими валютами можно смоделировать с помощью реляционных онтологий, где валютные пары рассматриваются как домены, а обменный курс рассматривается как морфизм, который их соединяет. Пример коммутативной диаграммы был приведен выше.
    2. Данные временных рядов: цены на форексе часто представляются в виде данных временных рядов, которые можно смоделировать с использованием реляционных онтологий, где данные временных рядов рассматриваются как домен, а изменения цен во времени рассматриваются как морфизмы.
    3. Технические индикаторы, такие как скользящие средние или индексы относительной силы, можно использовать для анализа цен на форексе. Эти индикаторы можно смоделировать с помощью реляционных онтологий, где индикатор рассматривается как домен, а значения индикатора рассматриваются как морфизмы.
    4. Торговые стратегии: трейдеры часто используют различные торговые стратегии, такие как следование за трендом, или стратегии, основанные на рыночном импульсе (моментуме). Эти стратегии могут быть смоделированы с использованием реляционных онтологий, где торговая стратегия рассматривается как домен, а сделки, которые выполняются на основе стратегии, рассматриваются как морфизмы.
    5. Стакан цен — это запись всех ордеров на покупку и продажу, которые были размещены на форексе. Эту систему можно смоделировать (если это предусмотрено брокером) с использованием реляционных онтологий, где стакан цен рассматривается как домен, а размещенные ордера рассматриваются как морфизмы.

    В целом реляционные онтологии полезны в теории категорий при использовании в трейдинге, поскольку позволяют моделировать и анализировать сложные системы и отношения в ясной и структурированной форме. Онтологии используют "типы" и "аспекты" для представления субъективного взгляда на категорию. Тип можно рассматривать как группу доменов в определенной категории. Он может быть простым или составным. Простой содержит только один домен, составной - несколько. Аспекты относятся к типам так же, как морфизмы относятся к доменам внутри категории. Реляционные онтологии, основанные на валютных парах, выглядят следующим образом:

    Типы:

    1. Валютная пара является основным типом, представляющим две валюты, которые торгуются друг против друга. Например, валютная пара EURUSD представляет обменный курс между евро и долларом США.
    2. Обменный курс — курс, по которому одна валюта может быть обменена на другую. Представляет собой морфизм между объектами валютной пары. Например, курс обмена валютной пары EURUSD может составлять 1,20, то есть 1 евро можно обменять на 1,20 доллара США.
    3. Время — тип, который можно использовать для представления времени, в которое применяется обменный курс. Его можно использовать для связи морфизма обменного курса с данными временных рядов.

    Аспекты:

    1. Исторические обменные курсы — обменные курсы, зарегистрированные в разные моменты времени. Их можно использовать для анализа трендов и закономерностей на рынке форекс.
    2. Волатильность — мера того, насколько обменный курс меняется с течением времени. Ее можно использовать для оценки риска, связанного с конкретной валютной парой.
    3. Корреляция — мера отношения между двумя валютными парами. Ее можно использовать для определения возможностей диверсификации или хеджирования на рынке форекс.

    В целом, реляционные онтологии обеспечивают четкое и структурированное представление взаимосвязей между валютными парами, обменными курсами, временем и другими аспектами рынка форекс. Их можно использовать для анализа рынка и принятия взвешенных решений. Универсумы Гротендика используются для определения концепции универсума типов, которая является ключевой в онтологиях теории категорий. Универсум типов — это набор типов в данной категории. Он позволяет сортировать типы и решает проблему "набора наборов".

    Чтобы увидеть онтологии в действии, рассмотрим пример из области финансов. Различные организации, такие как Комиссия по ценным бумагам и биржам (SEC) и хедж-фонд, могут использовать онтологии для распределения и классификации финансовых данных в одной и той же категории разными способами. Это может привести к различным типам и аспектам данных, представленных в онтологиях, используемых каждым объектом. С точки зрения SEC, онтологии могут использоваться для организации данных, связанных с ценными бумагами и торговой деятельностью, с акцентом на вопросы соответствия и регулирования. Сюда могут входить такие типы, как "ценные бумаги", "торговая деятельность", "инсайдерская торговля" и "нарушения законодательства о ценных бумагах". Онтологии могут также включать аспекты, связанные с соблюдением законодательства и правоприменением, такие как "расследования" и "наказания". С точки зрения хедж-фонда объектные данные той же категории могут использоваться для организации данных, связанных с инвестиционными стратегиями, управлением портфелем и показателями эффективности. Сюда могут входить такие типы, как "инвестиционные стратегии", "управление портфелем", "показатели эффективности" и "управление рисками". Онтологии могут также включать аспекты, связанные с операциями фонда и управлением им, такие как "активы под управлением" и "менеджеры фонда". Как мы видим, хотя обе организации могут использовать онтологии для организации финансовых данных, типы и аспекты, представленные в их моделях, различаются, отражая разные цели, точки зрения и проблемы SEC по сравнению с хедж-фондом. Таким образом, онтологии SEC будут сосредоточены на соблюдении, правилах и нарушениях в торговле ценными бумагами, в то время как онтологии хедж-фонда будут сосредоточены на инвестициях, управлении рисками и управлении портфелем.

     

    Применительно к форексу простые и составные типы относятся к типам данных, которые можно использовать для представления различных аспектов рынка. Простые типы — это базовые типы данных, которые могут быть представлены одним значением. Например, на форексе обменный курс между двумя валютами можно рассматривать как простой тип, представленный одним значением, таким как 1,20 (это означает, что 1 единица базовой валюты может быть обменена на 1,20 единицы котируемой валюты). Составные типы — это типы данных, состоящие из нескольких значений или других типов данных. Например, свечной график можно рассматривать как составной тип, поскольку он состоит из нескольких значений, таких как цена открытия, цена закрытия, самая высокая цена и самая низкая цена за заданный период времени. С точки зрения аспектов, простые аспекты — это те, которые связывают два простых типа. Например, обменный курс между двумя валютами можно считать простым аспектом. Составные аспекты — это те, которые соединяют два составных типа или составной тип и простой тип, например, торговая стратегия может считаться составным аспектом, поскольку она связывает стратегию со сделками, которые выполняются на ее основе. В целом, простые типы и аспекты являются базовыми строительными блоками, которые можно использовать для представления основных фрагментов информации в онтологиях, в то время как составные типы и аспекты представляют собой более сложные типы данных, состоящие из нескольких значений или других типов данных, которые можно использовать для представления более сложных аспектов моделируемой системы.

    Онтологические записи - способ организации и представления знаний путем предоставления логической структуры интересующего домена. Они помогают определять концепции, свойства и отношения в пределах определенного домена, поддомена, задачи, экземпляра или процесса. Онтологическая запись — это формальное представление набора понятий, свойств и отношений, существующих в определенном домене. Она используется для определения структуры знаний в этой области и для обеспечения последовательного и логичного представления знаний. Это облегчает машинам и людям понимание и использование информации в домене. Онтологические записи можно использовать в различных областях, таких как искусственный интеллект, обработка естественного языка, представление знаний и информатика. Они обычно используются в сочетании с другими типами онтологий, такими как онтологии высшего уровня и онтологии предметной области, чтобы обеспечить всестороннее представление предметной области. Онтологические записи обычно представляются в машиночитаемом формате, таком как OWL (Web Ontology Language, язык веб-онтологий) или RDF (Resource Description Framework, структура описания ресурсов), что позволяет легко обрабатывать и использовать их машинами. Они также удобочитаемы для человека, что облегчает людям понимание и использование информации, представленной в онтологической записи.

    В контексте теории категорий онтологические записи используются для организации и представления знаний путем предоставления логической структуры интересующей области. Они помогают определять концепции, свойства и отношения в пределах определенного домена, поддомена, задачи, экземпляра или процесса. Теория категорий — это раздел математики, изучающий структуру математических систем и обеспечивающий основу для моделирования отношений между объектами и морфизмами. В контексте теории категорий онтологические записи обеспечивают способ организации и представления знаний в предметной области структурированным и логичным образом.

    Существует несколько типов онтологических записей, которые обычно используются в теории категорий, например:

    1. Онтология высшего уровня: общая онтология, которая обеспечивает высокоуровневое представление домена и определяет наиболее общие понятия и отношения, применимые к нескольким поддоменам. Это распространенный способ обеспечения унифицирующей структуры для различных онтологий.
    2. Онтология предметной области: онтология, которая фокусируется на конкретной области (поддомене) в составе более крупной области (домена). Он определяет концепции и отношения, характерные для этого поддомена.
    3. Онтология задачи: онтология, которая фокусируется на конкретной задаче или проблеме в предметной области. Она определяет концепции и отношения, характерные для этой задачи или проблемы.
    4. Онтология экземпляра (instance ontology): онтология, которая фокусируется на экземплярах определенного понятия или класса. Она определяет свойства и отношения, характерные для этих экземпляров.
    5. Онтология процесса: онтология, фокусирующаяся на процессах или действиях, происходящих в домене. Она определяет концепции и отношения, характерные для этих процессов или действий.

    Эти типы онтологических записей используются для структурирования знаний и отношений внутри домена, а также для облегчения понимания, представления и обработки информации. Они помогают обеспечить согласованное и логичное представление знаний внутри домена и могут использоваться в сочетании с реляционными онтологиями для обеспечения всестороннего представления домена.

    Запись онтологии процесса — это особый тип онтологической записи, который фокусируется на процессах или действиях, происходящих в домене. Она определяет концепции и отношения, характерные для этих процессов или действий. Таким образом, типы аспектов, которые можно использовать в записи онтологии процесса, будут зависеть от конкретного домена и моделируемых процессов или действий. Вот несколько примеров аспектов, которые можно использовать в записи онтологии процесса:

    1. Входные и выходные данные: входные и выходные аспекты процесса могут использоваться для определения ресурсов, материалов или информации, которые требуются для запуска процесса, а также конечных продуктов, услуг или информации, генерируемых процессом.
    2. Шаги, или этапы: процесс можно разбить на более мелкие шаги, или этапы. Каждый этап можно определить как концепцию, представляющую действия и цели этого этапа. Отношения между шагами также могут быть смоделированы.
    3. Акторы: сущности, или агенты, участвующие в процессе, такие как люди, машины или организации. Отношения между акторами и их ролями в процессе могут быть определены.
    4. Ограничения: правила, положения или ограничения, которых должен придерживаться процесс. Этот аспект можно использовать для определения условий и требований, которые должны быть выполнены для успешного завершения процесса.
    5. Метрики: измерения или индикаторы, которые используются для оценки производительности процесса, например эффективности, качества или стоимости. Этот аспект можно использовать для определения измерений и показателей, используемых для оценки процесса, и способов их расчета.
    6. Временные аспекты: относятся к временным параметрам процесса, таким как время начала и окончания, продолжительность и частота процесса. Этот аспект можно использовать для моделирования временных аспектов процесса.

    В целом, запись онтологии процесса можно использовать для моделирования различных аспектов процесса, включая входные и выходные данные, шаги, или этапы, участников, ограничения, метрики и временные аспекты, а также отношения между ними структурированным и логическим образом, что упрощает понимание, представление и обработку информации. Примером онтологии процесса в категории валютного рынка (форекс) может быть процесс совершения сделки. Онтология процесса будет определять концепции и отношения, характерные для процесса совершения сделки. Вот пример того, как можно смоделировать аспекты этой онтологии процесса:

    1. Входные и выходные данные: входные данные процесса включают торговую стратегию, валютную пару для торговли и баланс торгового счета. Выходными данными является совершенная сделка.
    2. Шаги, или этапы: процесс можно разбить на более мелкие шаги, или этапы, например, выбор валютной пары, установка параметров сделки, размещение ордера и мониторинг сделки.
    3. Акторы: в процесс вовлечены трейдер, торговая платформа и рынок. Трейдер является основным актором, инициирующим процесс, торговая платформа — это инструмент, используемый для совершения сделки, а рынок — это среда, в которой происходит торговля.
    4. Ограничения: ограничения включают положения о марже, кредитном плече и управлении рисками. Эти ограничения должны соблюдаться для успешного завершения сделки.
    5. Метрики: Метрики, используемые для оценки производительности процесса, включают прибыль или убыток по сделке, соотношение риска и вознаграждения и процент успешных сделок.
    6. Временные аспекты: временные аспекты относятся к срокам процесса, таким как время начала и окончания сделки, продолжительность сделки и частота сделок.

    Эту запись онтологии процесса можно использовать для структурированного и логического моделирования различных аспектов процесса совершения сделки на рынке форекс. Ее можно использовать для облегчения понимания, представления и манипулирования информацией, связанной с процессом совершения сделки, а также в сочетании с другими типами онтологий для обеспечения комплексного представления о финансовых рынках.


    Заключение

    Теория категорий обеспечивает мощную основу для моделирования и анализа сложных систем, таких как финансовые рынки. Реализация теории категорий в MQL5 может помочь трейдерам лучше понимать и ориентироваться на рынке, предоставляя структурированное и логическое представление взаимосвязей между доменами и морфизмами. В статье подчеркивается важность определений аксиом категории в теории категорий и то, как они обеспечивают основу для моделирования отношений между доменами и морфизмами. В статье также обсуждалась концепция онтологических записей и то, как их можно использовать для предоставления логической структуры интересующей области, в данном случае финансовым рынкам. В целом, теория категорий в MQL5 может быть ценным инструментом для трейдеров, стремящихся глубже понять рынок и принимать более обоснованные торговые решения. Она обеспечивает структурированный и логический подход к анализу рынка, который может помочь трейдерам выявлять модели и возможности, которые иначе было бы трудно обнаружить.

    Перевод с английского произведен MetaQuotes Ltd.
    Оригинальная статья: https://www.mql5.com/en/articles/11958

    Прикрепленные файлы |
    ct_2.mq5 (62.16 KB)
    Работа с матрицами, расширение функционала Стандартной библиотеки матриц и векторов Работа с матрицами, расширение функционала Стандартной библиотеки матриц и векторов
    Матрица служит основой алгоритмов машинного обучения и компьютеров в целом из-за ее способности эффективно обрабатывать большие математические операции. В Стандартной библиотеке есть все, что нужно, но мы можем расширить ее, добавив несколько функций в файл utils.
    Популяционные алгоритмы оптимизации: Алгоритм растущих деревьев (Saplings Sowing and Growing up — SSG) Популяционные алгоритмы оптимизации: Алгоритм растущих деревьев (Saplings Sowing and Growing up — SSG)
    Алгоритм растущих деревьев (Saplings Sowing and Growing up, SSG) вдохновлен одним из самых жизнестойких организмов на планете, который является замечательным образцом выживания в самых различных условиях.
    Использование ONNX-моделей в MQL5 Использование ONNX-моделей в MQL5
    ONNX (Open Neural Network Exchange) — открытый стандарт представления моделей нейронных сетей. В данной статье мы рассмотрим процесс создания модели СNN-LSTM для прогнозирования финансовых временных рядов и использование созданной ONNX-модели в MQL5-эксперте.
    Разработка экспериментальной DLL с поддержкой многопоточности в C++ для MetaTrader 5 на Linux Разработка экспериментальной DLL с поддержкой многопоточности в C++ для MetaTrader 5 на Linux
    В статье рассмотрен процесс разработки для платформы MetaTrader 5 исключительно в системе Linux. При этом конечный продукт без проблем работает как в Windows, так и в Linux. Мы познакомимся с Wine и Mingw - важными инструментами кроссплатформенной разработки. В Mingw реализована потоковая передача (POSIX и Win32), что необходимо учитывать при выборе подходящего инструмента. Затем мы создадим DLL для проверки концепции и используем ее в коде MQL5, а также сравним производительность обеих реализаций потоков. Статья призвана стать отправной точкой для ваших собственных экспериментов. После прочтения статьи вы сможете создавать инструменты для MetaTrader в Linux.