رجحان کی حکمت عملیوں کو ڈیزائن کرتے وقت ، اشارے کا حساب لگانے کے لئے اکثر کافی تعداد میں K لائن باروں کی ضرورت ہوتی ہے۔ اشارے کا حساب لگانے کا انحصار ڈیٹا کے ذریعہ فراہم کردہ اعداد و شمار پر ہوتا ہے۔exchange.GetRecords()
ایف ایم زیڈ پلیٹ فارم اے پی آئی میں فنکشن ، جو ایکسچینج کے کے لائن انٹرفیس کے لئے ایک لفافہ ہے۔ کریپٹوکرنسی ایکسچینج اے پی آئی کے ابتدائی ڈیزائن میں ، کے لائن انٹرفیس میں صفحہ بندی کی کوئی حمایت نہیں تھی ، اور ایکسچینج کے کے لائن انٹرفیس نے صرف محدود مقدار میں ڈیٹا فراہم کیا تھا۔ اس کے نتیجے میں ، کچھ ڈویلپرز پیرامیٹر کی بڑی اقدار کے ساتھ اشارے کے حساب کتاب کے لئے ضروریات کو پورا کرنے سے قاصر تھے۔
بائننس
K لائن ڈیٹا
میں ہر K لائن کے افتتاحی وقتGET /dapi/v1/klines
اختتامی نقطہ کو ایک منفرد شناخت کے طور پر سمجھا جا سکتا ہے.
درخواست کا وزن
پیرامیٹرز:
سب سے پہلے ، ہمیں ایکسچینج API کی دستاویزات کا حوالہ دینے کی ضرورت ہے تاکہ K- لائن انٹرفیس کے مخصوص پیرامیٹرز کو سمجھ سکیں۔ ہم دیکھ سکتے ہیں کہ جب اس K- لائن کے اختتامی نقطہ کو کال کرتے ہیں تو ، ہمیں قسم ، K- لائن مدت ، ڈیٹا رینج (شروع اور اختتامی وقت) ، اور صفحات کی تعداد وغیرہ کی وضاحت کرنے کی ضرورت ہے۔
چونکہ ہماری ڈیزائن کی ضرورت ہے کہ مخصوص تعداد میں K- لائن کے ڈیٹا سے سوال کیا جائے، مثال کے طور پر، موجودہ لمحے سے ماضی کی طرف 1 گھنٹے K- لائن کے ڈیٹا کے 5000 بار سے سوال کرنے کے لئے، یہ واضح ہے کہ تبادلہ میں ایک واحد API کال کرنے سے مطلوبہ ڈیٹا حاصل نہیں ہوگا.
اس مقصد کو حاصل کرنے کے لئے ، ہم صفحہ بندی کو نافذ کرسکتے ہیں اور سوال کو موجودہ لمحے سے لے کر کسی مخصوص تاریخی لمحے تک حصوں میں تقسیم کرسکتے ہیں۔ چونکہ ہمیں مطلوبہ 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- لائن کے ڈیٹا کو بازیافت کیا جاسکے ، کیونکہ اس کے نتیجے میں غیر ضروری API کالز ہوں گی۔
لہذا، بعد میں ڈیٹا اپ ڈیٹس کے لئے ایک انٹرفیس ڈیزائن کرنے کے لئے بھی ضروری ہے:$.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
}
ٹیمپلیٹ میں، ہم صرف بائننس فیوچر معاہدے K لائن انٹرفیس کے لئے حمایت لاگو کیا ہے، یعنی،getRecordsForFuturesBinance
فنکشن۔ اسے دوسرے کریپٹوکرنسی تبادلے کے کے لائن انٹرفیس کی حمایت کرنے کے لئے بھی بڑھایا جاسکتا ہے۔
جیسا کہ آپ دیکھ سکتے ہیں ، ٹیمپلیٹ میں ان افعال کو نافذ کرنے کے لئے کوڈ وسیع نہیں ہے ، مجموعی طور پر 200 لائنوں سے بھی کم ہے۔ ٹیمپلیٹ کوڈ لکھنے کے بعد ، ٹیسٹنگ انتہائی ضروری ہے اور اسے نظرانداز نہیں کیا جانا چاہئے۔ مزید برآں ، اس طرح کے ڈیٹا کی بازیافت کے لئے ، مکمل ٹیسٹنگ کرنا ضروری ہے۔
اس کی جانچ کرنے کے لئے، آپ کو آپ کی حکمت عملی لائبریری میں
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_M5
5 منٹ کے K لائن مدت مقرر کرنے کے لئے اور 8000 بار حاصل کرنے کے لئے کی وضاحت. پھر ہم طویل K لائن کے اعداد و شمار کی طرف سے واپس کر دیا پر ایک پلاٹ ٹیسٹ انجام دے سکتے ہیںvar r = $.GetRecordsByLength(exchange, testPeriod, 8000)
interface.
// Use the plot test for easy observation
$.PlotRecords(r, "k")
طویل 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")
ان چیکوں کو منظور کرنے کے بعد، تصدیق کریں کہ کیا 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 لائن ڈیٹا اپ ڈیٹس اور اضافے صحیح طریقے سے کام کر رہے ہیں۔
روزانہ کے لائن کے اعداد و شمار کا استعمال کرتے ہوئے، ہم اسے 8000 بار حاصل کرنے کے لئے مقرر کرتے ہیں (یہ جانتے ہوئے کہ 8000 دن پہلے کے لئے کوئی مارکیٹ کا ڈیٹا دستیاب نہیں ہے) ۔ یہ ایک خام طاقت ٹیسٹ کے طور پر کام کرتا ہے:
چونکہ صرف 1309 روزانہ K لائنز ہیں، تب تبادلہ چارٹ کے اعداد و شمار کا موازنہ کریں:
آپ دیکھ سکتے ہیں کہ اعداد و شمار بھی مماثل ہیں۔
نمونہ کا پتہ:
مندرجہ بالا ٹیمپلیٹ اور حکمت عملی کا کوڈ صرف تعلیم اور سیکھنے کے استعمال کے لئے ہے ، براہ کرم براہ راست تجارت کی مخصوص ضروریات کے مطابق اصلاح اور ترمیم کریں۔