En el espacio de comercio de activos de criptomonedas, la obtención y el análisis de datos de mercado, las tasas de consulta y el monitoreo de los movimientos de activos de la cuenta son operaciones críticas.
Cuando se escribe un programa de estrategia comercial cuantitativa en la plataforma FMZ, lo primero que debe hacer cuando se encuentra con un requisito es analizarlo.
GET https://api.binance.com/api/v3/ticker/price
¿ Qué pasa?
En la plataforma FMZ, utilice elHttpQuery
Función para acceder a la interfaz del ticker de intercambio (interfaz pública que no requiere una firma).price fluctuations (%) = (current price - initial price) / initial price * 100
en Después de averiguar el problema, así como definir el programa, luego nos pusimos a trabajar en el diseño del programa.
var dictSymbolsPrice = {}
function main() {
while (true) {
// GET https://api.binance.com/api/v3/ticker/price
try {
var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))
if (!Array.isArray(arr)) {
Sleep(5000)
continue
}
var ts = new Date().getTime()
for (var i = 0; i < arr.length; i++) {
var symbolPriceInfo = arr[i]
var symbol = symbolPriceInfo.symbol
var price = symbolPriceInfo.price
if (typeof(dictSymbolsPrice[symbol]) == "undefined") {
dictSymbolsPrice[symbol] = {name: symbol, data: []}
}
dictSymbolsPrice[symbol].data.push({ts: ts, price: price})
}
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
// Calculate price fluctuations
var tbl = {
type : "table",
title : "Price fluctuations",
cols : ["trading pair", "current price", "price 4 hours ago", "price fluctuations", "data length", "earliest data time", "latest data time"],
rows : []
}
for (var symbol in dictSymbolsPrice) {
var data = dictSymbolsPrice[symbol].data
if (data[data.length - 1].ts - data[0].ts > 1000 * 60 * 60 * 4) {
dictSymbolsPrice[symbol].data.shift()
}
data = dictSymbolsPrice[symbol].data
dictSymbolsPrice[symbol].percentageChange = (data[data.length - 1].price - data[0].price) / data[0].price * 100
}
var entries = Object.entries(dictSymbolsPrice)
entries.sort((a, b) => b[1].percentageChange - a[1].percentageChange)
for (var i = 0; i < entries.length; i++) {
if (i > 9) {
break
}
var name = entries[i][1].name
var data = entries[i][1].data
var percentageChange = entries[i][1].percentageChange
var currPrice = data[data.length - 1].price
var currTs = _D(data[data.length - 1].ts)
var prePrice = data[0].price
var preTs = _D(data[0].ts)
var dataLen = data.length
tbl.rows.push([name, currPrice, prePrice, percentageChange + "%", dataLen, preTs, currTs])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(5000)
}
}
var dictSymbolsPrice = {}
: Un objeto vacío para almacenar información de precios para cada par de operaciones. La clave es el símbolo del par de operaciones, y el valor es un objeto que contiene el nombre del par de operaciones, una matriz de datos de precios e información sobre las fluctuaciones de precios.while (true) {
// ...
}
El programa monitorea continuamente los precios de los pares de comercio de Binance API a través de un bucle infinito. 2.2 Obtener información sobre los precios
var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))
Obtenga la información del precio actual del par de operaciones a través de Binance API. Si el retorno no es una matriz, espere 5 segundos y vuelva a intentar. 2.3 Actualización de los datos de precios
for (var i = 0; i < arr.length; i++) {
// ...
}
Iterar a través de la matriz de información de precios obtenida y actualizar los datos en dictSymbolsPrice. 2.4 Procesamiento de excepciones
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
Captura de excepciones y registro de la información de excepción para garantizar que el programa pueda continuar ejecutándose. 2.5. Calcular las fluctuaciones de precios
for (var symbol in dictSymbolsPrice) {
// ...
}
Iterar a través de dictSymbolsPrice, calcular las fluctuaciones de precios de cada par de operaciones, y eliminar los datos más antiguos si es más de 4 horas. Ordenar y generar tablas
var entries = Object.entries(dictSymbolsPrice)
entries.sort((a, b) => b[1].percentageChange - a[1].percentageChange)
for (var i = 0; i < entries.length; i++) {
// ...
}
Ordenar los pares de operaciones en orden decreciente de sus fluctuaciones de precios y generar una tabla que contenga información sobre los pares de operaciones. 2.7. Salida y retraso del registro
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(5000)
Saque la tabla y la hora actual en forma de registro y espere 5 segundos para continuar la siguiente ronda del bucle.
El programa obtiene la información de precios en tiempo real del par de operaciones a través de la API de Binance, luego calcula las fluctuaciones de precios y lo emite al registro en forma de tabla. El programa se ejecuta en un bucle continuo para realizar la función de monitoreo en tiempo real de los precios de los pares comerciales. Tenga en cuenta que el programa incluye procesamiento de excepciones para garantizar que la ejecución no se interrumpa por excepciones al obtener información de precios.
Dado que los datos solo se pueden recopilar poco a poco al principio, no es posible calcular las fluctuaciones de precios de forma continua sin recopilar suficientes datos para una ventana de 4 horas. Por lo tanto, el precio inicial se utiliza como base para el cálculo y, después de recopilar suficientes datos durante 4 horas, se eliminarán los datos más antiguos para mantener la ventana de 4 horas para calcular las fluctuaciones de precios.
Verificar la tasa de financiación es similar al código anterior, en primer lugar, necesitamos verificar la documentación de la API de Binance para encontrar la interfaz relacionada con la tasa de financiación.
GET https://fapi.binance.com/fapi/v1/premiumIndex
Dado que hay tantos contratos, estamos exportando las 10 mayores tasas de financiación aquí.
function main() {
while (true) {
// GET https://fapi.binance.com/fapi/v1/premiumIndex
try {
var arr = JSON.parse(HttpQuery("https://fapi.binance.com/fapi/v1/premiumIndex"))
if (!Array.isArray(arr)) {
Sleep(5000)
continue
}
arr.sort((a, b) => parseFloat(b.lastFundingRate) - parseFloat(a.lastFundingRate))
var tbl = {
type: "table",
title: "Top 10 funding rates for U-denominated contracts",
cols: ["contracts", "funding rate", "marked price", "index price", "current rate time", "next rate time"],
rows: []
}
for (var i = 0; i < 9; i++) {
var obj = arr[i]
tbl.rows.push([obj.symbol, obj.lastFundingRate, obj.markPrice, obj.indexPrice, _D(obj.time), _D(obj.nextFundingTime)])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
Sleep(1000 * 10)
}
}
La estructura de datos devuelta es la siguiente, y comprobar la documentación de Binance, muestra que la última tasa de financiación es la tasa de financiación que queremos.
{
"symbol":"STMXUSDT",
"markPrice":"0.00883606",
"indexPrice":"0.00883074",
"estimatedSettlePrice":"0.00876933",
"lastFundingRate":"0.00026573",
"interestRate":"0.00005000",
"nextFundingTime":1702828800000,
"time":1702816229000
}
Prueba de operación en vivo:
Un usuario ha pedido una versión de Python del ejemplo, y es para el intercambio OKX. Aquí hay un ejemplo:
Los datos devueltos por la interfazhttps://www.okx.com/priapi/v5/public/funding-rate-all?currencyType=1
:
{
"code":"0",
"data":[
{
"fundingTime":1702828800000,
"fundingList":[
{
"instId":"BTC-USDT-SWAP",
"nextFundingRate":"0.0001102188733642",
"minFundingRate":"-0.00375",
"fundingRate":"0.0000821861465884",
"maxFundingRate":"0.00375"
} ...
Código específico:
import requests
import json
from time import sleep
from datetime import datetime
def main():
while True:
# https://www.okx.com/priapi/v5/public/funding-rate-all?currencyType=1
try:
response = requests.get("https://www.okx.com/priapi/v5/public/funding-rate-all?currencyType=1")
arr = response.json()["data"][0]["fundingList"]
Log(arr)
if not isinstance(arr, list):
sleep(5)
continue
arr.sort(key=lambda x: float(x["fundingRate"]), reverse=True)
tbl = {
"type": "table",
"title": "Top 10 funding rates for U-denominated contracts",
"cols": ["contracts", "next rate", "minimum", "current", "maximum"],
"rows": []
}
for i in range(min(9, len(arr))):
obj = arr[i]
row = [
obj["instId"],
obj["nextFundingRate"],
obj["minFundingRate"],
obj["fundingRate"],
obj["maxFundingRate"]
]
tbl["rows"].append(row)
LogStatus(_D(), "\n", '`' + json.dumps(tbl) + '`')
except Exception as e:
Log(f"Error: {str(e)}")
sleep(10)
Prueba de operación en vivo:
Estos ejemplos proporcionan ideas básicas de diseño y métodos de llamada, el proyecto real puede necesitar hacer cambios y extensiones apropiados basados en las necesidades específicas.