Gửi và nhận tin nhắn¶
Giới thiệu ¶
Bài viết này đóng vai trò như một phần giới thiệu về việc sử dụng FIX API cho bất kỳ ai quan tâm đến việc tương tác với Spotware cServer bằng FIX.
Trong bài viết này, chúng tôi sẽ sử dụng một ví dụ bằng C# để mô tả chi tiết các nguyên tắc về cách xây dựng một tin nhắn FIX, gửi nó đến máy chủ và nhận phản hồi. Ví dụ này không phải là một ứng dụng hoàn hảo và được giữ đơn giản nhất có thể để cho phép các lập trình viên dễ dàng hiểu khái niệm sử dụng tin nhắn FIX API.
Để thiết lập và duy trì giao tiếp đúng với máy chủ và xử lý phản hồi đúng cách, cần có thêm chức năng, điều này đã được bỏ qua vì mục đích đơn giản và rõ ràng. Chúng tôi sẽ đề cập đến những chủ đề này trong các bài viết trong tương lai.
Mẫu mã ¶
Bạn có thể tìm thấy mẫu mã được thảo luận trong bài viết này trên kho lưu trữ GitHub của chúng tôi
Tổng quan về giao tiếp FIX ¶
Một tin nhắn FIX chỉ là một chuỗi bao gồm các bộ thẻ số và giá trị được phân tách bằng dấu gạch đứng (|). Mỗi thẻ đại diện cho một trường khác nhau mà một tập hợp giá trị nhất định được cho phép. Dưới đây bạn có thể thấy một mẫu tin nhắn FIX yêu cầu xác thực từ máy chủ.
8=FIX.4.4|9=126|35=A|49=theBroker.12345|56=CSERVER|34=1|52=20170117- 08:03:04|57=TRADE|50=any_string|98=0|108=30|141=Y|553=12345|554=passw0rd!|10=131|
Như bạn có thể thấy, mẫu lặp lại được tìm thấy trong mỗi tin nhắn FIX là:
Tag=Value|Tag=Value|Tag=Value|...
Tùy thuộc vào mục đích của mỗi tin nhắn, một bộ thẻ và giá trị khác nhau được yêu cầu mỗi lần. Các thẻ và giá trị cần thiết cho mỗi tin nhắn được mô tả chi tiết trong Quy tắc Tham gia của cTrader FIX engine (luôn kiểm tra quy tắc tham gia mới nhất).
Tương tự, các phản hồi được gửi lại từ máy chủ. Dưới đây bạn có thể thấy phản hồi của máy chủ cho tin nhắn trên.
8=FIX.4.4|9=106|35=A|34=1|49=CSERVER|50=TRADE|52=20170117- 08:03:04.509|56=theBroker.12345|57=any_string|98=0|108=30|141=Y|10=066|
Các bước liên quan đến quá trình giao tiếp với máy chủ FIX như sau:
-
Xây dựng một tin nhắn FIX
-
Truyền một tin nhắn FIX
-
Nhận một tin nhắn FIX
-
Phân tích cú pháp một tin nhắn FIX
Một tin nhắn FIX thô không phải là một định dạng dễ đọc vì nó được thiết kế với mục đích hiệu quả hơn là dễ hiểu. Do đó, đối với mỗi ứng dụng phần mềm sẽ luôn có một quá trình dịch thông tin được cung cấp thành tin nhắn FIX tương ứng.
Trong ứng dụng mẫu C# của chúng tôi, chúng tôi đã tạo một lớp để xử lý việc xây dựng tin nhắn cũng như các hàm để tạo tin nhắn FIX dựa trên thông tin liên quan.
Sau khi tin nhắn đã được xây dựng, chúng được truyền giữa máy chủ và máy khách qua internet thông qua các socket mạng. Khi tin nhắn được nhận, chúng cần được phân tích cú pháp để được trình bày ở định dạng có thể đọc được.
Trong bài viết này, chúng tôi sẽ đề cập đến quá trình xây dựng, truyền và nhận phản hồi. Chúng tôi sẽ đề cập đến việc phân tích cú pháp trong một bài viết trong tương lai.
Xây dựng một tin nhắn FIX ¶
Cấu trúc tin nhắn ¶
Trong ứng dụng mẫu của chúng tôi, chúng tôi đã tạo một lớp chịu trách nhiệm tạo tin nhắn FIX. Lớp này được gọi là MessageConstructor và có thể được tìm thấy trong dự án FIX API Library.
MessageConstructor được khởi tạo với các tham số sau:
-
Host(*)– địa chỉ nơi cServer của chúng tôi được đặt. -
Username(*)– số tài khoản -
Password(*)– mật khẩu -
SenderCompID(*)– được cung cấp trong biểu mẫu FIX API của cTrader. Nó có định dạng -
SenderSubID*– là phần thứ hai của SenderCompID -
TargetCompID(*)– được cung cấp trong biểu mẫu FIX API của cTrader (thường là cServer)
Bạn có thể tìm thấy thông tin này trong biểu mẫu FIX API cTrader của bạn.
Sau khi chúng ta đã khởi tạo một MessageConstructor thì chúng ta đã sẵn sàng để xây dựng tin nhắn FIX API.
Tất cả các tin nhắn đều được xây dựng theo cách tương tự. Dưới đây là một mẫu mã xây dựng tin nhắn Đăng nhập.
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 | |
Bạn có thể thấy rằng trước tiên chúng ta xây dựng phần thân, sau đó chúng ta truyền nó vào hàm tiêu đề và cuối cùng chúng ta truyền cả hai phần vào hàm đuôi. Ba phần này được mô tả chi tiết dưới đây.
Quá trình xây dựng tin nhắn chỉ là việc thêm các thẻ, giá trị và dấu phân cách cần thiết vào một chuỗi.
Thân ¶
Đầu tiên chúng ta sẽ bắt đầu bằng cách mô tả việc xây dựng thân, vì thân của tin nhắn cần được tạo trước. Chúng ta có thể thấy một ví dụ ở trên (tạo tin nhắn Đăng nhập).
Chúng ta bắt đầu bằng cách khởi tạo một lớp StringBuilder và chúng ta thêm các thẻ từng cái một dựa trên đầu vào của hàm. Dựa trên loại tin nhắn, thân phải được cấu tạo từ các bộ thẻ khác nhau, một số là bắt buộc và một số khác là tùy chọn.
Bạn có thể tìm thấy cấu trúc của từng tin nhắn trong Quy tắc Tham gia của chúng tôi (/FIX).
Sau đó chúng ta tạo một tiêu đề cho tin nhắn Đăng nhập và thêm vào đó thân của tin nhắn. Cuối cùng, sử dụng chuỗi headerAndBody chúng ta tạo ra đuôi. Tiếp theo, chúng ta sẽ xem cách chúng ta xây dựng một tiêu đề và một đuôi.
Tiêu đề ¶
Tiêu đề là phần đầu tiên của tin nhắn FIX và nó bao gồm các trường sau (giống nhau cho tất cả các tin nhắn):
BeginString– chuỗi bắt đầu xác định phiên bản giao thức FIX và trong trường hợp của chúng ta được cố định là FIX4.4.BodyLength– độ dài thân nêu rõ độ dài của tin nhắn tính bằng ký tự, không bao gồm các trườngBeginString,BodyLengthvà đuôi.MsgType– trong trường này chúng ta xác định loại tin nhắn, để người nhận biết cách phân tích cú pháp thân.SenderCompID– ở đây chúng ta đặtSenderCompID.TargetCompID– đây là đích của tin nhắn của chúng ta. Trong trường hợp của chúng ta, nó sẽ luôn là cServer.SenderSubID– đăng nhập của nhà giao dịch.MsgSeqNum– đây là số thứ tự của tin nhắn. Nó cần được tăng lên cho mỗi tin nhắn được gửi trong cùng một phiên.Sending Time– thời gian truyền tin nhắn.
Dưới đây bạn có thể thấy hàm ConstructHeader, chịu trách nhiệm xây dựng các tiê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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
Đuôi ¶
Đuôi chỉ là một thẻ chứa tổng kiểm tra của phần còn lại của tin nhắn.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Tin nhắn hệ thống ¶
Mẫu của chúng tôi chứa các hàm trả về các tin nhắn hệ thống sau:
- Nhịp tim:
MessageConstructor.HeartbeatMessage() - Yêu cầu kiểm tra:
MessageConstructor.TestRequestMessage() - Đăng nhập:
MessageConstructor.LogonMessage() - Đăng xuất:
MessageConstructor.LogoutMessage() - Yêu cầu gửi lại:
MessageConstructor.ResendMessage() - Từ chối:
MessageConstructor.RejectMessage() - Đặt lại chuỗi:
MessageConstructor.SequenceResetMessage()
Tin nhắn ứng dụng ¶
Mẫu của chúng tôi chứa các hàm trả về các tin nhắn hệ thống sau:
- Yêu cầu dữ liệu thị trường:
MessageConstructor.HeartbeatMessage() - Tổng quan thị trường/làm mới toàn bộ:
MessageConstructor.MarketDataSnapshotMessage() - Làm mới dữ liệu thị trường tăng dần:
MessageConstructor.MarketDataIncrementalRefreshMessage() - Lệnh đơn mới:
MessageConstructor.NewOrderSingleMessage() - Yêu cầu trạng thái lệnh:
MessageConstructor.OrderStatusRequest() - Báo cáo thực hiện:
MessageConstructor.ExecutionReport() - Từ chối thông điệp kinh doanh:
MessageConstructor.BusinessMessageReject() - Yêu cầu vị thế:
MessageConstructor.RequestForPositions() - Báo cáo vị thế:
MessageConstructor.PositionReport()
Gửi tin nhắn và nhận phản hồi ¶
Để gửi một tin nhắn FIX đến cServer, trước tiên bạn cần thiết lập kết nối với máy chủ. Bạn có thể làm điều này bằng cách tạo một TcpClient. Trong trường hợp của chúng tôi, chúng tôi tạo hai máy khách, vì tin nhắn báo giá và tin nhắn giao dịch được xử lý bởi các cổng khác nhau trên máy chủ.
Sau đó, chúng ta cần lấy hai luồng mà tin nhắn sẽ được gửi. Quá trình này diễn ra trong hàm tạo của biểu mẫu như được hiển thị dưới đây:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Trong hàm tạo, chúng tôi cũng khởi tạo một lớp MessageConstructor sẽ được sử dụng để tạo tin nhắn.
Tiếp theo, để gửi tin nhắn, chúng tôi đã tạo hai hàm khác nhau, SendPriceMessage() và SendTradeMessage(). Mỗi hàm lấy tin nhắn FIX làm đầu vào và sau đó gọi hàm SendMessage() với tin nhắn và luồng tương ứng làm đầu vào.
Hàm SendMessage() hoạt động như sau:
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 | |
Các bước chi tiết như sau:
- Mã hóa tin nhắn thành một mảng byte.
- Ghi mảng byte vào luồng.
- Đọc phản hồi từ luồng.
- Tăng số thứ tự tin nhắn.
- Mã hóa tin nhắn thành một chuỗi.
Hàm này nên trả về tin nhắn FIX được gửi bởi máy chủ.
Như bạn có thể đoán, bạn không thể hiển thị một tin nhắn FIX thô cho người dùng, vì vậy cần phát triển thêm một bước phân tích c
Kết luận ¶
Ứng dụng này là một minh họa ngắn gọn về cách giao tiếp với cServer bằng các thông điệp FIX. Đây chỉ là một ví dụ minh họa các khái niệm của Giao thức FIX và hoàn toàn không phải là một công cụ FIX đầy đủ. Nếu bạn muốn tránh việc tự xây dựng công cụ FIX của riêng mình, bạn có thể cân nhắc sử dụng một trong các công cụ FIX của bên thứ ba có sẵn.
Ghi chú
Bài viết này được cập nhật vào ngày 03/02/2017 và được phát triển với sự cân nhắc cho công cụ FIX của cTrader, Quy tắc Tham gia phiên bản 2.9.1.