No espaço de negociação de ativos de criptomoedas, a obtenção e análise de dados de mercado, as taxas de consulta e o monitoramento dos movimentos de ativos da conta são operações críticas.
Ao escrever um programa de estratégia quantitativa de negociação na plataforma FMZ, a primeira coisa que você precisa fazer quando você encontrar um requisito é analisá-lo.
GET https://api.binance.com/api/v3/ticker/price
- Não.
Na plataforma FMZ, use oHttpQuery
Função para aceder à interface do ticker de troca (interface pública que não requer uma assinatura).price fluctuations (%) = (current price - initial price) / initial price * 100
em Depois de resolvermos o problema e definirmos o programa, começámos a trabalhar no projeto.
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 = {}
: Um objeto vazio para armazenar informações de preço para cada par de negociação. A chave é o símbolo do par de negociação, e o valor é um objeto contendo o nome do par de negociação, uma matriz de dados de preço e informações sobre as flutuações de preços.while (true) {
// ...
}
O programa monitora continuamente os preços dos pares de negociação da Binance API através de um loop infinito. 2.2. Obter informações sobre os preços
var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))
Obtenha as informações de preço atuais do par de negociação através da API do Binance. 2.3 Atualização dos dados de preços
for (var i = 0; i < arr.length; i++) {
// ...
}
Iterar através da matriz de informações de preço obtidas e atualizar os dados em dictSymbolsPrice. 2.4 Processamento de exceções
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
Capturar exceções e registrar as informações de exceção para garantir que o programa possa continuar a ser executado. 2.5. Calcular as flutuações de preços
for (var symbol in dictSymbolsPrice) {
// ...
}
Iterar através do dictSymbolsPrice, calcular as flutuações de preços de cada par de negociação e remover os dados mais antigos se forem mais longos que 4 horas. 2.6. Ordenar e gerar tabelas
var entries = Object.entries(dictSymbolsPrice)
entries.sort((a, b) => b[1].percentageChange - a[1].percentageChange)
for (var i = 0; i < entries.length; i++) {
// ...
}
Ordenar os pares de negociação em ordem decrescente das suas flutuações de preços e gerar uma tabela contendo informações sobre os pares de negociação. 2.7. Saída e atraso do registo
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(5000)
Saia a tabela e a hora atual sob a forma de um log e espere 5 segundos para continuar a próxima rodada do loop.
O programa obtém as informações de preço em tempo real do par de negociação através da API do Binance, em seguida, calcula as flutuações de preço e as exporta para o log sob a forma de uma tabela.
Uma vez que os dados só podem ser recolhidos pouco a pouco no início, não é possível calcular as flutuações dos preços numa base contínua sem recolher dados suficientes para uma janela de 4 horas.
Verificar a taxa de financiamento é semelhante ao código acima, em primeiro lugar, precisamos verificar a documentação da API da Binance para encontrar a interface relacionada à taxa de financiamento.
GET https://fapi.binance.com/fapi/v1/premiumIndex
Dado que há tantos contratos, estamos a exportar as 10 maiores taxas de financiamento aqui.
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)
}
}
A estrutura de dados retornados é a seguinte, e verifique a documentação Binance, ele mostra que lastFundingRate é a taxa de financiamento que queremos.
{
"symbol":"STMXUSDT",
"markPrice":"0.00883606",
"indexPrice":"0.00883074",
"estimatedSettlePrice":"0.00876933",
"lastFundingRate":"0.00026573",
"interestRate":"0.00005000",
"nextFundingTime":1702828800000,
"time":1702816229000
}
Teste de execução de negociação em tempo real:
Um usuário pediu uma versão Python do exemplo, e é para o exchange OKX. Aqui está um exemplo:
Os dados devolvidos pela interfacehttps://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)
Teste de execução de negociação em tempo real:
Esses exemplos fornecem ideias básicas de design e métodos de chamada, o projeto real pode precisar fazer alterações e extensões apropriadas com base nas necessidades específicas.