Bỏ qua

Grid cBot

Tổng quan chiến lược

Grid cBot triển khai một chiến lược giao dịch lưới trong đó nhiều lệnh mua hoặc bán cho một ký hiệu được đặt ở các khoảng giá đều đặn hoặc "bước", tạo thành một "lưới" các vị thế. Khi giá ký hiệu thay đổi, các vị thế mới liên tục được mở để tận dụng các biến động.

Grid cBot sử dụng kết hợp các phép toán số học đơn giản và các kiểm tra logic để mở vị thế, tính toán lợi nhuận và quản lý các hoạt động giao dịch của nó. Nó hoạt động hiệu quả nhất trong các thị trường đi ngang hoặc trong phạm vi. Nó cũng hoạt động tốt trong các điều kiện biến động thấp và các thị trường có các mức kháng cự và hỗ trợ đã biết.

Tạo cBot

Tìm hiểu cách tạo cBot, sử dụng C# hoặc Python, trong các hướng dẫn từng bước của chúng tôi.

Mã nguồn Grid cBot có sẵn trong kho lưu trữ công khai C#Python của chúng tôi. Mã tương tự được cung cấp dưới dạng mẫu trong trình hướng dẫn tạo thuật toán trong cTrader Windows hoặc Mac, hoặc bạn có thể đơn giản sao chép và sử dụng đoạn mã bên dưới:

 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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 Grid : Robot
    {
        [Parameter("Volume (lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double VolumeInLots { get; set; }

        [Parameter("Trade Side")]
        public TradeType TradeType { get; set; }

        [Parameter("Step (pips)", DefaultValue = 5, MinValue = 0.1, Step = 0.1)]
        public double StepPips { get; set; }

        [Parameter("Target Profit", DefaultValue = 20)]
        public double TargetProfit { get; set; }

        private bool enoughMoney = true;

        protected override void OnStart()
        {
            if (GridPositions.Length == 0)
                OpenPosition();
        }

        protected override void OnTick()
        {
            if (GridPositions.Sum(p => p.NetProfit) >= TargetProfit)
            {
                Print("Target profit is reached. Closing all grid positions");
                CloseGridPositions();
                Print("All grid positions are closed. Stopping cBot");
                Stop();
            }
            if (GridPositions.Length > 0 && enoughMoney)
            {
                var lastGridPosition = GridPositions.OrderBy(p => p.Pips).Last();
                var distance = CalculateDistanceInPips(lastGridPosition);

                if (distance >= StepPips)
                    OpenPosition();
            }
        }

        private Position[] GridPositions
        {
            get
            {
                return Positions
                    .Where(p => p.SymbolName == SymbolName && p.TradeType == TradeType)
                    .ToArray();
            }
        }

        private double CalculateDistanceInPips(Position position)
        {
            if (position.TradeType == TradeType.Buy)
                return (position.EntryPrice - Symbol.Ask) / Symbol.PipSize;
            else
                return (Symbol.Bid - position.EntryPrice) / Symbol.PipSize;
        }

        private void OpenPosition()
        {
            var result = ExecuteMarketOrder(TradeType, SymbolName, Symbol.QuantityToVolumeInUnits(VolumeInLots), "Grid");
            if (result.Error == ErrorCode.NoMoney)
            {
                enoughMoney = false;
                Print("Not enough money to open additional positions");
            }
        }

        private void CloseGridPositions()
        {
            while (GridPositions.Length > 0)
            {
                foreach (var position in GridPositions)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}
 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class GridSample():
    def on_start(self):
        self.volumeInUnits = api.Symbol.QuantityToVolumeInUnits(api.VolumeInLots)
        self.enoughMoney = True
        if len(self.get_grid_positions()) == 0:
            self.open_position()

    def on_tick(self):
        grid_positions = self.get_grid_positions()
        net_profit_sum = sum([p.NetProfit for p in grid_positions])
        if net_profit_sum >= api.TargetProfit:
            api.Print("Target profit is reached. Closing all grid positions")
            self.close_grid_positions()
            api.Print("All grid positions are closed. Stopping cBot")
            api.Stop()

        if len(grid_positions) > 0 and self.enoughMoney == True:
            position_with_highest_pips = sorted(grid_positions, key=lambda pos: pos.Pips, reverse=True)[0]
            distance = self.get_distance_in_pips(position_with_highest_pips)          
            if distance >= api.StepPips:
                self.open_position()

    def get_grid_positions(self):
        return [pos for pos in api.Positions if pos.SymbolName == api.SymbolName and pos.TradeType == api.TradeType]

    def open_position(self):
        result = api.ExecuteMarketOrder(api.TradeType, api.SymbolName, self.volumeInUnits, "Grid")
        if result.Error == ErrorCode.NoMoney:
            self.enoughMoney = False
            api.Print("Not enough money to open additional positions")

    def close_grid_positions(self):
        for position in self.get_grid_positions():
            position.Close()

        if len(self.get_grid_positions()) > 0:
            self.close_grid_positions()

    def get_distance_in_pips(self, position):
        return (position.EntryPrice - api.Symbol.Ask if position.TradeType == TradeType.Buy else api.Symbol.Bid - position.EntryPrice) / api.Symbol.PipSize

Tích hợp chỉ báo

Grid cBot không dựa vào bất kỳ chỉ báo nào để xác định chiến lược lưới của nó; nó không cố gắng dự đoán liệu giá ký hiệu sẽ tăng hay giảm. Thay vào đó, nó nhắm đến các giao dịch có lợi nhuận từ các biến động giá theo bất kỳ hướng nào.

cBot thực hiện giao dịch dựa trên quy tắc đơn giản này: Nếu giá ký hiệu di chuyển vượt quá một số pip cụ thể (được xác định bởi tham số StepPips), cBot sẽ mở một vị thế mới.

Tính toán và logic

Thực hiện giao dịch ban đầu

Khi cBot khởi động, nó sẽ kiểm tra xem có bất kỳ vị thế nào đang mở trong lưới hay không. Nếu không có vị thế nào đang mở, cBot sẽ mở vị thế đầu tiên ngay lập tức thông qua phương thức OpenPosition(). Bước đầu tiên này đảm bảo rằng lưới bắt đầu với một giao dịch ban đầu dựa trên phía giao dịch được chỉ định (TradeType).

Theo dõi lãi

Trên mỗi tick (ví dụ: mỗi lần cập nhật giá), cBot sẽ kiểm tra xem lãi ròng tích lũy của tất cả các vị thế đang mở trong lưới có đạt hoặc vượt quá mức lãi mục tiêu được chỉ định (TargetProfit) hay không. Nếu mức lãi mục tiêu đã đạt được, tất cả các vị thế đang mở sẽ được đóng và cBot sẽ dừng hoạt động.

Mức lãi mục tiêu là tổng lãi ròng từ mỗi vị thế trong lưới.

\[ \text{Tổng lợi nhuận ròng} = \sum_{i=1}^{n} \text{NetProfit}(p_i) \]

\(n\) – số lượng vị thế đang mở trong lưới

\(\text{NetProfit}(p_i)\) – lãi ròng của vị thế \(i\)

Mở vị thế

Nếu mức lãi mục tiêu chưa đạt được và có các vị thế đang mở, cBot sẽ tính toán khoảng cách (tính bằng pip) giữa vị thế lưới được mở gần nhất và giá thị trường hiện tại.

Đối với vị thế mua:

\[ D_b = \frac{P_e - P_a}{S} \]

Đối với vị thế bán:

\[ D_s = \frac{P_b - P_e}{S} \]

\(D_b\) – khoảng cách tính bằng pip giữa giá vào lệnh và giá ask hiện tại.

\(D_s\) – khoảng cách tính bằng pip giữa giá bid hiện tại và giá vào lệnh.

\(P_e\) – giá mà vị thế mua cuối cùng cho ký hiệu được mở.

\(P_a\) – giá ask hiện tại cho ký hiệu.

\(P_b\) – giá bid hiện tại cho ký hiệu.

\(S\) – giá trị của một pip cho ký hiệu.

Nếu khoảng cách được tính toán lớn hơn hoặc bằng kích thước bước được định nghĩa (StepPips), một vị thế mới sẽ được mở bằng phương thức OpenPosition().

Mỗi lần trước khi mở một vị thế mới, cBot sẽ kiểm tra và xác nhận rằng có đủ tiền để thực hiện thao tác. Nếu không đủ tiền, cBot sẽ ngừng cố gắng mở các vị thế mới và ghi lại thông báo "Không đủ tiền để mở thêm vị thế".

Đóng các vị thế

Khi TargetProfit đạt được, cBot sẽ ghi lại thông báo "Mục tiêu lợi nhuận đã đạt được. Đóng tất cả các vị thế lưới".

Phương thức CloseGridPositions() sau đó sẽ lặp qua tất cả các vị thế mở trong lưới, đóng chúng và sau đó cBot sẽ ghi lại thông báo "Tất cả các vị thế lưới đã được đóng. Dừng cBot". Sau đó, cBot sẽ được dừng.

Tham số

Tham số Đơn vị Định nghĩa Mẹo
Số lượng Lot Khối lượng của mỗi giao dịch. Các nhà giao dịch thận trọng có thể chỉ định khối lượng nhỏ để giảm thiểu rủi ro và quản lý rủi ro một cách cẩn thận, đặc biệt là trong một thị trường biến động. Bằng cách này, bất kỳ khoản lỗ tiềm năng nào sẽ được giảm thiểu nếu thị trường di chuyển ngược lại với lưới.

Các nhà giao dịch mạo hiểm có thể chỉ định khối lượng lớn để tối đa hóa lợi nhuận khi họ tự tin vào thị trường. Mặc dù cách tiếp cận này rủi ro hơn, nhưng nó mang lại lợi nhuận lớn hơn khi lưới nắm bắt được các biến động giá lớn một cách hiệu quả.
Bên giao dịch Hướng của giao dịch (mua hoặc bán). Trong một thị trường tăng, các nhà giao dịch có thể chọn mua. Khi ký hiệu tạm thời điều chỉnh giảm, cBot sẽ mua ở các mức thấp hơn. Khi thị trường di chuyển trở lại, mỗi vị thế mua sẽ trở nên có lợi nhuận.

Trong một thị trường giảm, các nhà giao dịch có thể chọn bán. Khi giá ký hiệu tạm thời điều chỉnh tăng, cBot sẽ bán ở các mức cao hơn. Khi thị trường di chuyển trở lại, mỗi vị thế bán sẽ trở nên có lợi nhuận.
Nhiệm vụ Pip Khoảng cách giữa hai vị thế lưới liên tiếp. Khoảng cách càng nhỏ, các giao dịch mới sẽ được mở càng thường xuyên, trong khi khoảng cách lớn hơn sẽ dẫn đến ít giao dịch hơn. Trong một thị trường đi ngang hoặc có biến động thấp, các nhà giao dịch có thể đặt giá trị nhỏ. Cài đặt này đảm bảo rằng cBot sẽ mở các vị thế thường xuyên hơn và nắm bắt các biến động giá nhỏ, đặc biệt là khi giá di chuyển trong một phạm vi hẹp.

Trong các thị trường có xu hướng hoặc biến động mạnh hơn, các nhà giao dịch có thể đặt giá trị lớn. Cài đặt này giảm số lượng giao dịch được mở, cho phép cBot nắm bắt các biến động lớn hơn và giúp tránh giao dịch quá mức trong các xu hướng mạnh.
Mục tiêu lợi nhuận Lợi nhuận tích lũy bằng đơn vị tiền tệ của tài khoản phải đạt được trước khi Grid cBot đóng tất cả các vị thế đang mở và ngừng giao dịch. Nhà giao dịch tìm kiếm lợi nhuận nhỏ và nhanh có thể đặt giá trị thấp. Thiết lập này đảm bảo rằng lưới sẽ đóng ngay khi đạt được lợi nhuận nhỏ, giảm thiểu rủi ro khi giữ các vị thế quá lâu trong thị trường biến động mạnh.

Nhà giao dịch muốn chờ đợi lợi nhuận lớn có thể đặt giá trị cao. Thiết lập này cho phép lưới duy trì mở lâu hơn, cho phép Grid cBot tích lũy lợi nhuận qua một loạt các biến động thị trường lớn trước khi đóng tất cả các vị thế.

Sự ứng dụng

Thị trường đi ngang hoặc dao động trong phạm vi

Grid cBot hoạt động hiệu quả nhất trong các thị trường đi ngang khi giá dao động giữa các mức hỗ trợ và kháng cự. Trong các thị trường như vậy, khi giá thường xuyên di chuyển lên xuống trong một phạm vi xác định, Grid cBot mở các vị thế thường xuyên và tận dụng các biến động.

Trường hợp sử dụng

Hãy xem xét một kịch bản trong đó EURUSD duy trì trong phạm vi từ 1.1000 đến 1.1100. Grid cBot mở các vị thế mua khi giá giảm gần mức 1.1000 và mở các vị thế bán gần mức 1.1100. Khi giá dao động giữa các mức này, Grid cBot thu lợi nhuận từ mỗi đợt dao động.

Các phương pháp tốt nhất

  • Đặt kích thước bước nhỏ để nắm bắt các dao động giá thường xuyên.
  • Đặt mục tiêu lợi nhuận khiêm tốn để lưới đóng thường xuyên, cho phép bạn thu lợi nhuận nhỏ và ổn định.
  • Theo dõi tin tức thị trường hoặc các sự kiện sắp tới có thể dẫn đến phá vỡ giá (breakout) khỏi phạm vi và gây ra các khoản lỗ lớn.

Thị trường biến động thấp

Trong các thị trường có biến động thấp, biến động giá có xu hướng chậm và ít rõ rệt hơn. Khi giá di chuyển từ từ, Grid cBot có đủ thời gian để mở nhiều vị thế mà không phải đối mặt với rủi ro của các biến động thị trường lớn và nhanh chóng.

Trường hợp sử dụng

Hãy xem xét một kịch bản trong đó USDJPY thể hiện biến động thấp như thường thấy trong phiên giao dịch châu Á. Grid cBot có thể mở các vị thế với kích thước bước nhỏ và nắm bắt các biến động giá nhỏ, dần dần xảy ra trong những giờ yên tĩnh đó.

Các phương pháp tốt nhất

  • Sử dụng kích thước bước chặt chẽ để tận dụng các biến động giá nhỏ điển hình trong các thị trường có biến động thấp.
  • Đặt khối lượng giao dịch thấp để giảm rủi ro trong trường hợp biến động tăng đột ngột.
  • Theo dõi điều kiện thị trường, tin tức hoặc sự kiện bất ngờ và sẵn sàng dừng Grid cBot nhanh chóng.

Thị trường có các mức giá xác định

Grid cBot có thể hoạt động hiệu quả trong các thị trường có các mức hỗ trợ và kháng cự mạnh và rõ ràng. Những mức giá này đóng vai trò như các rào cản giá và khiến thị trường thường xuyên bật lại, tạo ra một phạm vi mà cBot có thể khai thác.

Trường hợp sử dụng

Hãy xem xét một kịch bản trong đó giá vàng (XAUUSD) dao động giữa mức hỗ trợ mạnh ở USD 2,000 và mức kháng cự ở USD 2,050. Grid cBot mở các lệnh mua gần USD 2,000 và các lệnh bán gần USD 2,050, thu lợi từ việc giá bật lại giữa các mức này.

Các phương pháp tốt nhất

  • Đặt kích thước bước dựa trên biến động thị trường. Một thị trường có biến động cao có thể yêu cầu kích thước bước lớn hơn, trong khi các thị trường có biến động thấp có thể sử dụng các bước nhỏ hơn.
  • Sử dụng Grid cBot xung quanh các thị trường có các mức hỗ trợ và kháng cự được thiết lập rõ ràng để tránh bị mắc kẹt trong một đợt phá vỡ.
  • Hãy thận trọng với các sự kiện hoặc tin tức có thể gây ra đợt phá vỡ để tránh thua lỗ lớn. cBot không được chuẩn bị để xử lý việc thị trường phá vỡ qua các mức hỗ trợ hoặc kháng cự.

Thị trường không có xu hướng rõ ràng

Một số cặp tiền tệ thể hiện sự biến động không có xu hướng rõ ràng với các biến động giá thường xuyên, nhưng giá của chúng không thể hiện một xu hướng dài hạn mạnh mẽ. Grid cBot hoạt động tốt trong các thị trường như vậy vì nó có thể nắm bắt các biến động thường xuyên mà không có nguy cơ bị mắc kẹt trong một xu hướng dài hạn.

Trường hợp sử dụng

Hãy xem xét một kịch bản trong đó EURCHF di chuyển theo cách không có xu hướng rõ ràng, một hiện tượng phổ biến do sự ổn định của khu vực đồng Euro và nền kinh tế Thụy Sĩ. Grid cBot có thể mở các vị thế với kích thước bước nhỏ, thu lợi từ các biến động thường xuyên mà không cần lo lắng về các xu hướng lớn.

Các phương pháp tốt nhất

  • Sử dụng kích thước bước nhỏ để nắm bắt các biến động giá thường xuyên.
  • Cân nhắc đặt khối lượng giao dịch thấp để quản lý rủi ro trong trường hợp thị trường phá vỡ thành một xu hướng.

Tổng quan

Grid cBot hoạt động dựa trên giả định rằng trong cả thị trường tăng và giảm, sẽ có các đợt điều chỉnh hoặc hồi lại. Nó mua thấp và bán cao trong thị trường tăng và bán cao mua thấp trong thị trường giảm; cBot thu lợi khi thị trường tiếp tục xu hướng chính sau các đợt điều chỉnh.

Vì cBot không sử dụng các chỉ báo, nó không thể đánh giá liệu thị trường đang có xu hướng hay đang dao động. Nó chỉ đơn giản mở các vị thế dựa trên biến động giá, bỏ qua tâm lý thị trường hoặc sức mạnh của xu hướng.

Việc không sử dụng các chỉ báo làm cho quá trình giao dịch hoàn toàn cơ học; cBot chỉ dựa vào các quy tắc định trước để mở các vị thế ở các khoảng thời gian đều đặn. Mặc dù cách tiếp cận này có thể có lợi nhuận trong các thị trường dao động, nhưng nó có xu hướng thua lỗ trong các thị trường có xu hướng, biến động cao hoặc thay đổi nhanh chóng.

Ngoài việc cấu hình cBot để áp dụng các chiến lược cá nhân, các nhà giao dịch có thể cân nhắc việc đưa các chỉ báo vào để lọc các giao dịch dựa trên điều kiện thị trường:

  • Moving Averages (MA) có thể giúp xác định xu hướng thị trường, cho phép cBot chỉ giao dịch theo hướng của xu hướng.
  • Relative Strength Index (RSI) có thể báo hiệu các điều kiện quá mua hoặc quá bán, giúp cBot tránh mở các vị thế mới khi thị trường bị kéo dài về một hướng.
  • Bollinger Bands có thể cung cấp cái nhìn sâu sắc về sự biến động giá, cho phép cBot điều chỉnh khoảng cách lưới hoặc tạm dừng giao dịch trong các giai đoạn biến động cao.