avatar of 发明者量化-小小梦 发明者量化-小小梦
집중하다 사신
4
집중하다
1271
수행원

FMZ 정량화: 암호화폐 시장에서의 일반적인 수요 설계 사례 분석(I)

만든 날짜: 2023-12-17 18:43:46, 업데이트 날짜: 2024-11-06 21:18:36
comments   3
hits   1810

FMZ 정량화: 암호화폐 시장에서의 일반적인 수요 설계 사례 분석(I)

암호화폐 자산 거래 분야에서는 시장 데이터를 수집하고 분석하고, 가격을 조회하고, 계좌 자산 변동 사항을 모니터링하는 것이 핵심 작업입니다. 다음은 몇 가지 일반적인 요구 사항을 구현하기 위한 코드 예입니다.

1. 4시간 이내에 바이낸스 현물 거래에서 가장 큰 증가를 보여주는 코드를 어떻게 작성해야 하나요?

FMZ에서 양적 거래 전략 프로그램을 작성할 때는 먼저 요구 사항을 분석해야 합니다. 따라서 우리는 요구 사항에 따라 다음과 같은 사항을 분석합니다.

  • 디자인을 작성하는 데 어떤 프로그래밍 언어가 사용됩니까? Javascript를 사용하여 구현을 계획했습니다.
  • 모든 통화에 대한 실시간 현물 시장 데이터가 필요합니다. 이 요구 사항을 확인했을 때 우리가 가장 먼저 한 일은 Binance의 API 문서를 살펴보고 통합된 시장 데이터가 있는지 확인하는 것이었습니다. (통합된 시장 데이터가 가장 좋습니다. 각 제품을 하나씩 확인하는 것은 시간이 많이 걸리고 힘들기 때문입니다.) 하나). 집계된 시장 정보 인터페이스 쿼리:GET https://api.binance.com/api/v3/ticker/price。 FMZ에서 다음을 사용하여 거래소 견적 인터페이스(서명이 필요하지 않은 공개 인터페이스)에 액세스합니다.HttpQuery기능.
  • 4시간의 롤링 윈도우 기간의 데이터를 계산해야 합니다. 이 통계 프로그램을 어떻게 구성할지 생각해 보세요.
  • 상승과 하락을 계산하고 정렬합니다 상승 및 하락 알고리즘에 대해 생각해 보세요.涨跌幅百分比 =(当前价格 - 初始价格)/ 初始价格 * 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)
        }
        
        // 计算涨跌幅
        var tbl = {
            type : "table",
            title : "涨跌幅",
            cols : ["交易对", "当前价格", "4小时前价格", "涨跌幅", "数据长度", "最早数据时间", "最新数据时间"],
            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. 메인 함수 main()
    • 2.1. 무한 루프
    while (true) {
        // ...
    }
    

    이 프로그램은 무한 루프를 통해 Binance API의 거래 쌍 가격을 지속적으로 모니터링합니다.

    • 2.2. 가격 정보 얻기
    var arr = JSON.parse(HttpQuery("https://api.binance.com/api/v3/ticker/price"))
    

    Binance API를 통해 거래 쌍의 현재 가격 정보를 얻으세요. 반환된 값이 배열이 아닌 경우, 5초간 기다렸다가 다시 시도하세요.

    • 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시간을 초과하면 가장 오래된 데이터를 삭제합니다.

    • 2.6. 테이블 정렬 및 생성
    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를 통해 거래 쌍의 실시간 가격 정보를 얻은 다음, 증가 또는 감소를 계산하여 표 형태로 로그에 출력합니다. 이 프로그램은 거래 쌍 가격을 실시간으로 모니터링하는 기능을 달성하기 위해 연속 루프로 실행됩니다. 가격 정보를 얻을 때 예외가 발생하여 실행이 중단되지 않도록 하기 위해 프로그램에는 예외 처리 기능이 포함되어 있다는 점에 유의하세요.

실제 디스크 동작 테스트

FMZ 정량화: 암호화폐 시장에서의 일반적인 수요 설계 사례 분석(I)

처음에는 데이터를 조금씩만 수집할 수 있으므로 4시간 분량의 데이터가 충분히 수집되지 않았다면 지속적으로 상승 및 하락을 계산하는 것은 불가능합니다. 따라서 처음에는 초기 가격을 계산의 벤치마크로 사용합니다. 4시간 동안 충분한 데이터를 수집한 후 가장 오래된 데이터를 하나씩 제거하여 상승 및 하락을 계산하는 4시간 윈도우 기간을 유지합니다.

2. 모든 바이낸스 U-마진 선물 계약의 자금 조달 비율을 확인하세요.

자금 조달 비율을 쿼리하는 것은 위의 코드와 비슷합니다. 먼저 Binance의 API 문서를 확인하여 자금 조달 비율 관련 인터페이스를 찾아야 합니다. 바이낸스는 자금 조달 비율을 쿼리하기 위한 여러 인터페이스를 가지고 있습니다. 여기서는 U 기반 계약의 인터페이스를 예로 들어보겠습니다.

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: "U本位合约资金费率前十",
                cols: ["合约", "资金费率", "标记价格", "指数价格", "当期费率时间", "下期费率时间"],
                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
}

실제 디스크 작동 테스트:

FMZ 정량화: 암호화폐 시장에서의 일반적인 수요 설계 사례 분석(I)

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": "U本位合约资金费率前十",
                "cols": ["合约", "下期费率", "最小", "当期", "最大"],
                "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)

실제 디스크 작동 테스트:

FMZ 정량화: 암호화폐 시장에서의 일반적인 수요 설계 사례 분석(I)

END

이러한 예는 기본적인 설계 아이디어와 호출 방법을 제공합니다. 실제 프로젝트에서는 특정 요구 사항에 따라 적절한 수정 및 확장이 필요할 수 있습니다. 이러한 코드가 암호화폐 디지털 자산 거래에서 다양한 요구 사항을 더 잘 충족하는 데 도움이 되기를 바랍니다.