2
tập trung vào
319
Người theo dõi

Một cuộc thảo luận ngắn gọn về các chiến lược tạo lập thị trường tiền kỹ thuật số: thiết kế kiến trúc của chiến lược tiếp thị lan tỏa và triển khai nền tảng FMZ

Được tạo ra trong: 2025-07-24 11:03:59, cập nhật trên: 2025-07-28 13:06:13
comments   0
hits   622

⚠️ Thông báo quan trọng

Bài viết này trình bày một chiến lược tăng khối lượng giao dịch để tìm hiểu về khuôn khổ giao dịch, về cơ bản khác với chiến lược tạo lập thị trường chênh lệch giá truyền thống. Mục đích chính của chiến lược này là tăng khối lượng giao dịch bằng cách mua và bán ở cùng một mức giá, và nhận được chiết khấu tỷ giá hoặc chiết khấu ngang bằng, thay vì kiếm lợi nhuận thông qua chênh lệch giá.

Mã nguồn được cung cấp trong bài viết này chỉ là một khung tham chiếu và không có bất kỳ kinh nghiệm vận hành thời gian thực nào. Việc triển khai chiến lược trong bài viết này chỉ nhằm mục đích học tập và nghiên cứu kỹ thuật, chưa được kiểm chứng đầy đủ trong môi trường thị trường thực tế. Khi độc giả tham khảo nội dung bài viết này, vui lòng thực hiện kiểm chứng ngược và đánh giá rủi ro đầy đủ, và không nên sử dụng trực tiếp cho giao dịch thời gian thực.


Trên thị trường tiền kỹ thuật số, chiến lược tạo lập thị trường không chỉ là công cụ cải thiện thanh khoản thị trường và thúc đẩy giao dịch, mà còn là thành phần chủ chốt của nhiều chiến lược giao dịch định lượng. Các nhà tạo lập thị trường kiếm lợi nhuận trong các môi trường thị trường khác nhau bằng cách niêm yết giá mua và bán và cung cấp thanh khoản. Việc triển khai mã của các nhà tạo lập thị trường chuyên nghiệp thường cực kỳ phức tạp, bao gồm các chức năng nâng cao như tối ưu hóa độ trễ tần suất cao, hệ thống kiểm soát rủi ro phức tạp và chênh lệch giá đa sàn. Lần này, chúng ta sẽ tìm hiểu những ý tưởng cơ bản của chiến lược giao dịch ngược khối lượng cọ và cách triển khai một khuôn khổ học tập đơn giản trên nền tảng Inventor Quantitative (FMZ).

Nội dung chính của bài viết này được trích từ cuốn “Ý tưởng và Phương pháp Viết Chiến lược Tạo lập Thị trường” của tác giả gốc Zinan. Một số phần đã được tối ưu hóa và tái bản trên nền tảng fmz. Theo quan điểm hiện tại, một số phương pháp viết có thể đã lỗi thời, nhưng việc hiểu cấu trúc mã và những ý tưởng cơ bản của giao dịch ngược chiều vẫn rất hữu ích cho mọi người:

Khái niệm về chiến lược tạo lập thị trường

Chiến lược tạo lập thị trường (Market Makers) là việc các nhà giao dịch (nhà tạo lập thị trường) đặt lệnh mua và bán trên thị trường cùng lúc, qua đó cung cấp thanh khoản để duy trì sự ổn định của thị trường. Chiến lược này không chỉ giúp duy trì độ sâu thị trường mà còn cung cấp đối tác cho các nhà giao dịch khác. Bằng cách cung cấp báo giá mua và bán ở các khoảng giá khác nhau, nhà tạo lập thị trường thu được lợi nhuận từ biến động giá.

Vai trò của các nhà tạo lập thị trường rất quan trọng đối với thị trường tiền điện tử, đặc biệt là ở những thị trường có khối lượng giao dịch thấp và biến động cao. Bằng cách cung cấp thanh khoản, các nhà tạo lập thị trường giúp giảm thiểu sự trượt giá của thị trường và giúp các nhà giao dịch dễ dàng giao dịch hơn.

Nguyên tắc cốt lõi của chiến lược tạo lập thị trường truyền thống là kiếm chênh lệch giá mua-bán bằng cách cung cấp thanh khoản. Giá lệnh mua do nhà tạo lập thị trường đưa ra thấp hơn giá lệnh bán, và lợi nhuận được tạo ra thông qua chênh lệch giá giao dịch. Ví dụ, khi giá giao ngay trên thị trường tăng, nhà tạo lập thị trường bán với giá cao hơn và mua với giá thấp hơn, kiếm được chênh lệch giá. Các nguồn thu nhập chính bao gồm:

  • Lây lan:Các nhà tạo lập thị trường truyền thống kiếm lợi nhuận bằng cách đặt lệnh mua và bán và tận dụng chênh lệch giá.
  • Doanh thu khối lượng giao dịch:Thu nhập của nhà tạo lập thị trường có liên quan chặt chẽ đến khối lượng giao dịch mà họ cung cấp. Khối lượng giao dịch lớn hơn không chỉ đồng nghĩa với tần suất giao dịch cao hơn và cơ hội lợi nhuận lớn hơn, mà còn mang lại những lợi ích bổ sung sau:
    • Hoàn phí:Để khuyến khích các nhà tạo lập thị trường cung cấp thanh khoản, nhiều sàn giao dịch sẽ hoàn lại một tỷ lệ phần trăm phí nhất định hoặc thậm chí cung cấp phí âm (tức là sàn giao dịch trả phí cho các nhà tạo lập thị trường)
    • Quyền lợi của cấp VIP:Khi khối lượng giao dịch đạt đến một ngưỡng nhất định, nhà tạo lập thị trường có thể nhận được mức phí xử lý thấp hơn và giảm chi phí giao dịch
    • Chương trình khuyến khích nhà tạo lập thị trường:Một số sàn giao dịch có chương trình khuyến khích dành riêng cho nhà tạo lập thị trường, trao thêm phần thưởng dựa trên chất lượng thanh khoản được cung cấp

Tuy nhiên, các nhà tạo lập thị trường cũng phải đối mặt với rủi ro biến động thị trường, đặc biệt là trong bối cảnh biến động mạnh của thị trường tiền kỹ thuật số. Những biến động mạnh trên thị trường có thể khiến lệnh mua và bán của các nhà tạo lập thị trường lệch đáng kể so với giá thực tế, dẫn đến thua lỗ.

Các loại chiến lược tạo lập thị trường

Trên thị trường tiền điện tử, các nhà tạo lập thị trường thường chọn các chiến lược tạo lập thị trường khác nhau dựa trên điều kiện thị trường, khối lượng giao dịch, tính biến động, v.v. Các loại chiến lược tạo lập thị trường phổ biến bao gồm:

  • Chiến lược tạo lập thị trường thụ động:Các nhà tạo lập thị trường đặt lệnh mua và bán dựa trên độ sâu thị trường, biến động lịch sử và các yếu tố khác, sau đó chờ đợi các giao dịch trên thị trường. Chiến lược này có đặc điểm là tần suất thấp và độ tin cậy cao, và các nhà tạo lập thị trường dựa vào biến động thị trường để thu lợi nhuận.

  • Chiến lược tạo lập thị trường chủ động: Theo chiến lược này, các nhà tạo lập thị trường điều chỉnh giá và khối lượng lệnh mua và bán theo thời gian thực dựa trên điều kiện thị trường để tăng khả năng giao dịch thành công. Các nhà tạo lập thị trường thường tăng lệnh khi giá gần với giá thị trường hiện tại để tận dụng tốt hơn những biến động của thị trường.

  • Chiến lược tăng khối lượng: Loại chiến lược mà bài viết này tập trung vào.Chiến lược tăng khối lượngĐây là một chiến lược nhằm tăng khối lượng giao dịch bằng cách mua và bán ở cùng một mức giá. Không giống như các chiến lược tạo lập thị trường truyền thống, mục đích chính của chiến lược này không phải là kiếm chênh lệch giá, mà là nhận được chiết khấu giao dịch, chiết khấu theo cấp độ hoặc phần thưởng khai thác thanh khoản thông qua số lượng lớn giao dịch.

Trong chiến lược rửa khối lượng, các nhà tạo lập thị trường đặt lệnh mua và bán ở cùng một mức giá. Khi lệnh được thực hiện, mặc dù không có lợi nhuận chênh lệch giá, khối lượng giao dịch có thể được tích lũy nhanh chóng. Mô hình lợi nhuận của chiến lược này hoàn toàn phụ thuộc vào cơ chế khuyến khích của sàn giao dịch, chứ không phải chênh lệch giá thị trường.

Các tính năng chính:

  • Giao dịch cùng giá:Khác với các chiến lược tạo lập thị trường truyền thống, giá mua và giá bán là như nhau và không tạo ra lợi nhuận chênh lệch giá.

  • Định hướng theo khối lượng:Mục tiêu cốt lõi của chiến lược này là nhanh chóng tích lũy khối lượng giao dịch thay vì chênh lệch giá.

  • Sự phụ thuộc vào các ưu đãi:Lợi nhuận hoàn toàn phụ thuộc vào chính sách hoàn tiền của sàn giao dịch, chiết khấu dành cho VIP hoặc chương trình khuyến khích của nhà tạo lập thị trường.

Sự khác biệt quan trọng: So với các chiến lược tạo lập thị trường truyền thống, chiến lược giao dịch rửa tiền không tạo ra lợi nhuận bằng cách cung cấp thanh khoản thị trường thực sự, mà bằng cách tạo ra khối lượng giao dịch giả tạo để nhận phần thưởng chính sách từ sàn giao dịch. Chiến lược này có thể gặp phải rủi ro tuân thủ ở một số khu vực pháp lý và cần được đánh giá cẩn thận khi áp dụng vào thực tế.

Logic lợi nhuận của chiến lược giao dịch ngược dựa trên khối lượng

Bằng cách phân tích mã, chúng ta có thể thấy rằng giá mua và giá bán trong chiến lược này hoàn toàn giống nhau:

def make_duiqiao_dict(self, trade_amount):
    mid_price = self.mid_price  # 中间价
    trade_price = round(mid_price, self.price_precision)  # 精准交易价格
    trade_dict = {
        'trade_price': trade_price,  # 买卖都使用同一个价格
        'amount': trade_amount
    }
    return trade_dict

Logic lợi nhuận thực tế

1. Chiến lược khối lượng giao dịch

  • Mục đích chính của chiến lược này là tăng khối lượng giao dịch thông qua số lượng lớn các giao dịch
  • Nhận tiền hoàn lại khi trao đổi, giảm giá theo cấp độ hoặc phần thưởng khai thác thanh khoản
  • Áp dụng cho các sàn giao dịch có chương trình khuyến khích nhà tạo lập thị trường

2. Cơ chế hoàn trả phí

  • Tùy thuộc vào chính sách phí âm của sàn giao dịch (Tỷ giá Maker là âm)
  • Nhận hoàn phí bằng cách cung cấp thanh khoản
  • Cần có sàn giao dịch hỗ trợ tỷ giá ưu đãi cho nhà tạo lập thị trường

Các tình huống và rủi ro áp dụng

✅ Các tình huống áp dụng

  • Sàn giao dịch có chính sách ưu đãi rõ ràng cho các nhà tạo lập thị trường
  • Phù hợp để nâng cấp lên cấp VIP với yêu cầu khối lượng giao dịch cao hơn
  • Nền tảng có hoạt động khai thác thanh khoản hoặc hoàn tiền

❌ Không áp dụng

  • Trao đổi không có cơ chế hoàn tiền
  • Nền tảng có phí giao dịch cao hơn
  • Các sàn giao dịch có hạn chế rõ ràng về giao dịch rửa tiền

⚠️ Nhắc nhở rủi ro

  • Nếu lệnh mua và lệnh bán được thực hiện cùng lúc, thường sẽ có khoản lỗ sau khi trừ phí xử lý.
  • Nếu chính sách trao đổi thay đổi, chiến lược có thể trở nên không hợp lệ
  • Yêu cầu theo dõi liên tục chi phí phí
  • Có thể phải đối mặt với rủi ro về tuân thủ (một số khu vực có hạn chế về hành vi đánh răng)

Phân tích khuôn khổ chiến lược tiếp nối

Bài viết này sẽ tham khảo khung mã của ông Zinan để giới thiệu một cách triển khai đơn giản chiến lược tăng khối lượng, tập trung vào cách tích lũy khối lượng giao dịch thông qua chiến lược mua và bán cùng giá trong môi trường sàn giao dịch. Khung chiến lược này bao gồm hai lớp chính:MidClassMarketMakerHai lớp này chịu trách nhiệm cho sự tương tác ở tầng giữa của quá trình trao đổi và thực hiện cụ thể chiến lược tiếp nối.

Kiến trúc chiến lược này áp dụng thiết kế phân lớp, tách biệt giao diện sàn giao dịch và chiến lược tạo lập thị trường để đảm bảo hệ thống có khả năng mở rộng và linh hoạt tốt. Các thành phần chính trong kiến trúc bao gồm:

  1. MidClass:Lớp trung gian trao đổi có trách nhiệm tương tác với giao diện trao đổi để lấy dữ liệu thị trường, thông tin tài khoản, trạng thái lệnh, v.v. Lớp này đóng gói tất cả các tương tác với các sàn giao dịch bên ngoài để đảm bảo logic giao dịch và giao diện trao đổi được tách biệt.
  2. MarketMaker:Lớp chiến lược tạo lập thị trường, chịu trách nhiệm thực hiện chiến lược knock-to-trade, tạo lệnh chờ, kiểm tra trạng thái lệnh, cập nhật trạng thái chiến lược, v.v. Nó tương tác với lớp trung gian của sàn giao dịch để cung cấp các hoạt động tạo lập thị trường và knock-to-trade cụ thể.

MidClass

MidClassLà lớp trung gian của sàn giao dịch, trách nhiệm chính của nó là xử lý tương tác với sàn giao dịch, đóng gói tất cả các lệnh gọi API bên ngoài và cung cấp giao diện ngắn gọn choMarketMakerSử dụng. Kiến trúc của nó bao gồm các chức năng chính sau:

  1. Thu thập dữ liệu thị trường

    • Nhận dữ liệu thời gian thực từ thị trường, chẳng hạn như giá thị trường, độ sâu, đường K, v.v. Cần làm mới dữ liệu thị trường thường xuyên để đảm bảo dữ liệu được cập nhật khi chiến lược được thực hiện.
  2. Quản lý thông tin tài khoản

    • Thu thập thông tin tài khoản, chẳng hạn như số dư tài khoản, trạng thái vị thế, v.v. Điều này rất quan trọng đối với việc quản lý quỹ và kiểm soát rủi ro.
  3. Quản lý đơn hàng

    • Cung cấp giao diện để tạo, truy vấn và hủy lệnh. Đây là cơ sở để thực hiện các chiến lược tạo lập thị trường và đảm bảo các lệnh đang chờ xử lý có thể được tạo và quản lý trên thị trường.
  4. Lưu trữ và cập nhật dữ liệu

    • Duy trì kết nối với các sàn giao dịch để liên tục cập nhật dữ liệu để sử dụng theo chiến lược.

Bằng cách đóng gói các chức năng này trongMidClassTrong ví dụ trên, bạn có thể đảm bảo rằng lớp chiến lược giao dịch (chẳng hạn nhưMarketMaker) Tập trung vào việc thực hiện các chiến lược giao dịch mà không cần phải lo lắng về cách tương tác với các sàn giao dịch. Cấu trúc này cải thiện khả năng bảo trì và khả năng mở rộng của hệ thống, giúp việc bổ sung hỗ trợ cho các sàn giao dịch khác nhau hoặc tối ưu hóa các chức năng hiện có trở nên dễ dàng hơn.

MarketMaker

MarketMakerĐây là lớp cốt lõi của chiến lược giao dịch chéo, chịu trách nhiệm thực hiện các hoạt động tạo lập thị trường và giao dịch chéo. Kiến trúc của nó bao gồm các mô-đun chính sau:

  1. khởi tạo

    • Khởi tạo lớp trung gian trao đổiMidClass, lấy thông tin cơ bản về sàn giao dịch, chẳng hạn như cặp giao dịch, độ chính xác, độ sâu thị trường, v.v.
    • Khởi tạo chiến lược tạo lập thị trường và thiết lập các thông số cần thiết, chẳng hạn như số lượng lệnh đang chờ xử lý, chênh lệch giá mua-bán, v.v. Các thông số này sẽ ảnh hưởng đến phương pháp thực hiện và hiệu quả của chiến lược.
  2. Làm mới dữ liệu

    • Thường xuyên làm mới dữ liệu thị trường, bao gồm thông tin tài khoản theo thời gian thực, giá thị trường, độ sâu, đường K, v.v. Những dữ liệu này cung cấp thông tin cơ bản để thực hiện các chiến lược.
    • Tần suất làm mới có thể được điều chỉnh theo sự biến động của thị trường để đảm bảo phản ứng kịp thời với những thay đổi của thị trường.
  3. Thực hiện chiến lược gõ cửa

    • Đang chờ tạo đơn hàng:Tạo từ điển lệnh chờ dựa trên độ sâu thị trường và biến động giá hiện tại. Từ điển lệnh chờ chứa giá và số lượng lệnh mua và bán, thường được tính toán tự động dựa trên các thông số chiến lược.
    • Thực hiện các giao dịch nối tiếp:Sau khi lệnh chờ được tạo,MarketMakerLệnh này sẽ được gửi lên thị trường và các lệnh mua và bán sẽ được thực hiện cùng lúc. Mục tiêu là nhanh chóng tích lũy khối lượng giao dịch bằng cách mua và bán ở cùng một mức giá.
    • Kiểm tra trạng thái đơn hàng:Khi thực hiện giao dịch liên hoàn,MarketMakerHệ thống sẽ liên tục kiểm tra trạng thái của lệnh để đảm bảo lệnh đang chờ xử lý được xử lý kịp thời. Nếu lệnh không được thực hiện, hệ thống sẽ điều chỉnh giá hoặc số lượng lệnh đang chờ xử lý cho đến khi lệnh được hoàn tất.
  4. Cập nhật trạng thái

    • Cập nhật trạng thái chính sách:Cập nhật thường xuyên trạng thái của chiến lược, bao gồm khối lượng giao dịch, lệnh đã hoàn thành, phí, v.v. Thông qua thông tin trạng thái này, người dùng có thể theo dõi hiệu suất của chiến lược theo thời gian thực.
    • Quản lý rủi ro:Chiến lược lan tỏa cần được thực hiện trong các môi trường thị trường khác nhau.MarketMakerPhương pháp thực hiện chiến lược sẽ được điều chỉnh linh hoạt để thích ứng với các môi trường thị trường khác nhau.

Sự tái tạo logic của chiến lược tiếp thị lan tỏa

Việc triển khai chiến lược giao dịch chéo phụ thuộc vào dữ liệu thị trường chính xác và thực hiện nhanh chóng.MarketMakerBằng cách theo dõi tình hình thị trường theo thời gian thực và sử dụng phương pháp đặt lệnh đối ứng (mua và bán ở cùng một mức giá), các mục tiêu chiến lược có thể đạt được bằng cách tích lũy nhanh chóng khối lượng giao dịch.

khởi tạo

hiện hữu MarketMakerTrong phương pháp khởi tạo lớp, trước tiên hãy lấy thông tin về độ chính xác của sàn giao dịch và khởi tạo các tham số chiến lược, chẳng hạn như độ chính xác về khối lượng giao dịch, độ chính xác về giá, v.v.

self.precision_info = self.exchange_mid.get_precision()  # 获取精度信息
self.price_precision = self.precision_info['price_precision']  # 价格精度
self.amount_precision = self.precision_info['amount_precision']  # 交易量精度

Tạo một từ điển các đơn đặt hàng liên tiếp

Cốt lõi của chiến lược giao dịch chéo là tạo ra một từ điển các lệnh giao dịch chéo, bao gồm giá mua và giá bán cũng như số lượng. Mã này tạo ra từ điển các lệnh giao dịch chéo bằng cách tính toán giá trung bình.

def make_duiqiao_dict(self, trade_amount):
    mid_price = self.mid_price  # 中间价
    trade_price = round(mid_price, self.price_precision)  # 精准交易价格
    trade_dict = {
        'trade_price': trade_price,
        'amount': trade_amount
    }
    return trade_dict

Thực hiện giao dịch nối tiếp

Theo từ điển lệnh giao dịch chéo được tạo ra, giao dịch giao dịch chéo sẽ được thực hiện.create_orderPhương pháp đặt lệnh mua và lệnh bán cùng lúc.

def make_trade_by_dict(self, trade_dict):
    if self.position_amount > trade_dict['amount'] and self.can_buy_amount > trade_dict['amount']:
        buy_id = self.exchange_mid.create_order('buy', trade_dict['trade_price'], trade_dict['amount'])  # 挂买单
        sell_id = self.exchange_mid.create_order('sell', trade_dict['trade_price'], trade_dict['amount'])  # 挂卖单
        self.traded_pairs['dui_qiao'].append({
            'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount']
        })

Kiểm tra trạng thái đơn hàng

Thường xuyên kiểm tra trạng thái đơn hàng và xử lý các đơn hàng chưa hoàn thành.GetOrderPhương pháp này lấy trạng thái đơn hàng và quyết định có hủy đơn hàng hay không dựa trên trạng thái đơn hàng. Logic xử lý của lệnh gõ cửa chủ yếu bao gồm các bước sau:

  1. Nhận trạng thái đơn hàng

    • Nhận trạng thái lệnh mua và bán thông qua giao diện sàn giao dịch.
    • Nếu không lấy được trạng thái đơn hàng (ví dụ: đơn hàng không tồn tại hoặc có sự cố mạng), đơn hàng sẽ bị hủy và xóa khỏi hồ sơ.
  2. Phán quyết về tình trạng đơn hàng

    • Dựa trên trạng thái đơn hàng, hãy xác định xem đơn hàng đã hoàn thành, hoàn thành một phần hay chưa hoàn thành.
    • Trạng thái đơn hàng có thể bao gồm:
      • 0(ORDER_STATE_PENDING): Chưa hoàn thành (đang chờ đơn hàng).
      • 1(ORDER_STATE_CLOSED): Đã hoàn thành (giao dịch đầy đủ).
      • 2(ORDER_STATE_CANCELED): Đã hủy bỏ.
      • 3(ORDER_STATE_UNKNOWN): Tình trạng chưa rõ.
  3. Xử lý trạng thái đơn hàng

    • Cả hai đơn hàng đều không hoàn thành
      • Nếu cả lệnh mua và lệnh bán đều không được hoàn thành (trạng thái là0), sau đó theo thời gian bỏ phiếu (current_time % 5 == 0) quyết định có nên hủy đơn hàng hay không.
      • Sau khi hủy đơn hàng, hãy cập nhật số lượng đơn hàng đang chờ xử lý và xóa đơn hàng khỏi hồ sơ.
    • Một đơn hàng đã hoàn thành, một đơn hàng khác chưa hoàn thành
      • Nếu một đơn hàng được hoàn thành (trạng thái là1), và một đơn hàng khác không được hoàn thành (trạng thái là0), sau đó quyết định có nên hủy đơn hàng chưa hoàn thành hay không dựa trên thời gian bỏ phiếu.
      • Sau khi hủy lệnh mở, hãy cập nhật khối lượng và danh sách lệnh mở và xóa lệnh khỏi hồ sơ.
    • Cả hai đơn hàng đã được hoàn thành
      • Nếu cả lệnh mua và lệnh bán đều được hoàn thành (trạng thái là1), khối lượng giao dịch được cập nhật và đơn hàng được xóa khỏi hồ sơ.
    • Trạng thái đơn hàng chưa rõ
      • Nếu trạng thái đơn hàng không phải là0Không thực sự1, nó được ghi lại ở trạng thái không xác định và được ghi lại.
  4. Cập nhật hồ sơ

    • Theo kết quả xử lý trạng thái đơn hàng, cập nhật khối lượng giao dịch, danh sách đơn hàng chưa hoàn thành và số lượng đơn hàng đang chờ xử lý.

Triển vọng chiến lược tiếp theo

Chiến lược tăng khối lượng giao dịch được trình bày trong bài viết này chủ yếu được sử dụng để tìm hiểu thiết kế kiến trúc của khung giao dịch, và giá trị ứng dụng thực tế của nó còn hạn chế. Nếu độc giả quan tâm đến các chiến lược tạo lập thị trường thực tế, chúng tôi sẽ giới thiệu thêm nội dung chiến lược thực tế sau:

1. Chiến lược tạo lập thị trường

  • Chiến lược chênh lệch giá thực sự dựa trên chênh lệch giá mua-bán
  • Đặt lệnh giữa giá mua và giá bán để kiếm được chênh lệch giá
  • Phù hợp hơn với mô hình lợi nhuận của các nhà tạo lập thị trường truyền thống

2. Chiến lược tạo lập thị trường năng động

  • Điều chỉnh giá lệnh chờ một cách linh hoạt dựa trên sự biến động của thị trường
  • Giới thiệu cơ chế quản lý hàng tồn kho và kiểm soát rủi ro
  • Tạo lập thị trường thích ứng để phù hợp với các môi trường thị trường khác nhau

3. Chiến lược tạo lập thị trường đa cấp

  • Đặt lệnh ở nhiều mức giá cùng lúc
  • Cải thiện sự ổn định lợi nhuận tổng thể bằng cách phân tán rủi ro
  • Gần hơn với hoạt động thực tế của các nhà tạo lập thị trường chuyên nghiệp

Các chiến lược này sẽ tập trung nhiều hơn vào logic lợi nhuận thực tế và quản lý rủi ro, cung cấp tài liệu tham khảo có giá trị hơn cho các nhà giao dịch định lượng.

Triển vọng chiến lược

Chiến lược giao dịch wash trading dựa trên chính sách khuyến khích của sàn giao dịch. Nếu chính sách thay đổi, chiến lược có thể trở nên vô hiệu. Do đó, chiến lược cần có khả năng ứng phó với những thay đổi về chính sách, chẳng hạn như theo dõi linh hoạt mức phí hoặc áp dụng nhiều mô hình lợi nhuận để giảm thiểu rủi ro phụ thuộc đơn lẻ. Ngoài ra, chiến lược wash trading có thể bị coi là thao túng thị trường và phải đối mặt với rủi ro pháp lý. Trong các ứng dụng thực tế, các nhà giao dịch cần chú ý chặt chẽ đến luật pháp và quy định liên quan để đảm bảo chiến lược tuân thủ và tránh thua lỗ do các vấn đề pháp lý.

Tôi hy vọng độc giả có thể tối ưu hóa và cải thiện chiến lược của mình dựa trên các khái niệm giao dịch và hiểu biết thị trường của riêng họ, dựa trên nền tảng cơ bản. Sức hấp dẫn của giao dịch định lượng nằm ở việc liên tục học hỏi, thực hành và cải thiện. Chúc tất cả các bạn luôn tiến bộ trên con đường giao dịch định lượng!

Mã chiến lược

import time, json

class MidClass:
    def __init__(self, exchange_instance):
        '''
        初始化交易所中间层
        
        Args:
            exchange_instance: FMZ的交易所结构
        '''
        self.init_timestamp = time.time()  # 记录初始化时间
        self.exchange = exchange_instance  # 保存交易所对象
        self.exchange_name = self.exchange.GetName()  # 获取交易所名称
        self.trading_pair = self.exchange.GetCurrency()  # 获取交易对名称(如 BTC_USDT)

    def get_precision(self):
        '''
        获取交易对的精度信息
        
        Returns:
            返回包含精度信息的字典,失败时返回 None
        '''
        symbol_code = self.exchange.GetCurrency()
        ticker = self.exchange.GetTicker(symbol_code)  # 回测系统需要
        exchange_info = self.exchange.GetMarkets()
        data = exchange_info.get(symbol_code)

        if not data:
            Log("获取市场信息失败", GetLastError())
            return None

        # 获取该交易对的精度信息
        self.precision_info = {
            'tick_size': data['TickSize'],                  # 价格精度
            'amount_size': data['AmountSize'],              # 数量精度
            'price_precision': data['PricePrecision'],      # 价格小数位精度
            'amount_precision': data['AmountPrecision'],    # 数量小数位精度
            'min_qty': data['MinQty'],                      # 最小下单数量
            'max_qty': data['MaxQty']                       # 最大下单数量
        }

        return self.precision_info

    def get_account(self):
        '''
        获取账户信息
        
        Returns:
            获取信息成功返回 True,获取信息失败返回 False
        '''

        self.balance = '---'  # 账户余额
        self.amount = '---'  # 账户持仓量
        self.frozen_balance = '---'  # 冻结余额
        self.frozen_stocks = '---'  # 冻结持仓量
        self.init_balance = None
        self.init_stocks = None
        self.init_equity = None

        try:
            account_info = self.exchange.GetAccount()  # 获取账户信息
            self.balance = account_info['Balance']  # 更新账户余额
            self.amount = account_info['Stocks']  # 更新持仓量
            self.frozen_balance = account_info['FrozenBalance']  # 更新冻结余额
            self.frozen_stocks = account_info['FrozenStocks']  # 更新冻结持仓量
            self.equity = self.balance + self.frozen_balance + (self.amount + self.frozen_stocks) * self.last_price
            
            if not self.init_balance or not self.init_stocks or not self.init_equity:
                if _G("init_balance") and _G("init_balance") > 0 and _G("init_stocks") and _G("init_stocks") > 0:
                    self.init_balance = round(_G("init_balance"), 2)
                    self.init_stocks = round(_G("init_stocks"), 2)
                    self.init_equity = round(_G("init_equity"), 2)
                else:
                    self.init_balance = round(self.balance + self.frozen_balance, 2)
                    self.init_stocks = self.amount + self.frozen_stocks
                    self.init_equity = round(self.init_balance + (self.init_stocks * self.last_price), 2)
                    _G("init_balance", self.init_balance)
                    _G("init_stocks", self.init_stocks)
                    _G("init_equity", self.init_equity)

                    Log('获取初始eqity', self.init_equity)

            self.profit = self.equity - self.init_equity
            self.profitratio = round((self.equity - self.init_equity)/self.init_equity, 4) * 100

            return True
        except:
            return False  # 获取账户信息失败

    def get_ticker(self):
        '''
        获取市价信息(如买一价、卖一价、最高价、最低价等)
        
        Returns:
            获取信息成功返回 True,获取信息失败返回 False
        '''
        self.high_price = '---'  # 最高价
        self.low_price = '---'  # 最低价
        self.sell_price = '---'  # 卖一价
        self.buy_price = '---'  # 买一价
        self.last_price = '---'  # 最新成交价
        self.volume = '---'  # 成交量
        
        try:
            ticker_info = self.exchange.GetTicker()  # 获取市价信息
        
            self.high_price = ticker_info['High']  # 更新最高价
            self.low_price = ticker_info['Low']  # 更新最低价
            self.sell_price = ticker_info['Sell']  # 更新卖一价
            self.buy_price = ticker_info['Buy']  # 更新买一价
            self.last_price = ticker_info['Last']  # 更新最新成交价
            self.volume = ticker_info['Volume']  # 更新成交量
            return True
        except:
            return False  # 获取市价信息失败
        
    def get_depth(self):
        '''
        获取深度信息(买卖盘的挂单列表)
        
        Returns:
            获取信息成功返回 True,获取信息失败返回 False
        '''
        self.ask_orders = '---'  # 卖盘挂单列表
        self.bid_orders = '---'  # 买盘挂单列表
        
        try:
            depth_info = self.exchange.GetDepth()  # 获取深度信息
            self.ask_orders = depth_info['Asks']  # 更新卖盘挂单列表
            self.bid_orders = depth_info['Bids']  # 更新买盘挂单列表
            return True
        except:
            return False  # 获取深度信息失败
        
    def get_ohlc_data(self, period=PERIOD_M5):
        '''
        获取K线信息
        
        Args:
            period: K线周期,PERIOD_M1 指1分钟, PERIOD_M5 指5分钟, PERIOD_M15 指15分钟,
            PERIOD_M30 指30分钟, PERIOD_H1 指1小时, PERIOD_D1 指一天。
        '''
        self.ohlc_data = self.exchange.GetRecords(period)  # 获取K线数据
        
    def create_order(self, order_type, price, amount):
        '''
        提交一个挂单信息
        
        Args:
            order_type:挂单类型,'buy'指挂买单,'sell'指挂卖单
            price:挂单价格
            amount:挂单数量
            
        Returns:
            挂单Id号,可用以取消挂单
        '''
        if order_type == 'buy':
            try:
                order_id = self.exchange.Buy(price, amount)  # 提交买单
            except:
                return False  # 买单提交失败
            
        elif order_type == 'sell':
            try:
                order_id = self.exchange.Sell(price, amount)  # 提交卖单
            except:
                return False  # 卖单提交失败
        
        return order_id  # 返回订单ID
    
    def get_orders(self):
        '''
        获取未完成的订单列表
        
        Returns:
            未完成的订单列表
        '''
        self.open_orders = self.exchange.GetOrders()  # 获取未完成订单
        return self.open_orders
    
    def cancel_order(self, order_id):
        '''
        取消一个挂单信息
        
        Args:
            order_id:希望取消的挂单ID号
            
        Returns:
            取消挂单成功返回 True,取消挂单失败返回 False
        '''
        return self.exchange.CancelOrder(order_id)  # 取消订单
        
    def refresh_data(self):
        '''
        刷新信息(账户、市价、深度、K线)
        
        Returns:
            刷新信息成功返回 'refresh_data_finish!' 否则返回相应刷新失败的信息提示
        '''

        if not self.get_ticker():  # 刷新市价信息
            return 'false_get_ticker'

        if not self.get_account():  # 刷新账户信息
            return 'false_get_account'
        
        if not self.get_depth():  # 刷新深度信息
            return 'false_get_depth'
        
        try:
            self.get_ohlc_data()  # 刷新K线信息
        except:
            return 'false_get_K_line_info'
        
        return 'refresh_data_finish!'  # 刷新成功

class MarketMaker:
    def __init__(self, mid_class):
        '''
        初始化做市策略
        
        Args:
            mid_class: 交易所中间层对象
        '''
        self.exchange_mid = mid_class  # 交易所中间层对象
        self.precision_info = self.exchange_mid.get_precision()  # 获取精度信息

        self.done_amount = {'dui_qiao': 0}  # 已完成交易量
        self.price_precision = self.precision_info['price_precision']  # 价格精度
        self.amount_precision = self.precision_info['amount_precision']  # 交易量精度
        
        self.traded_pairs = {'dui_qiao': []}  # 已挂单的交易对
        self.pending_orders = []  # 未完成的订单状态
        self.pending_order_count = 0  # 挂单次数

        self.buy_amount = 0
        self.sell_amount = 0

        self.fee = 0
        self.fee_rate = 0.08 / 100

        self.chart = {
            "__isStock": True,
            "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"},
            "title": {"text": "挂单数量"},
            "xAxis": {"type": "datetime"},
            "yAxis": {
                "title": {"text": "挂单数量"},
                "opposite": False
            },
            "series": [
                {"name": "挂单买量", "id": "挂单买量", "data": []},
                {"name": "挂单卖量", "id": "挂单卖量", "dashStyle": "shortdash", "data": []}
            ]
        }
    
    def refresh_data(self):
        '''
        刷新数据(账户、市价、深度、K线)
        '''
        self.exchange_mid.refresh_data()  # 刷新交易所数据
        self.position_amount = 0 if isinstance(self.exchange_mid.amount, str) else self.exchange_mid.amount  # 持仓量
        self.available_balance = 0 if isinstance(self.exchange_mid.balance, str) else self.exchange_mid.balance  # 账户余额
        Log('检查ticker', self.exchange_mid.buy_price)
        self.can_buy_amount = self.available_balance / float(self.exchange_mid.buy_price)  # 可买的数量
        self.mid_price = (self.exchange_mid.sell_price + self.exchange_mid.buy_price) / 2  # 中间价

    def make_duiqiao_dict(self, trade_amount):
        
        '''
        生成对敲挂单字典
        
        Args:
            trade_amount: 每次交易量
        
        Returns:
            对敲挂单字典列表
        '''
        Log('3制作对敲挂单字典')

        mid_price = self.mid_price  # 中间价

        trade_price = round(mid_price, self.price_precision)  # 精准交易价格

        trade_dict = {
            'trade_price': trade_price,
            'amount': trade_amount
        }

        Log('返回盘口挂单字典:', trade_dict)
        return trade_dict
    
    def make_trade_by_dict(self, trade_dict):
        '''
        根据交易字典执行交易
        
        Args:
            trade_dict: 交易字典
        '''
        Log('4按照字典开始交易')
        self.refresh_data()  # 刷新数据
        
        if trade_dict:
            Log('当前账户资金: 币数余额: ', self.position_amount, '资金余额: ', self.can_buy_amount)
            Log('检查开仓: 币数限制: ', self.position_amount > trade_dict['amount'], '资金限制: ', self.can_buy_amount > trade_dict['amount'])
            if self.position_amount > trade_dict['amount'] and self.can_buy_amount > trade_dict['amount']:
                buy_id = self.exchange_mid.create_order('buy', trade_dict['trade_price'], trade_dict['amount'])  # 挂买单
                sell_id = self.exchange_mid.create_order('sell', trade_dict['trade_price'], trade_dict['amount'])  # 挂卖单
                
                self.traded_pairs['dui_qiao'].append({
                    'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount']
                })
                    
                self.last_time = time.time()  # 更新上次交易时间
        
    def handle_pending_orders(self):
        '''
        处理未完成的订单
        '''
        pending_orders = self.exchange_mid.get_orders()  # 获取未完成订单
        if len(pending_orders) > 0:
            for order in pending_orders:
                self.exchange_mid.cancel_order(order['Id'])  # 取消未完成订单

    def check_order_status(self, current_time):
        '''
        检查订单状态
        current_time: 轮询检查次数
        '''
        Log('1开始订单信息检查')
        Log(self.traded_pairs['dui_qiao'])
        self.buy_pending = 0
        self.sell_pending = 0
        for traded_pair in self.traded_pairs['dui_qiao'].copy():
            Log('检查订单:', traded_pair['buy_id'], traded_pair['sell_id'])

            try:
                buy_order_status = self.exchange_mid.exchange.GetOrder(traded_pair['buy_id'])  # 获取买单状态
                sell_order_status = self.exchange_mid.exchange.GetOrder(traded_pair['sell_id'])  # 获取卖单状态
            except:
                Log(traded_pair, '取消')
                self.exchange_mid.cancel_order(traded_pair['buy_id'])  # 取消买单
                self.exchange_mid.cancel_order(traded_pair['sell_id'])  # 取消卖单
                self.traded_pairs['dui_qiao'].remove(traded_pair)  # 移除订单
                return

            Log('检查订单:', traded_pair['buy_id'], buy_order_status, traded_pair['sell_id'], sell_order_status, [sell_order_status['Status'], buy_order_status['Status']])
            if [sell_order_status['Status'], buy_order_status['Status']] == [0, 0]:
                self.buy_pending += 1
                self.sell_pending += 1
                if current_time % 5 == 0:
                    Log('检查挂单,取消挂单(两未完)', buy_order_status['Status'], sell_order_status['Status'], current_time % 5)
                    self.exchange_mid.cancel_order(traded_pair['buy_id'])  # 取消买单
                    self.exchange_mid.cancel_order(traded_pair['sell_id'])  # 取消卖单
                    self.pending_order_count += 1  # 挂单次数加1
                    self.traded_pairs['dui_qiao'].remove(traded_pair)  # 移除订单

            elif {sell_order_status['Status'], buy_order_status['Status']} == {1, 0}:
                if buy_order_status['Status'] == ORDER_STATE_PENDING:
                    self.buy_pending += 1
                if sell_order_status['Status'] == ORDER_STATE_PENDING:
                    self.sell_pending += 1
                if current_time % 5 == 0:
                    Log('检查挂单,取消挂单(一未完)', buy_order_status['Status'], sell_order_status['Status'])
                    self.done_amount['dui_qiao'] += traded_pair['amount']  # 更新交易量
                    if buy_order_status['Status'] == ORDER_STATE_PENDING:
                        self.sell_amount += traded_pair['amount']
                        self.fee += sell_order_status['Amount'] * self.fee_rate * sell_order_status['Price']
                        Log('取消该买订单,增加未完成买列表', traded_pair['buy_id'])
                        self.exchange_mid.cancel_order(traded_pair['buy_id'])  # 取消买单
                        self.pending_orders.append(['buy', buy_order_status['Status']])  # 记录未完成订单
                        Log('清除前:', self.traded_pairs['dui_qiao'])
                        Log('清除id:', traded_pair)
                        self.traded_pairs['dui_qiao'].remove(traded_pair)  # 移除订单
                        Log('清除后:', self.traded_pairs['dui_qiao'])
                    elif sell_order_status['Status'] == ORDER_STATE_PENDING:
                        self.buy_amount += traded_pair['amount']
                        self.fee += buy_order_status['Amount'] * self.fee_rate * buy_order_status['Price']
                        Log('取消该卖订单,增加未完成卖列表', traded_pair['sell_id'])
                        self.exchange_mid.cancel_order(traded_pair['sell_id'])  # 取消卖单
                        self.pending_orders.append(['sell', sell_order_status['Status']])  # 记录未完成订单
                        Log('清除前:', self.traded_pairs['dui_qiao'])
                        Log('清除id:', traded_pair)
                        self.traded_pairs['dui_qiao'].remove(traded_pair)  # 移除订单
                        Log('清除后:', self.traded_pairs['dui_qiao'])
                
            elif [sell_order_status['Status'], buy_order_status['Status']] == [1, 1]:
                Log('两订单都已完成')
                self.buy_amount += traded_pair['amount']
                self.sell_amount += traded_pair['amount']
                self.fee += buy_order_status['Amount'] * self.fee_rate * buy_order_status['Price']
                self.fee += sell_order_status['Amount'] * self.fee_rate * sell_order_status['Price']
                Log('完成状态:', buy_order_status['Status'], sell_order_status['Status'], traded_pair['amount'])
                self.done_amount['dui_qiao'] += 2 * traded_pair['amount']  # 更新交易量
                self.traded_pairs['dui_qiao'].remove(traded_pair)  # 移除订单
            else:
                Log('两订单处于未知状态:', buy_order_status, sell_order_status)
                Log('未知订单状态:', buy_order_status['Status'], sell_order_status['Status'])
                Log('未知订单信息:', traded_pair)
        
    def update_status(self):

        self.exchange_mid.refresh_data()

        table1 = {
            "type": "table",
            "title": "账户信息",
            "cols": [
                "初始资金", "现存资金", "对敲买入数量", "对敲卖出数量", "费率", "总收益", "收益率"
            ],
            "rows": [
                [   
                    self.exchange_mid.init_equity,
                    self.exchange_mid.equity,
                    round(self.buy_amount, 4),
                    round(self.sell_amount, 4),
                    round(self.fee, 2),
                    self.exchange_mid.profit,
                    str(self.exchange_mid.profitratio) + "%"
                ],
            ],
        }

        LogStatus(
            f"初始化时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.exchange_mid.init_timestamp))}\n",
            f"`{json.dumps(table1)}`\n",
            f"最后执行时间: {_D()}\n"
        )

        LogProfit(round(self.exchange_mid.profit, 3), '&')

    def plot_pending(self):
        
        Log('对敲挂单数量:', self.buy_pending, self.sell_pending)
        self.obj_chart = Chart(self.chart)
        now_time = int(time.time() * 1000)
        # 更新挂单买量数据
        self.obj_chart.add(0, [now_time, self.buy_pending])
        # 更新挂单卖量数据
        self.obj_chart.add(1, [now_time, self.sell_pending])


def main():
    '''
    主函数,运行做市策略
    '''
    exchange.IO('simulate', True)
    exchange.IO("trade_super_margin")
    
    target_amount = 1  # 目标交易量
    trade_amount = 0.01  # 每次交易量
    trade_dict = {}  # 初始化交易字典
    
    exchange_mid = MidClass(exchange)  # 初始化交易所中间层
    Log(exchange_mid.refresh_data())  # 刷新数据
    market_maker = MarketMaker(exchange_mid)  # 初始化做市策略

    check_times = 0
    
    while market_maker.done_amount['dui_qiao'] < target_amount:  # 循环直到完成目标交易量
        Log(market_maker.traded_pairs['dui_qiao'])
        market_maker.check_order_status(check_times)  # 检查订单状态
        Sleep(1000)  # 等待1秒
        market_maker.refresh_data()  # 刷新数据
        
        if len(market_maker.traded_pairs['dui_qiao']) < 1: # 价格移动,盘口挂单撤销,等待至所有挂单完毕,制定新的挂单字典
            
            Log('2盘口交易对数量小于1')
            trade_dict = market_maker.make_duiqiao_dict(trade_amount)  # 生成盘口挂单字典
            Log('新交易字典', trade_dict)
        
        if trade_dict:  # 判断字典是否非空
            market_maker.make_trade_by_dict(trade_dict)  # 执行交易

        Log('盘口做市数量:', market_maker.done_amount['dui_qiao'])  # 记录交易量

        market_maker.plot_pending()
        market_maker.update_status()

        check_times += 1
        
    Log(market_maker.position_amount, market_maker.can_buy_amount)  # 记录持仓量和可买数量
    Log('现存订单:', exchange.GetOrders())  # 记录现存订单

def onexit():
    Log("执行扫尾函数")

    _G("init_balance", None)
    _G("init_stocks", None)
    _G("init_equity", None)