Przejdź do treści

Operacje handlowe cBota

W tym przewodniku szczegółowo wyjaśniamy kluczowe operacje handlowe, które możesz wykonywać za pomocą cBota opracowanego przez Algo API.

Oto niektóre z obsługiwanych operacji dla cBotów:

  • Wysyłanie zleceń rynkowych.
  • Składanie zleceń oczekujących.
  • Modyfikowanie zleceń oczekujących i otwartych pozycji.
  • Zamykanie pozycji i anulowanie zleceń.
  • Subskrybowanie zdarzeń handlowych (pozycje, zlecenia i powiązana aktywność).

Wysyłaj zlecenia rynkowe

Zlecenie rynkowe jest wysyłane na serwer handlowy, gdy wywoływana jest metoda ExecuteMarketOrder(). Po utworzeniu nowego cBota możesz dodać tę metodę z kilkoma zdefiniowanymi właściwościami zlecenia rynkowego (symbol, wolumen, take profit, stop loss itp.). Poniższy przykład składa zlecenie rynkowe po uruchomieniu cBota.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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 TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
        }       
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import clr

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *

class TradeOperations():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000, "", 10, 10, "", False)

Wskazówka

W przykładzie kilka parametrów zlecenia zostało celowo pozostawionych niezdefiniowanych "". Sprawdź References, aby zobaczyć sygnatury i kolejność wszystkich parametrów ExecuteMarketOrder().

Po zbudowaniu cBota i dodaniu instancji zobaczysz, że zlecenie rynkowe z określonymi parametrami zostało wykonane na starcie. Zakładki Positions i Log w panelu Trade Watch wyświetlają odpowiednią pozycję i wpisy dziennika.

Positions

Log

Składaj zlecenia oczekujące

cTrader obsługuje trzy typy zleceń oczekujących, a mianowicie zlecenia stop, zlecenia z limitem i zlecenia stop-limit. Aby złożyć zlecenia oczekujące na starcie, możesz zastąpić zlecenie rynkowe następującymi fragmentami kodu we wcześniejszym przykładzie cBota.

1
2
3
PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);
1
2
3
api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask - (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
api.PlaceStopLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), 2, "", 10, 10, None, "", False)

Wskazówka

Aby szybko sprawdzić parametry metody, zacznij wpisywać nazwę metody i nawias otwierający. Zobaczysz wyskakujące okienko IntelliSense z dodatkowymi informacjami.

Image title

Wskazówka

Jeśli klikniesz metodę/parametr w cTrader Algo i naciśniesz F1, panel pomocy po prawej stronie okna kodu pokaże pasujące wyniki wyszukiwania. Jeśli kursor tekstowy pozostanie poza oknem kodu i naciśniesz F1, pojawi się okno Help Centre, aby Ci pomóc.

Po pomyślnym zbudowaniu i uruchomieniu cBota zobaczysz następujące wpisy w panelu Trade Watch.

Orders

Log

Modyfikuj zlecenia oczekujące i otwarte pozycje

Gdy zlecenia oczekujące zostaną złożone, stają się dostępne w kolekcji PendingOrders Twojego cBota. Za pomocą tej kolekcji możesz uzyskać do nich dostęp i je modyfikować. Istniejące zlecenia oczekujące można modyfikować, dostosowując ich poziom stop loss w następujący sposób.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
protected override void OnStart()
{
    PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);

    foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
    {
        order.ModifyStopLossPips(20);
    }
}     
1
2
3
4
5
6
7
8
def on_start(self):
    api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
    api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask - (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
    api.PlaceStopLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), 2, "", 10, 10, None, "", False)

    for order in api.PendingOrders:
        if order.SymbolName == api.SymbolName:
            order.ModifyStopLossPips(20)

Zakładka Log panelu Trade Watch pokazuje, że trzy zlecenia oczekujące zostały pomyślnie zmodyfikowane natychmiast po złożeniu.

Image title

Po pomyślnym wykonaniu różnych typów zleceń zostaną otwarte pozycje dla Twojego konta. Wszystkie otwarte pozycje są dostępne w kolekcji Positions Twojego cBota. Podobnie jak w przypadku modyfikowania zleceń oczekujących w poprzednim przykładzie, możesz zmodyfikować otwartą pozycję. Ponieważ zlecenia rynkowe są najszybszym sposobem otwierania pozycji, dodajmy metodę OnBar() z akcją modyfikacji pozycji do pierwszego cBota w tym przewodniku.

1
2
3
4
5
6
7
protected override void OnBar()
{
    foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
    {
        position.ModifyTakeProfitPips(20);
    }
}
1
2
3
4
def on_bar(self):
    for position in api.Positions:
        if position.SymbolName == api.SymbolName:
            position.ModifyTakeProfitPips(20)

Jak widać w dzienniku, otwarta pozycja została zmodyfikowana na pierwszym otwartym słupku.

Image title

Zamykaj pozycje i anuluj zlecenia

Poniżej znajdziesz przykład cBota, który zamyka wszystkie otwarte pozycje i anuluje wszystkie zlecenia oczekujące w piątek o 11:00 (UTC), wywołując metodę OnTick().

 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
namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
            PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
        }  

        protected override void OnTick()
        {
            if(Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 11)
            {
                foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
                {
                    position.Close();    
                }

                foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
                {
                    order.Cancel();
                }
            }
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from robot_wrapper import *

class TradeOperations():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000, "", 10, 10, "", False)
        api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)

    def on_tick(self):
        # Friday == 5 (Sunday=0)
        if api.Server.Time.DayOfWeek == 5 and api.Server.Time.Hour >= 11:
            for position in api.Positions:
                if position.SymbolName == api.SymbolName:
                    position.Close()
            for order in api.PendingOrders:
                if order.SymbolName == api.SymbolName:
                    order.Cancel()

Image title

Subskrybuj zdarzenia handlowe

cTrader umożliwia programistom algorytmów subskrybowanie zdarzeń handlowych i monitorowanie aktywności handlowej, niezależnie od tego, czy zostały one zainicjowane przez cBota, czy ręcznie. Osiąga się to poprzez nasłuchiwanie zdarzeń dostępnych w dwóch wcześniej pokazanych kolekcjach, Positions i PendingOrders.

Dla pozycji dostępne są trzy zdarzenia:

  • Open
  • Modified
  • Closed

Są one wyzwalane odpowiednio podczas otwierania, modyfikowania i zamykania pozycji na Twoim koncie.

W poniższym fragmencie kodu trzy zdarzenia są deklarowane w metodzie OnStart(), a metody, które mają być wywoływane, są przypisane. Automatycznie utworzą one dla nas sygnatury kodu do użycia. Następnie do każdej z metod zdarzeń dodawane są instrukcje Print().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
protected override void OnStart()
{
    Positions.Opened += Positions_Opened;
    Positions.Modified += Positions_Modified;
    Positions.Closed += Positions_Closed;                    
}  

private void Positions_Opened(PositionOpenedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was opened");
}

private void Positions_Modified(PositionModifiedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was modified");
}

private void Positions_Closed(PositionClosedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was closed");
}   
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def on_start(self):
    api.Positions.Opened += self.positions_opened
    api.Positions.Modified += self.positions_modified
    api.Positions.Closed += self.positions_closed

def positions_opened(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was opened")

def positions_modified(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was modified")

def positions_closed(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was closed")

Niezależnie od tego, czy to Ty, czy cBot wykonuje zdarzenia Open, Modified i Closed, algorytm będzie na nie reagował za każdym razem z wydrukowanymi komunikatami, jak pokazano w dzienniku poniżej.

Image title

Podobnie możesz subskrybować zdarzenia związane ze zleceniami oczekującymi. Dla zleceń oczekujących dostępne są cztery zdarzenia:

  • Created
  • Modified
  • Filled
  • Cancelled

Cztery zdarzenia są deklarowane w metodzie OnStart(), a procedury obsługi zdarzeń są dodawane w następujący sposób.

 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
protected override void OnStart()
{
    PendingOrders.Created += PendingOrders_Created;
    PendingOrders.Modified += PendingOrders_Modified;
    PendingOrders.Filled += PendingOrders_Filled;
    PendingOrders.Cancelled += PendingOrders_Cancelled;
}

private void PendingOrders_Created(PendingOrderCreatedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was created");
}

private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was modified");
}

private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was filled");
}

private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was cancelled");
}       
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def on_start(self):
    api.PendingOrders.Created += self.pending_orders_created
    api.PendingOrders.Modified += self.pending_orders_modified
    api.PendingOrders.Filled += self.pending_orders_filled
    api.PendingOrders.Cancelled += self.pending_orders_cancelled

def pending_orders_created(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was created")

def pending_orders_modified(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was modified")

def pending_orders_filled(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was filled")

def pending_orders_cancelled(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was cancelled")

Jeśli subskrybujesz zdarzenia związane ze zleceniami oczekującymi, cBot będzie reagował zarówno na ręczne, jak i zaprogramowane działania handlowe.

Image title

Podsumowanie

Podsumowując, cTrader wyposaża programistów algorytmów w imponujący arsenał operacji handlowych, które mogą być wykonywane przez cBoty. Umiejętnie je stosując, możesz realizować dostosowane i zaawansowane strategie handlowe.

Image title