Bỏ qua

Lấy dữ liệu biểu tượng

Lấy và diễn giải dữ liệu biểu tượng (ví dụ: giá mở và đóng của tất cả các thanh trong một khoảng thời gian cụ thể) là điều cần thiết trong bất kỳ ứng dụng nào có bất kỳ chức năng nào sau đây:

  • Biểu đồ – để xây dựng biểu đồ thanh hoặc đường, bạn cần biết cả dữ liệu thanh và giá lịch sử và thời gian thực.
  • Thống kê thị trường – nếu bạn muốn hiển thị thống kê thị trường (chẳng hạn như thay đổi giá hàng ngày cho các biểu tượng riêng lẻ), bạn phải lấy cả giá lịch sử và thời gian thực.
  • Replays – trong ứng dụng của bạn, bạn có thể cho phép các nhà giao dịch quay lại một khoảng thời gian trước đó và giao dịch trên dữ liệu lịch sử. Để làm điều đó, bạn sẽ cần lấy và xử lý dữ liệu thanh và tick trong quá khứ.

Trong hướng dẫn này, chúng tôi sẽ chỉ ra cách bạn có thể lấy và xử lý dữ liệu thanh và tick lịch sử và thời gian thực, và các báo giá độ sâu thời gian thực.

Lưu ý rằng hướng dẫn chỉ cung cấp một đoạn mã để lấy dữ liệu thanh lịch sử. Vì logic cốt lõi vẫn giữ nguyên bất kể hành động bạn đang thực hiện, bạn có thể điều chỉnh đoạn mã này để lấy các loại dữ liệu khác.

Hoạt động với JSON

Khi hoạt động với JSON, bạn vẫn có thể tái sử dụng mã từ hướng dẫn này; tuy nhiên, bạn sẽ cần điều chỉnh nó một chút tùy thuộc vào cách tiếp cận của bạn đối với tuần tự hóa và giải tuần tự hóa.

Lấy dữ liệu thanh lịch sử

Để nhận dữ liệu thanh lịch sử, hãy thực hiện các hành động sau:

  • Khởi tạo một đối tượng đại diện cho tin nhắn ProtoOAGetTrendbarsReq.
  • Điền các thuộc tính của đối tượng với ctidTraderAccountId, symbolId, ProtoOATrendbarPeriod, count của trendbars để trả về và các dấu thời gian Unix toTimestampfromTimestamp.

Hạn chế về Timestamp

Lưu ý rằng có một số hạn chế về khoảng cách tối đa có thể giữa toTimestampfromTimestamp. Những hạn chế này phụ thuộc vào ProtoOATrendPeriod được chỉ định. Để biết thêm thông tin, nhấp vào đây.

  • Gửi tin nhắn mới tạo và nhận phản hồi của loại ProtoOAGetTrendbarsRes. Truy cập trường trendbar của nó để đạt được danh sách các thanh xu hướng.
  • Chuyển đổi dữ liệu từ định dạng tương đối sang giá thực tế của biểu tượng. Để làm điều này, trước tiên, hãy lấy giá thấp của một thanh xu hướng và chia nó cho 100000. Sau đó, làm tròn kết quả đến số chữ số của biểu tượng (ví dụ: hai số sau dấu phân cách). Để đạt được giá cao, giá mở và giá đóng của một thanh xu hướng, hãy thêm delta của thanh xu hướng cho mỗi giá này vào giá thấp của thanh xu hướng. Sau đó, chia mỗi số cho 100000 và làm tròn kết quả đến số chữ số của biểu tượng.

Bạn có thể hoàn thành các hành động này bằng cách tái sử dụng 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
private static async void TrendbarRequest(ProtoOATrendbarPeriod period, int accountId, int symbolId, int days)
{
    Console.WriteLine("Sending ProtoOAGetTrendbarsReq...");

    var request = new ProtoOAGetTrendbarsReq
    {
        CtidTraderAccountId = accountId,
        SymbolId = symbolId,
        Period = period,
        FromTimestamp = DateTimeOffset.UtcNow.AddDays(-days).ToUnixTimeMilliseconds(),
        ToTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
    };

    Console.WriteLine($"FromTimestamp: {request.FromTimestamp} | ToTimestamp: {request.ToTimestamp}");

    await _client.SendMessage(request);
}

public static double GetPriceFromRelative(ProtoOASymbol symbol, long relative) => Math.Round(relative / 100000.0, symbol.Digits);

private List<Trendbar> OnHistoricalTrendbarsReceived(ProtoOAGetTrendbarsRes message) 
{
    var trendbars = message.Trendbar;

    var data = new List<Trendbar>();

    foreach (var trendbar in trendbars) 
    {
        data.Add(new Trendbar
        {
            Low = GetPriceFromRelative(symbol, trendbar.Low),
            High = GetPriceFromRelative(symbol, trendbar.Low + (int)trendbar.DeltaHigh),
            Open = GetPriceFromRelative(symbol, trendbar.Low + (int)trendbar.DeltaOpen),
            Close = GetPriceFromRelative(symbol, trendbar.Low + (int)trendbar.DeltaClose),
        }
        );
    }

    return data;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def sendProtoOAGetTrendbarsReq(ctidTraderAccountId, weeks, period, symbolId, clientMsgId = None):
    request = ProtoOAGetTrendbarsReq()
    request.ctidTraderAccountId = ctidTraderAccountId
    request.period = ProtoOATrendbarPeriod.Value(period)
    request.fromTimestamp = int(calendar.timegm((datetime.datetime.utcnow() - datetime.timedelta(weeks=int(weeks))).utctimetuple())) * 1000
    request.toTimestamp = int(calendar.timegm(datetime.datetime.utcnow().utctimetuple())) * 1000
    request.symbolId = int(symbolId)
    deferred = client.send(request, clientMsgId = clientMsgId)

def getPriceFromRelative(symbol, relative): round(relative / 100000.0, symbol.digits)

def onHistoricalTrendbarsReceived(message):

    trendbars = message.trendbars

    data = []

    for trendbar in trenbars:
        data.append(Trendbar(low=getPriceFromRelative(symbol, trendbar.low), high=getPriceFromRelative(symbol, trendbar.low + int(trendbar.deltaHigh)), open=getPriceFromRelative(symbol, trendbar.low + int(trendbar.deltaHigh)), close=getPriceFromRelative(symbol, trendbar.low +int(trendbar.deltaClose))))

    return data

Đạt được dữ liệu tick lịch sử

Để nhận dữ liệu tick lịch sử, thực hiện các hành động sau:

  • Khởi tạo một đối tượng đại diện cho tin nhắn ProtoOAGetTickDataReq.
  • Điền các thuộc tính của đối tượng với ctidTraderAccountId, symbolId, loại báo giá type cũng như fromTimestamptoTimestamp được yêu cầu.

Hạn chế về Timestamp

Không thể yêu cầu dữ liệu tick lịch sử cho một khoảng thời gian lớn hơn một tuần. Do đó, sự khác biệt giữa toTimestampfromTimestamp được chỉ định không được lớn hơn 604800000.

  • Gửi tin nhắn mới tạo và nhận phản hồi của loại ProtoOAGetTickDataRes. Truy cập trường tickData của nó để đạt được danh sách các phần tử thuộc loại ProtoOATickData.
  • Chuyển đổi dữ liệu từ định dạng tương đối sang giá thực tế của biểu tượng. Để làm điều này, chia mỗi tick cho 100000 và làm tròn kết quả đến số chữ số của biểu tượng.

Yêu cầu một số lượng lớn các tick

Có một giới hạn về số lượng tick có thể được trả về trong một tin nhắn ProtoOAGetTickDataRes. Nếu giới hạn này bị vượt quá (ví dụ: có một số lượng đáng kể các tick trong khoảng thời gian được chỉ định), tin nhắn ProtoOAGetTickDataRes sẽ chỉ bao gồm X tick đầu tiên, trong đó X là một số nhỏ hơn giới hạn tick. Giới hạn chính xác phụ thuộc vào cấu hình của backend cTrader.

Để kiểm tra xem có nhiều tick hơn những gì đã được trả về trong tin nhắn nhận được hay không, hãy sử dụng cờ hasMore.

Đạt được dữ liệu thanh trực tiếp

Để nhận các thanh trực tiếp, thực hiện các hành động sau:

  • Khởi tạo một biến đại diện cho tin nhắn ProtoOAGetTrendbarsReq.
  • Điền các thuộc tính của đối tượng với ctidTraderAccountId, symbolId, ProtoOATrendbarPeriod, số lượng count của các thanh xu hướng để trả về, toTimestampfromTimestamp Unix.

Hạn chế về Timestamp

Có một số hạn chế về khoảng cách tối đa có thể giữa toTimestampfromTimestamp. Những hạn chế này phụ thuộc vào ProtoOATrendPeriod được chỉ định. Để biết thêm thông tin, nhấp vào đây.

  • Gửi tin nhắn mới tạo và nhận phản hồi của loại ProtoOAGetTrendbarsRes. Truy cập trường trendbar của nó để đạt được danh sách các thanh xu hướng.

  • Chuyển đổi dữ liệu từ định dạng tương đối sang giá thực tế của biểu tượng. Để làm điều này, trước tiên hãy lấy giá thấp của một thanh xu hướng và chia nó cho 100000. Sau đó, làm tròn kết quả đến số chữ số của biểu tượng (ví dụ: hai số sau dấu phân cách). Để đạt được giá cao, giá mở và giá đóng của một thanh xu hướng, hãy thêm delta của thanh xu hướng cho mỗi giá này vào giá thấp của thanh xu hướng. Sau đó, chia mỗi số cho 100000 và làm tròn kết quả đến số chữ số của biểu tượng.

  • Khởi tạo một đối tượng đại diện cho tin nhắn ProtoOASubscribeLiveTrendbarReq.

  • Điền các thuộc tính của đối tượng với ctidTraderAccountId, ProtoOATrendbarPeriodsymbolId.

  • Làm tương tự cho một đối tượng đại diện cho tin nhắn ProtoOASubscribeSpotsReq.

  • Gửi tin nhắn ProtoOASubscribeSpotsReq và tin nhắn ProtoOASubscribeLiveTrendbarReq theo thứ tự đó và nhận phản hồi của loại ProtoOASubscribeSpotsResloại ProtoOASubscribeLiveTrenbarsRes. Tại thời điểm này, bạn đã đăng ký nhận dữ liệu thanh trực tiếp và bạn sẽ nhận được các tin nhắn thuộc loại ProtoOASpotEvent.

Đăng ký nhận thanh xu hướng trực tiếp

Để đăng ký thành công nhận thanh xu hướng trực tiếp, trước tiên cần đăng ký nhận sự kiện spot.

  • Khi bạn nhận được một tin nhắn ProtoOASpotEvent mới, hãy sử dụng trường trendbar của nó để lấy dữ liệu cho thanh đóng cuối cùng.
  • Chuyển đổi dữ liệu từ định dạng tương đối sang giá thực tế của biểu tượng. Để làm điều này, trước tiên, hãy lấy giá thấp của một thanh xu hướng và chia nó cho 100000. Sau đó, làm tròn kết quả đến số chữ số của biểu tượng (ví dụ: hai số sau dấu phân cách). Để đạt được giá cao, giá mở và giá đóng của một thanh xu hướng, hãy thêm delta của thanh xu hướng cho mỗi giá này vào giá thấp của thanh xu hướng. Sau đó, chia mỗi số cho 100000 và làm tròn kết quả đến số chữ số của biểu tượng.

Để hủy đăng ký nhận dữ liệu thanh xu hướng trực tiếp, bạn luôn có thể gửi tin nhắn ProtoOAUnsubscribeLiveTrendbarsReq chứa symbolId, periodctidTraderAccountId của bạn. Nếu yêu cầu của bạn thành công, bạn sẽ nhận được phản hồi của loại ProtoOAUnsubscribeLiveTrenbarRes. Đăng ký nhận sự kiện spot của bạn vẫn sẽ được giữ nguyên.

Đạt được báo giá trực tiếp

Để nhận báo giá bid và ask trực tiếp cho một biểu tượng, thực hiện các hành động sau:

  • Khởi tạo một đối tượng đại diện cho tin nhắn ProtoOASubscribeSpotsReq.
  • Điền các thuộc tính của đối tượng với ctidTraderAccountId, symbolId và, tùy chọn, bool subscribeToSpotTimestamp.
  • Gửi tin nhắn mới tạo và nhận phản hồi của loại ProtoOASubscribeSpotsRes. Tại thời điểm này, bạn đã đăng ký nhận dữ liệu báo giá trực tiếp và bạn sẽ nhận được các tin nhắn thuộc loại ProtoOASpotEvent.
  • Khi bạn nhận được một tin nhắn ProtoOASpotEvent mới, hãy truy cập các trường bidask của nó để đạt được các báo giá mới nhất. Lưu ý rằng bạn vẫn phải chuyển đổi dữ liệu thành giá trị giá thực tế bằng cách chia nó cho 100000 và làm tròn nó đến số chữ số của biểu tượng.

Trường bid và ask

Vì các trường bidask là tùy chọn, bạn có thể không nhất thiết phải thấy các tin nhắn ProtoOASpotEvent trong đó cả hai được chỉ định.

Để hủy đăng ký nhận dữ liệu báo giá, bạn luôn có thể gửi tin nhắn ProtoOAUnsubscribeSpotsReq chứa symbolIdctidTraderAccountId của bạn. Nếu yêu cầu của bạn thành công, bạn sẽ nhận được phản hồi của loại ProtoOAUnsubscribeSpotsRes. Tại thời điểm này, bạn sẽ ngừng nhận các sự kiện spot.

Báo giá độ sâu

Cuối cùng nhưng không kém phần quan trọng, bạn cũng có thể nhận báo giá độ sâu hoặc Level II trực tiếp cho một biểu tượng. Để làm điều này, thực hiện các hành động sau.

Bạn có thể đăng ký và nhận báo giá độ sâu hoặc Level II trực tiếp cho một biểu tượng từ API.

  • Khởi tạo một đối tượng đại diện cho tin nhắn ProtoOASubscribeDepthQuotesReq.
  • Điền các thuộc tính của đối tượng với ctidTraderAccountIdsymbolId.
  • Gửi tin nhắn mới tạo và nhận phản hồi của loại ProtoOASubscribeDepthQuotesRes. Tại thời điểm này, bạn đã đăng ký nhận báo giá độ sâu, nghĩa là bạn sẽ bắt đầu nhận các tin nhắn loại ProtoOADepthEvent.
  • Khi bạn nhận được một tin nhắn ProtoOADepthEvent mới, bạn sẽ cần sử dụng các trường newQuotesdeletedQuotes của nó để lấy dữ liệu độ sâu mới nhất. Bạn cũng sẽ cần chuyển đổi dữ liệu thành giá trị giá thực tế bằng cách chia nó cho 100000 và làm tròn kết quả đến số chữ số của biểu tượng. Bạn cũng sẽ cần chuyển đổi kích thước báo giá độ sâu thành đơn vị bằng cách chia nó cho 100.

Để hủy đăng ký nhận sự kiện độ sâu, bạn luôn có thể sử dụng tin nhắn ProtoOAUnsubscribeDepthQuotesReq trong khi chỉ định symbolIdctidTraderAccountId. Bạn sẽ nhận được một tin nhắn thuộc loại ProtoOAUnsubscribeDepthQuotesRes; sau đó, bạn sẽ ngừng nhận các sự kiện độ sâu.