Przykłady kodu cBotów
Ta strona zawiera kilka przykładów kodu w Pythonie i C# do tworzenia botów handlowych i rozwijania algorytmów. Należy pamiętać, że żaden z wymienionych poniżej cBotów nie gwarantuje żadnych zwrotów finansowych. Przed wdrożeniem jakichkolwiek instancji na koncie rzeczywistym należy przeprowadzić backtesting i dostosować cBoty.
Repozytoria przykładów cBotów
Kompleksowe przykłady kodu cBotów, w tym gotowe do uruchomienia szablony dla różnych zautomatyzowanych strategii i stylów handlu, są dostępne w oddzielnych repozytoriach Python i C# w GitHub.
Operacje synchroniczne
Wszystkie cBoty w tej sekcji wykonują swoje operacje synchronicznie.
Wykonuj zlecenia rynkowe
-
Prosty cBot wykonujący udane operacje
Poniższy bot handlowy tworzy zlecenie rynkowe przy uruchomieniu i zapisuje wynik w zmiennej
result.Jeśli wykonanie zlecenia zakończy się sukcesem, cena otwarcia zostaje wyświetlona w dzienniku.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000); if (result.IsSuccessful) { var position = result.Position; Print("Position entry price is {0}", position.EntryPrice); } } }1 2 3 4 5 6 7
class Sample_cBot(): def on_start(self): result = api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000) if result.IsSuccessful: position = result.Position api.Print(f"Position entry price is {position.EntryPrice}")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD ZAKOŃCZONE SUKCESEM, Pozycja PID14576001
- Cena otwarcia pozycji wynosi 1.19067
-
Prosty cBot z konfigurowalnymi parametrami
Podczas deklarowania różnych właściwości cBota możesz przekształcić je w konfigurowalne parametry za pomocą deklaracji
[Parameter()]. Gdy uruchamiana jest nowa instancja Twojego cBota, Ty (lub inni użytkownicy) będziecie mogli przypisać niestandardowe wartości do nich.Rozważ poniższy przykład.
1 2
[Parameter("SMA Period", DefaultValue = 14)] public int SmaPeriod { get; set; }Uwaga
cBoty w Pythonie używają konfigurowalnych parametrów zadeklarowanych w ich plikach
.cs.1 2
[Parameter("SMA Period", DefaultValue = 14)] public int SmaPeriod { get; set; }W powyższym przykładzie definiujemy następujące cechy:
- Nazwę parametru. Następnie pojawi się ona w interfejsie użytkownika cTrader (
"SMA Period"). - Wartość domyślną parametru, która będzie stosowana do wszystkich nowych instancji, chyba że zostanie zmieniona przez użytkowników (
DefaultValue = 14).
W poniższym kodzie pokazujemy, jak właściwość
SmaPeriodmoże być używana w rzeczywistym bocie handlowym.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class SamplecBotReferenceSMA : Robot { [Parameter("Source")] public DataSeries Source { get; set; } [Parameter("SMA Period", DefaultValue = 14)] public int SmaPeriod { get; set; } private SampleSMA sma; protected override void OnStart() { sma = Indicators.GetIndicator<SampleSMA>(Source, SmaPeriod); } protected override void OnTick() { Print("{0}", sma.Result.LastValue); } }Uwaga
cBoty w Pythonie używają konfigurowalnych parametrów zadeklarowanych w ich plikach
.cs.1 2 3 4 5 6
class Sample_cBot(): def on_start(self): self.sma = api.Indicators.GetIndicator<SampleSMA>(api.Source, api.SmaPeriod) def on_tick(self): api.Print(f"{self.sma.Result.LastValue}")Nasz bot pobiera konfigurowalną właściwość
SmaPeriodi przy uruchomieniu przekazuje jej wartość do metodyIndicators.GetIndicator<SampleSMA>(). Ta metoda zwraca wartość prostej średniej ruchomej dla określonego okresu.Podczas tworzenia instancji cBota wszystkie regulowane parametry można skonfigurować w oknie Dodaj instancję.
Po uruchomieniu cBot informuje nas o tym, jaka była ostatnia wartość prostej średniej ruchomej przy każdym ticku.
Wynik dziennika
- Uruchomiono instancję cBota [Sample cBot Reference SMA, EURUSD, h1].
- 0.975685714285714
- 0.975681428571429
- 0.97568
- Instancja cBota [Sample cBot Reference SMA, EURUSD, h1] zatrzymana przez użytkownika.
- Nazwę parametru. Następnie pojawi się ona w interfejsie użytkownika cTrader (
-
Wykonaj zlecenie rynkowe z większą liczbą argumentów
W poprzednim przykładzie przekazaliśmy minimalną możliwą liczbę argumentów do metody
ExecuteMarketOrder(). Były to typ transakcji (TradeType.Buy), symbol (Symbol) i wolumen (-1).Metoda
ExecuteMarketOrder()może być wywoływana z dodatkowymi argumentami, takimi jakLabel,StopLoss,TakeProfitiComment. Poniższy przykład określa etykietę ("order 1"), mechanizm ochrony Stop loss (10) i poziom Take profit (10).1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[Robot(TimeZone = TimeZones.UTC)] public class Sample_cBot : Robot { protected override void OnStart() { var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, "order 1", 10, 10); if (result.IsSuccessful) { var position = result.Position; Print("Position entry price is {0}", position.EntryPrice); Print("Position SL price is {0}", position.StopLoss); } } }1 2 3 4 5 6 7 8
class Sample_cBot(): def on_start(self): result = api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000, "order 1", 10, 10) if result.IsSuccessful: position = result.Position api.Print(f"Position entry price is {position.EntryPrice}") api.Print(f"Position SL price is {position.StopLoss}")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10)
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10) ZAKOŃCZONE SUKCESEM, Pozycja PID14576098
- Cena otwarcia pozycji wynosi 1.1896
- Cena SL pozycji wynosi 1.1886
Modyfikacja pozycji
W poniższym przykładzie dodajemy tylko wartość Take profit (10) podczas wykonywania zlecenia. Następnie modyfikujemy pozycję, aby dodać Stop loss.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD (TP: 10)
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD (TP: 10) ZAKOŃCZONE SUKCESEM, Pozycja PID14576161
- Cena SL pozycji wynosi null
- Modyfikowanie pozycji PID14576161 (SL: 1.18744, TP: 1.18944)
- Modyfikowanie pozycji PID14576161 (SL: 1.18744, TP: 1.18944) ZAKOŃCZONE SUKCESEM, Pozycja PID14576161
- Nowa cena SL pozycji wynosi 1.18744
Zamknij pozycję
-
Wykonaj pełne zamknięcie
Poniższy przykład kodu składa zlecenie rynkowe. Jeśli zysk brutto wynikowej pozycji przekracza określoną wartość (
null && position.GrossProfit > 10), zostaje ona zamknięta.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, "myLabel"); } protected override void OnTick() { var position = Positions.Find("myLabel"); if (position != null && position.GrossProfit > 10) { ClosePosition(position); Stop(); } } }1 2 3 4 5 6 7 8 9
class Sample_cBot(): def on_start(self): api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 10000, "myLabel") def on_tick(self): position = api.Positions.Find("myLabel") if position is not None and position.GrossProfit > 10: api.ClosePosition(position) api.Stop()Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD ZAKOŃCZONE SUKCESEM, Pozycja PID14576180
-
Wykonaj częściowe zamknięcie
Zmodyfikujemy poprzedni przykład, aby utworzyć dwa zlecenia rynkowe z tymi samymi etykietami (
"myLabel"). Przy każdym nowym słupku nasz bot handlowy zamknie dokładnie połowę jednego z tych zleceń, ale tylko wtedy, gdy jego wolumen będzie równy lub większy niż 20 000.Używamy również metody
Positions.FindAll(). Zwraca ona listę pozycji, przez które możemy iterować.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { ExecuteMarketOrder(TradeType.Buy, SymbolName, 20000, "myLabel"); ExecuteMarketOrder(TradeType.Buy, SymbolName, 30000, "myLabel"); } protected override void OnBar() { var positions = Positions.FindAll("myLabel", SymbolName, TradeType.Buy); foreach (var position in positions) { if (position.VolumeInUnits >= 20000) { ClosePosition(position, 15000); } } } }1 2 3 4 5 6 7 8 9 10
class Sample_cBot(): def on_start(self): api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 20000, "myLabel") api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 30000, "myLabel") def on_tick(self): positions = api.Positions.FindAll("myLabel", api.SymbolName, TradeType.Buy) for position in positions: if position.VolumeInUnits >= 20000: api.ClosePosition(position, 15000)Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Wykonywanie zlecenia rynkowego kupna 20000 EURUSD
- Wykonywanie zlecenia rynkowego kupna 20000 EURUSD ZAKOŃCZONE SUKCESEM, Pozycja PID14579299
- Wykonywanie zlecenia rynkowego kupna 30000 EURUSD
- Wykonywanie zlecenia rynkowego kupna 30000 EURUSD ZAKOŃCZONE SUKCESEM, Pozycja PID14579300
Twórz zlecenia oczekujące
-
Twórz zlecenia z limitem i zlecenia stop
Zlecenia z limitem i zlecenia stop to zlecenia oczekujące; mimo to są tworzone podobnie do zleceń rynkowych. Jednak podczas tworzenia zleceń z limitem i zleceń stop musisz również określić ich cenę docelową i nie ma dopuszczalnego poślizgu.
Ten cBot tworzy dwa zlecenia z limitem i zlecenie stop. Następnie iteruje przez zlecenia i wyświetla ich etykiety oraz identyfikatory w dzienniku.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { PlaceLimitOrder(TradeType.Buy, SymbolName, 10000, Symbol.Bid, "myLimitOrder"); PlaceLimitOrder(TradeType.Buy, SymbolName, 20000, Symbol.Bid-2*Symbol.PipSize, "myLimitOrder"); PlaceStopOrder(TradeType.Buy, SymbolName, 10000, Symbol.Ask, "myStopOrder"); foreach (var pendingOrder in PendingOrders) { Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id); } } }1 2 3 4 5 6 7 8
class Sample_cBot(): def on_start(self): api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Bid, "myLimitOrder") api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 20000, api.Symbol.Bid - 2 * api.Symbol.PipSize, "myLimitOrder") api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask, "myStopOrder") for pendingOrder in api.PendingOrders: Print(f"Order placed with label {pendingOrder.Label}, id {pendingOrder.Id}")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19036)
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19036) POWIODŁO SIĘ, PendingOrder OID25220794
- Składanie zlecenia z limitem kupna 20000 EURUSD (Cena: 1.19017)
- Składanie zlecenia z limitem kupna 20000 EURUSD (Cena: 1.19017) POWIODŁO SIĘ, PendingOrder OID25220795
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19040)
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19040) POWIODŁO SIĘ, PendingOrder OID25220796
- Złożono zlecenie z etykietą myLimitOrder, id 25220794
- Złożono zlecenie z etykietą myLimitOrder, id 25220795
- Złożono zlecenie z etykietą myStopOrder, id 25220796
-
Tworzenie zleceń oczekujących z większą liczbą parametrów
Podobnie jak w przypadku zleceń rynkowych, możesz również określić etykietę zlecenia, różne mechanizmy ochrony, datę wygaśnięcia zlecenia i dodać komentarz.
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
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { var midnight = Server.Time.AddDays(1).Date; PlaceLimitOrder(TradeType.Buy, SymbolName, 10000, Symbol.Bid, "mySample_cBot", 10, null, midnight, "First"); PlaceStopOrder(TradeType.Buy, SymbolName, 10000, Symbol.Ask, "mySample_cBot", 10, 10, null, "Second"); foreach (var order in PendingOrders) { var sl = order.StopLoss == null ? "" : "SL: " + order.StopLoss; var tp = order.TakeProfit == null ? "" : " TP: " + order.TakeProfit; var text = string.Format("{0} {1}", sl, tp); if (order.OrderType == PendingOrderType.Limit) Print(order.Comment + " Limit Order " + text); else Print(order.Comment + " Stop Order " + text); } } }1 2 3 4 5 6 7 8 9 10 11 12
class Sample_cBot(): def on_start(self): midnight = api.Server.Time.AddDays(1).Date api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Bid, "mySample_cBot", 10, None, midnight, "First") api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask, "mySample_cBot", 10, 10, None, "Second") for order in api.PendingOrders: sl = "" if order.StopLoss is None else f"SL: {order.StopLoss}" tp = "" if order.TakeProfit is None else f"TP: {order.TakeProfit}" api.Print(f"{order.Comment} {order.OrderType} Order {sl} {tp}")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00)
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19049, SL: 10, ExpireTime: 12/05/2018 00:00:00) POWIODŁO SIĘ, PendingOrder OID25220807
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19053, SL: 10, TP: 10)
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19053, SL: 10, TP: 10) POWIODŁO SIĘ, PendingOrder OID25220808
- Zlecenie z limitem
- Pierwsze zlecenie z limitem SL: 1.18949
- Drugie zlecenie Stop SL: 1.18953 TP: 1.19153
Modyfikuj zlecenia oczekujące
Możliwa jest modyfikacja kilku cech zleceń oczekujących.
Poniższy przykład pokazuje, jak zmodyfikować cenę docelową, poziomy ochrony lub datę i godzinę wygaśnięcia zlecenia oczekującego.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25)
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19254, SL: 10, TP: 10, ExpireTime: 11/05/2018 20:07:25) POWIODŁO SIĘ, PendingOrder OID25220877
Anuluj zlecenia oczekujące
Składnia anulowania zlecenia to CancelPendingOrder(order), gdzie order jest typu PendingOrder.
Poniższy przykład pokazuje anulowanie wszystkich zleceń z etykietą "myLabel".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 | |
Zdarzenia pozycji
Możliwa jest subskrypcja zdarzeń związanych z różnymi operacjami handlowymi. Na przykład, aby sprawdzić, czy pozycja jest otwarta, subskrybujemy zdarzenie, które jest wywoływane dla wszystkich obiektów Position przy otwarciu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10)
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10) POWIODŁA SIĘ, Position PID14579468
- Pozycja otwarta po 1.19224
Podobnie możliwa jest subskrypcja zdarzeń, które są wywoływane za każdym razem, gdy pozycja jest zamykana.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10)
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10) POWIODŁA SIĘ, Position PID14579479
- Zamykanie pozycji PID14579299
- Zamykanie pozycji PID14579299 POWIODŁO SIĘ, Position PID14579299
- Pozycja zamknięta z zyskiem 20.64
Konwersja współrzędnych
Poniższy cBot umożliwia użytkownikom składanie zleceń z limitem w odpowiednim kierunku poprzez kliknięcie prawym przyciskiem myszy na wykresie. Osiąga to poprzez konwersję współrzędnych Y myszy na współrzędne Y wykresu (które w przypadku symboli odpowiadają cenom symboli).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 | |
Wykonywanie asynchroniczne
Powyższe przykłady kodu zostały zaprojektowane w celu implementacji robotów handlowych przy użyciu wykonywania synchronicznego. Zarówno C#, jak i Python obsługują operacje asynchroniczne, umożliwiając cBotowi wykonywanie kilku działań w tym samym przedziale czasowym.
Asynchroniczna realizacja zleceń rynkowych
Składnia metod asynchronicznych jest podobna do składni metod synchronicznych. Chociaż przyjmują te same typy argumentów, ich typem zwracanym jest TradeOperation zamiast TradeResult.
-
Podstawowe operacje asynchroniczne
Poniższy cBot demonstruje, jak działają operacje asynchroniczne. Tworzone jest zlecenie rynkowe; w następnym warunku cBot sprawdza, czy operacja jest wykonywana.
1 2 3 4 5 6 7 8 9 10 11 12 13
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { var operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000); if (operation.IsExecuting) { Print("Operation Is Executing"); } } }1 2 3 4 5 6
class Sample_cBot(): def on_start(self): operation = api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000) if operation.IsExecuting: api.Print("Operation Is Executing")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD
- Operacja jest wykonywana
- Realizacja zlecenia rynkowego kupna 10000 EURUSD POWIODŁA SIĘ, Position PID14579532
-
Realizacja zlecenia
Następny przykład podkreśla różnicę między metodami synchronicznymi i asynchronicznymi.
cBot sprawdza, czy operacja jest wykonywana zaraz po wywołaniu metody asynchronicznej. Robi to ponownie po wywołaniu metody synchronicznej. Dane wyjściowe dziennika dla tych dwóch działań są różne.
1 2 3 4 5 6 7 8 9 10 11
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { var operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000); Print(operation.IsExecuting ? "Operation Is Executing" : "Operation executed"); ExecuteMarketOrder(TradeType.Buy, SymbolName, 20000); Print(operation.IsExecuting ? "Operation Is Executing" : "Operation executed"); } }1 2 3 4 5 6
class Sample_cBot(): def on_start(self): operation = api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000) api.Print("Operation Is Executing" if operation.IsExecuting else "Operation executed") api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 20000) api.Print("Operation Is Executing" if operation.IsExecuting else "Operation executed")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD
- Operacja jest wykonywana
- Realizacja zlecenia rynkowego kupna 20000 EURUSD
- Realizacja zlecenia rynkowego kupna 10000 EURUSD POWIODŁA SIĘ, Position PID14579541
- Realizacja zlecenia rynkowego kupna 20000 EURUSD POWIODŁA SIĘ, Position PID14579542
- Operacja zrealizowana
-
Realizacja zlecenia z większą liczbą parametrów
Poniższy cBot składa zlecenie określając jego etykietę (
"myLabel"), poziomy ochrony (10, 10), symbol (SymbolName) i wolumen (10000).Przykład zawiera również kolekcję
Positionsi metodęFindAll().Find()iFindAll()mogą być używane do znajdowania pozycji z tą samą etykietą, symbolem i typem transakcji.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000, "myLabel", 10, 10); } protected override void OnTick() { var positions = Positions.FindAll("myLabel", SymbolName, TradeType.Buy); if (positions.Length == 0) return; foreach (var position in positions) Print("Buy at {0} SL {1}", position.EntryPrice, position.StopLoss); Stop(); } }1 2 3 4 5 6 7 8 9 10 11 12 13 14
class Sample_cBot(): def on_start(self): api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000, "myLabel", 10, 10) def on_tick(self): positions = api.Positions.FindAll("myLabel", api.SymbolName, TradeType.Buy) if positions.Length == 0: return for position in positions: api.Print(f"Buy at {position.EntryPrice} SL {position.StopLoss}") api.Stop()Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10)
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (SL: 10, TP: 10) POWIODŁA SIĘ, Position PID14579719
- Kupno po 1.19087 SL null
- Kupno po 1.19357 SL 1.19257
- cBot "New cBot" został zatrzymany dla EURUSD, h1.
Asynchroniczna modyfikacja pozycji
Poniższy cBot składa zlecenie rynkowe, a następnie modyfikuje nowo otwartą pozycję.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (TP: 10)
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (TP: 10) POWIODŁA SIĘ, Position PID14579736
- Modyfikacja pozycji PID14579300 (SL: 1.19213, TP: null)
- Modyfikacja pozycji PID14579300 (SL: 1.19213, TP: null) POWIODŁA SIĘ, Position PID14579300
Asynchroniczne zamykanie pozycji
Następny przykład demonstruje asynchroniczne zamykanie pozycji, jeśli istnieje.
Metoda Find() jest używana do przeszukiwania kolekcji Positions w poszukiwaniu pozycji z określoną etykietą.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (TP: 10)
- Realizacja zlecenia rynkowego kupna 10000 EURUSD (TP: 10) POWIODŁA SIĘ, Position PID14579740
- Zamykanie pozycji PID14579300
- Zamykanie pozycji PID14579300 POWIODŁO SIĘ, Position PID14579300
- cBot "New cBot" został zatrzymany dla EURUSD, h1.
Asynchroniczne składanie zleceń z limitem i zleceń stop
Jak wspomniano powyżej, składanie zleceń oczekujących jest podobne do tworzenia zleceń rynkowych.
Istnieją jednak pewne niewielkie różnice w argumentach między tymi dwiema metodami. Dopuszczalny poślizg nie występuje na liście argumentów. Ponadto musisz określić cenę docelową i możesz przekazać opcjonalny argument określający datę wygaśnięcia zlecenia.
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19382, ExpireTime: 12/05/2018 00:18:19)
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19487, ExpireTime: 12/05/2018 00:18:19)
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19382, ExpireTime: 12/05/2018 00:18:19) POWIODŁO SIĘ, PendingOrder OID25221859
- Składanie zlecenia Stop kupna 10000 EURUSD (Cena: 1.19487, ExpireTime: 12/05/2018 00:18:19) POWIODŁO SIĘ, PendingOrder OID25221860
Modyfikuj zlecenia oczekujące asynchronicznie
Poniższy cBot modyfikuje zlecenia z limitem asynchronicznie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 | |
Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19347, TP: 10, ExpireTime: 12/05/2018 00:22:08)
- Modyfikacja zlecenia oczekującego OID25221860 (Wolumen: 10000, Cena: 1.19487, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:18:19)
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19347, TP: 10, ExpireTime: 12/05/2018 00:22:08) POWIODŁO SIĘ, PendingOrder OID25221906
- Modyfikacja zlecenia oczekującego OID25221860 (Wolumen: 10000, Cena: 1.19487, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:18:19) POWIODŁO SIĘ, PendingOrder OID25221860
- Modyfikacja zlecenia oczekującego OID25221906 (Wolumen: 10000, Cena: 1.19347, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:22:08)
- Modyfikacja zlecenia oczekującego OID25221906 (Wolumen: 10000, Cena: 1.19347, SL: 10, TP: 10, ExpireTime: 12/05/2018 00:22:08) POWIODŁO SIĘ, PendingOrder OID25221906
Anuluj zlecenia oczekujące asynchronicznie
-
Anuluj wszystkie zlecenia oczekujące
Poniższy cBot asynchronicznie anuluje wszystkie aktualnie oczekujące zlecenia.
1 2 3 4 5 6 7 8 9 10 11
[Robot()] public class Sample_cBot : Robot { protected override void OnBar() { foreach (var pendingOrder in PendingOrders) { CancelPendingOrderAsync(pendingOrder); } } }1 2 3 4
class Sample_cBot(): def on_bar(self): for order in api.PendingOrders: api.CancelPendingOrderAsync(order)Wynik dziennika
- cBot "cancel pending order" został pomyślnie uruchomiony dla EURUSD, h1.
- Anulowanie zlecenia oczekującego OID274705
- Anulowanie zlecenia oczekującego OID274706
- Anulowanie zlecenia oczekującego OID274707
- Anulowanie zlecenia oczekującego OID274708
- Anulowanie zlecenia oczekującego OID274709
- Anulowanie zlecenia oczekującego OID274705 POWIODŁO SIĘ, PendingOrder OID274705
- Anulowanie zlecenia oczekującego OID274706 POWIODŁO SIĘ, PendingOrder OID274706
- Anulowanie zlecenia oczekującego OID274707 POWIODŁO SIĘ, PendingOrder OID274707
- Anulowanie zlecenia oczekującego OID274708 POWIODŁO SIĘ, PendingOrder OID274708
- Anulowanie zlecenia oczekującego OID274709 POWIODŁO SIĘ, PendingOrder OID274709
-
Anuluj zlecenia oczekujące z określoną etykietą
Ten cBot anuluje tylko zlecenia oczekujące z określoną etykietą.
1 2 3 4 5 6 7 8 9 10 11 12
[Robot()] public class Sample_cBot : Robot { protected override void OnBar() { foreach (var pendingOrder in PendingOrders) { if (pendingOrder.Label == "myLabel") CancelPendingOrderAsync(pendingOrder); } } }1 2 3 4 5
class Sample_cBot(): def on_bar(self): for order in api.PendingOrders: if order.Label == "myLabel": api.CancelPendingOrderAsync(order)
Funkcje wywołania zwrotnego dla metod asynchronicznych
Po zwróceniu wyniku, korzystanie z operacji asynchronicznych często wymaga kontrolowania wykonania. Aby sobie z tym poradzić, możesz dodać funkcję wywołania zwrotnego na końcu listy parametrów wszystkich metod asynchronicznych.
Ta funkcja zostanie wywołana, gdy tylko zostanie otrzymana odpowiedź z serwera. Na przykład może zostać wywołana, gdy pozycja zostanie otwarta, zmodyfikowana lub zamknięta.
-
Asynchroniczne zlecenie rynkowe z wywołaniem zwrotnym
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { var operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, 10000, PositionOpened); if (operation.IsExecuting) Print(operation.ToString()); else Print(operation.TradeResult.ToString()); } private void PositionOpened(TradeResult tradeResult) { var position = tradeResult.Position; Print(tradeResult.ToString()); if (tradeResult.IsSuccessful) Print("Position {0} opened at {1}", position.Id, position.EntryPrice); } }1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
from System import Action class Sample_cBot(): def on_start(self): operation = api.ExecuteMarketOrderAsync(TradeType.Buy, api.SymbolName, 10000, Action[TradeResult](self.on_position_opened)) if (operation.IsExecuting) api.Print(operation.ToString()) else api.Print(operation.TradeResult.ToString()) def on_position_opened(self, tradeResult): position = tradeResult.Position api.Print(tradeResult.ToString()) if tradeResult.IsSuccessful: api.Print(f"Position {position.Id} opened at {position.EntryPrice}")Wynik dziennika
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD
- TradeOperation (Wykonywanie zlecenia rynkowego kupna 10000 EURUSD WYKONYWANIE)
- Wykonywanie zlecenia rynkowego kupna 10000 EURUSD POWIODŁO SIĘ, Position PID14579835
- TradeResult (Success, Position: PID14579835)
- Pozycja 14579835 otwarta po 1.19414
-
Używanie wyrażeń lambda
Zamiast definiować nazwaną metodę wywołania zwrotnego, możesz użyć wyrażeń lambda.
W poniższym przykładzie, gdy zlecenie zostanie złożone, opis wyniku zostanie wydrukowany w dzienniku.
1 2 3 4 5 6 7 8 9
[Robot()] public class Sample_cBot : Robot { protected override void OnStart() { PlaceLimitOrderAsync(TradeType.Buy, SymbolName, 10000, Symbol.Ask - 20 * Symbol.PipSize, "myLabel", result => Print(result.ToString())); } }1 2 3 4 5
from System import Action class Samples(): def on_start(self): operation = api.PlaceLimitOrderAsync(TradeType.Buy, api.SymbolName, 10000, api.Symbol.Ask - 20 * api.Symbol.PipSize, "myLabel", Action[TradeResult](lambda result: api.Print(result.ToString())))Log output
- cBot "New cBot" został pomyślnie uruchomiony dla EURUSD, h1.
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19320)
- Składanie zlecenia z limitem kupna 10000 EURUSD (Cena: 1.19320) POWIODŁO SIĘ, PendingOrder OID25222083
- TradeResult (Success, PendingOrder: OID25222083)
