آپ کو ایک ٹیمپلیٹ کلاس لائبریری ڈیزائن کرنے کے لئے سکھاتا ہے جس میں مخصوص K لمبائی کی لائن کے اعداد و شمار کو حاصل کیا جاسکتا ہے

مصنف:چھوٹا سا خواب, تخلیق: 2023-06-27 13:37:01, تازہ کاری: 2023-09-18 19:34:23

img

آپ کو ایک ٹیمپلیٹ کلاس لائبریری ڈیزائن کرنے کے لئے سکھاتا ہے جس میں مخصوص K لمبائی کی لائن کے اعداد و شمار کو حاصل کیا جاسکتا ہے

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

اگر بائننس کنٹریکٹ API کے K لائن انٹرفیس میں صفحہ بندی کے سوالات کی حمایت کی جاتی ہے تو ، یہ مضمون آپ کو بائننس K لائن API کی مثال کے طور پر ایک صفحہ بندی کے سوالات کو نافذ کرنے اور FMZ پلیٹ فارم ٹیمپلیٹ لائبریری کو بار کی تعداد تک رسائی کی وضاحت کرنے کے لئے سکھاتا ہے۔

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

img

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

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

اس کے بعد ہم صفحہ بندی کے ساتھ سوالات کرتے ہیں اور موجودہ لمحے سے تاریخ کے کسی لمحے تک وقفے وقفے سے کام کرتے ہیں۔ ہمیں معلوم ہے کہ K لائن کے اعداد و شمار کے دورانیے کی ضرورت ہوتی ہے تاکہ ہر وقفے کے آغاز اور اختتام کا وقت حساب لگایا جاسکے۔ صرف وقفے وقفے سے تاریخی لمحے کی سمت میں سوالات کریں ، جب تک کہ آپ کافی بار کی تعداد میں سوالات نہ کریں۔ اگر آپ کو یہ خیال آسان نہیں لگتا ہے تو ، اس پر عمل کریں!

ڈیزائن "جاوا اسکرپٹ ورژن میں صفحہ بندی کے لئے K لائن کی تاریخ کے اعداد و شمار کے سانچوں"

ڈیزائن ٹیمپلیٹس کے لئے انٹرفیس کی افعال:$.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 لائنوں کو اپ ڈیٹ کرنے کی ضرورت ہوتی ہے۔ اس فنکشن کو کال کرنے کی ضرورت نہیں ہے تاکہ بہت لمبی 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
}

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

ٹیسٹ لنک

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

اس ٹیسٹ کے لیے یہ "جاوا اسکرپٹ ورژن صفحہ بندی کے لیے K لائن کی تاریخی ڈیٹا ٹیمپلیٹ" اور "ڈرائنگ لائن لائبریری" ٹیمپلیٹ کو اپنی پالیسی لائبریری میں کاپی کرنا ضروری ہے۔حکمت عملی کی چوٹیاس کے بعد ہم نے ایک نئی حکمت عملی بنائی اور ان دونوں ٹیمپلیٹس کو منتخب کیا:

img

img

img

"ڈرائنگ لائن کلاس لائبریری" کا استعمال اس لئے کیا جاتا ہے کیونکہ ہمیں حاصل کردہ K لائن ڈیٹا کو ڈرائنگ اور مشاہدہ کرنے کی ضرورت ہے۔

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یہ جملہ، 5 منٹ کی لائن سائیکل مقرر کریں، 8000 بار حاصل کرنے کی وضاحت کریں؛ پھرvar r = $.GetRecordsByLength(exchange, testPeriod, 8000)انٹرفیس کی طرف سے واپس آنے والے طویل K لائن کے اعداد و شمار کو گرافکس ٹیسٹ کے لئے استعمال کیا جاتا ہے:

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

اس کے بعد اس لمبی 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("检测通过")

1، چیک کریں کہ کیا K لائن بار میں کوئی تکرار ہے۔ 2، K لائن بار کی مستقل مزاجی کی جانچ پڑتال کریں ((اگر ہمسایہ بار کے وقت کے فاصلے کا فرق برابر ہے)

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

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

اس کوڈ کا حصہ، جب ہم اسے چلاتے ہیں تو، اسٹریٹجک چارٹ پر K لائنز کو مسلسل آؤٹ پٹ کرتا ہے، جس سے ہم چیک کرتے ہیں کہ K لائن بار ڈیٹا اپ ڈیٹ یا شامل کیا جاتا ہے.

img

img

روزہ K لائن تک رسائی حاصل کرنے کے لئے ، 8000 جڑیں حاصل کرنے کے لئے سیٹ کریں (یہ جان کر کہ 8000 دن پہلے ، مارکیٹ کا کوئی ڈیٹا نہیں تھا) ، اس طرح سے تشدد کی جانچ کریں:

img

اس کے علاوہ ، یہ بھی واضح ہے کہ اس کے علاوہ ، یہ بھی کہا گیا ہے کہ اس کے علاوہ ، یہ بھی کہا گیا ہے کہ اس کے علاوہ ، یہ بھی کہا گیا ہے کہ اس کے علاوہ ، یہ بھی کہا گیا ہے کہ اس کے علاوہ ، یہ بھی کہا گیا ہے کہ اس کے علاوہ ، یہ بھی کہا گیا ہے:

img

img

آپ دیکھ سکتے ہیں کہ اعداد و شمار بھی مماثل ہیں۔

اختتام

ٹیمپلیٹ کا پتہ:"جاوا اسکرپٹ ورژن صفحہ بندی کے لئے K لائن کی تاریخ کے اعداد و شمار کے سانچوں کی تلاش"ٹیمپلیٹ کا پتہ:ڈرائنگ لائن کلاس لائبریری

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


مزید