English Русский 中文 Español 日本語 Português
preview
Kategorientheorie in MQL5 (Teil 2)

Kategorientheorie in MQL5 (Teil 2)

MetaTrader 5Integration | 9 März 2023, 09:30
150 0
Stephen Njuki
Stephen Njuki

Einführung

Dies ist eine Fortsetzung eines früheren Artikels über die Verwendung der Kategorientheorie in MQL5. Zur Erinnerung: Wir haben die Kategorientheorie als einen Zweig der Mathematik eingeführt, der besonders nützlich für die Organisation und Klassifizierung von Informationen ist. In diesem Zusammenhang haben wir einige grundlegende Konzepte der Kategorientheorie erörtert und erörtert, wie sie auf die Analyse von Finanzzeitreihendaten angewendet werden können. Konkret haben wir Elemente, Domänen und Morphismen untersucht. Elemente sind die grundlegenden Informationseinheiten in einem kategorientheoretischen System, und sie werden normalerweise als Mitglieder einer Menge betrachtet, die in dieser Reihe als Domäne bezeichnet wird. Eine Domäne kann durch einen Morphismus mit anderen Domänen in Beziehung stehen. In diesem Artikel werden wir uns zunächst damit befassen, was eine Kategorie ausmacht, indem wir die Axiome der Identität und der Assoziation, des kommutativen Diagramms betrachten. Dabei werden wir im gesamten Artikel Beispiele untersuchen und auch Beispiele für Nicht-Kategorien hervorheben. Abschließend werden wir die Ontologieprotokolle vorstellen.

Bevor wir uns mit den Axiom-Definitionen einer Kategorie befassen, kann es hilfreich sein, sich einige alltägliche Beispiele für Kategorien „in Aktion“ anzuschauen. Wir haben bereits Domänen und die darin enthaltenen Elemente definiert. Wenn wir also zunächst eine Kategorie als eine Sammlung verwandter Bereiche betrachten, könnten die folgenden Beispiele zur Veranschaulichung dienen.

    • Eine Kategorie von Verkehrsträgern, wobei die Domänen verschiedene Verkehrsträger repräsentieren (z. B. Auto, Flugzeug, Zug usw.). Die Elemente der einzelnen Bereiche wären die jeweiligen Arten von Transportfahrzeugen. Bei Autos könnten wir z. B. Fahrgemeinschaften, Autovermietungen, Privatwagen und Taxis haben; bei Flugzeugen könnten wir Privatjets, kommerzielle Flugzeuge oder geleaste Flugzeuge haben; bei Zügen könnten wir Straßenbahnen, Hochgeschwindigkeitszüge, Dampfloks usw. haben. Der Morphismus zwischen diesen könnte dann dazu dienen, eine vollständige Reiseroute zu definieren. Wenn Sie z. B. mit einem Taxi zum Flughafen gefahren sind, einen kommerziellen Flug genommen haben und dann mit dem Hochgeschwindigkeitszug von diesem Flughafen zu Ihrem Zielort gefahren sind, kann jede dieser Möglichkeiten leicht in dieser Kategorie abgebildet werden.  
    • Eine Kategorie von Gängen einer Mahlzeit, mit Domänen, die Menüs für jeden Gang darstellen. Nehmen wir an, wir haben 5 Gänge, nämlich: Vorspeise, Suppe, Hauptgericht, Dessert und Käse. In diesem Fall wären die Elemente der einzelnen Bereiche die Lebensmittel auf der Speisekarte für den jeweiligen Gang. Zum Beispiel könnte der Vorspeisengang in seinem Bereich (Menü) aus verschiedenen Auswahlmöglichkeiten bestehen: Kandierte Karotten mit Honig, Kreuzkümmel und Paprika; ODER mit Pecorino Romano, Knoblauch und Semmelbröseln gefüllte Pilze; ODER gebratener Brokkoli mit Shishito-Paprika und eingelegten Zwiebeln; So könnte die Suppendomäne aussehen: Toskanische Suppe aus weißen Bohnen und geröstetem Knoblauch; ODER Kürbis-Salbei-Suppe; ODER Kaltschale von Melonen mit Basilikum. Jeder dieser Menüpunkte steht für ein Element in seinem Bereich. In ähnlicher Weise dient der Morphismus zwischen diesen beiden zur Definition einer vollständigen Mahlzeit, die von einem Restaurantkunden ausgewählt wurde. Wenn der Kunde z. B. kandierte Karotten, dann Kürbis und so weiter für alle anderen Gänge gewählt hat, kann jede dieser Auswahlmöglichkeiten wie oben beschrieben leicht innerhalb der Kategorie abgebildet werden.
    • Ein weiteres Beispiel für eine Kategorie sind die Arten der wöchentlichen Unterhaltung. Hier können unsere Domänen Live-Sport, TV-Streaming und Parkbesuche sein. Die Elemente eines jeden Bereichs könnten sein: NFL oder MLB oder NBA für den Bereich Live-Sport; Netflix oder HBO oder AMC für den Bereich TV-Streaming und Disney oder Zoo oder Naturpark für Parkbesuche. Auch hier kann das Publikum aus jedem Bereich ein Sportspiel, eine Fernsehsendung und einen Park auswählen, den es besuchen möchte. Und die Kette von Auswahlschritten zwischen diesen Bereichen (Morphismen) ermöglicht es, diese Informationen leicht zuzuordnen.

    All dies und natürlich noch viel mehr kann mit der Kategorientheorie erfasst werden. Aber zu welchem Zweck?  Ein Sprichwort lautet: „Ein schlechter Handwerker gibt seinem Werkzeug die Schuld“, und ich glaube, das trifft hier zu. Denn die Verwendung wird wirklich vom Nutzer bestimmt. Meiner Meinung nach dient die Kategorientheorie dazu, Äquivalenzen kritisch zu quantifizieren. Dieses Thema werden wir in weiteren Artikeln behandeln, nachdem wir uns mit den grundlegenden Konzepten vertraut gemacht haben. Es genügt zu sagen, dass dies der Grund dafür ist, dass zwei getrennte Kategorien zu verschiedenen Themen entdeckt werden, die auf den ersten Blick nichts miteinander zu tun haben, sich aber bei näherer Betrachtung als identisch oder spiegelbildlich erweisen. Diese Erkenntnisse sind für die Entscheidungsfindung von entscheidender Bedeutung, da man zum Zeitpunkt der Entscheidungsfindung nur selten über genügend Informationen verfügt. Wenn Sie jedoch korrelierbare Kategorien haben, kann die Informationslücke überbrückt werden. 


    Identität

    Die Isomorphie von Kategorien ist eine entscheidende Eigenschaft von Homomorphismen in der Kategorientheorie, da sie sicherstellt, dass die Struktur der Domänen in der Zielkategorie unter der Abbildung erhalten bleibt. Sie garantiert auch die Beibehaltung der algebraischen Operationen der Domänen in der Ausgangskategorie. Betrachten wir zum Beispiel eine Bekleidungskategorie, deren Domänen Hemden und Hosen sind, und die Morphismen sind die Funktionen, die die Größe eines Hemdes auf die Größe einer Hose abbilden. Ein Homomorphismus in dieser Kategorie wäre eine Funktion, die die Zuordnung der Hemdengrößen zu den jeweiligen Hosengrößen beibehält. Ein Isomorphismus in dieser Kategorie wäre eine Funktion, die nicht nur die algebraische Paarung der Größen bewahrt, sondern auch eine Eins-zu-Eins-Entsprechung zwischen den Größen der Hemden und der Hosen herstellt. Das bedeutet, dass es für jede Hemdengröße genau eine entsprechende Hosengröße gibt und umgekehrt. Nehmen wir zum Beispiel die Funktion, die die Größe eines Hemdes (z. B. „small“, „medium“, „large“) auf die Größe einer Hose (z. B. „26“, „28“, „30“, „32“) abbildet. Diese Funktion ist ein Homomorphismus, da sie eine Paarung der Größen bewahrt und definiert (z. B. kann „small“ mit „26“ gepaart werden). Es handelt sich jedoch nicht um einen Isomorphismus, da er keine Eins-zu-Eins-Entsprechung zwischen den Hemden- und Hosengrößen herstellt, da „small“ auch mit „28“ oder „26“ getragen werden kann. Es gibt keine Reversibilität.


    non_iso


    Betrachten wir andererseits die Funktion, die die Größe eines Hemdes (z. B. „small“, „medium“, „large“) nur den Größen einer Hose (z. B. „28“, „30“, „32“) abbildet. Diese Funktion ist nicht nur ein Homomorphismus, sondern auch ein Isomorphismus, da sie auch Umkehrbarkeit zulässt.


    iso


    Im Beispiel einer Bekleidungskategorie, in der die Domänen Hemden und Hosen sind und die Morphismen die Funktionen sind, die die Größe eines Hemdes auf die Größe einer Hose abbilden, kann ein einzelner Morphismus nicht isomorph sein, da alle einzelnen Morphismen von Natur aus reversibel und damit „isomorph“ sind. Die Eigenschaft des Isomorphismus bezieht sich auf eine Gruppe von Morphismen (auch bekannt als Homomorphismenmenge) von einem Bereich zu einem anderen Bereich, und sie kann nur dann als gegeben angesehen werden, wenn alle Morphismen als Gruppe umgekehrt werden können, wobei die algebraischen Paarungseigenschaften des Homomorphismus erhalten bleiben. Deshalb ist es wichtig, alle Morphismen einer Domäne aufzuzählen, bevor die Isomorphie bestätigt wird. Ohne alle möglichen Morphismen zu berücksichtigen, kann es den Anschein haben, dass zwei Objekte isomorph sind, obwohl sie es in Wirklichkeit nicht sind. Eine Vorstufe zur Isomorphie ist die Mächtigkeit oder Kardinalität der Domänen. Dieser Wert muss für beide Domänen gleich sein. Wenn die Kardinalität der Bereiche nicht übereinstimmt, kann der Homomorphismus zwischen ihnen nicht umgekehrt werden, da von einem Bereich mehr als ein Element auf dasselbe Koelement abgebildet wird. Daher benötigen wir eine Gruppe von Morphismen zwischen Domänen, um Isomorphismus zu definieren. In der Regel benötigen wir zwei Morphismen, einen von Hemden zu Hosen und einen von Hosen zu Hemden, die eine Eins-zu-Eins-Entsprechung zwischen den Größen von Hemden und Hosen herstellen. Diese Morphismen sollten invers zueinander sein, d. h. wenn ein Morphismus ein Hemd der Größe „small“ in eine Hose der Größe „28“ verwandelt, sollte der andere Morphismus eine Hose der Größe „28“ in ein Hemd der Größe „small“ verwandeln. Und wenn wir diese beiden Morphismen zusammensetzen, sollten wir den Identitätsmorphismus für den Bereich erhalten, mit dem wir begonnen haben.

    Diese Axiom-Anforderung in der Kategorientheorie hat zu einem Bedarf an selbstabbildenden Morphismen geführt. Die Frage, ob sie für die Definition einer Kategorie relevant sind, ist jedoch noch offen: identity map requirement in the definition of category

    Lassen Sie uns nun aber einen Isomorphismus in MQL5 veranschaulichen. Ich habe den größten Teil des Skripts aus dem ersten Artikel umgeschrieben, sodass es jetzt auch Vorlagen enthält. Alle Klassen, von der Elementklasse bis zur Kategorieklasse, enthalten die Verwendung von Vorlagedatentypen für mehr Flexibilität. Ich habe jedoch die innerhalb der Kategorieklasse verfügbaren „enumerierten“ Typen. Diese sind: ‚datetime‘, ‚string‘, ‚double‘ und ‚int‘. Der Typ ‚int‘ ist die Standardeinstellung und wird verwendet, wenn ein Datentyp wie z. B. ‚color‘ verwendet wird. Der gesamte Code ist am Ende des Artikels beigefügt. Hier ist unsere neue Homomorphismenklasse.

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

    Um die Isomorphie zu prüfen, verwenden wir dieselben Domänen wie im vorherigen Artikel und lassen sie durch die Funktion „IsIsomorph“ laufen. Diese Funktion gibt einen booleschen Wert zurück, wobei true den Erfolg und false den Misserfolg anzeigt.

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

    Der Ausgangshomomorphismus muss jedoch bei on set angegeben werden, und in unserem Fall verwenden wir die Variable ‚_h_i‘. Dieser Ausgabewert, der ein Array der Homomorphismenklasse ist, enthält eine Aufzählung aller möglichen isomorphen Homomorphismen zwischen den beiden Eingabebereichen.

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

    Wenn wir diesen Code ausführen, sollten wir das folgende Protokoll erhalten.

    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
    
    

    Dies ist mit einem geraden Bereich, dessen Ausdruck ist:

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

    Und einen ungeraden Bereich mit einem Ausdruck von:

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


    Assoziation

    In der Kategorientheorie ist das Assoziativgesetz eine der grundlegenden Eigenschaften, die eine Kategorie erfüllen muss. Am Beispiel einer Bekleidungskategorie, in der die Domänen spezifische Kleidungsstücke sind, wie Hemden, Hosen und Schuhe, wären die Morphismen die Funktionen, die die Kleidungsstücke je nach Eignung miteinander verbinden. Das Assoziativitätsgesetz, auch bekannt als „Assoziationsaxiom“, besagt, dass die Komposition von Morphismen assoziativ ist. Das bedeutet, dass beim Zusammensetzen mehrerer Morphismen die Reihenfolge, in der sie angewendet werden, keinen Einfluss auf das Endergebnis hat.

    Betrachten wir zum Beispiel den Morphismus „wird getragen mit“ über alle 3 Bereiche der Kleidung (Hemden, Hosen und Schuhe). Nehmen wir an, wir haben einen Morphismus f: T-Shirt -> Hemd mit Knöpfen, g: Hemd mit Knöpfen -> Jeans und h: Jeans -> Turnschuhe. Mit Hilfe des Assoziationsaxioms können wir die Verknüpfung dieser Morphismen als h o (g o f) = (h o g) o f definieren. Das bedeutet, dass die Reihenfolge der Morphismen keine Rolle spielt und wir sie beliebig zusammenfassen können. Dies macht die Definition einer Kategorie einfacher, da wir so die Klammern mehrerer Morphismen nicht berechnen müssen. Stattdessen können wir Morphismen unabhängig von ihrer Reihenfolge zusammenfassen, und das Endergebnis wird dasselbe sein.

    Sehen wir uns dies in MQL5 in Aktion an. Wir müssen die Kategorieklasse, die ich im vorigen Artikel vorgestellt habe, neu zusammenstellen.

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

    Beachten Sie die zulässigen „enumerierten“ Datentypen. Ich werde versuchen, dies übersichtlicher zu gestalten, indem ich sie in zukünftigen Artikeln als ein Objekt in ein einziges Array integriere. Neben der Funktion „FillDomain“, die einen Bereich mit natürlichen Zahlen füllt, wurde eine weitere Funktion hinzugefügt.

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

    Um also die Assoziation zu prüfen, erstellen wir eine Kategorie ‚_ca‘. Wir deklarieren dann 3 einfache Sätze vom Typ String, die jeweils mit einem Bekleidungstyp gefüllt werden. Wir kopieren diese Mengen (Arrays) in neue Element-Arrays (‚_et‘, ‚_ep‘, ‚_es‘) und fügen dann jedes dieser Elemente zu seinem eigenen Bereich (‚_dt‘, ‚_dp‘, ‚_ds‘) hinzu. Danach setzen wir die Anzahl der Bereiche für unsere Kategorie auf 3 und fahren dann fort, die Bereiche in jedem Index mit den neu erstellten Bereichen zu versehen, die mit den Elementen des Typs Kleidung gefüllt wurden.

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

    Um die Assoziativität zu prüfen, werden wir die Ergebnisse der Morphismen in Ontologieprotokollen ausgeben. Dazu werden wir eine Klasse ‚COntology‘ erstellen. Dies wird im Folgenden anhand einer Aufzählung und einer gleichnamigen Struktur erläutert.

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

    Ausgehend von der Ontologie-Ausgabe sollte die Ausführung des Skripts Folgendes protokolliert.

    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
    


     

    Zusammenfassend lässt sich sagen, dass das Assoziationsaxiom eine einfache Definition einer Kategorie ermöglicht, da die Komposition von Morphismen assoziativ sein kann, wodurch die Notwendigkeit entfällt, bei der Definition mehrerer Morphismen Klammern zu berechnen. Dies macht es einfacher, die Beziehungen zwischen den Objekten einer Kategorie zu verstehen, in diesem Fall Kleidungsstücke in allen drei Bereichen: Hemden, Hosen und Schuhe. 


    Kommutative Diagramme

    Ein Kommutatives Diagramm ist ein Diagramm, das die Beziehung zwischen zwei Morphismen in einer Kategorie darstellt. Sie besteht aus einer Menge von Domänen, Morphismen und ihren Verknüpfungen, die so angeordnet sind, dass die Morphismen kommutieren, d. h. dass die Reihenfolge, in der sie komponiert werden, keine Rolle spielt, was bedeutet, dass für drei beliebige Domänen A, B und C in einer Kategorie und für ihre Morphismen f: A -> B, g: B -> C, und h: A -> C; die Komposition dieser Morphismen muss genügen:

    f o g = h

    Ein Beispiel für eine Umrechnung mit Hilfe von Devisenkursen könnte die Arbitrage sein, also die Beziehung zwischen den Kursen von beispielsweise EURUSD, EURJPY und USDJPY. In diesem Beispiel könnten die Domänen die Währungen selbst sein (EUR, USD, JPY), während die Morphismen den Prozess der Umrechnung einer Währung in eine andere auf der Grundlage des Wechselkurses darstellen könnten. Nehmen wir zum Beispiel f: EUR -> USD ist der Morphismus, der den Prozess der Konvertierung von EUR in USD zum Wechselkurs EURUSD darstellt; sei g: USD -> JPY ist der Morphismus, der den Prozess der Umwandlung von USD in JPY zum Wechselkurs USDJPY darstellt; und h: EUR -> JPY ist der Morphismus, der die Umwandlung von EUR in JPY darstellt. Nach der obigen Kommutationsregel: f o g = h, würde dies bedeuten:

    Umrechnung von EUR in USD zum EURUSD-Kurs, dann Umrechnung dieses USD in JPY zum USDJPY-Kurs = Umrechnung von EUR in JPY zum EURJPY-Kurs.

    Lassen Sie uns dies anhand von MQL5 veranschaulichen. Wir deklarieren eine Kategorie „_cc“ und füllen sie mit 3 Domänen mit jeweils 2 Währungen. Die Bereiche können als Portfolios in der Vermögensverteilung betrachtet werden. Wie beim Assoziationsaxiom werden wir unsere Kategoriewerte mithilfe von Ontologieprotokollen füllen und überprüfen (siehe unten).

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

    Wir prüfen die Kommutierung, indem wir den Satz des Kommutierungsmorphismus „_m_ac“ mit dem Produkt der beiden Sätze der Morphismen „_m_ab“ und „_m_bc“ vergleichen. Es gibt Diskrepanzen, aber diese sind meist auf die Qualität der Daten der historischen Broker und die Berücksichtigung des Spreads (es werden nur Gebote verwendet) zurückzuführen. Die Ausführung dieses Skripts sollte diese Protokolle liefern.

    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
    



    Ontologie-Protokolle

    Ontologien sind subjektive Zusammenfassungen einer Kategorie. Sie sind ein wichtiges Werkzeug in der Kategorientheorie, da sie eine Möglichkeit bieten, die Struktur und die Beziehungen der Domänen über Morphismen in einer bestimmten Kategorie zu interpretieren. Anders ausgedrückt sind sie eine mathematische Struktur (oder ein Datenmodell, das einem Datenbankschema entspricht), die die Typen von Domänen und ihre Morphismen in der Domäne beschreibt. Es gibt verschiedene Arten von Ontologien, unter anderem:
    • Taxonomische Ontologien beschreiben eine Reihe von Objekten und ihre Unterklassen und definieren die Beziehungen zwischen ihnen in Form von „ist-ein“-Beziehungen.
    • Hierarchische Ontologien beschreiben eine Reihe von Objekten und deren Eigenschaften und definieren die Beziehungen zwischen ihnen in Form von „gehört-zu“-Beziehungen.
    • Relationale Ontologien beschreiben eine Menge von Objekten und deren Beziehungen und definieren die Beziehungen zwischen ihnen in Form von beliebigen binären Beziehungen.

    Für ein Devisenhandelssystem dürfte eine relationale Ontologie am besten geeignet sein. Dies würde die Modellierung verschiedener Arten von Handelsstrategien und der Beziehungen zwischen ihnen ermöglichen, z. B. welche Strategien unter bestimmten Marktbedingungen am effektivsten sind. Darüber hinaus können relationale Ontologien leicht um zusätzliche Informationen wie historische Daten erweitert werden, die bei der Entwicklung eines Handelssystems nützlich sein könnten.

    Wie relationale Ontologien in der Praxis aussehen, wenn sie in der Kategorientheorie bereichsübergreifend eingesetzt werden, lässt sich anhand verschiedener Beispiele auf den Finanzmärkten zeigen. Hier sind fünf Beispiele:

    1. Währungspaare: Der Devisenmarkt besteht aus Währungspaaren, d. h. aus zwei Währungen, die gegeneinander gehandelt werden. Die Beziehung zwischen diesen Währungen kann mit Hilfe einer relationalen Ontologie modelliert werden, wobei die Währungspaare als Domänen und der Wechselkurs als Morphismus, der sie verbindet, betrachtet werden. Ein Beispiel dafür wurde bereits oben mit dem Kommutativdiagramm gegeben.
    2. Zeitreihendaten: Devisenkurse werden häufig als Zeitreihendaten dargestellt, die mit Hilfe einer relationalen Ontologie modelliert werden können, wobei die Zeitreihendaten als Domäne und die Preisänderungen im Laufe der Zeit als Morphismen betrachtet werden.
    3. Technische Indikatoren: Technische Indikatoren wie gleitende Durchschnitte oder Indizes der relativen Stärke können zur Analyse von Devisenkursen verwendet werden. Diese Indikatoren können mithilfe einer relationalen Ontologie modelliert werden, wobei der Indikator als Domäne und die Indikatorwerte als Morphismen betrachtet werden.
    4. Handelsstrategien: Händler verwenden häufig verschiedene Handelsstrategien, wie z. B. Trendfolge- oder Momentum-Strategien. Diese Strategien können mit Hilfe einer relationalen Ontologie modelliert werden, in der die Handelsstrategie als Domäne und die auf der Grundlage der Strategie ausgeführten Trades als Morphismen betrachtet werden.
    5. Orderbuch: Das Orderbuch ist eine Aufzeichnung aller Kauf- und Verkaufsaufträge, die auf dem Devisenmarkt erteilt wurden. Dies kann (sofern von einem Makler bereitgestellt) mit Hilfe einer relationalen Ontologie modelliert werden, in der das Orderbuch als Domäne und die erteilten Aufträge als Morphismen betrachtet werden.

    Insgesamt sind relationale Ontologien in der Kategorientheorie nützlich, wenn sie bereichsübergreifend im Handel eingesetzt werden, da sie die Modellierung und Analyse komplexer Systeme und Beziehungen in einer klaren und strukturierten Weise ermöglichen. Ontologien verwenden „Typen“ und „Aspekte“, um eine subjektive Sicht auf eine Kategorie darzustellen. Ein Typ kann als eine Gruppe von Domänen innerhalb einer bestimmten Kategorie betrachtet werden. Sie kann einfach oder zusammengesetzt sein. Wenn sie einfach ist, enthält sie nur den einen Bereich. Wenn er zusammengesetzt ist, vereint er mehr als einen Bereich. Aspekte sind für Typen das, was Morphismen für Domänen innerhalb einer Kategorie sind.  Eine relationale Ontologie auf der Grundlage von Währungspaaren auf dem Devisenmarkt kann wie folgt modelliert werden:

    Typen:

    1. Währungspaar: Das Währungspaar ist der Haupttyp in dieser Ontologie und repräsentiert die beiden Währungen, die gegeneinander gehandelt werden. Das Währungspaar „EUR/USD“ stellt zum Beispiel den Wechselkurs zwischen dem Euro und dem US Dollar dar.
    2. Wechselkurse: Der Wechselkurs ist der Kurs, zu dem eine Währung in eine andere umgetauscht werden kann. Sie stellt den Morphismus zwischen den Objekten der Währungspaare dar. Der Wechselkurs für das Währungspaar EUR/USD könnte zum Beispiel 1,20 betragen, was bedeutet, dass 1 Euro gegen 1,20 US-Dollar getauscht werden kann.
    3. Zeit: Zeit ist ein Typ, der verwendet werden kann, um den Zeitpunkt darzustellen, zu dem der Wechselkurs gilt. Er kann verwendet werden, um Wechselkursmorphismus mit Zeitreihendaten zu verbinden.

    Aspekte:

    1. Historische Wechselkurse: Historische Wechselkurse sind die Wechselkurse, die zu verschiedenen Zeitpunkten aufgezeichnet wurden. Sie können zur Analyse von Trends und Mustern auf dem Devisenmarkt verwendet werden.
    2. Volatilität: Die Volatilität ist ein Maß dafür, wie stark sich der Wechselkurs im Laufe der Zeit verändert. Er kann dazu verwendet werden, das mit einem bestimmten Währungspaar verbundene Risiko zu bewerten.
    3. Korrelation: Die Korrelation ist ein Maß für die Beziehung zwischen zwei Währungspaaren. Er kann zur Ermittlung von Diversifizierungs- oder Absicherungsmöglichkeiten auf dem Devisenmarkt verwendet werden.

    Insgesamt ermöglicht diese relationale Ontologie eine klare und strukturierte Darstellung der Beziehungen zwischen Währungspaaren, Wechselkursen, Zeit und anderen Aspekten auf dem Devisenmarkt. Sie kann dazu verwendet werden, die Dynamik des Marktes zu analysieren und fundierte Entscheidungen zu treffen. Ein Grothendieck-Universum wird verwendet, um das Konzept eines Universums von Typen zu definieren, das in kategorientheoretischen Ontologien von zentraler Bedeutung ist: Ein Universum von Typen ist eine Menge von Typen innerhalb einer bestimmten Kategorie. Es ermöglicht die Sortierung der Typen und löst das Problem der „Mengen von Mengen“.

    Um Ontologien in der Praxis zu sehen, betrachten wir ein Beispiel aus der Finanzbranche. Verschiedene Stellen, wie die Securities and Exchange Commission (SEC) und ein Hedgefonds, können Ontologien verwenden, um Finanzdaten derselben Kategorie auf unterschiedliche Weise zu organisieren und zu kategorisieren. Dies kann dazu führen, dass unterschiedliche Arten und Aspekte der Daten in den von den einzelnen Einrichtungen verwendeten Ontologien dargestellt werden. Aus der Sicht der SEC könnte eine Ontologie zur Organisation von Daten im Zusammenhang mit Wertpapieren und Handelsaktivitäten verwendet werden, wobei der Schwerpunkt auf Compliance- und Regulierungsfragen liegt. Dazu gehören beispielsweise die Begriffe „Wertpapiere“, „Handelsaktivitäten“, „Insiderhandel“ und „Verstöße gegen Wertpapiergesetze“. Die Ontologie könnte auch Aspekte im Zusammenhang mit der Einhaltung und Durchsetzung von Vorschriften, wie „Untersuchungen“ und „Sanktionen“, enthalten. Aus der Sicht eines Hedge-Fonds könnte eine Ontologie zur gleichen Kategorie verwendet werden, um Daten im Zusammenhang mit Anlagestrategien, Portfoliomanagement und Leistungskennzahlen zu organisieren. Dies könnte Typen wie „Anlagestrategien“, „Portfoliomanagement“, „Leistungskennzahlen“ und „Risikomanagement“ umfassen. Die Ontologie könnte auch Aspekte im Zusammenhang mit dem Betrieb und der Verwaltung des Fonds enthalten, wie z. B. „verwaltetes Vermögen“ und „Fondsmanager“. Wie wir sehen, verwenden zwar beide Stellen Ontologien, um Finanzdaten zu organisieren, aber die Arten und Aspekte, die in ihren Ontologien dargestellt werden, sind unterschiedlich und spiegeln die unterschiedlichen Ziele, Perspektiven und Anliegen der SEC und eines Hedgefonds wider. So würde sich die Ontologie der SEC auf die Einhaltung von Vorschriften, Regelungen und Verstöße im Wertpapierhandel konzentrieren, während die Ontologie des Hedgefonds auf Investitionen, Risikomanagement und Portfoliomanagement ausgerichtet wäre.

     

    Zur weiteren Veranschaulichung der Typen im Forex-Bereich beziehen sich einfache und zusammengesetzte Typen auf die Datentypen, die zur Darstellung verschiedener Aspekte des Marktes verwendet werden können. Einfache Typen sind grundlegende Datentypen, die durch einen einzigen Wert dargestellt werden können. Im Devisenhandel beispielsweise kann der Wechselkurs zwischen zwei Währungen als einfacher Typ betrachtet werden, der durch einen einzigen Wert wie 1,20 dargestellt wird (was bedeutet, dass 1 Einheit der Basiswährung gegen 1,20 Einheiten der Kurswährung getauscht werden kann). Zusammengesetzte Typen hingegen sind Datentypen, die aus mehreren Werten oder anderen Datentypen zusammengesetzt sind. Ein Kerzen-Chart kann beispielsweise als zusammengesetzter Typ betrachtet werden, da es sich aus mehreren Werten wie dem Eröffnungskurs, dem Schlusskurs, dem Höchstkurs und dem Tiefstkurs für einen bestimmten Zeitraum zusammensetzt. Bei den Aspekten handelt es sich um einfache Aspekte, die zwei einfache Typen miteinander verbinden, zum Beispiel kann der Wechselkurs zwischen zwei Währungen als einfacher Aspekt betrachtet werden. Zusammengesetzte Aspekte sind diejenigen, die zwei zusammengesetzte Arten oder eine zusammengesetzte Art und eine einfache Art miteinander verbinden, z. B. kann eine Handelsstrategie als zusammengesetzter Aspekt betrachtet werden, da sie die Strategie mit den darauf basierenden Geschäften verbindet. Insgesamt sind einfache Typen und Aspekte grundlegende Bausteine, die zur Darstellung grundlegender Informationen in Ontologien verwendet werden können, während zusammengesetzte Typen und Aspekte komplexere Datentypen sind, die aus mehreren Werten oder anderen Datentypen zusammengesetzt sind und zur Darstellung komplexerer Aspekte des zu modellierenden Systems verwendet werden können.

    Ontologie-Protokolle sind eine Möglichkeit, Wissen zu organisieren und darzustellen, indem sie dem betreffenden Bereich eine logische Struktur geben. Sie helfen dabei, Konzepte, Eigenschaften und Beziehungen innerhalb einer bestimmten Domäne, Unterdomäne, Aufgabe, Instanz oder eines Prozesses zu definieren. Ein Ontologieprotokoll ist eine formale Darstellung einer Reihe von Konzepten, Eigenschaften und Beziehungen, die in einem bestimmten Bereich existieren. Sie wird verwendet, um die Struktur des Wissens innerhalb dieses Bereichs zu definieren und eine konsistente und logische Darstellung des Wissens zu liefern. Dadurch wird es für Maschinen und Menschen einfacher, die Informationen innerhalb des Bereichs zu verstehen und zu nutzen. Ontologie-Protokolle können in einer Vielzahl von Bereichen eingesetzt werden, z. B. in der künstlichen Intelligenz, der Verarbeitung natürlicher Sprache, der Wissensdarstellung und der Informationswissenschaft. Sie werden häufig in Verbindung mit anderen Arten von Ontologien verwendet, wie z. B. Oberontologien und Domänenontologien, um eine umfassende Sicht auf eine Domäne zu erhalten. Ontologieprotokolle werden in der Regel in einem maschinenlesbaren Format wie OWL (Web Ontology Language) oder RDF (Resource Description Framework) dargestellt, so dass sie leicht von Maschinen verarbeitet und genutzt werden können. Sie sind auch für Menschen lesbar, was das Verständnis und die Nutzung der im Ontologieprotokoll dargestellten Informationen erleichtert.

    Im Rahmen der Kategorientheorie werden Ontologieprotokolle verwendet, um Wissen zu organisieren und darzustellen, indem sie dem betreffenden Bereich eine logische Struktur verleihen. Sie helfen dabei, Konzepte, Eigenschaften und Beziehungen innerhalb einer bestimmten Domäne, Unterdomäne, Aufgabe, Instanz oder eines Prozesses zu definieren. Die Kategorientheorie ist ein Teilgebiet der Mathematik, das sich mit der Struktur mathematischer Systeme befasst und einen Rahmen für die Modellierung der Beziehungen zwischen Objekten und Morphismen bietet. Ontologieprotokolle bieten im Rahmen der Kategorientheorie eine Möglichkeit, das Wissen in einem Bereich strukturiert und logisch zu organisieren und darzustellen.

    Es gibt verschiedene Arten von Ontologieprotokollen, die in der Kategorientheorie häufig verwendet werden, z. B:

    1. Upper ontology: Eine Oberontologie ist eine allgemeine Ontologie, die einen Überblick über eine Domäne bietet und die allgemeinsten Konzepte und Beziehungen definiert, die für mehrere Unterdomänen gelten. Es ist eine gängige Methode, um eine einheitliche Struktur für verschiedene Ontologien zu schaffen.
    2. Domain ontology: Eine Domänenontologie ist eine spezifische Ontologie, die sich auf eine bestimmte Teildomäne innerhalb einer größeren Domäne konzentriert. Sie definiert die für diesen Teilbereich spezifischen Konzepte und Beziehungen.
    3. Ontologie der Aufgaben: Eine Aufgabenontologie ist eine spezifische Ontologie, die sich auf eine bestimmte Aufgabe oder ein Problem innerhalb einer Domäne konzentriert. Sie definiert die für diese Aufgabe oder dieses Problem spezifischen Konzepte und Beziehungen.
    4. Instance ontology: Eine Instanzontologie ist eine spezifische Ontologie, die sich auf die Instanzen eines bestimmten Konzepts oder einer Klasse konzentriert. Sie definiert die für diese Instanzen spezifischen Eigenschaften und Beziehungen.
    5. Process ontology: Eine Prozessontologie ist eine spezifische Ontologie, die sich auf die Prozesse oder Aktionen konzentriert, die innerhalb einer Domäne stattfinden. Sie definiert die für diese Prozesse oder Aktionen spezifischen Konzepte und Beziehungen.

    Diese Arten von Ontologieprotokollen werden verwendet, um das Wissen und die Beziehungen in einem Bereich zu strukturieren und das Verständnis, die Darstellung und die Bearbeitung der Informationen zu erleichtern. Sie helfen bei der konsistenten und logischen Darstellung des Wissens innerhalb einer Domäne und können in Verbindung mit relationalen Ontologien verwendet werden, um einen umfassenden Überblick über eine Domäne zu erhalten.

    Ein Prozess-Ontologie-Protokoll ist eine spezielle Art von Ontologie-Protokoll, das sich auf die Prozesse oder Aktionen konzentriert, die innerhalb einer Domäne stattfinden. Sie definiert die für diese Prozesse oder Aktionen spezifischen Konzepte und Beziehungen. Die Arten von Aspekten, die in einem Prozess-Ontologie-Protokoll verwendet werden können, hängen von der jeweiligen Domäne und den zu modellierenden Prozessen oder Aktionen ab. Hier sind einige Beispiele für Aspekte, die in einem Prozess-Ontologie-Protokoll verwendet werden könnten:

    1. Inputs und Outputs: Die Ein- und Ausgabe-Aspekte eines Prozesses können verwendet werden, um die Ressourcen, Materialien oder Informationen zu definieren, die erforderlich sind, um den Prozess zu initiieren, sowie die Endprodukte, Dienstleistungen oder Informationen, die durch den Prozess erzeugt werden.
    2. Steps or Phases: Der Prozess kann in kleinere Schritte oder Phasen unterteilt werden, und jeder Schritt kann als Konzept definiert werden, das die Maßnahmen und Ziele des jeweiligen Schritts darstellt. Auch die Beziehungen zwischen den einzelnen Schritten können modelliert werden.
    3. Actors: Akteure sind die in den Prozess involvierten Einheiten oder Agenten, wie Menschen, Maschinen oder Organisationen. Die Beziehungen zwischen den Akteuren und ihre Rollen im Prozess können definiert werden.
    4. Constraints: Nebenbedingungen sind die Regeln, Vorschriften oder Einschränkungen, die der Prozess einhalten muss. Dieser Aspekt kann dazu verwendet werden, die Bedingungen und Anforderungen zu definieren, die erfüllt sein müssen, damit der Prozess erfolgreich abgeschlossen werden kann.
    5. Metrics: Metriken sind die Messungen oder Indikatoren, die zur Bewertung der Leistung des Prozesses verwendet werden, z. B. Effizienz, Qualität oder Kosten. Unter diesem Aspekt können die Messungen und Indikatoren zur Bewertung des Prozesses und deren Berechnung festgelegt werden.
    6. Temporal aspects: Zeitliche Aspekte beziehen sich auf den zeitlichen Ablauf des Prozesses, wie Start- und Endzeitpunkt, Dauer und Häufigkeit des Prozesses. Dieser Aspekt kann genutzt werden, um die zeitlichen Aspekte des Prozesses zu modellieren.

    Insgesamt kann ein Prozess-Ontologie-Protokoll verwendet werden, um die verschiedenen Aspekte eines Prozesses, einschließlich Inputs und Outputs, Schritte oder Phasen, Akteure, Einschränkungen, Metriken und zeitliche Aspekte sowie die Beziehungen zwischen ihnen, in einer strukturierten und logischen Weise zu modellieren, was das Verständnis, die Darstellung und die Handhabung der Informationen erleichtern kann. Ein Beispiel für eine Prozessontologie in der Kategorie des Devisenmarktes könnte der Prozess der Ausführung eines Handels sein. Die Prozessontologie würde die Konzepte und Beziehungen definieren, die für den Prozess der Ausführung eines Geschäfts spezifisch sind. Es folgt ein Beispiel dafür, wie die Aspekte dieser Prozessontologie modelliert werden könnten:

    1. Inputs und Outputs: Zu den Eingaben des Prozesses gehören die Handelsstrategie, das zu handelnde Währungspaar und der Saldo des Handelskontos. Das Ergebnis des Prozesses ist der ausgeführte Handel.
    2. Steps or Phases: Der Prozess kann in kleinere Schritte oder Phasen unterteilt werden, wie z. B. die Auswahl des Währungspaares, die Festlegung der Handelsparameter, die Erteilung des Auftrags und die Überwachung des Handels.
    3. Actors: Zu den am Prozess beteiligten Akteuren gehören der Händler, die Handelsplattform und der Markt. Der Händler ist der Hauptakteur, der den Prozess in Gang setzt, die Handelsplattform ist das Instrument, mit dem der Handel ausgeführt wird, und der Markt ist das Umfeld, in dem der Handel stattfindet.
    4. Constraints: Zu den Beschränkungen gehören Vorschriften über Einschuss, Hebelwirkung und Risikomanagement. Diese Auflagen müssen eingehalten werden, damit der Handel erfolgreich abgeschlossen werden kann.
    5. Metrics: Zur Bewertung der Leistung des Prozesses werden u. a. der Gewinn oder Verlust aus dem Handel, das Risiko-Ertrags-Verhältnis und der Prozentsatz der erfolgreichen Geschäfte herangezogen.
    6. Temporal aspects: Zeitliche Aspekte beziehen sich auf den zeitlichen Ablauf des Prozesses, wie z. B. die Anfangs- und Endzeit des Handels, die Dauer des Handels und die Häufigkeit des Handels.

    Dieses Prozess-Ontologie-Protokoll kann verwendet werden, um die verschiedenen Aspekte des Prozesses der Ausführung eines Handels auf dem Devisenmarkt in einer strukturierten und logischen Weise zu modellieren. Es kann verwendet werden, um das Verständnis, die Darstellung und die Bearbeitung von Informationen im Zusammenhang mit dem Prozess der Ausführung eines Geschäfts zu erleichtern, und es kann in Verbindung mit anderen Arten von Ontologien verwendet werden, um einen umfassenden Überblick über die Finanzmärkte zu geben.


    Schlussfolgerung

    Zusammenfassend lässt sich sagen, dass die Kategorientheorie einen leistungsfähigen Rahmen für die Modellierung und Analyse komplexer Systeme, wie z. B. der Finanzmärkte, bietet. Die Implementierung der Kategorientheorie in MQL5 kann Händlern helfen, den Markt besser zu verstehen und zu navigieren, indem sie eine strukturierte und logische Darstellung der Beziehungen zwischen Domänen und Morphismen bietet. Der Artikel hat die Bedeutung der Axiomdefinitionen einer Kategorie in der Kategorientheorie hervorgehoben und zeigt, wie sie eine Grundlage für die Modellierung der Beziehungen zwischen Domänen und Morphismen bilden. In dem Artikel wurde auch das Konzept der Ontologieprotokolle erörtert und wie sie verwendet werden können, um einem Thema von Interesse, in diesem Fall den Finanzmärkten, eine logische Struktur zu geben. Insgesamt kann die Implementierung der Kategorientheorie in MQL5 ein wertvolles Werkzeug für Händler sein, die ein tieferes Verständnis des Marktes erlangen und fundiertere Handelsentscheidungen treffen wollen. Es bietet einen strukturierten und logischen Ansatz für die Marktanalyse, der Händlern helfen kann, Muster und Gelegenheiten zu erkennen, die andernfalls schwer zu entdecken wären.

    Übersetzt aus dem Englischen von MetaQuotes Ltd.
    Originalartikel: https://www.mql5.com/en/articles/11958

    Beigefügte Dateien |
    ct_2.mq5 (62.16 KB)
    Das Murray-System neu überdenken Das Murray-System neu überdenken
    Grafische Preisanalysesysteme sind bei den Händlern zu Recht sehr beliebt. In diesem Artikel beschreibe ich das komplette Murray-System, einschließlich seiner berühmten Level, sowie einige andere nützliche Techniken, um die aktuelle Kurslage zu bewerten und eine Handelsentscheidung zu treffen.
    Erstellen eines EA, der automatisch funktioniert (Teil 05): Manuelle Auslöser (II) Erstellen eines EA, der automatisch funktioniert (Teil 05): Manuelle Auslöser (II)
    Heute werden wir sehen, wie man einen Expert Advisor erstellt, der einfach und sicher im automatischen Modus arbeitet. Am Ende des vorigen Artikels habe ich vorgeschlagen, dass es angebracht wäre, eine manuelle Nutzung des EA zuzulassen, zumindest für eine Weile.
    Entwicklung einer DLL für eine Machbarkeitsstudie mit C++ Multi-Threading-Unterstützung für MetaTrader 5 unter Linux Entwicklung einer DLL für eine Machbarkeitsstudie mit C++ Multi-Threading-Unterstützung für MetaTrader 5 unter Linux
    Wir beginnen die Reise, um die Schritte und den Arbeitsablauf zu erforschen, wie man die Entwicklung für die MetaTrader 5 Plattform ausschließlich auf einem Linux-System basiert, in dem das Endprodukt nahtlos sowohl auf Windows- als auch auf Linux-Systemen funktioniert. Wir werden Wine und Mingw kennenlernen; beides sind die wichtigsten Werkzeuge für die plattformübergreifende Entwicklung. Vor allem Mingw für seine Threading-Implementierungen (POSIX und Win32), die wir bei der Auswahl der Software berücksichtigen müssen. Anschließend erstellen wir eine Proof-of-Concept-DLL und verwenden sie in MQL5-Code, um schließlich die Leistung der beiden Threading-Implementierungen zu vergleichen. Alles als eine Grundlage, die Sie selbst weiter ausbauen können. Nach der Lektüre dieses Artikels sollten Sie mit der Erstellung von MT-bezogenen Tools unter Linux vertraut sein.
    Algorithmen zur Populationsoptimierung Optimierung mit invasiven Unkräutern (IWO) Algorithmen zur Populationsoptimierung Optimierung mit invasiven Unkräutern (IWO)
    Die erstaunliche Fähigkeit von Unkräutern, unter verschiedensten Bedingungen zu überleben, wurde zur Idee für einen leistungsstarken Optimierungsalgorithmus. IWO (Invasive Weed Optimization) ist einer der besten Algorithmen unter den bisher geprüften.