avatar of 发明者量化-小小梦 发明者量化-小小梦
پر توجہ دیں نجی پیغام
4
پر توجہ دیں
1271
پیروکار

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

میں تخلیق کیا: 2023-06-27 13:37:01, تازہ کاری: 2023-09-18 19:34:23
comments   0
hits   1285

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

کچھ رجحان کی حکمت عملیوں کو ڈیزائن کرتے وقت، انڈیکیٹرز کا حساب لگانے کے لیے اکثر K-لائن بارز کی کافی تعداد کی ضرورت ہوتی ہے۔ FMZ پلیٹ فارم API پر منحصر ہے:exchange.GetRecords()فنکشن کے ذریعہ دی گئی ڈیٹا کی مقدار، اورexchange.GetRecords()یہ ایکسچینج K-line انٹرفیس کی encapsulation ہے۔ کریپٹو کرنسی ایکسچینج API انٹرفیس کے ابتدائی ڈیزائن میں، کوئی صفحہ بندی کا سوال نہیں تھا، اور ایکسچینج کے K-لائن انٹرفیس نے صرف ایک محدود مقدار میں ڈیٹا فراہم کیا، اس لیے بڑے پیرامیٹرز کے ساتھ اشارے کے حساب کے لیے کچھ ڈویلپرز کی ضروریات پوری نہیں کی جاسکیں۔

Binance معاہدہ API کا K-line انٹرفیس صفحہ بندی کے استفسار کو سپورٹ کرتا ہے یہ مضمون بائنانس K-line API انٹرفیس کو ایک مثال کے طور پر لیتا ہے تاکہ آپ کو صفحہ بندی شدہ استفسار کو کیسے لاگو کیا جائے اور بارز کی تعداد حاصل کرنے کے لیے FMZ پلیٹ فارم ٹیمپلیٹ لائبریری کی وضاحت کی جائے۔

بائننس کے لائن انٹرفیس

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

سب سے پہلے، آپ کو انٹرفیس کے مخصوص پیرامیٹرز کو دیکھنے کے لیے ایکسچینج API دستاویزات کو پڑھنے کی ضرورت ہے۔ ہم دیکھ سکتے ہیں کہ اس K-line انٹرفیس کو کال کرتے وقت، پروڈکٹ، K-line کی مدت، ڈیٹا کی حد (شروع اور اختتام کا وقت)، صفحات کی تعداد وغیرہ کی وضاحت کرنا ضروری ہے۔

چونکہ ہماری ڈیزائن کی ضرورت K-line ڈیٹا کی ایک مخصوص تعداد سے استفسار کرنا ہے، مثال کے طور پر، 1-hour K-line سے استفسار کرنے کے لیے، موجودہ وقت سے گزشتہ وقت تک دھکیلنا، تعداد 5,000 بار ہے۔ اس طرح، آپ ایکسچینج API انٹرفیس استفسار پر صرف ایک بار کال کرکے ظاہر ہے کہ آپ مطلوبہ ڈیٹا حاصل نہیں کر سکتے۔

پھر ہم صفحات میں استفسار کریں گے، موجودہ لمحے سے تاریخ کے ایک خاص لمحے تک حصوں میں پروسیسنگ کریں گے۔ جب تک ہم مطلوبہ K-line ڈیٹا کی مدت کو جانتے ہیں، ہر سیگمنٹ کے آغاز اور اختتام کے وقت کا حساب لگانا آسان ہے۔ بس ترتیب میں تاریخی لمحات کی سمت میں استفسار کریں جب تک کہ آپ کو کافی سلاخیں نہ مل جائیں۔ خیال آسان لگتا ہے، ٹھیک ہے؟

“پیجنگ استفسار K-line تاریخی ڈیٹا ٹیمپلیٹ کا جاوا اسکرپٹ ورژن” ڈیزائن کریں۔

ڈیزائن ٹیمپلیٹ انٹرفیس فنکشن:$.GetRecordsByLength(e, period, length)

/**
 * desc: $.GetRecordsByLength 是该模板类库的接口函数,该函数用于获取指定K线长度的K线数据
 * @param {Object} e - 交易所对象
 * @param {Int} period - K线周期,秒数为单位
 * @param {Int} length - 指定获取的K线数据的长度,具体和交易所接口限制有关
 * @returns {Array<Object>} - K线数据
 */

ڈیزائن$.GetRecordsByLengthیہ فنکشن عام طور پر حکمت عملی کے آپریشن کے ابتدائی مرحلے میں استعمال ہوتا ہے جب اشارے کا حساب لگانے کے لیے ایک لمبی K-لائن کی ضرورت ہوتی ہے۔ اس فنکشن کے مکمل ہونے کے بعد، یہ کافی لمبا ڈیٹا حاصل کرتا ہے، اور پھر اسے صرف نئے K-line ڈیٹا کو اپ ڈیٹ کرنے کی ضرورت ہوتی ہے۔ سپر لانگ K-لائن ڈیٹا حاصل کرنے کے لیے اس فنکشن کو کال کرنے کی ضرورت نہیں ہے، جو غیر ضروری انٹرفیس کالز کا سبب بنے گی۔

لہذا، بعد میں ڈیٹا اپ ڈیٹس کے لیے ایک انٹرفیس ڈیزائن کرنا بھی ضروری ہے:$.UpdataRecords(e, records, period)

/**
 * desc: $.UpdataRecords 是该模板类库的接口函数,该函数用于更新K线数据
 * @param {Object} e - 交易所对象
 * @param {Array<Object>} records - 需要更新的K线数据源
 * @param {Int} period - K线周期,需要和records参数传入的K线数据周期一致
 * @returns {Bool}  - 是否更新成功
 */

اگلا مرحلہ ان انٹرفیس افعال کو نافذ کرنا ہے۔

/**
 * desc: $.GetRecordsByLength 是该模板类库的接口函数,该函数用于获取指定K线长度的K线数据
 * @param {Object} e - 交易所对象
 * @param {Int} period - K线周期,秒数为单位
 * @param {Int} length - 指定获取的K线数据的长度,具体和交易所接口限制有关
 * @returns {Array<Object>} - K线数据
 */
$.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 币安期货交易所获取K线数据函数的具体实现
 * @param {Object} e - 交易所对象
 * @param {Int} period - K线周期,秒数为单位
 * @param {Int} length - 指定获取的K线数据的长度,具体和交易所接口限制有关
 * @returns {Array<Object>} - K线数据
 */
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 -> 分钟; h -> 小时; d -> 天; w -> 周; M -> 月
    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 最大值: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
        // startTime 与 endTime 之间最多只可以相差200天
        // limit 最大值: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) {
        // 计算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
        }

        // 超出交易所可查询范围,查询不到数据时
        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 是该模板类库的接口函数,该函数用于更新K线数据
 * @param {Object} e - 交易所对象
 * @param {Array<Object>} records - 需要更新的K线数据源
 * @param {Int} period - K线周期,需要和records参数传入的K线数据周期一致
 * @returns {Bool}  - 是否更新成功
 */
$.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) {
            // 添加新Bar
            records.push(r[i])
            // 更新上一个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) {
            // 更新Bar
            records[records.length - 1] = r[i]
        }
    }
    return true
}

ٹیمپلیٹ میں، ہم صرف Binance معاہدہ K-line انٹرفیس کی حمایت کو نافذ کرتے ہیں، یعنی،getRecordsForFuturesBinanceفنکشن، اسے دوسرے کریپٹو کرنسی ایکسچینجز کے K-لائن انٹرفیس کو سپورٹ کرنے کے لیے بھی بڑھایا جا سکتا ہے۔

ٹیسٹنگ

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

ٹیسٹ کے لیے اس “صفحہ کے استفسار کے K-line تاریخی ڈیٹا ٹیمپلیٹ کے جاوا اسکرپٹ ورژن” اور “لائن ڈرائنگ لائبریری” ٹیمپلیٹ کو آپ کی اپنی حکمت عملی لائبریری میں کاپی کرنے کی ضرورت ہے (میںاسٹریٹجی اسکوائرمیں تلاش کیا جا سکتا ہے)۔ پھر ہم ایک نئی حکمت عملی بناتے ہیں اور ان دو ٹیمپلیٹس کو چیک کرتے ہیں:

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

“لائن ڈرائنگ لائبریری” کا استعمال اس لیے کیا جاتا ہے کیونکہ ہمیں مشاہدے کے لیے حاصل کردہ K-line ڈیٹا کو کھینچنا ہوتا ہے۔

function main() {
	LogReset(1)
	var testPeriod = PERIOD_M5
    Log("当前测试的交易所:", exchange.GetName())

    // 如果是期货则需要设置合约
    exchange.SetContractType("swap")

    // 使用$.GetRecordsByLength获取指定长度的K线数据
    var r = $.GetRecordsByLength(exchange, testPeriod, 8000)
    Log(r)

    // 使用画图测试,方便观察
    $.PlotRecords(r, "k")

    // 检测数据
    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++) {
            // 检查重复Bar
            if (i != j && r[i].Time == r[j].Time) {
                Log(r[i].Time, i, r[j].Time, j)
                throw "有重复Bar"
            }
        }
        
        // 检查Bar连续性
        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不连续"
            }            
        }
    }
    Log("检测通过")

    Log("$.GetRecordsByLength函数返回的数据长度:", r.length)

    // 更新数据
    while (true) {
        $.UpdataRecords(exchange, r, testPeriod)
        LogStatus(_D(), "r.length:", r.length)
        $.PlotRecords(r, "k")
        Sleep(5000)
    }
}

یہاں ہم استعمال کرتے ہیں۔var testPeriod = PERIOD_M5یہ جملہ K-line کی مدت کو 5 منٹ پر سیٹ کرتا ہے اور 8000 بار حاصل کرنے کی وضاحت کرتا ہے۔ پھر کے لیےvar r = $.GetRecordsByLength(exchange, testPeriod, 8000)انٹرفیس ڈرائنگ ٹیسٹ کے لیے ایک طویل K-line ڈیٹا واپس کرتا ہے:

    // 使用画图测试,方便观察
    $.PlotRecords(r, "k")

اگلا، ہم اس بہت طویل K-line ڈیٹا کی جانچ کریں گے:

    // 检测数据
    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++) {
            // 检查重复Bar
            if (i != j && r[i].Time == r[j].Time) {
                Log(r[i].Time, i, r[j].Time, j)
                throw "有重复Bar"
            }
        }
        
        // 检查Bar连续性
        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不连续"
            }            
        }
    }
    Log("检测通过")
  1. چیک کریں کہ آیا K-line بار میں کوئی ڈپلیکیٹس موجود ہیں۔
  2. K-line بار کے تسلسل کو چیک کریں (کیا ملحقہ بارز کے ٹائم اسٹیمپ کا فرق برابر ہے)

ان چیکس کے پاس ہونے کے بعد، K لائن کو اپ ڈیٹ کرنے کے لیے استعمال ہونے والے انٹرفیس کو چیک کریں۔$.UpdataRecords(exchange, r, testPeriod)عام:

    // 更新数据
    while (true) {
        $.UpdataRecords(exchange, r, testPeriod)
        LogStatus(_D(), "r.length:", r.length)
        $.PlotRecords(r, "k")
        Sleep(5000)
    }

یہ کوڈ اسٹریٹیجی چارٹ پر K-لائن کو مسلسل آؤٹ پٹ کرے گا جب یہ حقیقی ٹریڈنگ میں چل رہا ہو، تاکہ ہم چیک کر سکیں کہ آیا K-line بار کا ڈیٹا عام طور پر اپ ڈیٹ اور شامل کیا گیا ہے۔

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

روزانہ K-line ایکوائزیشن فنکشن کا استعمال کریں اور حصول کو 8,000 پر سیٹ کریں (یہ جانتے ہوئے کہ 8,000 دنوں سے پہلے کوئی مارکیٹ ڈیٹا نہیں ہے) اور اس طرح ایک بروٹ فورس ٹیسٹ کریں:

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

ایکسچینج چارٹ پر ڈیٹا کے مقابلے میں صرف 1309 یومیہ لائنیں ہیں:

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

مخصوص لمبائی کے K-line ڈیٹا حاصل کرنے کے لیے آپ کو ٹیمپلیٹ لائبریری ڈیزائن کرنا سکھائیں۔

آپ دیکھ سکتے ہیں کہ ڈیٹا مطابقت رکھتا ہے۔

END

ٹیمپلیٹ ایڈریس:「جاوا اسکرپٹ ورژن کا صفحہ شدہ سوال K-line تاریخی ڈیٹا ٹیمپلیٹ」 ٹیمپلیٹ ایڈریس:لائن ڈرائنگ لائبریری

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