Przejdź do treści

Cykl życia cBota

W tym artykule i towarzyszącym mu filmie przechodzimy przez strukturę kodu i wyjaśniamy logikę stojącą za zdarzeniami i cyklem życia cBota cTrader.

Przypominamy, że możesz uzyskać dostęp do swoich cBotów w aplikacji Algo w cTrader. Aby utworzyć nowego cBota, po prostu kliknij przycisk Nowy cBot lub wybierz tę opcję z menu rozwijanego pokazanego poniżej.

Zinterpretuj podstawowy szablon

Po utworzeniu nowego cBota powinieneś zobaczyć następującą podstawową strukturę w oknie edytora kodu.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = "Hello world!")]
        public string Message { get; set; }

        protected override void OnStart()
        {
            // To learn more about cTrader Algo visit our Help Center:
            // https://help.ctrader.com/ctrader-algo

            Print(Message);
        }

        protected override void OnTick()
        {
            // Handle price updates here
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

Zauważ, że w podstawowym szablonie wyświetlane są tylko trzy zdarzenia; te zdarzenia są obsługiwane przez metody OnStart(), OnTick() i OnStop(). Dodamy dwie dodatkowe metody (OnBar() i OnException()) i wyjaśnimy, jak działają później; najpierw omówimy metodę OnStart().

Użyj metody OnStart()

Metoda OnStart() jest wywoływana, gdy cBot uruchamia się po raz pierwszy. Służy do inicjalizacji wszelkich zmiennych, których planujesz użyć w swoim cBocie, w tym wskaźników, liczników, procedur obsługi zdarzeń lub timerów.

Uwaga

Początkowy szablon kodu zawiera już instrukcję kodu do wydrukowania komunikatu w dzienniku po uruchomieniu cBota. Jak widać, nasz cBot ma parametr Message, a metoda OnStart() przekazuje wartość tego parametru do metody Print().

Możemy zademonstrować, jak działa metoda OnStart(), po prostu uruchamiając wystąpienie cBota w aplikacji Trade i otwierając kartę Dziennik, aby zobaczyć wynik.

Możemy również w każdej chwili zatrzymać cBota, zmienić wartość parametru Message w karcie Parametry i ponownie uruchomić nasze wystąpienie. Po uruchomieniu nasz nowy komunikat nadal zostanie wydrukowany w dzienniku.

Użyj metody OnTick()

Metoda OnTick() jest wywoływana za każdym razem, gdy zmienia się cena bid lub ask symbolu. Wewnątrz tej metody możesz zazwyczaj zaprogramować warunki wejścia i wyjścia z pozycji, a także wszelkie inne funkcje pomocnicze, które musisz uruchomić po nadejściu nowego tiku danych.

Dodamy następujący kod do metody OnTick(), aby drukowała komunikat w dzienniku.

1
Print("OnTick. Bid: ", Symbol.Bid, ", Ask: ", Symbol.Ask);

Jak widać poniżej, nasz cBot drukuje teraz ceny bid i ask w dzienniku przy każdej zmianie ceny.

Użyj metody OnBar()

Metoda OnBar() nie jest uwzględniona w domyślnym szablonie kodu cBota, więc dodamy następujący fragment kodu, aby ją dodać.

1
2
3
4
protected override void OnBar() 
{
    Print("OnBar");
}

Metoda OnBar() jest wywoływana za każdym razem, gdy na wykresie, do którego dołączony jest cBot, rysowany jest nowy słupek lub świeca. Podobnie jak w przypadku metody OnTick(), możesz użyć metody OnBar() do zaprogramowania warunków wejścia i wyjścia z pozycji, a także wszelkich innych logik, które muszą zostać wykonane przy tworzeniu każdego nowego słupka.

Jak wywoływana jest metoda OnBar()

Jeśli masz wykres H1, nowy słupek jest tworzony co godzinę, co oznacza, że metoda OnBar() będzie wywoływana raz na godzinę. Jeśli masz wykres m1, ta sama metoda będzie wywoływana raz na minutę.

Nasza metoda OnBar() będzie drukować „OnBar" przy każdym nowym słupku/świecy. Aby zademonstrować, jak to działa, dołączymy naszego cBota do wykresu m1 i spojrzymy na dziennik.

Użyj metody OnStop()

Metoda OnStop() jest wywoływana, gdy cBot zostaje zatrzymany przez użytkownika lub za pomocą kodu. Gdy to się stanie, wykonywany jest dowolny kod wewnątrz metody OnStop(). Może to być wykorzystane do wykonania końcowych operacji, takich jak zamykanie pozycji.

Dodamy następujący kod do naszej metody OnStop() - jak zwykle, nasz cBot wydrukuje wartość parametru Message, gdy zostanie zatrzymany.

1
Print(Message);

Na poniższym zrzucie ekranu uruchamiamy i zatrzymujemy wystąpienie naszego cBota, aby zademonstrować, jak to wszystko działa.

Użyj metody OnException()

Metoda OnException() zapewnia tolerancję błędów poprzez przechwytywanie nieobsłużonych wyjątków, pozwalając Ci zdecydować, jak je obsłużyć. Nie jest uwzględniona w domyślnym szablonie kodu, więc dodamy ją sami, używając następującego fragmentu.

1
2
3
4
protected override void OnException(Exception exception) 
{
    Print("Ooops, unhandled exception! No worries, cBot still alive");            
}

Aby wywołać metodę OnException(), napiszemy kod przechwytujący wyjątek, który występuje, gdy próbujemy uzyskać dostęp do informacji o transakcji, która już nie istnieje. Dodamy poniższy kod do metody OnStart().

1
ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "my label");

Kod, który napisaliśmy w metodzie OnStart(), wykona zlecenie rynkowe z następującymi konfigurowalnymi parametrami.

  • Typ transakcji będzie zleceniem kupna.
  • Transakcja zostanie wykonana dla bieżącego symbolu wykresu, do którego dołączony jest cBot.
  • Wolumen zlecenia wyniesie 1000 jednostek.
  • Unikalna etykieta dołączona do zlecenia będzie brzmiała „my label".

Dodamy również następujący kod do metody OnTick().

1
2
3
var position = Positions.Find("my label");
if (Positions.Find("my label") != null) Print("PositionId: ", position.Id);
Print("Message below");

Kod, który napisaliśmy w metodzie OnTick(), znajdzie pozycję, która została otwarta w metodzie OnStart(), używając nazwy etykiety „my label".

Jeśli pozycja zostanie znaleziona z tą samą etykietą, wydrukuje ona w dzienniku identyfikator pozycji otwartej transakcji. Wydrukuje również kolejny komunikat o nazwie „Message below", gdy zostanie wykonana następna linia kodu.

Gdy nasz cBot zostanie uruchomiony, a metoda OnTick() zostanie wywołana i zlecenie zostanie znalezione, cBot wydrukuje identyfikator zlecenia w dzienniku, a po identyfikatorze zlecenia wydrukuje komunikat „Message below".

Jak widać, nie pojawiają się żadne wyjątki, a nasz cBot wykonuje swoją pracę perfekcyjnie.

Teraz jednak ręcznie zamkniemy pozycję otwartą przez cBota i wprowadzimy niewielkie zmiany w kodzie, aby wyjątek na pewno wystąpił. W metodzie OnStart() zmienimy etykietę zlecenia na „cTrader". W metodzie OnTick() zakomentujemy warunek sprawdzający, czy istnieje pozycja z etykietą „my label".

Oto końcowy kod naszego cBota - zauważ, że ten kod zawsze wywoła wyjątek.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class LifecycleTest : Robot
    {
        [Parameter(DefaultValue = "cTrader rocks!")]
        public string Message { get; set; }

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "cTrader");
        }

        protected override void OnTick()
        {
            var position = Positions.Find("my label");
            //if (Positions.Find("my label") != null) 
            Print("PositionId: ", position.Id);
            Print("Message below");
        }

        protected override void OnStop()
        {
            Print(Message);
        }

        protected override void OnException(Exception exception) 
        {
            Print("Ooops, unhandled exception! No worries, cBot still alive");            
        }
    }
}

Uruchomimy cBota ponownie i zobaczymy, co się stanie.

To, co się stało, to utworzenie nowego zlecenia rynkowego po uruchomieniu cBota. Etykieta dołączona do tego zlecenia brzmiała "cTrader". W metodzie OnTick() kod próbował uzyskać pozycję z etykietą "my label", a ponieważ zakomentowaliśmy linię kodu z warunkiem. Następnie próbował wydrukować w dzienniku identyfikator pozycji.

Spowodowało to błąd wyjątku, który normalnie zatrzymałby cBota w poprzednich wersjach cTrader, ale dzięki nowej metodzie OnException() możemy teraz przechwycić i obsłużyć ten błąd. cBot będzie nadal działał, a my możemy zarejestrować błąd, aby można go było naprawić.

Podsumowanie

Cykl życia cBota składa się z kilku kluczowych zdarzeń, które można obsługiwać za pomocą metod OnStart(), OnTick(), OnStop(), OnBar() i OnException(). Dostosowując sposób, w jaki cBot reaguje na główne zdarzenia, możesz zapewnić, że Twoje algorytmy będą zachowywać się dokładnie zgodnie z oczekiwaniami.