2
ফোকাস
319
অনুসারী

সালিসি কৌশলগুলির একটি সংক্ষিপ্ত বিশ্লেষণ: স্বল্প সময়ের ব্যবধানে কম ঝুঁকিপূর্ণ সুযোগগুলি কীভাবে গ্রহণ করা যায়

তৈরি: 2025-03-07 14:11:55, আপডেট করা হয়েছে: 2025-03-10 17:38:06
comments   0
hits   1386

সালিসি কৌশলগুলির একটি সংক্ষিপ্ত বিশ্লেষণ: স্বল্প সময়ের ব্যবধানে কম ঝুঁকিপূর্ণ সুযোগগুলি কীভাবে গ্রহণ করা যায়

এই কৌশলের অনুপ্রেরণা এসেছে ঝিহু লেখক “ড্রিম ডিলার” -এর “ট্রাম্প অ্যান্ড মেলানিয়া লো-রিস্ক কোরিলেশন আরবিট্রেজ মডেল” - এর সুযোগ পোস্ট থেকে। এই প্রবন্ধটি BN (TRUMP এবং MELANIA) তে চালু হওয়া দুটি চুক্তির মধ্যে মূল্যের পারস্পরিক সম্পর্ক অন্বেষণ করে এবং স্বল্পমেয়াদী বাজারের ওঠানামা ধরার এবং কম ঝুঁকিপূর্ণ সালিশ অর্জনের চেষ্টা করার জন্য দুটি চুক্তির মধ্যে সূক্ষ্ম সময় বিলম্ব ব্যবহার করে। এরপর, আমরা এই কৌশলের নীতিমালা, কোড বাস্তবায়নের যুক্তি ব্যাখ্যা করব এবং সম্ভাব্য অপ্টিমাইজেশনের দিকনির্দেশনাগুলি অন্বেষণ করব।

আগে থেকে জানা দরকার।লক্ষ্য করুনসমস্যা হলো এই কৌশলটি একটি ম্যানুয়াল ট্রেডিং কাজের সমতুল্য। দুটি উপযুক্ত ট্রেডিং জোড়া খুঁজে বের করার পরেই এটিতে একটি নির্দিষ্ট লাভের সুযোগ থাকে এবং ট্রেডিং জোড়ার লাভের আয়ু কম হতে পারে। যখন দেখা যায় যে কোনও লাভের সুযোগ নেই, তখন লাভের হ্রাস বা এমনকি ক্ষতি রোধ করার জন্য সময়মতো কৌশলটি বন্ধ করা প্রয়োজন।


১. কৌশলগত নীতিমালা এবং বাজারের প্রাসঙ্গিকতা

১.১ কৌশলগত পটভূমি

ট্রাম্প এবং মেলানিয়া উভয় চুক্তি একই ইস্যুকারী দল দ্বারা জারি করা হয় এবং একই নিয়ন্ত্রণকারী তহবিল থাকে, তাই তাদের মূল্য প্রবণতা বেশিরভাগ সময় অত্যন্ত সুসংগত থাকে। তবে, চুক্তি নকশা বা বাজার বাস্তবায়নের মতো কারণগুলির কারণে, মেলানিয়ার দাম ট্রাম্পের দামের চেয়ে ১-২ সেকেন্ড পিছিয়ে থাকে। এই সামান্য বিলম্বের ফলে সালিশকারীদের দামের পার্থক্য ধরার এবং উচ্চ-ফ্রিকোয়েন্সি কপি ট্রেডিং পরিচালনা করার সুযোগ পাওয়া যায়। সহজ কথায়, যখন ট্রাম্প দ্রুত ওঠানামা করে, মেলানিয়া খুব শীঘ্রই একই পদ্ধতি অনুসরণ করে। এই বিলম্বের সুযোগ গ্রহণ করে, লেনদেন কম ঝুঁকিতে সম্পন্ন করা যেতে পারে।

সালিসি কৌশলগুলির একটি সংক্ষিপ্ত বিশ্লেষণ: স্বল্প সময়ের ব্যবধানে কম ঝুঁকিপূর্ণ সুযোগগুলি কীভাবে গ্রহণ করা যায়

সালিসি কৌশলগুলির একটি সংক্ষিপ্ত বিশ্লেষণ: স্বল্প সময়ের ব্যবধানে কম ঝুঁকিপূর্ণ সুযোগগুলি কীভাবে গ্রহণ করা যায়

১.২ ক্রিপ্টো বাজারে ব্যাপকতা

ক্রিপ্টো বাজারে অনুরূপ পারস্পরিক সম্পর্ক ঘটনা অস্বাভাবিক নয়:

  • একই প্রকল্পের বিভিন্ন চুক্তি বা ডেরিভেটিভস: একই অন্তর্নিহিত সম্পদ বা দলের পটভূমির কারণে, বিভিন্ন পণ্যের দামের মধ্যে প্রায়শই শক্তিশালী সংযোগ থাকে।
  • ক্রস-এক্সচেঞ্জ আরবিট্রেজ: বিভিন্ন এক্সচেঞ্জে একই সম্পদের তারল্য এবং মিল প্রক্রিয়ার পার্থক্যের কারণে সামান্য মূল্যের পার্থক্য থাকতে পারে।
  • স্টেবলকয়েন এবং ফিয়াট-পেগড পণ্য: এই পণ্যগুলিতে প্রায়শই বিনিময় হারের বিচ্যুতি প্রত্যাশিত থাকে এবং সালিশকারীরা সামান্য ওঠানামা থেকে লাভবান হতে পারেন।

এই পারস্পরিক সম্পর্ক উচ্চ-ফ্রিকোয়েন্সি ব্যবসায়ী এবং সালিশকারীদের স্থিতিশীল ট্রেডিং সংকেত এবং কম ঝুঁকিপূর্ণ পরিচালনার সুযোগ প্রদান করে, তবে এর জন্য ট্রেডিং কৌশলগুলিকে বাজারের সূক্ষ্ম পরিবর্তনের প্রতি অত্যন্ত সংবেদনশীল হতে হবে এবং বাস্তব সময়ে প্রতিক্রিয়া জানাতে সক্ষম হতে হবে।


2. কোড লজিকের বিস্তারিত ব্যাখ্যা

কোডটি মূলত বেশ কয়েকটি অংশ নিয়ে গঠিত, প্রতিটি মডিউল সালিসি কৌশলের মূল ধাপগুলির সাথে মিলে যায়।

২.১ সহায়ক ফাংশনের বর্ণনা

অবস্থানের তথ্য পান

function GetPosition(pair){
    let pos = exchange.GetPosition(pair)
    if(pos.length == 0){
        return {amount:0, price:0, profit:0}
    }else if(pos.length > 1){
        throw '不支持双向持仓'
    }else if(pos.length == 1){
        return {amount:pos[0].Type == 0 ? pos[0].Amount : -pos[0].Amount, price:pos[0].Price, profit:pos[0].Profit}
    }else{
        Log('未获取仓位数据')
        return null
    }
}
  • কার্যকারিতা: এই ফাংশনটি নির্দিষ্ট ট্রেডিং পেয়ারের অবস্থানের তথ্য সমানভাবে পেতে এবং দীর্ঘ এবং সংক্ষিপ্ত অবস্থানগুলিকে ধনাত্মক এবং ঋণাত্মক সংখ্যায় রূপান্তর করতে ব্যবহৃত হয়।
  • যুক্তি: যদি পজিশনটি খালি থাকে, তাহলে ডিফল্ট শূন্য পজিশনটি ফেরত দিন; যদি একাধিক অর্ডার থাকে, তাহলে একটি ত্রুটি রিপোর্ট করা হয় (একমুখী পজিশন নিশ্চিত করার জন্য); অন্যথায়, বর্তমান পজিশনের দিকনির্দেশনা, মূল্য এবং ভাসমান লাভ এবং ক্ষতি ফেরত দিন।

অ্যাকাউন্ট শুরু করুন

function InitAccount(){
    let account = _C(exchange.GetAccount)
    let total_eq = account.Equity

    let init_eq = 0
    if(!_G('init_eq')){
        init_eq = total_eq
        _G('init_eq', total_eq)
    }else{
        init_eq = _G('init_eq')
    }

    return init_eq
}
  • কার্যকারিতা: এই ফাংশনটি পরবর্তী লাভ এবং ক্ষতির গণনার ভিত্তি হিসাবে অ্যাকাউন্ট ইক্যুইটি শুরু এবং রেকর্ড করতে ব্যবহৃত হয়।

মুলতুবি থাকা অর্ডার বাতিল করুন

function CancelPendingOrders() {
    orders = exchange.GetOrders();  // 获取订单
    for (let order of orders) {
        if (order.Status == ORDER_STATE_PENDING) {  // 只取消未完成的订单
            exchange.CancelOrder(order.Id);  // 取消挂单
        }
    }
}
  • কার্যকারিতা: অর্ডার দেওয়ার আগে, অর্ডারের দ্বন্দ্ব বা ডুপ্লিকেট অর্ডার প্রতিরোধ করার জন্য পূর্বে অসম্পূর্ণ যেকোনো অর্ডার বাতিল করতে ভুলবেন না।

২.২ প্রধান লেনদেনের যুক্তি

প্রধান ফাংশনটি নিম্নলিখিত ধাপগুলি ধারাবাহিকভাবে সম্পাদন করার জন্য একটি অসীম লুপ ব্যবহার করে:

  1. তথ্য অর্জন এবং বাজার গণনা
    প্রতিটি চক্র শুরু হয়exchange.GetRecords যথাক্রমে Pair_A এবং Pair_B এর বাজার তথ্য পান।

    • গণনার সূত্র: [ ratio = \frac{Close{A} - Open{A}}{Open{A}} - \frac{Close{B} - Open{B}}{Open{B}} ] দুটির উত্থান এবং পতনের তুলনা করে, আমরা নির্ধারণ করতে পারি যে দামের অস্বাভাবিক পার্থক্য আছে কিনা। যখন দামের পার্থক্য প্রিসেট ডিফলেভেলের চেয়ে বেশি হয়, তখন খোলার অবস্থা ট্রিগার হয়।
  2. খোলার শর্ত নির্ধারণ করুন এবং একটি অর্ডার দিন
    যখন কোন বর্তমান অবস্থান (position_B.amount == 0) না থাকে এবং ট্রেডিং অনুমোদিত হয় (afterTrade==1):

    • যদি অনুপাত diffLevel এর চেয়ে বেশি হয়, তাহলে মনে করা হয় যে বাজারটি উঠতে চলেছে, তাই Pair_B (বাই লং পজিশন) এর জন্য একটি বাই অর্ডার জারি করা হয়।
    • যদি অনুপাত -diffLevel-এর কম হয়, তাহলে ধরে নেওয়া হবে যে বাজার পতনের পথে এবং একটি বিক্রয় আদেশ জারি করা হবে (একটি সংক্ষিপ্ত অবস্থান খোলা হবে)। অর্ডার দেওয়ার আগে, বর্তমান অর্ডারের অবস্থা পরিষ্কার করা হয়েছে তা নিশ্চিত করার জন্য অর্ডার বাতিলকরণ ফাংশনটি কল করা হবে।
  3. স্টপ-প্রফিট এবং স্টপ-লস যুক্তি
    একবার একটি পজিশন প্রতিষ্ঠিত হয়ে গেলে, কৌশলটি পজিশনের দিকনির্দেশনা অনুসারে সংশ্লিষ্ট টেক-প্রফিট এবং স্টপ-লস অর্ডার সেট করবে:

    • দীর্ঘ পজিশন (কিনুন): টেক প্রফিট মূল্যকে (1 + stopProfitLevel) দ্বারা গুণিত পজিশন মূল্যে এবং স্টপ লস মূল্যকে (1 - stopLossLevel) দ্বারা গুণিত পজিশন মূল্যে সেট করুন।
    • শর্ট পজিশন (বিক্রয়): টেক প্রফিট মূল্য (1 - stopProfitLevel) দ্বারা গুণিত পজিশন মূল্যে সেট করা হয়, এবং স্টপ লস মূল্য (1 + stopLossLevel) দ্বারা গুণিত পজিশন মূল্যে সেট করা হয়। সিস্টেমটি রিয়েল-টাইম বাজার মূল্য পর্যবেক্ষণ করবে। একবার টেক-প্রফিট বা স্টপ-লস শর্তাবলী চালু হয়ে গেলে, মূল পেন্ডিং অর্ডার বাতিল করা হবে এবং পজিশনটি বন্ধ করার জন্য একটি অর্ডার দেওয়া হবে।
  4. পজিশন বন্ধ করার পর লাভের পরিসংখ্যান এবং লগ রেকর্ড
    প্রতিটি পজিশন বন্ধ হওয়ার পর, সিস্টেম অ্যাকাউন্ট ইকুইটির পরিবর্তনগুলি গ্রহণ করবে এবং লাভের সংখ্যা, ক্ষতির সংখ্যা এবং ক্রমবর্ধমান লাভ/ক্ষতির পরিমাণ গণনা করবে।
    একই সময়ে, টেবিল এবং গ্রাফগুলি বর্তমান অবস্থানের তথ্য, লেনদেনের পরিসংখ্যান এবং চক্র বিলম্বকে বাস্তব সময়ে প্রদর্শন করতে ব্যবহৃত হয়, যা পরবর্তী কৌশলগত প্রভাব বিশ্লেষণের জন্য সুবিধাজনক।


৩. কৌশল অপ্টিমাইজেশন এবং সম্প্রসারণ পদ্ধতি

যদিও এই কৌশলটি দুটি অত্যন্ত সম্পর্কযুক্ত চুক্তির মধ্যে সূক্ষ্ম বিলম্বকে কাজে লাগায়, তবুও অনেক ক্ষেত্র উন্নত করা যেতে পারে:

৩.১ প্যারামিটার অপ্টিমাইজেশন এবং গতিশীল সমন্বয়

  • থ্রেশহোল্ড সমন্বয়: বিভিন্ন বাজার পরিবেশে diffLevel, stopProfitLevel এবং stopLossLevel এর মতো প্যারামিটারগুলি সামঞ্জস্য করার প্রয়োজন হতে পারে। এই প্যারামিটারগুলি স্বয়ংক্রিয়ভাবে ঐতিহাসিক তথ্যের ব্যাকটেস্টিংয়ের মাধ্যমে অথবা রিয়েল টাইমে মডেলগুলিকে গতিশীলভাবে সামঞ্জস্য করে (যেমন, মেশিন লার্নিং অ্যালগরিদম) অপ্টিমাইজ করা যেতে পারে।
  • পজিশন ব্যবস্থাপনা:বর্তমান কৌশলে একটি পজিশন খোলার জন্য একটি নির্দিষ্ট ট্রেড_নাম্বার ব্যবহার করা হয়। ভবিষ্যতে, আমরা একটি গতিশীল পজিশন ম্যানেজমেন্ট বা ব্যাচে পজিশন খোলার এবং ধীরে ধীরে লাভ নেওয়ার একটি প্রক্রিয়া চালু করার কথা বিবেচনা করতে পারি যাতে একটি একক লেনদেনের ঝুঁকি কমানো যায়।

৩.২ ট্রেডিং সিগন্যাল ফিল্টারিং

  • বহুমুখী সংকেত: শুধুমাত্র দাম বৃদ্ধি এবং হ্রাসের উপর ভিত্তি করে অনুপাত গণনা করলে শব্দের প্রভাব পড়তে পারে। মিথ্যা সংকেত আরও ফিল্টার করার জন্য আপনি ট্রেডিং ভলিউম, অর্ডার বুকের গভীরতা এবং প্রযুক্তিগত সূচক (যেমন RSI, MACD, ইত্যাদি) প্রবর্তন করার কথা বিবেচনা করতে পারেন।
  • বিলম্ব ক্ষতিপূরণ: মেলানিয়ায় ১-২ সেকেন্ড বিলম্ব হওয়ার কথা বিবেচনা করে, আরও সঠিক সময় সিঙ্ক্রোনাইজেশন এবং সংকেত পূর্বাভাস প্রক্রিয়া তৈরি করা প্রবেশের সময়ের নির্ভুলতা উন্নত করতে সাহায্য করবে।

৩.৩ সিস্টেমের দৃঢ়তা এবং ঝুঁকি নিয়ন্ত্রণ

  • ত্রুটি হ্যান্ডলিং: নেটওয়ার্ক বিলম্ব বা এক্সচেঞ্জ ইন্টারফেসের অসঙ্গতির সম্মুখীন হলে সময়মত প্রতিক্রিয়া নিশ্চিত করতে এবং সিস্টেম ব্যর্থতার কারণে অপ্রত্যাশিত ক্ষতি প্রতিরোধ করতে ব্যতিক্রম হ্যান্ডলিং এবং লগিং যোগ করুন।
  • ঝুঁকি নিয়ন্ত্রণ কৌশল: চরম বাজার পরিবেশে ধারাবাহিক ক্ষতি রোধ করার জন্য দৈনিক বা একক লেনদেনের ক্ষতির সীমা নির্ধারণের জন্য মূলধন ব্যবস্থাপনা এবং সর্বাধিক ড্রডাউন নিয়ন্ত্রণ একত্রিত করুন।

৩.৪ কোড এবং আর্কিটেকচার অপ্টিমাইজেশন

  • অ্যাসিনক্রোনাস প্রক্রিয়াকরণ: বর্তমানে, কৌশল লুপটি প্রতি ১০০ মিলিসেকেন্ডে কার্যকর করা হয়। অ্যাসিঙ্ক্রোনাস প্রক্রিয়াকরণ এবং মাল্টি-থ্রেডেড অপ্টিমাইজেশনের মাধ্যমে, বিলম্ব এবং কার্যকরকরণ ব্লকিংয়ের ঝুঁকি হ্রাস করা যেতে পারে।
  • কৌশল ব্যাকটেস্টিং এবং সিমুলেশন: বিভিন্ন বাজার পরিস্থিতিতে কৌশলগুলির কর্মক্ষমতা যাচাই করার জন্য এবং বাস্তব ট্রেডিংয়ে কৌশলগুলিকে আরও স্থিতিশীলভাবে চালাতে সহায়তা করার জন্য একটি সম্পূর্ণ ব্যাকটেস্টিং সিস্টেম এবং রিয়েল-টাইম সিমুলেটেড ট্রেডিং পরিবেশ প্রবর্তন করুন।

4. সারাংশ

এই প্রবন্ধে স্বল্প-সময়ের জন্য পিছিয়ে থাকা চুক্তির পারস্পরিক সম্পর্ক সালিসি কৌশলের মৌলিক নীতি এবং বাস্তবায়ন কোড সম্পর্কে বিস্তারিত আলোচনা করা হয়েছে। মূল্য বৃদ্ধি এবং হ্রাসের পার্থক্যকে কাজে লাগানো থেকে শুরু করে প্রবেশের সুযোগগুলি দখল করা, অবস্থান ব্যবস্থাপনার জন্য স্টপ-প্রফিট এবং স্টপ-লস নির্ধারণ করা পর্যন্ত, এই কৌশলটি ক্রিপ্টো বাজারে সম্পদের মধ্যে উচ্চ পারস্পরিক সম্পর্কের পূর্ণ সুবিধা গ্রহণ করে। একই সাথে, আমরা রিয়েল-টাইম অ্যাপ্লিকেশনগুলিতে কৌশলটির স্থিতিশীলতা এবং লাভজনকতা আরও উন্নত করার জন্য গতিশীল প্যারামিটার সমন্বয়, সিগন্যাল ফিল্টারিং, সিস্টেম শক্তিশালীকরণ এবং কোড অপ্টিমাইজেশন সহ বেশ কয়েকটি অপ্টিমাইজেশন পরামর্শও পেশ করেছি।

যদিও কৌশলটি অনন্যভাবে অনুপ্রাণিত এবং বাস্তবায়ন করা সহজ, উচ্চ-ফ্রিকোয়েন্সি এবং অস্থির ক্রিপ্টো বাজারে যেকোনো সালিসি কার্যক্রম সতর্কতার সাথে পরিচালনা করতে হবে। আমি আশা করি এই নিবন্ধটি পরিমাণগত ট্রেডিং এবং সালিসি কৌশল সম্পর্কে আগ্রহী বন্ধুদের জন্য মূল্যবান তথ্যসূত্র এবং অনুপ্রেরণা প্রদান করতে পারবে।


দ্রষ্টব্য: কৌশল পরীক্ষার পরিবেশ হল OKX সিমুলেশন ট্রেডিং, এবং বিভিন্ন এক্সচেঞ্জের জন্য নির্দিষ্ট বিবরণ পরিবর্তন করা যেতে পারে।

function GetPosition(pair){
    let pos = exchange.GetPosition(pair)
    if(pos.length == 0){
        return {amount:0, price:0, profit:0}
    }else if(pos.length > 1){
        throw '不支持双向持仓'
    }else if(pos.length == 1){
        return {amount:pos[0].Type == 0 ? pos[0].Amount : -pos[0].Amount, price:pos[0].Price, profit:pos[0].Profit}
    }else{
        Log('未获取仓位数据')
        return null
    }
}

function InitAccount(){
    let account = _C(exchange.GetAccount)
    let total_eq = account.Equity

    let init_eq = 0
    if(!_G('init_eq')){
        init_eq = total_eq
        _G('init_eq', total_eq)
    }else{
        init_eq = _G('init_eq')
    }

    return init_eq
}

function CancelPendingOrders() {
    orders = exchange.GetOrders();  // 获取订单
    for (let order of orders) {
        if (order.Status == ORDER_STATE_PENDING) {  // 只取消未完成的订单
            exchange.CancelOrder(order.Id);  // 取消挂单
        }
    }
}

var pair_a = Pair_A + "_USDT.swap";
var pair_b = Pair_B + "_USDT.swap";


function main() {
    exchange.IO('simulate', true);
    LogReset(0);
    Log('策略开始运行')

    var precision = exchange.GetMarkets();
    var ratio = 0

    var takeProfitOrderId = null;
    var stopLossOrderId = null;
    var successCount = 0;
    var lossCount = 0;
    var winMoney = 0;
    var failMoney = 0;
    var afterTrade = 1;

    var initEq = InitAccount();

    var curEq = initEq

    var pricePrecision = precision[pair_b].PricePrecision;

    while (true) {
        try{
            let startLoopTime = Date.now();
            let position_B = GetPosition(pair_b);
            let new_r_pairB = exchange.GetRecords(pair_b, 1).slice(-1)[0];

            if (!new_r_pairB || !position_B) {
                Log('跳过当前循环');
                continue;
            }
            
            // 合并交易条件:检查是否可以开仓并进行交易
            if (afterTrade == 1 && position_B.amount == 0) {
                
                let new_r_pairA = exchange.GetRecords(pair_a, 1).slice(-1)[0];
                if (!new_r_pairA ) {
                    Log('跳过当前循环');
                    continue;
                }
                
                ratio = (new_r_pairA.Close - new_r_pairA.Open) / new_r_pairA.Open - (new_r_pairB.Close - new_r_pairB.Open) / new_r_pairB.Open;

                if (ratio > diffLevel) {
                    CancelPendingOrders();
                    Log('实时ratio:', ratio, '买入:', pair_b, position_B.amount);
                    exchange.CreateOrder(pair_b, "buy", -1, Trade_Number);
                    afterTrade = 0;
                } else if (ratio < -diffLevel) {
                    CancelPendingOrders();
                    Log('实时ratio:', ratio, '卖出:', pair_b, position_B.amount);
                    exchange.CreateOrder(pair_b, "sell", -1, Trade_Number);
                    afterTrade = 0;
                }            
            }

            

            // 判断止盈止损
            if (position_B.amount > 0 && takeProfitOrderId == null && stopLossOrderId == null && afterTrade == 0) {
                Log('多仓持仓价格:', position_B.price, '止盈价格:', position_B.price * (1 + stopProfitLevel), '止损价格:', position_B.price * (1 - stopLossLevel));
                takeProfitOrderId = exchange.CreateOrder(pair_b, "closebuy", position_B.price * (1 + stopProfitLevel), position_B.amount);
                Log('止盈订单:', takeProfitOrderId);
            }

            if (position_B.amount > 0 && takeProfitOrderId != null && stopLossOrderId == null && new_r_pairB.Close < position_B.price * (1 - stopLossLevel) && afterTrade == 0) {
                CancelPendingOrders();
                takeProfitOrderId = null
                Log('多仓止损');
                stopLossOrderId = exchange.CreateOrder(pair_b, "closebuy", -1, position_B.amount);
                Log('多仓止损订单:', stopLossOrderId);
            }

            if (position_B.amount < 0 && takeProfitOrderId == null && stopLossOrderId == null && afterTrade == 0) {
                Log('空仓持仓价格:', position_B.price, '止盈价格:', position_B.price * (1 - stopProfitLevel), '止损价格:', position_B.price * (1 + stopLossLevel));
                takeProfitOrderId = exchange.CreateOrder(pair_b, "closesell", position_B.price * (1 - stopProfitLevel), -position_B.amount);
                Log('止盈订单:', takeProfitOrderId, '当前价格:', new_r_pairB.Close );
            }

            if (position_B.amount < 0 && takeProfitOrderId != null && stopLossOrderId == null && new_r_pairB.Close > position_B.price * (1 + stopLossLevel) && afterTrade == 0) {
                CancelPendingOrders();
                takeProfitOrderId = null
                Log('空仓止损');
                stopLossOrderId = exchange.CreateOrder(pair_b, "closesell", -1, -position_B.amount);
                Log('空仓止损订单:', stopLossOrderId);
            }


            // 平市价单未完成
            if (takeProfitOrderId == null && stopLossOrderId != null && afterTrade == 0) {
                
                let stoplosspos = GetPosition(pair_b)
                if(stoplosspos.amount > 0){
                    Log('平多仓市价单未完成')
                    exchange.CreateOrder(pair_b, 'closebuy', -1, stoplosspos.amount)
                }
                if(stoplosspos.amount < 0){
                    Log('平空仓市价单未完成')
                    exchange.CreateOrder(pair_b, 'closesell', -1, -stoplosspos.amount)
                }
            }

            // 未平仓完毕
            if (Math.abs(position_B.amount) < Trade_Number && Math.abs(position_B.amount) > 0 && afterTrade == 0){
                Log('未平仓完毕')
                if(position_B.amount > 0){
                    exchange.CreateOrder(pair_b, 'closebuy', -1, position_B.amount)
                }else{
                    exchange.CreateOrder(pair_b, 'closesell', -1, -position_B.amount)
                }
            }

            // 计算盈亏
            if (position_B.amount == 0 && afterTrade == 0) {
                if (stopLossOrderId != null || takeProfitOrderId != null) {
                    stopLossOrderId = null;
                    takeProfitOrderId = null;

                    let afterEquity = exchange.GetAccount().Equity;
                    let curAmount = afterEquity - curEq;

                    curEq = afterEquity

                    if (curAmount > 0) {
                        successCount += 1;
                        winMoney += curAmount;
                        Log('盈利金额:', curAmount);
                    } else {
                        lossCount += 1;
                        failMoney += curAmount;
                        Log('亏损金额:', curAmount);
                    }
                    afterTrade = 1;
                }
            }

            if (startLoopTime % 10 == 0) {  // 每 10 次循环记录一次
                let curEquity = exchange.GetAccount().Equity

                // 输出交易信息表
                let table = {
                    type: "table",
                    title: "交易信息",
                    cols: [
                        "初始权益", "当前权益", Pair_B + "仓位", Pair_B + "持仓价", Pair_B + "收益", Pair_B + "价格", 
                        "盈利次数", "盈利金额", "亏损次数", "亏损金额", "胜率", "盈亏比"
                    ],
                    rows: [
                        [
                            _N(_G('init_eq'), 2),  // 初始权益
                            _N(curEquity, 2),  // 当前权益
                            _N(position_B.amount, 1),  // Pair B 仓位
                            _N(position_B.price, pricePrecision),  // Pair B 持仓价
                            _N(position_B.profit, 1),  // Pair B 收益
                            _N(new_r_pairB.Close, pricePrecision),  // Pair B 价格
                            _N(successCount, 0),  // 盈利次数
                            _N(winMoney, 2),  // 盈利金额
                            _N(lossCount, 0),  // 亏损次数
                            _N(failMoney, 2),  // 亏损金额
                            _N(successCount + lossCount === 0 ? 0 : successCount / (successCount + lossCount), 2),  // 胜率
                            _N(failMoney === 0 ? 0 : winMoney / failMoney * -1, 2)  // 盈亏比
                        ]
                    ]
                };

                $.PlotMultLine("ratio plot", "幅度变化差值", ratio, startLoopTime);
                $.PlotMultHLine("ratio plot", diffLevel, "差价上限", "red", "ShortDot");
                $.PlotMultHLine("ratio plot", -diffLevel, "差价下限", "blue", "ShortDot");

                LogStatus("`" + JSON.stringify(table) + "`");
                LogProfit(curEquity - initEq, '&')
            }
        }catch(e){
            Log('策略出现错误:', e)
        }

        
        Sleep(200);
    }
}