2
پر توجہ دیں
319
پیروکار

ڈیجیٹل کرنسی مارکیٹ بنانے کی حکمت عملی (2): مارکیٹ کی حکمت عملی پر ایک مختصر گفتگو

میں تخلیق کیا: 2025-08-01 11:28:35, تازہ کاری: 2025-08-04 14:15:40
comments   0
hits   692

دیباچہ

ہمارے پچھلے مضمون، “ڈیجیٹل کرنسی میں تجارت کی حکمت عملیوں کو دھونا،” میں ہم نے ایک ہی قیمت پر خرید و فروخت کرکے تجارتی حجم کو جمع کرنے کے لیے حکمت عملی کے فریم ورک کی تفصیل دی ہے۔ اس حکمت عملی کا بنیادی مقصد قیمت کے ثالثی سے فائدہ اٹھانے کے بجائے تبادلے کی چھوٹ یا درجے کے فوائد حاصل کرنا ہے۔ اگرچہ واش ٹریڈنگ کی حکمت عملی تجارتی فریم ورک کے بارے میں سیکھنے کے لیے قیمتی ہے، لیکن ان کا حقیقی منافع محدود ہے اور انہیں تعمیل کے خطرات کا سامنا کرنا پڑ سکتا ہے۔

یہ مضمون پچھلے مضمون کی بنیاد پر مارکیٹ بنانے کی ایک اور عملی حکمت عملی متعارف کرائے گا:معذوری کی حکمت عملیواش ٹریڈنگ حکمت عملی کے برعکس، مارکیٹ بنانے والی حکمت عملی ایک حقیقی ثالثی حکمت عملی ہے جو خرید و فروخت کی قیمتوں کے درمیان پھیلاؤ قائم کرکے منافع پیدا کرتی ہے، جو کہ روایتی مارکیٹ سازوں کے منافع کے ماڈل کے مطابق ہے۔

⚠️ اہم اطلاع

اس مضمون میں پیش کردہ مارکیٹ حکمت عملی کوڈ کا مقصد صرف سیکھنے کے فریم ورک کے طور پر ہے اور یہ حقیقی دنیا کے تجارتی تجربے کی عکاسی نہیں کرتا ہے۔ یہاں پیش کردہ حکمت عملیوں کا مقصد صرف تکنیکی سیکھنے اور تحقیقی مقاصد کے لیے ہے اور حقیقی دنیا کی مارکیٹ کے حالات میں ان کی مکمل توثیق نہیں کی گئی ہے۔ قارئین کو مشورہ دیا جاتا ہے کہ وہ اس معلومات کو استعمال کرنے سے پہلے مکمل بیک ٹیسٹنگ اور خطرے کا جائزہ لیں، اور اسے حقیقی دنیا کی تجارت میں براہ راست استعمال نہیں کرنا چاہیے۔


معذوری کی حکمت عملی کے اصول

مارکیٹ آرڈر بک کی حکمت عملی مارکیٹ بنانے کی حکمت عملی ہے جو ثالثی کے لیے مارکیٹ آرڈر بک (یعنی مارکیٹ کی گہرائی) سے فائدہ اٹھاتی ہے۔ اس حکمت عملی کے تحت، مارکیٹ بنانے والے متحرک طور پر بولی کے درمیان کے وقفے کے اندر آرڈر کی قیمت کو ایڈجسٹ کرتے ہیں اور مارکیٹ کے اتار چڑھاو، آرڈر دینے اور منسوخ کرنے کی بنیاد پر قیمتیں پوچھتے ہیں، اس طرح منافع پیدا کرنے کے لیے مارکیٹ کی لیکویڈیٹی اور قیمت کے قلیل مدتی اتار چڑھاو سے فائدہ اٹھاتے ہیں۔

بنیادی خصوصیات

  1. زیر التواء آرڈر کی قیمتوں کو متحرک طور پر ایڈجسٹ کریں۔:متحرک طور پر خرید و فروخت کے آرڈرز کی قیمتوں کو مارکیٹ کی گہرائی اور قیمت کے اتار چڑھاو کی بنیاد پر ایڈجسٹ کریں تاکہ لین دین کا امکان بڑھ سکے۔
  2. زیر التواء آرڈرز کی تعداد کو کنٹرول کریں۔: اکاؤنٹ کے فنڈز اور پوزیشنز کی بنیاد پر زیر التواء آرڈرز کی تعداد کو کنٹرول کریں تاکہ مارکیٹ کے خطرات کی حد سے زیادہ نمائش سے بچا جا سکے۔
  3. آرڈر کی حیثیت کا انتظام: آرڈر کی صورتحال کو باقاعدگی سے چیک کریں اور نامکمل آرڈرز پر کارروائی کریں۔

دستک کی حکمت عملی سے فرق

خصوصیت حجم بڑھانے کی حکمت عملی معذوری کی حکمت عملی
خرید و فروخت کی قیمتیں۔ ایک ہی قیمت مختلف قیمتیں (قیمت کے فرق کے ساتھ)
منافع کا ماڈل تبادلے کی چھوٹ / مراعات بولی پوچھنا پھیلاؤ
خطرے کی نمائش کم (ایک ہی قیمت کا لین دین) زیادہ (قیمت میں اتار چڑھاؤ کا خطرہ)
عملییت محدود اعلی

معذوری کی حکمت عملی کے فوائد

  • مارکیٹ لیکویڈیٹی کو بہتر بنائیں:مارکیٹ پر آرڈر دے کر، ہم مارکیٹ کی خرید و فروخت کی گہرائی کو بڑھا سکتے ہیں اور مزید تاجروں کو شرکت کے لیے راغب کر سکتے ہیں۔
  • بولی پوچھنے کا پھیلاؤ کمائیں۔: لیکویڈیٹی فراہم کر کے، مارکیٹ بنانے والے بولی مانگنے کا پھیلاؤ کما سکتے ہیں اور اس طرح منافع کما سکتے ہیں۔
  • مارکیٹ کے اتار چڑھاؤ کا لچکدار طریقے سے جواب دیں۔مارکیٹ کے خطرات کو کم کرنے کے لیے مارکیٹ کی حکمت عملی مارکیٹ کے اتار چڑھاو کے مطابق زیر التواء آرڈر کی قیمت کو متحرک طور پر ایڈجسٹ کر سکتی ہے۔

معذوری کی حکمت عملی کے چیلنجز

  • مارکیٹ رسک: مارکیٹ کی قیمتوں میں اتار چڑھاؤ مارکیٹ بنانے والے کے احکامات پر عمل درآمد میں ناکامی کا سبب بن سکتا ہے، یا اس کے نتیجے میں نقصان بھی ہو سکتا ہے۔
  • مالی دباؤ:مارکیٹ بنانے والوں کو مارکیٹ کی خرید و فروخت کی گہرائی کو برقرار رکھنے کے لیے کافی فنڈز کی ضرورت ہوتی ہے۔ ناکافی فنڈز حکمت عملی کے ناکام ہونے کا سبب بن سکتے ہیں۔
  • پیچیدہ آرڈر مینجمنٹ:مارکیٹ کی حکمت عملی کے لیے آرڈر کی حیثیت کی باقاعدگی سے جانچ پڑتال اور نامکمل آرڈرز کی کارروائی کی ضرورت ہوتی ہے، جس سے حکمت عملی کی پیچیدگی بڑھ جاتی ہے۔

معذوری کی حکمت عملی کا ڈھانچہ

ہڑتال کی حکمت عملی سے مطابقت رکھتے ہوئے، اس مضمون کا کوڈ مارکیٹ کوٹیشن کی حکمت عملی پر مبنی مارکیٹ سازی کی حکمت عملی کو نافذ کرتا ہے، جسے بنیادی طور پر دو قسموں میں تقسیم کیا گیا ہے:

  1. MidClass: ایکسچینج کی درمیانی پرت مارکیٹ ڈیٹا، اکاؤنٹ کی معلومات، آرڈر اسٹیٹس وغیرہ حاصل کرنے کے لیے ایکسچینج انٹرفیس کے ساتھ تعامل کے لیے ذمہ دار ہے۔
  2. MarketMaker: مارکیٹ بنانے کی حکمت عملی کی کلاس، مارکیٹ کی حکمت عملی پر عمل درآمد کے لیے ذمہ دار، متحرک طور پر زیر التواء آرڈر کی قیمتیں پیدا کرنا، زیر التواء آرڈر تیار کرنا، آرڈر کی حیثیت کی جانچ کرنا، حکمت عملی کی حیثیت کو اپ ڈیٹ کرنا وغیرہ۔

معذوری کی حکمت عملی کا عمل

1. آغاز

موجود MarketMakerکلاس شروع کرنے کے طریقہ کار میں، پہلے ایکسچینج کی درستگی کی معلومات حاصل کریں اور حکمت عملی کے پیرامیٹرز کو شروع کریں، جیسے کہ لین دین کے حجم کی درستگی، قیمت کی درستگی، وغیرہ۔

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. زیر التواء آرڈرز کی ایک لغت تیار کریں۔

مارکیٹ کی حکمت عملی کا بنیادی مقصد زیر التواء آرڈرز کی ایک لغت تیار کرنا ہے، جس میں خرید و فروخت کی قیمتیں اور مقدار شامل ہیں۔ کوڈ اس لغت کو درمیانی قیمت اور قیمت آفسیٹ کا حساب لگا کر تیار کرتا ہے۔

3. زیر التواء آرڈر کی قیمتوں کی نقل و حرکت

زیر التواء آرڈر کی قیمت کی نقل و حرکت قیمت آفسیٹ کا حساب لگا کر حاصل کی جاتی ہے۔ قیمت آفسیٹ قیمت کی حد پر مبنی ہے (price_range) اور کم از کم قیمت کا وقفہ (min_price_step) کا حساب لگایا گیا۔

price_offset = price_range - self.pending_order_count * min_price_step  # 计算价格偏移量
do_trade = price_offset > 0
  • price_range: قیمت کی حد، زیر التواء آرڈر کی قیمت اور درمیانی قیمت کے درمیان انحراف کی حد کی نشاندہی کرتی ہے۔
  • min_price_step: کم از کم قیمت کا وقفہ، ہر زیر التواء آرڈر کی قیمت کے کم از کم ایڈجسٹمنٹ مرحلے کی نشاندہی کرتا ہے۔
  • price_offset: قیمت آفسیٹ، جو موجودہ آرڈر کی قیمت اور درمیانی قیمت کے درمیان انحراف کی نشاندہی کرتی ہے۔

اگر قیمت آفسیٹ 0 سے زیادہ ہے، تو اس کا مطلب ہے کہ آرڈر جاری رکھا جا سکتا ہے۔ بصورت دیگر، زیر التواء آرڈرز کی تعداد دوبارہ ترتیب دی جائے گی۔

4. زیر التواء آرڈر لغت تیار کریں۔

قیمت آفسیٹ کی بنیاد پر، خرید و فروخت کی قیمتوں کا حساب لگایا جاتا ہے اور زیر التواء آرڈرز کی ایک لغت تیار کی جاتی ہے۔

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: بولی کی قیمت، درمیانی قیمت مائنس قیمت آفسیٹ کے طور پر شمار کی جاتی ہے۔
  • sell_price: قیمت پوچھیں، درمیانی قیمت کے علاوہ قیمت آفسیٹ کے حساب سے۔
  • trade_dict: زیر التواء آرڈرز کی لغت، بشمول خرید و فروخت کی قیمتیں اور مقدار۔

5. مارکیٹ کی تجارت کو انجام دیں۔

تیار کردہ آرڈر لغت کے مطابق، آرڈر کے لین دین کو انجام دیں۔create_orderطریقہ، ایک ہی وقت میں خرید آرڈر اور فروخت کے آرڈرز رکھیں۔

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. آرڈر کی حیثیت چیک کریں۔

باقاعدگی سے آرڈر کی حیثیت چیک کریں اور نامکمل آرڈرز پر کارروائی کریں۔ آرڈر اسٹیٹس پروسیسنگ منطق کراس ٹریڈنگ حکمت عملی سے ملتی جلتی ہے، لیکن قیمت کے فرق کی وجہ سے، جزوی طور پر عمل درآمد کے نتیجے میں حقیقی منافع یا نقصان ہو سکتا ہے۔

معذور حکمت عملی کے اہم نقصانات

1. زیر التواء آرڈرز کی قیمت کی نقل و حرکت کافی لچکدار نہیں ہے۔

اس حکمت عملی میں قیمت کو ایڈجسٹ کرنے کا طریقہ کار نسبتاً آسان ہے، درج ذیل حدود کے ساتھ:

price_offset = price_range - self.pending_order_count * min_price_step  # 计算价格偏移量
  • لکیری ایڈجسٹمنٹ کی حد: قیمت آفسیٹ ایک لکیری کمی کا طریقہ اپناتا ہے اور اسے مارکیٹ کی اصل اتار چڑھاؤ کے مطابق متحرک طور پر ایڈجسٹ نہیں کیا جا سکتا
  • پیرامیٹر کو مستحکم کرناprice_range اورmin_price_stepیہ ایک مقررہ پیرامیٹر ہے اور اسے مارکیٹ کے حالات کے مطابق حقیقی وقت میں ایڈجسٹ نہیں کیا جا سکتا
  • جوابی ہسٹریسیس: جب مارکیٹ کی قیمتیں تیزی سے تبدیل ہوتی ہیں، حکمت عملی کی قیمتوں کی ایڈجسٹمنٹ مارکیٹ کی تال کے مطابق نہیں رہ سکتی ہے۔
  • مارکیٹ بیداری کا فقدان: اس میں مارکیٹ کے مائیکرو اسٹرکچر عوامل جیسے آرڈر بک کی گہرائی اور تجارتی حجم کو مدنظر نہیں رکھا جاتا ہے۔

بہتری کی سمت

  • اتار چڑھاؤ پر مبنی ایک متحرک قیمت ایڈجسٹمنٹ کا طریقہ کار متعارف کرانا
  • مارکیٹ کی گہرائی اور لیکویڈیٹی کی بنیاد پر زیر التواء آرڈر کی قیمتوں کو ایڈجسٹ کریں۔
  • مارکیٹ کے رجحانات کے بارے میں اپنے فیصلے کو بہتر بنائیں اور رجحان کے خلاف آرڈر دینے سے گریز کریں۔

2. انوینٹری رسک

مارکیٹ کی حکمت عملی کو انوینٹری کے خطرے کے سنگین مسائل کا سامنا ہے:

رسک پرفارمنس

  • یکطرفہ لین دین کا خطرہ:جب صرف آرڈرز خریدنے یا بیچنے کے آرڈرز پر عمل درآمد ہوتا ہے تو یہ غیر متوازن پوزیشن کا باعث بنے گا
  • دشاتمک خطرہ: ایک رجحان ساز مارکیٹ میں، ایک طرفہ پوزیشنوں کی ایک بڑی مقدار جمع ہو سکتی ہے۔
  • سرمائے کا قبضہ: ضرورت سے زیادہ انوینٹری بہت سارے فنڈز پر قبضہ کرے گی اور حکمت عملی کی کارکردگی کو متاثر کرے گی۔

کوڈ میں رسک پوائنٹس

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']  # 只有买单成交,积累多头持仓

انوینٹری کے خطرے کا اثر

  • منافع میں کمی: یکطرفہ پوزیشنوں کے نتیجے میں قیمتوں میں غیر موافق تبدیلیاں ہونے پر نقصان ہو گا۔
  • لیکویڈیٹی پریشر: انوینٹری کے خطرات سے نمٹنے کے لیے اضافی فنڈز کی ضرورت ہے۔
  • حکمت عملی ناکام: انتہائی صورتوں میں، حکمت عملی جاری نہیں رہ سکتی ہے۔

رسک مینجمنٹ کے اقدامات

  • انوینٹری پابندیاں: ضرورت سے زیادہ جمع ہونے سے بچنے کے لیے زیادہ سے زیادہ پوزیشن کی حد مقرر کریں۔
  • متحرک ہیجنگ: جب انوینٹری حد سے تجاوز کر جائے تو فعال طور پر بند کریں یا ہیج کریں۔
  • قیمت کا جھکاؤ: ریورس لین دین کی حوصلہ افزائی کے لیے موجودہ انوینٹری کی بنیاد پر خرید و فروخت کی قیمتوں کو ایڈجسٹ کریں

حکمت عملی کا خلاصہ

مارکیٹ بنانے کی حکمت عملی مارکیٹ کی گہرائی پر مبنی مارکیٹ بنانے کی حکمت عملی ہے۔ یہ خرید و فروخت کے آرڈرز کی قیمت اور مقدار کو متحرک طور پر ایڈجسٹ کرکے مارکیٹ کی لیکویڈیٹی کو برقرار رکھتا ہے۔ واش ٹریڈنگ حکمت عملی کے مقابلے میں، مارکیٹ سازی کی حکمت عملی میں درج ذیل خصوصیات ہیں:

✅ فوائد

  • قیمت کے فرق کے ذریعے حقیقی ثالثی منافع حاصل کریں۔
  • روایتی مارکیٹ سازوں کے منافع کے ماڈل کے مطابق
  • حقیقی مارکیٹ لیکویڈیٹی فراہم کرنا

❌ چیلنج

  • مارکیٹ کی قیمتوں میں اتار چڑھاؤ کے خطرات کا سامنا ہے۔
  • مزید نفیس رسک مینجمنٹ کی ضرورت ہے۔
  • فنڈز اور ٹیکنالوجی کے لیے اعلی تقاضے
  • قیمت ایڈجسٹمنٹ کا طریقہ کار کافی لچکدار نہیں ہے۔: لکیری قیمت کی نقل و حرکت کے طریقہ کار کو مارکیٹ کے پیچیدہ ماحول کے مطابق ڈھالنا مشکل ہے۔
  • انوینٹری کے نمایاں خطرات: یک طرفہ لین دین آسانی سے غیر متوازن پوزیشنوں کا باعث بن سکتا ہے، اور یہ خطرہ خاص طور پر رجحان ساز بازاروں میں نمایاں ہے۔

🔮 مستقبل کی اصلاح کی ہدایات

موجودہ معذوری کی حکمت عملی کی خامیوں کے پیش نظر، ہم اسے مستقبل میں درج ذیل سمتوں میں بہتر اور بہتر بنا سکتے ہیں:

  1. متحرک مارکیٹ بنانے کی حکمت عملی

    • منڈی کے اتار چڑھاؤ کی بنیاد پر قیمت کی موافقت
    • آرڈر بک کی گہرائی کی بنیاد پر زیر التواء آرڈر کی حکمت عملیوں کو متحرک طور پر ایڈجسٹ کریں۔
    • مارکیٹ کی سمت کا اندازہ لگانے کے لیے مشین لرننگ کا تعارف
  2. انوینٹری مینجمنٹ کی حکمت عملی

    • ریئل ٹائم انوینٹری کی نگرانی اور خطرے کی تشخیص
    • ڈائنامک ہیجنگ میکانزم اور انوینٹری بیلنسنگ الگورتھم
    • انوینٹری کی حیثیت پر مبنی قیمت کے جھکاؤ کی حکمت عملی
  3. ملٹی لیول مارکیٹ بنانے کی حکمت عملی

    • ایک ساتھ قیمت کی متعدد سطحوں پر لیکویڈیٹی فراہم کرنا
    • واحد نکاتی خطرات کو منتشر کریں اور مجموعی استحکام کو بہتر بنائیں
    • پیشہ ورانہ مارکیٹ سازوں کے اصل آپریشن کے قریب
  4. ذہین رسک مینجمنٹ

    • ریئل ٹائم رسک انڈیکیٹر مانیٹرنگ
    • خودکار اسٹاپ لاس اور رسک کنٹرول میکانزم
    • غیر معمولی مارکیٹ کے حالات کا ہنگامی ہینڈلنگ

حکمت عملی کوڈ (نظر ثانی شدہ)

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)