Strategy vault / Tools & templates
JavaScript Version Paginated Query K Line Historical Data Template Lesson
Related article reference:https://www.fmz.com/bbs-topic/10105
JavaScriptTools & templates
Related article reference:https://www.fmz.com/bbs-topic/10105
Source JavaScript
/**
* desc: $.GetRecordsByLength This is the interface function of the template library, used to obtain candlestick data of a specified candlestick length
* @param {Object} e - Exchange object
* @param {Int} period - KLine period, in seconds
* @param {Int} length - Specify the length of candlestick data to fetch, depending on the exchange interface limitations
* @returns {Array<Object>} - KLine 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 Specific implementation of the function to obtain candlestick data from Binance Futures
* @param {Object} e - Exchange object
* @param {Int} period - KLine period, in seconds
* @param {Int} length - Specify the length of candlestick data to fetch, depending on the exchange interface limitations
* @returns {Array<Object>} - KLine 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 -> Sky/Heaven; w -> week; M -> Moon
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
// startTime and endTime Can differ by at most200Sky/Heaven
// 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) {
// Calculationlimit
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
}
// Exceeds the exchange's queryable range, when data cannot be retrieved
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 This is the interface function of the template library, which is used to update candlestick data
* @param {Object} e - Exchange object
* @param {Array<Object>} records - candlestick data source that needs to be updated
* @param {Int} period - Kperiod must match the candlestick data period passed in by the рекордs parameter
* @returns {Bool} - Is the update 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 newBar
records.push(r[i])
// Update the previous oneBar
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) {
// UpdateBar
records[records.length - 1] = r[i]
}
}
return true
}
// Template test function
function main() {
Log("Currently testing exchanges:", exchange.GetName())
// If it is futures, a contract needs to be set
exchange.SetContractType("swap")
// Use$.GetRecordsByLengthGet the specified lengthKLine data, specified period is60seconds, that is, one minuteKLine, specified length is8000Root
var r = $.GetRecordsByLength(exchange, 60, 8000)
Log(r)
// Detection 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 for duplicatesBar
if (i != j && r[i].Time == r[j].Time) {
Log(r[i].Time, i, r[j].Time, j)
throw "DuplicateBar"
}
}
// CheckBarContinuity
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 "BarDiscontinuity"
}
}
}
Log("Test passed")
Log("$.GetRecordsByLengthData length returned by the function:", r.length)
// UseGetRecordsData update obtained by the functionr
while (true) {
$.UpdataRecords(exchange, r, 60)
LogStatus(_D(), ", r.length:", r.length)
Log(_D(r[r.length - 1].Time), r[r.length - 1])
Sleep(5000)
}
}Published by 发明者量化-小小梦 on the FMZ strategy square · last modified 2023-06-27. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.
Build this with AgenKit
A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.
/agenkit build a tested, production-ready module from strategies/JavaScript-Version-Paginated-Query-K-Line-Historical-Data-Template-Lesson.md- npx agenkit install engineering-kit in your project
- Paste the command into your agent and approve each phase
- Get tests, backtest, risk controls and a paper-trading switch
Understand it first
Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.
Related specs
- Binance Account Cross Transfer Small ToolJavaScript · Tools & templates
- Get cryptocurrency current and max supplyJavaScript · Tools & templates
- Interaction TemplateJavaScript · Tools & templates
- KuCoin Fund Transfer PluginJavaScript · Tools & templates
- Moving Average Bot 30 linesJavaScript · Tools & templates · 1d
- OKEx V5 Candlestick Data Paginated Query ExampleJavaScript · Tools & templates