2
fokus pada
319
Pengikut

Perbincangan Ringkas mengenai Strategi Membuat Pasaran Mata Wang Digital (2): Strategi Pasaran

Dicipta dalam: 2025-08-01 11:28:35, dikemas kini pada: 2025-08-04 14:15:40
comments   0
hits   692

Mukadimah

Dalam artikel kami sebelum ini, “Wash Trading Strategies in Cryptocurrency,” kami memperincikan rangka kerja strategi untuk mengumpul volum dagangan dengan membeli dan menjual pada harga yang sama. Tujuan utama strategi ini adalah untuk mendapatkan rebat pertukaran atau faedah peringkat, dan bukannya mendapat keuntungan daripada arbitraj harga. Walaupun strategi perdagangan basuh adalah berharga untuk mempelajari tentang rangka kerja perdagangan, keuntungan sebenar mereka adalah terhad dan mereka mungkin menghadapi risiko pematuhan.

Artikel ini akan memperkenalkan satu lagi strategi membuat pasaran yang lebih praktikal berdasarkan artikel sebelumnya:Strategi CacatBerbeza dengan strategi jual beli, strategi pembuat pasaran ialah strategi arbitraj sebenar yang menjana keuntungan dengan menetapkan sebaran antara harga beli dan jual, yang lebih selari dengan model keuntungan pembuat pasaran tradisional.

⚠️ Notis Penting

Kod strategi pasaran yang dibentangkan dalam artikel ini hanya bertujuan sebagai rangka kerja pembelajaran dan tidak menggambarkan sebarang pengalaman perdagangan dunia sebenar. Strategi yang dibentangkan di sini adalah bertujuan untuk pembelajaran teknikal dan tujuan penyelidikan sahaja dan belum disahkan sepenuhnya dalam keadaan pasaran dunia sebenar. Pembaca dinasihatkan untuk menjalankan ujian belakang dan penilaian risiko yang menyeluruh sebelum menggunakan maklumat ini, dan tidak boleh menggunakannya secara langsung dalam perdagangan dunia sebenar.


Prinsip Strategi Handicap

Strategi buku pesanan pasaran ialah strategi membuat pasaran yang mengeksploitasi buku pesanan pasaran (iaitu, kedalaman pasaran) untuk arbitraj. Di bawah strategi ini, pembuat pasaran melaraskan harga pesanan secara dinamik dalam jurang antara harga bida dan permintaan berdasarkan turun naik pasaran, meletakkan dan membatalkan pesanan, dengan itu memanfaatkan kecairan pasaran dan turun naik harga jangka pendek untuk menjana keuntungan.

Ciri Teras

  1. Laraskan harga pesanan belum selesai secara dinamik:Laraskan harga pesanan beli dan jual secara dinamik berdasarkan kedalaman pasaran dan turun naik harga untuk meningkatkan kebarangkalian transaksi.
  2. Kawal bilangan pesanan yang belum selesai: Kawal bilangan pesanan yang belum selesai berdasarkan dana akaun dan kedudukan untuk mengelakkan pendedahan yang berlebihan kepada risiko pasaran.
  3. Pengurusan status pesanan: Semak status pesanan dengan kerap dan proses pesanan yang belum selesai.

Perbezaan daripada strategi knock-on

ciri Strategi meningkatkan volum Strategi Cacat
Harga jual beli Harga yang sama Harga berbeza (dengan perbezaan harga)
Model keuntungan Rebat/insentif pertukaran penyebaran bid-ask
Pendedahan Risiko Rendah (urus niaga harga yang sama) Tinggi (risiko turun naik harga)
Kepraktisan terhad Lebih tinggi

Kelebihan Strategi Handicap

  • Meningkatkan kecairan pasaran:Dengan membuat pesanan di pasaran, kami boleh meningkatkan kedalaman pembelian dan penjualan pasaran dan menarik lebih ramai peniaga untuk mengambil bahagian.
  • Peroleh hamparan bid-ask: Dengan menyediakan kecairan, pembuat pasaran boleh memperoleh spread bid-ask dan dengan itu memperoleh keuntungan.
  • Fleksibel bertindak balas terhadap turun naik pasaran:Strategi pasaran boleh melaraskan harga pesanan belum selesai secara dinamik mengikut turun naik pasaran untuk mengurangkan risiko pasaran.

Cabaran Strategi Handicap

  • Risiko Pasaran: Turun naik harga pasaran boleh menyebabkan pesanan pembuat pasaran gagal dilaksanakan, malah mengakibatkan kerugian.
  • Tekanan kewangan:Pembuat pasaran memerlukan dana yang mencukupi untuk mengekalkan kedalaman pembelian dan penjualan pasaran. Dana yang tidak mencukupi boleh menyebabkan strategi gagal.
  • Pengurusan pesanan yang kompleks:Strategi pasaran memerlukan pemeriksaan tetap status pesanan dan pemprosesan pesanan yang belum selesai, yang meningkatkan kerumitan strategi.

Struktur strategi kecacatan

Selaras dengan strategi mogok, kod dalam artikel ini melaksanakan strategi membuat pasaran berdasarkan strategi sebut harga pasaran, yang terbahagi terutamanya kepada dua kategori:

  1. MidClass: Lapisan tengah pertukaran bertanggungjawab untuk berinteraksi dengan antara muka pertukaran untuk mendapatkan data pasaran, maklumat akaun, status pesanan, dsb.
  2. MarketMaker: Kelas strategi membuat pasaran, bertanggungjawab untuk melaksanakan strategi pasaran, menjana harga pesanan belum selesai secara dinamik, menjana pesanan belum selesai, menyemak status pesanan, mengemas kini status strategi, dsb.

Proses Strategi Handicap

1. Inisialisasi

wujud MarketMakerDalam kaedah permulaan kelas, mula-mula dapatkan maklumat ketepatan pertukaran dan mulakan parameter strategi, seperti ketepatan volum transaksi, ketepatan harga, dsb.

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

2. Hasilkan kamus pesanan yang belum selesai

Teras strategi pasaran adalah untuk menjana kamus pesanan belum selesai, yang mengandungi harga dan kuantiti beli dan jual. Kod menjana kamus ini dengan mengira harga pertengahan dan mengimbangi harga.

3. Pergerakan harga pending order

Pergerakan harga pesanan belum selesai dicapai dengan mengira harga mengimbangi. Pengimbangan harga adalah berdasarkan julat harga (price_range) dan selang harga minimum (min_price_step) dikira.

price_offset = price_range - self.pending_order_count * min_price_step  # 计算价格偏移量
do_trade = price_offset > 0
  • price_range: Julat harga, menunjukkan julat sisihan antara harga pesanan belum selesai dan harga pertengahan.
  • min_price_step: Selang harga minimum, menunjukkan langkah pelarasan minimum bagi setiap harga pesanan belum selesai.
  • price_offset: Harga mengimbangi, yang menunjukkan sisihan antara harga pesanan semasa dan harga pertengahan.

Jika offset harga lebih besar daripada 0, bermakna pesanan boleh terus dibuat; jika tidak, bilangan pesanan yang belum selesai ditetapkan semula.

4. Hasilkan kamus pesanan belum selesai

Berdasarkan offset harga, harga beli dan jual dikira dan kamus pesanan belum selesai dijana.

if do_trade:
    buy_price = mid_price - price_offset  # 计算买价
    buy_price = round(buy_price, self.price_precision)  # 四舍五入买价
    
    sell_price = mid_price + price_offset  # 计算卖价
    sell_price = round(sell_price, self.price_precision)  # 四舍五入卖价

    trade_dict = {
        'do_trade': do_trade,
        'buy_price': buy_price,
        'sell_price': sell_price,
        'amount': trade_amount
    }

    Log('返回盘口挂单字典:', trade_dict)
    return trade_dict
else:
    self.pending_order_count = 0  # 重置挂单次数
  • buy_price: Harga bida, dikira sebagai harga pertengahan tolak harga mengimbangi.
  • sell_price: Harga tanya, dikira sebagai harga pertengahan ditambah dengan harga yang diimbangi.
  • trade_dict: Kamus pesanan belum selesai, termasuk harga dan kuantiti beli dan jual.

5. Laksanakan dagangan pasaran

Menurut kamus pesanan yang dijana, laksanakan transaksi pesanan.create_orderKaedah, buat pesanan beli dan jual pada masa yang sama.

def make_trade_by_dict(self, trade_dict):
    if trade_dict['do_trade']:
        buy_id = self.exchange_mid.create_order('buy', trade_dict['buy_price'], trade_dict['amount'])  # 挂买单
        sell_id = self.exchange_mid.create_order('sell', trade_dict['sell_price'], trade_dict['amount'])  # 挂卖单
        
        self.traded_pairs['pan_kou'].append({
            'buy_id': buy_id, 'sell_id': sell_id, 'init_time': time.time(), 'amount': trade_dict['amount']
        })

6. Semak status pesanan

Semak status pesanan secara kerap dan proses pesanan yang tidak dipenuhi. Logik pemprosesan status pesanan adalah serupa dengan strategi perdagangan silang, tetapi disebabkan oleh perbezaan harga, pelaksanaan separa boleh mengakibatkan untung atau rugi sebenar.

Kelemahan utama strategi kecacatan

1. Pergerakan harga pesanan belum selesai tidak cukup fleksibel

Mekanisme pelarasan harga dalam strategi ini agak mudah, dengan batasan berikut:

price_offset = price_range - self.pending_order_count * min_price_step  # 计算价格偏移量
  • Had pelarasan linear:Mengimbangi harga menggunakan kaedah penurunan linear dan tidak boleh diselaraskan secara dinamik mengikut turun naik pasaran sebenar
  • Pemejalan parameterprice_range danmin_price_stepIa adalah parameter tetap dan tidak boleh dilaraskan dalam masa nyata mengikut keadaan pasaran
  • Histeresis tindak balas: Apabila harga pasaran berubah dengan cepat, pelarasan harga strategi mungkin tidak mengikuti rentak pasaran
  • Kurang kesedaran pasaran: Ia tidak mengambil kira faktor mikrostruktur pasaran seperti kedalaman buku pesanan dan volum dagangan

Arah penambahbaikan

  • Memperkenalkan mekanisme pelarasan harga dinamik berdasarkan turun naik
  • Laraskan harga pesanan belum selesai berdasarkan kedalaman dan kecairan pasaran
  • Tingkatkan pertimbangan anda tentang arah aliran pasaran dan elakkan membuat pesanan bertentangan dengan arah aliran

2. Risiko Inventori

Strategi pasaran menghadapi masalah risiko inventori yang serius:

Prestasi Risiko

  • Risiko transaksi unilateral:Apabila hanya pesanan beli atau pesanan jual dilaksanakan, ia akan membawa kepada kedudukan yang tidak seimbang
  • Risiko arah: Dalam pasaran arah aliran, sejumlah besar kedudukan sehala mungkin terkumpul
  • Pendudukan modal: Inventori yang berlebihan akan menempati banyak dana dan menjejaskan kecekapan strategi

Mata risiko dalam kod

if buy_order_status['Status'] == ORDER_STATE_PENDING:
    self.sell_amount += traded_pair['amount']  # 只有卖单成交,积累空头持仓
elif sell_order_status['Status'] == ORDER_STATE_PENDING:
    self.buy_amount += traded_pair['amount']  # 只有买单成交,积累多头持仓

Kesan risiko inventori

  • Keuntungan yang merosot: Kedudukan unilateral akan mengakibatkan kerugian apabila berlaku perubahan harga yang tidak menguntungkan
  • Tekanan kecairan:Dana tambahan diperlukan untuk melindung nilai risiko inventori
  • Strategi gagal: Dalam kes yang melampau, strategi mungkin tidak terus berjalan

Langkah Pengurusan Risiko

  • Sekatan inventori: Tetapkan had kedudukan maksimum untuk mengelakkan pengumpulan berlebihan
  • Lindung Nilai Dinamik: Apabila inventori melebihi ambang, tutup atau lindung nilai secara aktif
  • Kecondongan harga:Laraskan harga belian dan jualan berdasarkan inventori semasa untuk menggalakkan transaksi terbalik

Ringkasan Strategi

Strategi membuat pasaran ialah strategi membuat pasaran berdasarkan kedalaman pasaran. Ia mengekalkan kecairan pasaran dengan melaraskan harga dan kuantiti pesanan beli dan jual secara dinamik. Berbanding dengan strategi perdagangan cucian, strategi pembuatan pasaran mempunyai ciri-ciri berikut:

✅ Kelebihan

  • Dapatkan keuntungan arbitraj sebenar melalui perbezaan harga
  • Selaras dengan model keuntungan pembuat pasar tradisional
  • Menyediakan kecairan pasaran sebenar

❌ Cabaran

  • Berdepan dengan risiko turun naik harga pasaran
  • Pengurusan risiko yang lebih canggih diperlukan
  • Keperluan yang lebih tinggi untuk dana dan teknologi
  • Mekanisme pelarasan harga tidak cukup fleksibel:Mekanisme pergerakan harga linear sukar untuk disesuaikan dengan persekitaran pasaran yang kompleks
  • Risiko inventori yang menonjol: Urus niaga sebelah pihak dengan mudah boleh membawa kepada kedudukan tidak seimbang, dan risikonya amat ketara dalam pasaran trend.

🔮 Arah pengoptimuman masa hadapan

Memandangkan kelemahan strategi kecacatan semasa, kami boleh mengoptimumkan dan memperbaikinya mengikut arah berikut pada masa hadapan:

  1. Strategi membuat pasaran dinamik

    • Pelarasan harga adaptif berdasarkan turun naik pasaran
    • Laraskan strategi pesanan belum selesai secara dinamik berdasarkan kedalaman buku pesanan
    • Memperkenalkan pembelajaran mesin untuk meramal arah pasaran
  2. Strategi pengurusan inventori

    • Pemantauan inventori masa nyata dan penilaian risiko
    • Mekanisme lindung nilai dinamik dan algoritma pengimbangan inventori
    • Strategi kecondongan harga berdasarkan status inventori
  3. Strategi membuat pasaran pelbagai peringkat

    • Menyediakan kecairan pada pelbagai peringkat harga secara serentak
    • Menyuraikan risiko satu titik dan meningkatkan kestabilan keseluruhan
    • Lebih dekat dengan operasi sebenar pembuat pasaran profesional
  4. Pengurusan Risiko Pintar

    • Pemantauan penunjuk risiko masa nyata
    • Henti rugi automatik dan mekanisme kawalan risiko
    • Pengendalian kecemasan situasi pasaran yang tidak normal

Kod Strategi (Disemak)

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 = {'pan_kou': 0}  # 已完成交易量
        # 修正:正确分配精度信息
        self.price_precision = self.precision_info['price_precision']  # 价格精度
        self.amount_precision = self.precision_info['amount_precision']  # 交易量精度
        
        self.traded_pairs = {'pan_kou': []}  # 已挂单的交易对
        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  # 账户余额

        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_trade_by_dict(self, trade_dict):
        '''
        根据交易字典执行交易
        
        Args:
            trade_dict: 交易字典
        '''
        Log('4按照字典开始交易')
        self.refresh_data()  # 刷新数据
        
        if trade_dict['do_trade']:
            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['buy_price'], trade_dict['amount'])  # 挂买单
                sell_id = self.exchange_mid.create_order('sell', trade_dict['sell_price'], trade_dict['amount'])  # 挂卖单
                
                self.traded_pairs['pan_kou'].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 make_pankou_dict(self, price_range, min_price_step, trade_amount):
        
        '''
        生成盘口挂单字典
        
        Args:
            price_range: 价格范围
            min_price_step: 最小价格间隔
            trade_amount: 每次交易量
        
        Returns:
            盘口挂单字典列表
        '''
        Log('3制作盘口挂单字典', '移动盘口次数', self.pending_order_count)
        mid_price = self.mid_price  # 中间价
        
        price_offset = price_range - self.pending_order_count * min_price_step  # 计算价格偏移量
        do_trade = price_offset > 0

        if do_trade:
            buy_price = mid_price - price_offset  # 计算买价
            buy_price = round(buy_price, self.price_precision)  # 四舍五入买价
            
            sell_price = mid_price + price_offset  # 计算卖价
            sell_price = round(sell_price, self.price_precision)  # 四舍五入卖价

            trade_dict = {
                'do_trade': do_trade,
                'buy_price': buy_price,
                'sell_price': sell_price,
                'amount': trade_amount
            }

            Log('返回盘口挂单字典:', trade_dict)
            return trade_dict
        else:
            Log('重置移动盘口次数:', self.pending_order_count)
            self.pending_order_count = 0  # 重置移动盘口次数
            # 修正:当不能交易时返回None或空字典
            return None
            
    
    def check_order_status(self, current_time):
        '''
        检查订单状态
        
        Args:
            current_time: 当前时间戳
        '''
        Log('1开始订单信息检查')
        Log(self.traded_pairs['pan_kou'])
        self.buy_pending = 0
        self.sell_pending = 0
        for traded_pair in self.traded_pairs['pan_kou'].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['pan_kou'].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['pan_kou'].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['pan_kou'] += 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['pan_kou'])
                        Log('清除id:', traded_pair)
                        self.traded_pairs['pan_kou'].remove(traded_pair)  # 移除订单
                        Log('清除后:', self.traded_pairs['pan_kou'])
                    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['pan_kou'])
                        Log('清除id:', traded_pair)
                        self.traded_pairs['pan_kou'].remove(traded_pair)  # 移除订单
                        Log('清除后:', self.traded_pairs['pan_kou'])
                
            elif [sell_order_status['Status'], buy_order_status['Status']] == [1, 1]:
                Log('两订单都已完成')
                Log('完成状态:', buy_order_status['Status'], sell_order_status['Status'], traded_pair['amount'])
                self.done_amount['pan_kou'] += 2 * traded_pair['amount']  # 更新交易量
                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']
                self.traded_pairs['pan_kou'].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) #OKX现货模拟账户
    exchange.IO("trade_super_margin")

    current_time = 0
    target_amount = 1  # 目标交易量
    
    price_range = 5  # 价格范围
    min_price_step = 1  # 最小价格间隔
    trade_amount = 0.01  # 每次交易量
    
    exchange_mid = MidClass(exchange)  # 初始化交易所中间层
    Log(exchange_mid.refresh_data())  # 刷新数据
    market_maker = MarketMaker(exchange_mid)  # 初始化做市策略
    
    # 修正:初始化trade_dict
    trade_dict = None
    
    while market_maker.done_amount['pan_kou'] < target_amount:  # 循环直到完成目标交易量
        Log(market_maker.traded_pairs['pan_kou'])
        market_maker.check_order_status(current_time)  # 检查订单状态
        Sleep(1000)  # 等待1秒
        market_maker.refresh_data()  # 刷新数据
        
        if len(market_maker.traded_pairs['pan_kou']) < 1: # 价格移动,盘口挂单撤销,等待至所有挂单完毕,制定新的挂单字典
            
            Log('2盘口交易对数量小于1')
            trade_dict = market_maker.make_pankou_dict(price_range, min_price_step, trade_amount)  # 生成盘口挂单字典
            Log('新交易字典', trade_dict)
        
        # 修正:确保trade_dict存在且不为None
        if trade_dict and trade_dict.get('do_trade', False):
            market_maker.make_trade_by_dict(trade_dict)  # 执行交易

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

        market_maker.plot_pending()
        market_maker.update_status()
        current_time += 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)