Bỏ qua

Cách làm việc với bộ nhớ cục bộ

Trong bài viết này và video tương ứng, chúng tôi sẽ giải thích bộ nhớ cục bộ là gì và cách nó có thể được sử dụng trong các thuật toán cTrader của bạn. Chúng tôi cũng sẽ cung cấp các ví dụ hữu ích và giải thích cách phạm vi bộ nhớ cục bộ hoạt động.

Tại sao sử dụng bộ nhớ cục bộ

Có nhiều trường hợp khi bạn muốn thuật toán của mình lưu một thứ gì đó vào hoặc truy cập một thứ gì đó từ hệ thống tệp cục bộ. Ví dụ, bạn có thể muốn lưu nhật ký của tất cả các hoạt động cBot. Tuy nhiên, điều này thường yêu cầu thuật toán phải có quyền truy cập nâng cao (AccessRights.FullAccess), điều này không lý tưởng cho người dùng. Nếu một thuật toán yêu cầu người dùng cung cấp quyền nâng cao, người dùng ít có khả năng tin tưởng thuật toán hơn, đặc biệt nếu nó được phân phối mà không có mã nguồn. Bộ nhớ cục bộ là một cách thuận tiện để truy cập an toàn vào hệ thống tệp cục bộ mà không gây ra bất kỳ lo ngại về bảo mật nào. Sử dụng bộ nhớ cục bộ cho phép các nhà phát triển giữ quyền truy cập của thuật toán của họ được đặt thành AccessRights.None.

Lưu chuỗi trong bộ nhớ cục bộ

Mỗi loại thuật toán cTrader đều có thuộc tính LocalStorage cho phép thực hiện các hoạt động đọc và ghi. Để minh họa cách bộ nhớ cục bộ hoạt động, chúng ta sẽ tạo một cBot mới. Trong trình xử lý OnStart của nó, chúng ta sẽ sử dụng phương thức LocalStorage.SetString(string key, string value). Như bạn có thể thấy, nó nhận hai đối số, cụ thể là một khóa mà thông tin sẽ được lưu và giá trị cần lưu.

1
LocalStorage.SetString("Message", Message);

Để truy xuất giá trị, chúng ta sẽ sử dụng phương thức GetString(string key) trong trình xử lý OnTick của cBot.

1
Print(LocalStorage.GetString("Message"));

Miễn là Message không phải là null, chúng ta có thể xây dựng cBot và thấy giá trị được truy xuất được in chính xác trong nhật ký.

Lưu đối tượng trong bộ nhớ cục bộ

Ngoài chuỗi, bạn có thể sử dụng bộ nhớ cục bộ để lưu bất kỳ loại đối tượng nào. Đằng sau hậu trường, cTrader tuần tự hóa và giải tuần tự hóa các đối tượng trong bộ nhớ cục bộ, cho phép chia sẻ bất kỳ loại dữ liệu nào. Để minh họa điều này, chúng ta có thể tạo một lớp mới để lưu trữ thông tin, lưu nó và sau đó truy xuất nó. Chúng ta sẽ đặt tên lớp này là Signal.

1
2
3
4
5
6
class Signal
{
    public TradeType TradeType { get; set; }
    public double SL { get; set; }
    public double TP { get; set; }
}

Trong phương thức OnStart(), chúng ta sẽ tạo một phiên bản mới của lớp này và khởi tạo các thuộc tính của nó.

1
2
3
4
5
var signal = new Signal{
    TradeType = TradeType.Sell,
    SL = 50,
    TP = 50,
};

Chúng ta sẽ sử dụng phương thức SetObject(string key, Object object) để lưu và truy xuất số dư tài khoản.

 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()
{
    var signal = new Signal{
    TradeType = TradeType.Sell,
    SL = 50,
    TP = 50,
    };        

    LocalStorage.SetString("Message",Message);
    LocalStorage.SetObject("Signal 1", signal);
}

protected override void OnTick()
{
Print(LocalStorage.GetString("Message")); 

var signal = LocalStorage.GetObject<Signal>("Signal 1"); 
Print(signal.TradeType);
Print(signal.SL);
Print(signal.TP);
}

Nếu chúng ta xây dựng cBot và khởi chạy nó, chúng ta sẽ thấy các giá trị chính xác được in trong nhật ký.

Phạm vi của bộ nhớ cục bộ

Khi sử dụng bộ nhớ cục bộ, bạn cũng có thể xác định phạm vi mà các giá trị đã lưu được hiển thị để truy xuất trong tương lai. Có ba phạm vi khác nhau có sẵn:

  • Phạm vi phiên bản - các giá trị đã lưu chỉ có sẵn cho một phiên bản cụ thể.
  • Phạm vi loại - các giá trị đã lưu có sẵn cho tất cả các phiên bản của một thuật toán cụ thể.
  • Phạm vi thiết bị - các giá trị đã lưu có sẵn cho tất cả các thuật toán bất kể loại của chúng.

Đây là cách sử dụng phạm vi phiên bản có thể trông như thế nào.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[Parameter()]
public bool IsWriter { get; set; }


protected override void OnStart()
{   
    if(IsWriter)
    { 
        LocalStorage.SetString("Message",Message, LocalStorageScope.Instance);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        if(LocalStorage.GetString("Message") != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Lưu ý rằng chúng ta đã chỉ định rõ ràng phạm vi trong phương thức SetString().

Chúng ta có thể thêm nhiều phiên bản của cBot này và cấu hình chúng để một phiên bản ghi vào bộ nhớ cục bộ trong khi phiên bản khác truy xuất thông tin. Trong trường hợp này, việc đọc thông tin sẽ không thể thực hiện được. Tuy nhiên, nếu chỉ một phiên bản được thiết lập để thực hiện cả hai thao tác ghi và đọc, cBot sẽ hoạt động như dự định.

Đây là một ví dụ về việc sử dụng phạm vi kiểu.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
protected override void OnStart()
{   
    if(IsWriter)
    {             
        LocalStorage.SetString("Message",Message, LocalStorageScope.Type);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        if(LocalStorage.GetString("Message", LocalStorageScope.Type) != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Nếu chúng ta tạo hai phiên bản của bot này và thiết lập chúng sao cho một phiên bản ghi vào bộ nhớ cục bộ và phiên bản khác đọc giá trị đã lưu, mọi thứ sẽ hoạt động mà không gây ra bất kỳ lỗi nào.

Cuối cùng nhưng không kém phần quan trọng, phạm vi thiết bị cho phép trao đổi thông tin giữa các thuật toán khác nhau. Đây là một ví dụ về việc sử dụng loại phạm vi này.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
protected override void OnStart()
{   
    if(IsWriter)
    {             
        LocalStorage.SetString("Message",Message, LocalStorageScope.Device);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        if(LocalStorage.GetString("Message", LocalStorageScope.Device) != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Chúng ta có thể xây dựng một số cBot đều sử dụng cùng một mã. Nếu chúng ta thiết lập chúng đúng cách, một cBot có thể lưu thông tin vào bộ nhớ cục bộ trong khi cBot khác truy xuất nó. Miễn là phạm vi bằng LocalStorageScope.Device, hệ thống của chúng ta sẽ hoạt động như dự định.

Sử dụng các phương thức Flush()Reload()

Nếu bạn muốn chia sẻ thông tin giữa nhiều phiên bản của cTrader, hãy gọi các phương thức Flush()Reload().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
protected override void OnStart()
{   
    if(IsWriter)
    {             
        LocalStorage.SetString("Message",Message, LocalStorageScope.Device);
        LocalStorage.Flush(LocalStorageScope.Device);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        LocalStorage.Reload(LocalStorageScope.Device);
        if(LocalStorage.GetString("Message", LocalStorageScope.Device) != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Nếu chúng ta xây dựng một số cBot với mã này và tiến hành thử nghiệm để chia sẻ thông tin giữa các phiên bản khác nhau của cTrader, chúng ta sẽ thấy rằng các giá trị đã lưu của chúng ta được duy trì như dự định.