রিসোর্স লোড হচ্ছে... লোডিং...

ক্রিপ্টোকারেন্সি স্পট হেজিং কৌশল (2)

লেখক:নিনাবাদাস, সৃষ্টিঃ ২০২২-০৪-১৪ ১৬ঃ১৭ঃ৪৬, আপডেটঃ ২০২২-০৪-১৫ ১৪ঃ১৬ঃ২৩

ক্রিপ্টোকারেন্সি স্পট হেজিং কৌশল (2)

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

কৌশল উন্নত করার প্রয়োজনীয়তা

  • স্পট এক্সচেঞ্জ অবজেক্ট মার্জিন মোড পরিবর্তন করুন এই পরিবর্তনটি শুধুমাত্র বট সম্পর্কিত। কিছু স্পট প্ল্যাটফর্মের স্পট মার্জিন ইন্টারফেস রয়েছে, যা এফএমজেডেও ক্যাপসুল করা হয়। এক্সচেঞ্জ অবজেক্টগুলির জন্য যা সরাসরি এফএমজেডে ক্যাপসুল করা হয় এবং স্পট মার্জিন সমর্থন করে, আপনি সরাসরি মোডটি স্যুইচ করতে পারেন।
  • আরো স্প্রেড চার্ট প্রদর্শন যোগ করুন আরো স্প্রেড চার্ট প্রদর্শন যোগ করার জন্য, এবং আমরা শুধুমাত্র স্প্রেড বক্ররেখা প্লটA->BএবংB->A, পাশাপাশি অনুভূমিক বিস্তার ট্রিগার লাইন, আমরা সরাসরি ব্যবহার করতে পারেনchart plot library; সুবিধা হল সরলতা এবং সহজ ব্যবহার. এখান থেকে, আমরা কিভাবে FMZ ফাংশন ব্যবহার করতে শিখতেtemplate library together.
  • একতরফা হেজিং এর ফাংশন এই পরিবর্তনটি তুলনামূলকভাবে বড়, কারণ নির্দিষ্ট হেজ ট্রেডিংয়ের সময় দুটি প্ল্যাটফর্মের মধ্যে দামের স্প্রেড সম্পূর্ণরূপে বিপরীত করা কঠিন। বেশিরভাগ সময়, এক প্ল্যাটফর্মের দাম অন্য প্ল্যাটফর্মের দামের তুলনায় ধারাবাহিকভাবে বেশি থাকে। এই সময়ে, যদি আমাদের সম্পদগুলি সম্পূর্ণরূপে হেজ করা হয় (অর্থাৎ, সমস্ত মুদ্রা প্রতীকগুলি কম দামের প্ল্যাটফর্মে থাকে এবং সম্পদগুলি উচ্চতর দামের প্ল্যাটফর্মে থাকে) । হেজিং স্থবির হয় এবং মুনাফা অর্জনের জন্য স্প্রেড অস্থিরতার উপর নির্ভর করা আর সম্ভব নয়। এই সময়ে, আপনাকে কেবলমাত্র অল্প পরিমাণে সম্পদ হারাতে হেজিং এবং মুদ্রা প্রতীকগুলি ফিরিয়ে দেওয়ার কৌশলটি করতে হবে (মুদ্রা প্রতীকগুলিকে আবার উচ্চ মূল্যের প্ল্যাটফর্মে ফিরিয়ে দিন) । যখন দামের স্প্রেড আবার বড় হয়, আপনি হেজিং চালিয়ে যেতে পারেন এবং লাভ করতে পারেন।
  • ইন্টারেক্টিভভাবে হেজ স্প্রেড লাইন মত পরামিতি পরিবর্তন
    কৌশলটিতে ইন্টারেক্টিভ ফাংশন যোগ করুন, যাতে রিয়েল টাইমে স্প্রেড ট্রিগার লাইন পরিবর্তন করা যায়।
  • স্ট্যাটাস বার তথ্য পরিচালনা করুন এবং টেবিল বিন্যাসে এটি প্রদর্শন করুন সুবিধাজনক পর্যবেক্ষণের জন্য প্রদর্শিত হওয়া তথ্যগুলি সাজানো এবং পরিচালনা করা।

এরপর, আসুন একের পর এক সেই ডিজাইনিং আইডিয়াগুলো বাস্তবায়ন করি।

স্পট এক্সচেঞ্জ অবজেক্ট মার্জিন মোড পরিবর্তন করুন

উদাহরণস্বরূপ Binance স্পট বট নিন। স্পট মার্জিন মোডে স্যুইচ করতে, কোড ব্যবহার করুনexchanges[i].IO, পরামিতি আমদানি করুনtrade_normalআইসোলেটেড মার্জিনে স্যুইচ করতে এবং আমদানি করতেtrade_super_marginto cross margin তে স্যুইচ করা হয়েছে, যা ব্যাকটেস্টে সমর্থিত নয়। এটি শুধুমাত্র বটগুলিতে ব্যবহার করা যেতে পারে।

এর প্রস্তুতির সময়mainফাংশন, যোগ করুনঃ

    // switch the margin mode 
    for (var i = 0 ; i < exchanges.length ; i++) {   // traverse and detect all exchange objects added
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   // if the exchange object represented by the current index i is Binance Spot, and the parameter marginType on the strategy interface is not selected as the "common spot" option, execute the switch
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "set to isolated margin")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "set to cross margin")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

এখানে কৌশলটি শুধুমাত্র Binance Spot এর স্পট মার্জিন মোড স্যুইচ করার জন্য কোড যোগ করে, তাই কৌশল পরামিতিতে স্যুইচ সেটিং শুধুমাত্র Binance Spot এর জন্য কাজ করে।

আরো স্প্রেড চার্ট প্রদর্শন যোগ করুন

ক্যাপসুল প্লট টেমপ্লেট ব্যবহার খুব সহজ. টেমপ্লেট নাম আমরা এখানে ব্যবহার করা হয়chart plot Libraryআপনি সরাসরি এফএমজেড প্ল্যাটফর্মে এটি অনুসন্ধান করতে পারেন ।

img

অথবা আপনি সরাসরি লিঙ্কে ক্লিক করতে পারেনঃhttps://www.fmz.com/strategy/27293টেমপ্লেটের অনুলিপি পৃষ্ঠায় যেতে।

img

বোতামটি ক্লিক করুন এবং আপনি সহজেই আপনার নিজস্ব কৌশল লাইব্রেরিতে টেমপ্লেট কপি করতে পারেন।

img

তারপর, কৌশল সম্পাদনা পৃষ্ঠায়, আপনি টেমপ্লেট কলামে ব্যবহার করা টেমপ্লেট লাইব্রেরি চেক করতে পারেন। এটি চেক করার পরে কৌশল সংরক্ষণ করুন, এবং কৌশল এই টেমপ্লেট ব্যবহার করবে। এটি টেমপ্লেট লাইব্রেরির ব্যবহারের একটি সংক্ষিপ্ত বিবরণ মাত্র। যেহেতু কৌশল ইতিমধ্যে এই টেমপ্লেটটি উল্লেখ করেছে, অপারেশনটি পুনরাবৃত্তি করার দরকার নেই। যখন আপনি স্কয়ারে কৌশল কোডটি অনুলিপি করেন, আপনি দেখতে পারেন যেchart plot Libraryকৌশল সম্পাদনা পৃষ্ঠার টেমপ্লেট বারে উল্লেখ করা হয়েছে।

এখানে আমরা প্রধানত শিখব কিভাবেchart plot libraryপ্লট করতে।

img

আমরা পরিকল্পনা করছি যে,A->BএবংB->A, এবং স্প্রেডের ট্রিগার লাইন। আমাদের দুটি বক্ররেখা (বর্তমানে, A থেকে B এবং B থেকে A এর স্প্রেড) এবং দুটি অনুভূমিক রেখা (স্প্রেড ট্রিগার লাইন) অঙ্কন করতে হবে, যেমন উপরের চিত্রটিতে দেখানো হয়েছে।

কারণ আমরা একটি একতরফা hedge ডিজাইন করতে চান, এর ট্রিগার লাইনA->BএবংB->Aএবং আমরা পূর্ববর্তী নিবন্ধে নকশা ব্যবহার করতে পারবেন না। পূর্ববর্তী নিবন্ধে:

      var targetDiffPrice = hedgeDiffPrice
      if (diffAsPercentage) {
          targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
      }

শুধুমাত্র একটি ট্রিগার স্প্রেড আছেtargetDiffPrice. সুতরাং, এখানে আমাদের কোড পরিবর্তন করতে হবে, এবং প্রথমে আমাদের প্যারামিটার পরিবর্তন করতে হবে।

img

তারপর, কোড পরিবর্তন করুনঃ

        var targetDiffPriceA2B = hedgeDiffPriceA2B
        var targetDiffPriceB2A = hedgeDiffPriceB2A
        if (diffAsPercentage) {
            targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
            targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
        }

সুতরাং, স্প্রেড ট্রিগার লাইন পূর্ববর্তী এক থেকে পরিবর্তিত হয়েছেtargetDiffPriceদুই, যথাtargetDiffPriceA2BএবংtargetDiffPriceB2A. এরপরে, আপনি চার্ট প্লট লাইব্রেরির চার্ট প্লট ফাংশন ব্যবহার করে চার্টে তথ্য আঁকতে পারেন।

        // plot
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // the first parameter of the function is the value of the horizontal line in the Y-axis direction, and the second parameter is the display text
        $.PlotHLine(targetDiffPriceB2A, "B->A")

যখন কৌশলটি চালানো হবে, চার্টটি এভাবে প্রদর্শিত হবে।

img

পরবর্তী, রিয়েল-টাইম স্প্রেড কার্ভ আঁকুন; অতিরিক্ত অঙ্কন এড়ানোর জন্য, ব্যালেন্স সনাক্তকরণে রিয়েল-টাইম স্প্রেড কার্ভগুলি প্লট করে এমন কোডটি রাখুন। s

        if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
            nowAccs = _C(updateAccs, exchanges)
            var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
            cancelAll()
            if (isBalance) {
                lastKeepBalanceTS = ts
                if (isTrade) {
                    var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
                    isTrade = false 
                }                
            }

            $.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price)  // plot real-time spread curves
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // the first parameter is the curve name, and the second parameter is the curve value at the current moment, that is, the value in the Y-axis direction at the current moment
        }

চার্ট প্রদর্শনের সাথে কৌশলটি চালানোর জন্য প্লট কোডটি কেবল 4 টি লাইনের প্রয়োজন।

একতরফা হেজ এর ফাংশন

উপরে উল্লিখিত হিসাবে, স্প্রেড ট্রিগার লাইনের সংখ্যা দুটিতে পরিবর্তন করা হয়েছে, যা যথাক্রমে হেজ ট্রিগারকে নিয়ন্ত্রণ করেA->BএবংB->Aএই ভাবে, পূর্ববর্তী অর্ডার মূল্য অ্যালগরিদম ব্যবহার করা যাবে না, এবং পরিবর্তে বাজার মূল্য স্লাইড মূল্য যোগ করার পদ্ধতি ব্যবহার করা হয়।

        if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A->B market condition satisfied             
            var priceSell = depthA.Bids[0].Price - slidePrice
            var priceBuy = depthB.Asks[0].Price + slidePrice
            var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
            if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
                Log("triggerA->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // prompt message
                hedge(exB, exA, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        } else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) {   // B->A market condition satisfied 
            var priceBuy = depthA.Asks[0].Price + slidePrice
            var priceSell = depthB.Bids[0].Price - slidePrice
            var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
            if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
                Log("triggerB->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  // prompt message
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

যেহেতু ক্রয় ও বিক্রয় মূল্য দুটি ডেটা টুকরা বিভক্ত করা হয়,hedgeকাজটিও পরিবর্তন করা দরকার।

function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
    var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
    var sellRoutine = sellEx.Go("Sell", priceSell, amount)
    Sleep(500)
    buyRoutine.wait()
    sellRoutine.wait()
}

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

ইন্টারেক্টিভভাবে হেজ স্প্রেড লাইন মত পরামিতি পরিবর্তন

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

img

দুটি কন্ট্রোল যোগ করা হয়েছে, একটি A2B নামে এবং অন্যটি B2A নামে পরিচিত। কন্ট্রোল ইনপুট বাক্সে একটি মান প্রবেশ করার পরে, ইনপুট বাক্সে ডানদিকে বোতামটি ক্লিক করুন। একটি কমান্ড অবিলম্বে কৌশল পাঠানো হবে, উদাহরণস্বরূপঃ মান লিখুন123ইনপুট বাক্সে, ক্লিক করুনA2Bবোতাম, এবং একটি কমান্ড অবিলম্বে কৌশল পাঠানো হবে.

A2B:123

কৌশল কোডে ইন্টারেক্টিভ সনাক্তকরণ এবং প্রক্রিয়াকরণ কোড ডিজাইন করুন।

        // interaction 
        var cmd = GetCommand()   // every time when the loop is operated here, it will detect whether an interactive command is sent; if no, return null string 
        if (cmd) {               // interactive command detected, such as A2B:123
            Log("received command:", cmd)
            var arr = cmd.split(":")   // split out the interactive control name and the value in the input box; arr[0] means A2B, and arr[1] means 123
            if (arr[0] == "A2B") {     // judge whether the triggered interactive control is A2B
                Log("modify parameterA2B,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // modify the spread trigger line 
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // modify the spread trigger line 
                }
            } else if (arr[0] == "B2A") {           // detected the triggered control is B2A 
                Log("modify parameterB2A,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

স্ট্যাটাস বার তথ্য পরিচালনা করুন এবং টেবিল বিন্যাসে এটি প্রদর্শন করুন

স্ট্যাটাস বার ডেটা প্রদর্শন আরও নিয়ন্ত্রিত এবং পর্যবেক্ষণ করা সহজ করুন।

        var tbl = {
            "type" : "table", 
            "title" : "data", 
            "cols" : ["platform", "Currency", "frozenCurrrency", "quoteCurrency", "frozenQuoteCurrency", "triggerSpread", "currentSpread"], 
            "rows" : [], 
        }
        tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
        tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")

img

ব্যাকটেস্ট

ব্যাকটেস্টটি কেবল একটি প্রাথমিক সনাক্তকরণ ফাংশন হিসাবে কৌশলটির একটি পরীক্ষা। অনেক বাগ আসলে ব্যাকটেস্ট পর্যায়ে পরীক্ষা করা যেতে পারে। ব্যাকটেস্টের ফলাফল সম্পর্কে খুব বেশি চিন্তা করার দরকার নেই। শেষ পর্যন্ত, কৌশলটি এখনও বাস্তব বটগুলির সাথে বাস্তব পরিবেশে পরীক্ষা করা দরকার।

img

img

কৌশল উৎস কোডঃhttps://www.fmz.com/strategy/302834


আরো