В пространстве торговли криптовалютными активами получение и анализ рыночных данных, запросы по ставкам и мониторинг движения активов счетов являются критическими операциями. Ниже приведены примеры реализации для некоторых общих требований.
Когда вы пишете программу количественной торговой стратегии на платформе FMZ, первое, что вам нужно сделать, когда вы столкнетесь с требованием, это проанализировать его.
GET https://api.binance.com/api/v3/ticker/price
- Да.
На платформе FMZ используйтеHttpQuery
функция для доступа к интерфейсу exchange ticker (публичный интерфейс, не требующий подписи).price fluctuations (%) = (current price - initial price) / initial price * 100
в После того, как мы решили проблему, а также определили программу, мы приступили к разработке программы.
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 = {}
: Пустой объект для хранения ценовой информации для каждой торговой пары. Ключ - это символ торговой пары, а значение - объект, содержащий название торговой пары, массив ценовых данных и информацию о колебаниях цен.while (true) {
// ...
}
Программа непрерывно отслеживает цены торговых пар Binance API через бесконечную петлю. 2.2. Получить информацию о ценах
var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))
Получите текущую информацию о цене торговой пары через API Binance. 2.3 Обновление данных о ценах
for (var i = 0; i < arr.length; i++) {
// ...
}
Итерация по массиву полученной информации о ценах и обновление данных в dictSymbolsPrice. Для каждой торговой пары добавьте текущую временную метку и цену в соответствующий массив данных. 2.4 Обработка исключений
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
Поймать исключения и записать информацию об исключениях, чтобы обеспечить продолжение выполнения программы. 2.5. Расчет колебаний цен
for (var symbol in dictSymbolsPrice) {
// ...
}
Итерация через dictSymbolsPrice, вычисление колебаний цены каждой торговой пары, и удаление самых ранних данных, если он длится более 4 часов. Сортировать и генерировать таблицы
var entries = Object.entries(dictSymbolsPrice)
entries.sort((a, b) => b[1].percentageChange - a[1].percentageChange)
for (var i = 0; i < entries.length; i++) {
// ...
}
Сортировать торговые пары в порядке их снижения и создать таблицу с информацией о торговых парах. 2.7. Выход и задержка журналов
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(5000)
Выведите таблицу и текущее время в виде журнала и подождите 5 секунд, чтобы продолжить следующий раунд цикла.
Программа получает информацию о ценах торговой пары в режиме реального времени через API Binance, затем рассчитывает колебания цен и выводит ее в журнал в виде таблицы. Программа выполняется в непрерывной петле для реализации функции мониторинга цен торговых пар в режиме реального времени.
Поскольку данные могут быть собраны только понемногу в начале, невозможно рассчитать колебания цен на текущей основе без сбора достаточного количества данных для 4-часового окна. Поэтому начальная цена используется в качестве основы для расчета, и после сбора достаточного количества данных в течение 4 часов самые старые данные будут удалены, чтобы сохранить 4-часовое окно для расчета колебаний цен.
Проверка ставки финансирования аналогична вышеуказанному коду, прежде всего, нам нужно проверить документацию API Binance, чтобы найти интерфейс, связанный с ставкой финансирования.
GET https://fapi.binance.com/fapi/v1/premiumIndex
Поскольку контрактов так много, мы экспортируем 10 самых высоких показателей финансирования.
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)
}
}
Структура возвращенных данных выглядит следующим образом, и проверьте документацию Binance, она показывает, что lastFundingRate - это ставка финансирования, которую мы хотим.
{
"symbol":"STMXUSDT",
"markPrice":"0.00883606",
"indexPrice":"0.00883074",
"estimatedSettlePrice":"0.00876933",
"lastFundingRate":"0.00026573",
"interestRate":"0.00005000",
"nextFundingTime":1702828800000,
"time":1702816229000
}
Тест на ходу в режиме реального времени:
Пользователь попросил версию примера на Python, и это для обмена OKX. Вот пример:
Данные, возвращенные интерфейсомhttps://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"
} ...
Специфический код:
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)
Тест на ходу в режиме реального времени:
Эти примеры предоставляют основные идеи дизайна и методы вызова, фактическому проекту может потребоваться внести соответствующие изменения и расширения на основе конкретных потребностей.