FMZ Quant: Анализ общих требований Примеры проектирования на рынке криптовалют (I)

Автор:Лидия., Создано: 2023-12-19 16:02:58, Обновлено: 2024-01-02 21:21:58

img

В пространстве торговли криптовалютными активами получение и анализ рыночных данных, запросы по ставкам и мониторинг движения активов счетов являются критическими операциями. Ниже приведены примеры реализации для некоторых общих требований.

Как написать код, чтобы получить валюту с самым высоким ростом за 4 часа на Binance Spot?

Когда вы пишете программу количественной торговой стратегии на платформе FMZ, первое, что вам нужно сделать, когда вы столкнетесь с требованием, это проанализировать его.

  • Какой язык программирования использовать? План состоит в том, чтобы использовать Javascript для его реализации.
  • Требует спотовых котировок в реальном времени во всех валютах Первое, что мы сделали, когда увидели требование, это посмотрели на документ API Binance, чтобы узнать, есть ли какие-либо агрегированные котировки (лучше иметь агрегированные котировки, это много работы, чтобы искать по одному). Мы нашли интерфейс совокупных цитат:GET https://api.binance.com/api/v3/ticker/price- Да. На платформе FMZ используйтеHttpQueryфункция для доступа к интерфейсу exchange ticker (публичный интерфейс, не требующий подписи).
  • Необходимо подсчитать данные за проходящий период окна в 4 часа Концептуализировать, как разработать структуру статистической программы.
  • Расчет колебаний цен и сортировка Если подумать об алгоритме колебаний цен, это: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)
    }
}

Анализ кода

    1. Структура данныхvar dictSymbolsPrice = {}: Пустой объект для хранения ценовой информации для каждой торговой пары. Ключ - это символ торговой пары, а значение - объект, содержащий название торговой пары, массив ценовых данных и информацию о колебаниях цен.
    1. Главная функция 2.1 Бесконечная петля
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, затем рассчитывает колебания цен и выводит ее в журнал в виде таблицы. Программа выполняется в непрерывной петле для реализации функции мониторинга цен торговых пар в режиме реального времени.

Тест на ход торговли в реальном времени

img

Поскольку данные могут быть собраны только понемногу в начале, невозможно рассчитать колебания цен на текущей основе без сбора достаточного количества данных для 4-часового окна. Поэтому начальная цена используется в качестве основы для расчета, и после сбора достаточного количества данных в течение 4 часов самые старые данные будут удалены, чтобы сохранить 4-часовое окно для расчета колебаний цен.

2. Проверьте полное разнообразие ставок финансирования для контрактов Binance в формате U

Проверка ставки финансирования аналогична вышеуказанному коду, прежде всего, нам нужно проверить документацию 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
}

Тест на ходу в режиме реального времени:

img

Получение ставок финансирования биржевого контракта OKX версии Python

Пользователь попросил версию примера на 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)

Тест на ходу в режиме реального времени:

img

Окончание

Эти примеры предоставляют основные идеи дизайна и методы вызова, фактическому проекту может потребоваться внести соответствующие изменения и расширения на основе конкретных потребностей.


Больше