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

নির্দিষ্ট দৈর্ঘ্যের কে-লাইন ডেটা পেতে টেমপ্লেট ক্লাস লাইব্রেরি ডিজাইন করতে শেখান

লেখক:এফএমজেড-লিডিয়া, সৃষ্টিঃ ২০২৩-০৬-২৯ ১৭ঃ২৭ঃ৫৯, আপডেটঃ ২০২৩-০৯-১৮ ১৯ঃ৩৩ঃ৩৩

img

নির্দিষ্ট দৈর্ঘ্যের কে-লাইন ডেটা পেতে টেমপ্লেট ক্লাস লাইব্রেরি ডিজাইন করতে শেখান

প্রবণতা কৌশলগুলি ডিজাইন করার সময়, সূচকগুলি গণনা করার জন্য প্রায়শই পর্যাপ্ত সংখ্যক কে-লাইন বার থাকা প্রয়োজন। সূচকগুলির গণনাexchange.GetRecords()এফএমজেড প্ল্যাটফর্ম এপিআইতে একটি ফাংশন রয়েছে, যা এক্সচেঞ্জের কে-লাইন ইন্টারফেসের জন্য একটি আবরণ। ক্রিপ্টোকারেন্সি এক্সচেঞ্জ এপিআইগুলির প্রাথমিক নকশায়, কে-লাইন ইন্টারফেসে পেইজিংয়ের জন্য কোনও সমর্থন ছিল না এবং এক্সচেঞ্জের কে-লাইন ইন্টারফেস কেবল সীমিত পরিমাণে ডেটা সরবরাহ করেছিল। ফলস্বরূপ, কিছু বিকাশকারী বৃহত্তর পরামিতি মান সহ সূচক গণনার প্রয়োজনীয়তা পূরণ করতে অক্ষম ছিল।

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

বিন্যান্সের কে-লাইন ইন্টারফেস

কে-লাইন ডেটা

প্রতিটি কে-লাইনের খোলার সময়GET /dapi/v1/klinesএন্ডপয়েন্টকে একটি অনন্য আইডি হিসেবে বিবেচনা করা যেতে পারে।

অনুরোধের ওজন LIMIT প্যারামিটারের মানের উপর নির্ভর করে।

img

পরামিতিঃ

img

প্রথমত, আমাদের এক্সচেঞ্জের এপিআই ডকুমেন্টেশনটি দেখতে হবে যাতে আমরা কে-লাইন ইন্টারফেসের নির্দিষ্ট পরামিতিগুলি বুঝতে পারি। আমরা দেখতে পাচ্ছি যে এই কে-লাইন এন্ডপয়েন্টটি কল করার সময় আমাদের টাইপ, কে-লাইন পিরিয়ড, ডেটা ব্যাপ্তি (শুরু এবং শেষ সময়) এবং পৃষ্ঠাগুলির সংখ্যা ইত্যাদি নির্দিষ্ট করতে হবে।

যেহেতু আমাদের ডিজাইন প্রয়োজনীয়তা একটি নির্দিষ্ট সংখ্যক কে-লাইন ডেটা অনুসন্ধান করা, উদাহরণস্বরূপ, বর্তমান মুহুর্ত থেকে অতীতের দিকে 1 ঘন্টা কে-লাইন, 5000 বার 1 ঘন্টা কে-লাইন ডেটা অনুসন্ধান করা, এটি স্পষ্ট যে এক্সচেঞ্জের একটি একক এপিআই কল করা পছন্দসই ডেটা পুনরুদ্ধার করবে না।

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

ডিজাইন পৃষ্ঠায়িত ক্যোয়ারির জাভাস্ক্রিপ্ট সংস্করণ K-লাইন ঐতিহাসিক তথ্য টেমপ্লেট

ডিজাইন টেমপ্লেটের জন্য ইন্টারফেস ফাংশনঃ$.GetRecordsByLength(e, period, length).

/**
 * desc: $.GetRecordsByLength is the interface function of this template library, this function is used to get the K-line data of the specified K-line length
 * @param {Object} e - exchange object
 * @param {Int} period - K-line period, in seconds
 * @param {Int} length - Specify the length of the acquired K-line data, which is related to the exchange interface limits
 * @returns {Array<Object>} - K-line data
 */

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

অতএব, পরবর্তী ডেটা আপডেটের জন্য একটি ইন্টারফেস ডিজাইন করাও প্রয়োজনঃ$.UpdataRecords(e, records, period).

/**
 * desc: $.UpdataRecords is the interface function of this template library, this function is used to update the K-line data.
 * @param {Object} e - exchange object
 * @param {Array<Object>} records - K-line data sources that need to be updated
 * @param {Int} period - K-line period, needs to be the same as the K-line data period passed in the records parameter
 * @returns {Bool}  - Whether the update was successful
 */

পরবর্তী ধাপ হল এই ইন্টারফেস ফাংশন বাস্তবায়ন করা।

/**
 * desc: $.GetRecordsByLength is the interface function of this template library, this function is used to get the K-line data of the specified K-line length
 * @param {Object} e - exchange object
 * @param {Int} period - K-line period, in seconds
 * @param {Int} length - Specify the length of the acquired K-line data, which is related to the exchange interface limits
 * @returns {Array<Object>} - K-line data
 */
$.GetRecordsByLength = function(e, period, length) {
    if (!Number.isInteger(period) || !Number.isInteger(length)) {
        throw "params error!"
    }

    var exchangeName = e.GetName()
    if (exchangeName == "Futures_Binance") {
        return getRecordsForFuturesBinance(e, period, length)
    } else {
        throw "not support!"
    }
}

/**
 * desc: getRecordsForFuturesBinance, the specific implementation of the function to get K-line data for Binance Futures Exchange
 * @param {Object} e - exchange object
 * @param {Int} period - K-line period, in seconds
 * @param {Int} length - Specify the length of the acquired K-line data, which is related to the exchange interface limits
 * @returns {Array<Object>} - K-line data
 */
function getRecordsForFuturesBinance(e, period, length) {
    var contractType = e.GetContractType()
    var currency = e.GetCurrency()
    var strPeriod = String(period)

    var symbols = currency.split("_")
    var baseCurrency = ""
    var quoteCurrency = ""
    if (symbols.length == 2) {
        baseCurrency = symbols[0]
        quoteCurrency = symbols[1]
    } else {
        throw "currency error!"
    }

    var realCt = e.SetContractType(contractType)["instrument"]
    if (!realCt) {
        throw "realCt error"
    }
    
    // m -> minute; h -> hour; d -> day; w -> week; M -> month
    var periodMap = {}
    periodMap[(60).toString()] = "1m"
    periodMap[(60 * 3).toString()] = "3m"
    periodMap[(60 * 5).toString()] = "5m"
    periodMap[(60 * 15).toString()] = "15m"
    periodMap[(60 * 30).toString()] = "30m"
    periodMap[(60 * 60).toString()] = "1h"
    periodMap[(60 * 60 * 2).toString()] = "2h"
    periodMap[(60 * 60 * 4).toString()] = "4h"
    periodMap[(60 * 60 * 6).toString()] = "6h"
    periodMap[(60 * 60 * 8).toString()] = "8h"
    periodMap[(60 * 60 * 12).toString()] = "12h"
    periodMap[(60 * 60 * 24).toString()] = "1d"
    periodMap[(60 * 60 * 24 * 3).toString()] = "3d"
    periodMap[(60 * 60 * 24 * 7).toString()] = "1w"
    periodMap[(60 * 60 * 24 * 30).toString()] = "1M"
    
    var records = []
    var url = ""
    if (quoteCurrency == "USDT") {
        // GET https://fapi.binance.com  /fapi/v1/klines  symbol , interval , startTime , endTime , limit 
        // limit maximum value:1500

        url = "https://fapi.binance.com/fapi/v1/klines"
    } else if (quoteCurrency == "USD") {
        // GET https://dapi.binance.com  /dapi/v1/klines  symbol , interval , startTime , endTime , limit
        // The difference between startTime and endTime can be up to 200 days.
        // limit maximum value:1500

        url = "https://dapi.binance.com/dapi/v1/klines"
    } else {
        throw "not support!"
    }

    var maxLimit = 1500
    var interval = periodMap[strPeriod]
    if (typeof(interval) !== "string") {
        throw "period error!"
    }

    var symbol = realCt
    var currentTS = new Date().getTime()

    while (true) {
        // Calculate limit
        var limit = Math.min(maxLimit, length - records.length)
        var barPeriodMillis = period * 1000
        var rangeMillis = barPeriodMillis * limit
        var twoHundredDaysMillis = 200 * 60 * 60 * 24 * 1000
        
        if (rangeMillis > twoHundredDaysMillis) {
            limit = Math.floor(twoHundredDaysMillis / barPeriodMillis)
            rangeMillis = barPeriodMillis * limit
        }

        var query = `symbol=${symbol}&interval=${interval}&endTime=${currentTS}&limit=${limit}`
        var retHttpQuery = HttpQuery(url + "?" + query)
        
        var ret = null 
        try {
            ret = JSON.parse(retHttpQuery)
        } catch(e) {
            Log(e)
        }
        
        if (!ret || !Array.isArray(ret)) {
            return null
        }

        // When the data cannot be searched because it is beyond the searchable range of the exchange
        if (ret.length == 0 || currentTS <= 0) {
            break
        }

        for (var i = ret.length - 1; i >= 0; i--) {
            var ele = ret[i]
            var bar = {
                Time : parseInt(ele[0]),
                Open : parseFloat(ele[1]),
                High : parseFloat(ele[2]),
                Low : parseFloat(ele[3]), 
                Close : parseFloat(ele[4]),
                Volume : parseFloat(ele[5])
            }

            records.unshift(bar)
        }

        if (records.length >= length) {
            break
        }

        currentTS -= rangeMillis
        Sleep(1000)
    }

    return records
}

/**
 * desc: $.UpdataRecords is the interface function of this template library, this function is used to update the K-line data.
 * @param {Object} e - exchange object
 * @param {Array<Object>} records - K-line data sources that need to be updated
 * @param {Int} period - K-line period, needs to be the same as the K-line data period passed in the records parameter
 * @returns {Bool}  - Whether the update was successful
 */
$.UpdataRecords = function(e, records, period) {
    var r = e.GetRecords(period)
    if (!r) {
        return false 
    }

    for (var i = 0; i < r.length; i++) {
        if (r[i].Time > records[records.length - 1].Time) {
            // Add a new Bar
            records.push(r[i])
            // Update the previous Bar
            if (records.length - 2 >= 0 && i - 1 >= 0 && records[records.length - 2].Time == r[i - 1].Time) {
                records[records.length - 2] = r[i - 1]
            }            
        } else if (r[i].Time == records[records.length - 1].Time) {
            // Update Bar
            records[records.length - 1] = r[i]
        }
    }
    return true
}

টেমপ্লেটে, আমরা শুধুমাত্র Binance ফিউচার চুক্তি K-লাইন ইন্টারফেস জন্য সমর্থন বাস্তবায়ন করেছি, অর্থাৎ,getRecordsForFuturesBinanceএটি অন্যান্য ক্রিপ্টোকারেন্সি এক্সচেঞ্জের কে-লাইন ইন্টারফেসগুলিকে সমর্থন করার জন্যও প্রসারিত করা যেতে পারে।

টেস্ট সেশন

যেমন আপনি দেখতে পাচ্ছেন, টেমপ্লেটে এই কার্যকারিতা বাস্তবায়নের জন্য কোডটি বিস্তৃত নয়, মোট 200 টিরও কম লাইন রয়েছে। টেমপ্লেট কোডটি লেখার পরে, পরীক্ষা অত্যন্ত গুরুত্বপূর্ণ এবং উপেক্ষা করা উচিত নয়। তদতিরিক্ত, এই জাতীয় ডেটা পুনরুদ্ধারের জন্য, পুঙ্খানুপুঙ্খ পরীক্ষা করা গুরুত্বপূর্ণ।

এটি পরীক্ষা করার জন্য, আপনাকে আপনার কৌশল লাইব্রেরিতে জাভাস্ক্রিপ্ট সংস্করণ পেইজিং ক্যোয়ারী কে-লাইন ঐতিহাসিক তথ্য টেমপ্লেট এবং প্লট লাইব্রেরি টেমপ্লেট উভয়ই অনুলিপি করতে হবেস্ট্র্যাটেজি স্কয়ার) তারপর, একটি নতুন কৌশল তৈরি করুন এবং এই দুটি টেমপ্লেট নির্বাচন করুন।

img

img

প্লট লাইব্রেরি ব্যবহার করা হয়, কারণ আমাদের পর্যবেক্ষণের জন্য প্রাপ্ত কে-লাইন ডেটা আঁকতে হবে।

function main() {
	LogReset(1)
	var testPeriod = PERIOD_M5
    Log("Current exchanges tested:", exchange.GetName())

    // If futures, you need to set up a contract
    exchange.SetContractType("swap")

    // Get K-line data of specified length using $.GetRecordsByLength
    var r = $.GetRecordsByLength(exchange, testPeriod, 8000)
    Log(r)

    // Use the Plot test for easy observation
    $.PlotRecords(r, "k")

    // Test data
    var diffTime = r[1].Time - r[0].Time 
    Log("diffTime:", diffTime, " ms")
    for (var i = 0; i < r.length; i++) {
        for (var j = 0; j < r.length; j++) {
            // Check the repeat bar
            if (i != j && r[i].Time == r[j].Time) {
                Log(r[i].Time, i, r[j].Time, j)
                throw "With duplicate Bar"
            }
        }
        
        // Check Bar continuity
        if (i < r.length - 1) {            
            if (r[i + 1].Time - r[i].Time != diffTime) {
                Log("i:", i, ", diff:", r[i + 1].Time - r[i].Time, ", r[i].Time:", r[i].Time, ", r[i + 1].Time:", r[i + 1].Time)
                throw "Bar discontinuity"
            }            
        }
    }
    Log("Test passed")

    Log("The length of the data returned by the $.GetRecordsByLength function:", r.length)

    // Update data
    while (true) {
        $.UpdataRecords(exchange, r, testPeriod)
        LogStatus(_D(), "r.length:", r.length)
        $.PlotRecords(r, "k")
        Sleep(5000)
    }
}

এখানে, আমরা লাইন ব্যবহারvar testPeriod = PERIOD_M55 মিনিটের কে-লাইন সময়কাল সেট করুন এবং 8000 বার পুনরুদ্ধার করতে নির্দিষ্ট করুন. তারপর আমরা দীর্ঘ কে-লাইন তথ্য ফিরে দ্বারা একটি ট্রল পরীক্ষা সম্পাদন করতে পারেনvar r = $.GetRecordsByLength(exchange, testPeriod, 8000) interface.

    // Use the plot test for easy observation
    $.PlotRecords(r, "k")

দীর্ঘ কে-লাইন ডেটার জন্য পরবর্তী পরীক্ষাটি হলঃ

    // Test data
    var diffTime = r[1].Time - r[0].Time 
    Log("diffTime:", diffTime, " ms")
    for (var i = 0; i < r.length; i++) {
        for (var j = 0; j < r.length; j++) {
            // Check the repeat Bar
            if (i != j && r[i].Time == r[j].Time) {
                Log(r[i].Time, i, r[j].Time, j)
                throw "With duplicate Bar"
            }
        }
        
        // Check Bar continuity
        if (i < r.length - 1) {            
            if (r[i + 1].Time - r[i].Time != diffTime) {
                Log("i:", i, ", diff:", r[i + 1].Time - r[i].Time, ", r[i].Time:", r[i].Time, ", r[i + 1].Time:", r[i + 1].Time)
                throw "Bar discontinuity"
            }            
        }
    }
    Log("Test passed")
  1. কে-লাইন ডেটাতে কোন ডুপ্লিকেট বার আছে কিনা তা পরীক্ষা করুন।
  2. কে-লাইন ডেটার ধারাবাহিকতা পরীক্ষা করুন (পরবর্তী বারগুলির মধ্যে টাইমস্ট্যাম্প পার্থক্য সমান কিনা) ।

এই চেক পাস করার পর, যাচাই করুন যে K-লাইন ডেটা আপডেট করার জন্য ইন্টারফেস ব্যবহার করা হয় কিনা,$.UpdateRecords(exchange, r, testPeriod), সঠিকভাবে কাজ করছে।

    // Update data
    while (true) {
        $.UpdataRecords(exchange, r, testPeriod)
        LogStatus(_D(), "r.length:", r.length)
        $.PlotRecords(r, "k")
        Sleep(5000)
    }

এই কোডটি লাইভ ট্রেডিংয়ের সময় কৌশল চার্টে ক্রমাগত K-লাইন ডেটা আউটপুট করবে, যা আমাদেরকে K-লাইন ডেটা আপডেট এবং সংযোজন সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করতে দেয়।

img

img

দৈনিক কে-লাইন ডেটা ব্যবহার করে, আমরা এটি 8000 বার পুনরুদ্ধার করতে সেট করেছি (জানি যে 8000 দিন আগে কোন বাজার ডেটা পাওয়া যায় না) । এটি একটি ব্রুট ফোর্স টেস্ট হিসাবে কাজ করেঃ

img

যেহেতু প্রতিদিন মাত্র ১৩০৯টি কে-লাইন রয়েছে, তাই বিনিময় চার্টের তথ্যগুলো তুলনা করুনঃ

img

img

আপনি দেখতে পাচ্ছেন যে তথ্যগুলোও মিলছে।

END

টেমপ্লেট ঠিকানাঃজাভাস্ক্রিপ্ট সংস্করণ পেইজিং ক্যোয়ারী কে-লাইন ঐতিহাসিক তথ্য টেমপ্লেটটেমপ্লেট ঠিকানাঃপ্লট লাইব্রেরি

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


সম্পর্কিত

আরো