Bỏ qua

Truy cập mạng

Hướng dẫn này xác định cách bạn có thể tạo các thuật toán có thể truy cập Internet. Dưới đây là bản tóm tắt một phút về tính năng API này.

Truy cập mạng trong một phút!

  • Các giải pháp thuật toán của bạn có thể lấy thông tin từ các trang web tin tức giao dịch hoặc các API web liên quan đến Forex. Sử dụng tính năng này để đảm bảo rằng cBot, plugin và chỉ báo của bạn phản ứng với các sự kiện và thông tin thời sự quan trọng.
  • Bằng cách sử dụng các phương thức trong các không gian tên System.Text.JsonSystem.Text.Json.Serialization, bạn có thể nhanh chóng tuần tự hóa hoặc giải tuần tự hóa các đối tượng thành và từ các tệp JSON, cho phép cBot dễ dàng sử dụng các điểm cuối và xử lý thông tin có giá trị.
  • Giao thức WebSocket cho phép nhận dữ liệu từ một dịch vụ theo thời gian thực thay vì phải thực hiện một yêu cầu HTTP mỗi lần. Sử dụng websocket để tích hợp mượt mà các thuật toán của bạn với các tài nguyên web. Lớp WebSocketClient chứa tất cả các phương thức và tham số cần thiết để sử dụng kết nối websocket.
  • Khi sử dụng websocket, bạn có thể gửi và nhận chuỗi và dữ liệu byte thô. Làm việc với các cấu trúc dữ liệu khác nhau và tuần tự hóa chúng thành byte để sử dụng các dịch vụ bên thứ ba có giá trị.
  • AccessRights.None là đủ cho các chức năng mạng.

HTTP

Giao diện Http mới chứa một số phương thức mà khi được triển khai, sẽ cho phép cBots và các loại thuật toán khác truy cập Internet. Để minh họa, hãy xem ví dụ sau:

  • HttpResponse Http.Get(string uri). Thực hiện yêu cầu GET đến URI được chỉ định trong chuỗi uri đã truyền vào và trả về một đối tượng HttpsResponse chứa kết quả của yêu cầu này.

Lớp HttpsRequest cho phép thực hiện các yêu cầu phức tạp hơn bao gồm cả yêu cầu POST. Để thực hiện các yêu cầu này, hãy đặt thuộc tính HttpsRequest.Method thành một trong các giá trị của enum HttpMethod như HttpMethod.Put hoặc HttpMethod.Patch.

Đến lượt nó, thuộc tính HttpsRequest.Uri chứa URI mà yêu cầu được gửi đến trong khi thuộc tính HttpsRequest.Body có thể được sử dụng để đặt nội dung yêu cầu. Xem bên dưới để biết ví dụ về cách bạn có thể sử dụng đối tượng HttpsRequest.

  • HttpResponse Http.Send(HttpRequest request). Thực hiện yêu cầu đến URI được chỉ định làm giá trị của thuộc tính request.Uri của đối tượng HttpsRequest được truyền vào phương thức này. Sau đó, trả về một đối tượng HttpsResponse chứa kết quả của yêu cầu này. Loại yêu cầu được đặt làm giá trị của thuộc tính equest.Method.

Truy cập mạng trong backtest và tối ưu hóa

Tất cả các phương thức trong giao diện Http hoạt động như dự định trong backtest và tối ưu hóa. Lưu ý rằng, khi truy cập tài nguyên web trong backtest hoặc tối ưu hóa, phiên bản cập nhật của tài nguyên này sẽ được yêu cầu thay vì phiên bản lịch sử.

Tạo cBots ví dụ

Thực hiện yêu cầu GET

Chúng ta sẽ tạo một cBot đơn giản thực hiện các hành động sau:

  • Gửi yêu cầu GET và truy cập tệp JSON thông qua API tại https://forexApiExample.com/v1/exchangerate (lưu ý rằng API này hoàn toàn giả).
  • Nếu phản hồi GET thành công, cBot sẽ giải tuần tự hóa nội dung phản hồi thành một đối tượng của lớp SymbolPrice tùy chỉnh (chúng tôi đã tạo lớp này cho mục đích minh họa).
  • Đặt lệnh giới hạn bán cho một biểu tượng ở mức giá cao hơn một chút so với giá được chỉ định trong API.

Lưu ý rằng cBot này hoàn toàn được tạo ra. Mặc dù mã sẽ được biên dịch, nhưng nó sẽ không thực hiện bất kỳ hành động có ý nghĩa nào.

Cách tuần tự hóa hoặc giải tuần tự hóa chuỗi từ tệp JSON

Mã của cBot của chúng ta bao gồm hai câu lệnh using quan trọng, cụ thể là System.Text.JsonSystem.Text.Json.Serialization. Các không gian tên này chứa một số phương thức cho phép dễ dàng tuần tự hóa và giải tuần tự hóa chuỗi từ tệp JSON như JsonSerializer.Deserialize<T>().

Đây là mã của cBot ví dụ của chúng ta:

 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
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;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NetworkAccessTest : Robot
    {

        protected override void OnStart()
        {

            var responseToGet = Http.Get("https://forexApiExample.com/v1/exchangerate");

            if (responseToGet.IsSuccessful)
            {
                var tradedSymbol = JsonSerializer.Deserialize<SymbolPrice>(responseToGet.Body);
                var result = PlaceLimitOrder(TradeType.Sell, tradedSymbol.SymbolName, 10000, tradedSymbol.ConversionRate + 0.15);

            }
        }
    }

    public class SymbolPrice
    {
        public string SymbolName { get; set; }
        public double ConversionRate { get; set; }
    }
}

Nếu cBot này truy cập một API thực, nó sẽ thực hiện thành công.

Thực hiện yêu cầu POST

Chúng ta cũng có thể tạo một cBot nâng cao hơn đạt được các mục tiêu sau:

  • Gửi yêu cầu POST đến cùng API giả tại https://anotherForexApiExample.com/commodities/v1/getaccesstoken. Điều này được thực hiện để lấy mã truy cập cho API này.
  • Lưu trữ mã thông báo từ nội dung phản hồi trong biến token.
  • Thực hiện yêu cầu GET đến cùng API với giá trị của biến token được truyền dưới dạng tham số truy vấn trong URI (https://anotherForexApiExample.com/commodities/v1/getprices).
  • Sử dụng tuần tự hóa JSON (đã thảo luận ở trên), đặt lệnh dừng để mua ở mức giá thấp hơn một chút so với giá nhận được từ API.

Một lần nữa, lưu ý rằng cBot này sẽ không thực hiện bất kỳ hành động có ý nghĩa nào khi được biên dịch. Nó chỉ tồn tại cho mục đích ví dụ.

 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
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;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NetworkAccessTestTwo : Robot
    {

        protected override void OnStart()
        {
            var uriForAccessToken = new Uri("https://anotherForexApiExample.com/commodities/v1/getaccesstoken");

            var postRequest = new HttpRequest(uriForAccessToken);

            postRequest.Method = HttpMethod.Post;

            var responseToPost = Http.Send(postRequest);

            var token = responseToPost.Body;

            var response = Http.Get($"https://anotherForexApiExample.com/commodities/v1/getprices?token={token}");

            if (response.IsSuccessful)
            {
                var tradedSymbol = JsonSerializer.Deserialize<SymbolPrice>(response.Body);

                var result = PlaceStopOrder(TradeType.Buy, tradedSymbol.SymbolName, 10000, tradedSymbol.ConversionRate - 0.15);

            }
        }
    }

    public class SymbolPrice
    {
        public string SymbolName { get; set; }
        public double ConversionRate { get; set; }
    }
}

Máy khách WebSocket

API Algo cho phép bất kỳ ai sử dụng các dịch vụ và tài nguyên web khác nhau bằng kết nối websocket. So với giao thức HTTP được sử dụng trong tính năng truy cập mạng, giao thức WebSocket nhanh hơn và cho phép nhận dữ liệu trong thời gian thực.

Sử dụng máy khách WebSocket

Sử dụng máy khách WebSocket rất đơn giản:

  1. Chọn một dịch vụ có điểm cuối cho kết nối websocket
  2. Khởi tạo một đối tượng của lớp WebSocketClientOptions và chỉ định các tham số của nó để cấu hình máy khách của bạn.
  3. Khởi tạo một đối tượng của lớp WebSocketClient và truyền các tùy chọn đã tạo trước đó vào hàm tạo.
  4. Sử dụng phương thức Connect() để kết nối với tài nguyên bạn đã chọn và gửi dữ liệu thông qua phương thức Send().
  5. Sử dụng các trình xử lý sự kiện TextReceived()BinaryReceived() để đặt những gì thuật toán của bạn nên làm khi máy khách WebSocket nhận được dữ liệu mới.

Dưới đây, chúng ta sẽ tạo một cBot đơn giản kết nối với một dịch vụ tin tức kinh tế tưởng tượng thông qua websocket. Khi một tin tức mới được đăng về biểu tượng mà cBot hiện đang được gắn vào, thuật toán sẽ hiển thị một hộp thông báo chứa nội dung tin tức.

Ghi chú

cBot này chỉ dành cho mục đích ví dụ. Mặc dù nó được biên dịch thành công, nhưng nó không thực hiện bất kỳ hành động nào khi được gắn vào biểu đồ.

 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
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 ExampleWebSocketBot : Robot
    {

        private static WebSocketClientOptions _webSocketClientOptions = new WebSocketClientOptions 
        {
            KeepAliveInterval = new TimeSpan(0, 1, 30),
            UseDefaultCredentials = true,
        };
        private WebSocketClient _webSocketClient = new WebSocketClient(_webSocketClientOptions);
        private readonly Uri _targetUri = new Uri("ws://amazingnews.com:8000");

        protected override void OnStart()
        {
            _webSocketClient.Connect(_targetUri);
            _webSocketClient.Send("Hello");
            _webSocketClient.TextReceived += NewsReceived;
        }

        protected override void OnStop()
        {
            _webSocketClient.Close(WebSocketClientCloseStatus.NormalClosure);
        }

        private void NewsReceived(WebSocketClientTextReceivedEventArgs args) 
        {
            if (args.Text.Contains(SymbolName)) 
            {
                MessageBox.Show(args.Text, "News!", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
        }
    }
}

Như bạn có thể thấy, mã của chúng ta khá nhỏ gọn vì chúng ta có thể xử lý sự kiện WebSocketClient.TextReceived để hiển thị hộp thông báo. Lưu ý rằng cBot của chúng ta không chủ động yêu cầu thông tin từ các dịch vụ. Thay vào đó, nó phản ứng động với thông tin mới được cung cấp cho nó.

Cảnh báo

Khi máy khách websocket của bạn ngắt kết nối vì bất kỳ lý do nào (chẳng hạn như lỗi phía máy chủ dẫn đến vượt quá khoảng thời gian giữ kết nối), bạn sẽ cần gọi lại phương thức WebSocketClient.Connect(). Để xử lý các trường hợp như vậy theo chương trình, hãy sử dụng sự kiện WebSocketClient.Disconnected.

Lợi ích của WebSocket

Vì websocket cho phép phản ứng với dữ liệu mới từ web theo thời gian thực, nó hoàn hảo để tích hợp với các dịch vụ bên thứ ba có thể tự động thông báo cho các thuật toán của bạn về điều gì đó. Dưới đây là một vài ví dụ về các tài nguyên web mà bạn có thể sử dụng với máy khách WebSocket.

  • Lịch tin tức kinh tế. Khi một tin tức mới được phát hành, thuật toán của bạn có thể hiển thị một hộp thông báo với thông tin chính.
  • Dịch vụ AI tạo sinh. Khi một dịch vụ AI bắt đầu cung cấp phản hồi cho một lời nhắc, bạn có thể hiển thị kết quả từng từ một thay vì phải đợi phản hồi hoàn chỉnh.
  • Luồng giá cho tất cả các biểu tượng có tương quan với biểu tượng mà thuật toán được gắn vào. Khi giá được cập nhật, chúng được hiển thị ngay lập tức và chính xác cho người dùng thuật toán.
  • Một mạng xã hội tập trung vào giao dịch. Khi có tin nhắn mới được đăng về một biểu tượng cụ thể, thuật toán có thể hiển thị nội dung của chúng cho người dùng.

Nhìn chung, kết nối websocket mang lại những lợi ích sau so với HTTPS thông thường:

  • Kết nối WebSocket hiệu quả hơn. Bất kỳ yêu cầu HTTP nào cũng phải chứa dữ liệu bổ sung như tiêu đề. Với websocket, kết nối của bạn chỉ được thiết lập một lần, sau đó không cần phải gửi dữ liệu dư thừa.
  • Kết nối WebSocket cung cấp khả năng đồng thời được cải thiện. Không cần phải dừng các hoạt động của thuật toán cho đến khi bạn chờ phản hồi sau khi gửi yêu cầu HTTP. Với websocket, bạn có thể gửi và nhận dữ liệu bất cứ lúc nào và xử lý nó một cách bất đồng bộ.

Máy khách WebSocket cho phép tất cả các loại thuật toán tương tác động với các tài nguyên web; sự tương tác này nhanh hơn và hiệu quả hơn so với việc sử dụng HTTP. Sử dụng máy khách WebSocket để xây dựng các thuật toán mạnh mẽ tích hợp với các dịch vụ của bên thứ ba.

Truy cập mạng và thuộc tính AccessRights

Tóm lại, enum AccessRights xác định liệu các thuật toán có quyền truy cập vào dữ liệu bên ngoài cTrader như hệ thống tệp của máy tính cục bộ của bạn hay không. Bạn có thể tìm hiểu thêm trong hướng dẫn này.

Đặt AccessRights thành AccessRights.FullAccess cho phép các thuật toán thực hiện các hoạt động nâng cao (như lấy thông tin từ registry của Windows). Tuy nhiên, người dùng cuối có thể thấy việc cấp quyền truy cập đầy đủ cho cBot hoặc chỉ báo là rủi ro vì nó có thể dẫn đến rò rỉ dữ liệu.

Do đó, AccessRights.None thường là lựa chọn hợp lý nhất nếu bạn muốn chia sẻ sản phẩm thuật toán của mình với người khác. Tuy nhiên, ngay cả khi bạn chọn tùy chọn này, các sản phẩm cTrader của bạn vẫn có thể tự do truy cập web. Việc bổ sung chức năng truy cập mạng vào cTrader Algo API có nghĩa là cBot không còn yêu cầu thuộc tính AccessRights phải được đặt thành AccessRights.FullAccess để làm việc với các tài nguyên trên Internet.

Điều này mở rộng đáng kể cơ hội cho các nhà phát triển thuật toán khi lập trình các sản phẩm cTrader mà họ dự định phân phối cho các nhà giao dịch khác.

Tổng quan

Tóm lại, truy cập mạng là một tính năng mạnh mẽ cho phép mở rộng đáng kể số lượng hoạt động mà thuật toán của bạn có thể thực hiện mà không gây ra thêm rủi ro nào.