디지털 화폐 거래소를 사용하여 시장 인터페이스를 통합하여 다양한 전략을 구축합니다.

저자:작은 꿈, 2021-03-17 18:38:47로 제작, 2023-09-26 20:58:11로 업데이트

img

디지털 화폐 거래소를 사용하여 시장 인터페이스를 통합하여 다양한 전략을 구축합니다.

FMZ 양적 거래 플랫폼전략적 포괄적 영역이 문서에서는 여러 가지 다양한 전략을 통해 수십 개 또는 하나의 거래소 전체 시장을 탐지하는 것을 자주 볼 수 있습니다. 어떻게 할 수 있습니까? 그리고 어떻게 설계해야합니까? 이 기사는 거래소의 통합 시장 인터페이스를 사용하여 다양한 전략을 구축하는 방법을 함께합니다.

이 두 거래소를 나열하고, 거래소 API 문서를 살펴보면 모두 통합 시장 인터페이스가 있음을 알 수 있습니다:

비즈니스 인터페이스

  • 비안안 계약:https://fapi.binance.com/fapi/v1/ticker/bookTicker인터페이스는 데이터를 반환합니다.

    [
        {
            "symbol": "BTCUSDT", // 交易对
            "bidPrice": "4.00000000", //最优买单价
            "bidQty": "431.00000000", //挂单量
            "askPrice": "4.00000200", //最优卖单价
            "askQty": "9.00000000", //挂单量
            "time": 1589437530011   // 撮合引擎时间
        }
        ...
    ]
    
  • 코인 현금:https://api.huobi.pro/market/tickers인터페이스는 데이터를 반환합니다.

    [  
        {  
            "open":0.044297,      // 开盘价
            "close":0.042178,     // 收盘价
            "low":0.040110,       // 最低价
            "high":0.045255,      // 最高价
            "amount":12880.8510,  
            "count":12838,
            "vol":563.0388715740,
            "symbol":"ethbtc",
            "bid":0.007545,
            "bidSize":0.008,
            "ask":0.008088,
            "askSize":0.009
        }, 
        ...
    ]
    

    그러나 실제로는 그렇지 않습니다. 토큰 인터페이스가 실제로 반환하는 구조는 다음과 같습니다.

    {
        "status": "ok",
        "ts": 1616032188422,
        "data": [{
      	  "symbol": "hbcbtc",
      	  "open": 0.00024813,
      	  "high": 0.00024927,
      	  "low": 0.00022871,
      	  "close": 0.00023495,
      	  "amount": 2124.32,
      	  "vol": 0.517656218,
      	  "count": 1715,
      	  "bid": 0.00023427,
      	  "bidSize": 2.3,
      	  "ask": 0.00023665,
      	  "askSize": 2.93
        }, ...]
    }
    

    인터페이스에서 반환되는 데이터를 처리할 때 주의가 필요합니다.

전략적 절차 프레임워크 구축

이 두 개의 인터페이스를 전략적으로 어떻게 포괄하고 데이터를 어떻게 처리할 것인가? 이 모든 것은 우리 모두가 함께 천천히 볼 수 있는 것입니다.

먼저, 컨트롤 객체를 구성하기 위해 구성 함수를 작성하십시오.

// 参数e用于传入exchange交易所对象,参数subscribeList是需要处理的交易对列表,例如["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]
function createManager(e, subscribeList) {           
    var self = {}
    self.supportList = ["Futures_Binance", "Huobi"]  // 支持的交易所的

    // 对象属性
    self.e = e
    self.name = e.GetName()
    self.type = self.name.includes("Futures_") ? "Futures" : "Spot"
    self.label = e.GetLabel()
    self.quoteCurrency = ""  
    self.subscribeList = subscribeList   // subscribeList : [strSymbol1, strSymbol2, ...]
    self.tickers = []                    // 接口获取的所有行情数据,定义数据格式:{bid1: 123, ask1: 123, symbol: "xxx"}}
    self.subscribeTickers = []           // 需要的行情数据,定义数据格式:{bid1: 123, ask1: 123, symbol: "xxx"}}
    self.accData = null                  // 用于记录账户资产数据

    // 初始化函数
    self.init = function() { 
    	// 判断是否支持该交易所
        if (!_.contains(self.supportList, self.name)) {        	
        	throw "not support"
        }
    }

    // 判断数据精度
    self.judgePrecision = function (p) {
        var arr = p.toString().split(".")
        if (arr.length != 2) {
            if (arr.length == 1) {
                return 0
            }
            throw "judgePrecision error, p:" + String(p)
        }
        
        return arr[1].length
    }

    // 更新资产
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

    // 更新行情数据
    self.updateTicker = function(url, callBackFuncGetArr, callBackFuncGetTicker) {
    	var tickers = []
    	var subscribeTickers = []
    	var ret = self.httpQuery(url)
    	if (!ret) {
    		return false 
    	}
    	try {
            _.each(callBackFuncGetArr(ret), function(ele) {
            	var ticker = callBackFuncGetTicker(ele)
            	tickers.push(ticker)
            	for (var i = 0 ; i < self.subscribeList.length ; i++) {
            		if (self.subscribeList[i] == ele.symbol) {
            			subscribeTickers.push(ticker)
            		}
            	}
            })
        } catch(err) {
        	Log("错误:", err)
        	return false 
        }

        self.tickers = tickers
        self.subscribeTickers = subscribeTickers
        return true 
    }

    self.httpQuery = function(url) {
    	var ret = null
        try {
            var retHttpQuery = HttpQuery(url)
            ret = JSON.parse(retHttpQuery)
        } catch (err) {
            // Log("错误:", err)
            ret = null
        }
        return ret 
    }

    self.returnTickersTbl = function() {
        var tickersTbl = {
        	type : "table", 
        	title : "tickers",
        	cols : ["symbol", "ask1", "bid1"], 
        	rows : []
        }
        _.each(self.subscribeTickers, function(ticker) {        
        	tickersTbl.rows.push([ticker.symbol, ticker.ask1, ticker.bid1])
        })
        return tickersTbl
    }

    // 初始化
    self.init()
	return self 
}

FMZ를 사용하는 API 함수HttpQuery함수 요청, 거래소 인터페이스에 액세스.HttpQuery비정상 처리가 필요한 경우try...catch인터페이스 반환 실패와 같은 예외를 처리합니다. 여기 있는 학생들 중 몇몇은 이런 질문을 할 수 있습니다. " 거래소 인터페이스에서 돌아오는 데이터 구조는 서로 다릅니다. 어떻게 처리해야 할까요? 같은 방식으로 처리할 수는 없죠". 사실, 거래소 인터페이스가 반환하는 데이터 구조가 다르기뿐만 아니라 반환되는 데이터 필드의 이름도 다릅니다. 같은 의미는 다른 이름을 가질 수 있습니다. 예를 들어, 위와 같은 인터페이스. 같은 표현은 가격을 구입하는 것을 의미합니다.bidPrice이 토큰은bid

우리는 여기서 소환 함수를 사용하여 이 특수 처리 부분을 분리하여 해결합니다. 위와 같은 객체를 초기화하면 다음과 같이 사용됩니다. (하래의 코드는 구성 함수를 제외합니다.createManager(중략) 이 계약들은 이화인자 선물로 모니터링됩니다.["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]코인 현금은 이러한 코인 거래에 대해 모니터링합니다.["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"]예를 들어,

function main() {
    var manager1 = createManager(exchanges[0], ["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"])
    var manager2 = createManager(exchanges[1], ["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"])   

    while (true) {
    	// 更新行情数据
    	var ticker1GetSucc = manager1.updateTicker("https://fapi.binance.com/fapi/v1/ticker/bookTicker", 
    		function(data) {return data}, 
    		function (ele) {return {bid1: ele.bidPrice, ask1: ele.askPrice, symbol: ele.symbol}})
    	var ticker2GetSucc = manager2.updateTicker("https://api.huobi.pro/market/tickers", 
    		function(data) {return data.data}, 
    		function(ele) {return {bid1: ele.bid, ask1: ele.ask, symbol: ele.symbol}})
        if (!ticker1GetSucc || !ticker2GetSucc) {
        	Sleep(1000)
        	continue
        }
        
        var tbl1 = {
        	type : "table", 
        	title : "期货行情数据",
        	cols : ["期货合约", "期货买一", "期货卖一"], 
        	rows : []
        }
        _.each(manager1.subscribeTickers, function(ticker) {
        	tbl1.rows.push([ticker.symbol, ticker.bid1, ticker.ask1])
        })
        var tbl2 = {
        	type : "table", 
        	title : "现货行情数据",
        	cols : ["现货合约", "现货买一", "现货卖一"], 
        	rows : []
        }
        _.each(manager2.subscribeTickers, function(ticker) {
        	tbl2.rows.push([ticker.symbol, ticker.bid1, ticker.ask1])
        })
        LogStatus(_D(), "\n`" + JSON.stringify(tbl1) + "`", "\n`" + JSON.stringify(tbl2) + "`")
        Sleep(10000)
    }
}

실행 테스트: 첫 번째 거래소 객체는 동전 선물, 두 번째 거래소 객체는 토큰 현금을 추가합니다img

img

여기서 볼 수 있듯이, 인터페이스에서 반환된 데이터를 가져오는 방법과 같은 작업은 호출 함수를 사용하여 서로 다른 거래소에 특화된 처리를 수행합니다.

    	var ticker1GetSucc = manager1.updateTicker("https://fapi.binance.com/fapi/v1/ticker/bookTicker", 
    		function(data) {return data}, 
    		function (ele) {return {bid1: ele.bidPrice, ask1: ele.askPrice, symbol: ele.symbol}})
    	var ticker2GetSucc = manager2.updateTicker("https://api.huobi.pro/market/tickers", 
    		function(data) {return data.data}, 
    		function(ele) {return {bid1: ele.bid, ask1: ele.ask, symbol: ele.symbol}})

시장 인수를 정립하고, 다음으로 계정 자산 인수를 정립할 수 있다. 다종양 전략으로, 계정 자산 데이터는 또한 다중이어야 한다. 거래소 계정 자산 인터페이스에서는 일반적으로 전체 자산 데이터를 반환한다.

이 함수들은createManager자산을 획득하는 방법을 추가합니다

    // 更新资产
    self.updateAcc = function(callBackFuncGetAcc) {
        var ret = callBackFuncGetAcc(self)
        if (!ret) {
        	return false 
        }
        self.accData = ret 
        return true 
    }

또한 거래소 인터페이스가 반환하는 형식 때문에 필드 이름도 다양하며, 여기서도 호출 함수의 특화 처리가 필요합니다.

토큰 현금, 동전 선물의 예를 들어, 회환 함수는 다음과 같이 쓸 수 있습니다.

    // 获取账户资产的回调函数
    var callBackFuncGetHuobiAcc = function(self) {
        var account = self.e.GetAccount()
        var ret = []
        if (!account) {
        	return false 
        }
        // 构造资产的数组结构
        var list = account.Info.data.list
        _.each(self.subscribeList, function(symbol) {
            var coinName = symbol.split("usdt")[0]
            var acc = {symbol: symbol}
            for (var i = 0 ; i < list.length ; i++) {
            	if (coinName == list[i].currency) {
                    if (list[i].type == "trade") {
                        acc.Stocks = parseFloat(list[i].balance)
                    } else if (list[i].type == "frozen") {
                    	acc.FrozenStocks = parseFloat(list[i].balance)
                    }
                } else if (list[i].currency == "usdt") {
                	if (list[i].type == "trade") {
                		acc.Balance = parseFloat(list[i].balance)
                	} else if (list[i].type == "frozen") {
                		acc.FrozenBalance = parseFloat(list[i].balance)
                	}
                }
            }
            ret.push(acc)
        })
        return ret 
    }

    var callBackFuncGetFutures_BinanceAcc = function(self) {
    	self.e.SetCurrency("BTC_USDT")   // 设置为U本位合约的交易对
        self.e.SetContractType("swap")   // 合约都是永续合约
        var account = self.e.GetAccount() 
        var ret = []
        if (!account) {
        	return false 
        }
        var balance = account.Balance
        var frozenBalance = account.FrozenBalance
        // 构造资产数据结构
        _.each(self.subscribeList, function(symbol) {
            var acc = {symbol: symbol}
            acc.Balance = balance
            acc.FrozenBalance = frozenBalance
            ret.push(acc)
        })
        return ret 
    }

시장, 자산 기능에 접근할 수 있는 전략적 틀을 운영

이 사건은:img

자산:img

시장 데이터에 접근한 후, 다양한 품종의 차이점을 계산하는 데이터를 처리하고 여러 거래 쌍의 현금 차이점을 모니터링 할 수 있습니다. 이 경우, 다양한 종류의 선물 헤지킹 전략을 설계할 수 있습니다.

이런 디자인을 통해 다른 거래소들도 확장될 수 있고, 관심있는 동료들도 직접 시도할 수 있습니다.


관련

더 많은

제이미를 사랑해요갱신 자산 안의 callBackFuncGetAcc은 매개 변수인가 아니면 함수인가? 또한 자산 계정을 얻는 두 개의 회수 함수인 callBackFuncGetHuobiAcc와 callBackFuncGetFutures_BinanceAcc은 callBackFuncGetAcc과 어떤 관련이 있습니까?

제이미를 사랑해요질문: 화폐가격 차이에서 거래 쌍의 현금 Bid1과 화폐 Ask1의 가격을 동시에 추출하는 방법은 무엇입니까?

zltim정말 멋지네요

작은 꿈바우다 리콜 함수.

작은 꿈두 개의 순환이 얽혀서 지나가는 것입니다.

작은 꿈제가 여러분에게 말씀드린 것은 현금과 선물의 차이입니다. 이 자료들은 모두, 어떻게 계산할 것인가, 당신은 그것을 줄이거나 없습니까?

제이미를 사랑해요제 생각에는 맞지 않나요? 만약 BTCUSDT 현금 구매 가격과 BTCUSDT 선물 판매 가격의 차이를 얻으려면: 먼저 선물 시장 매트리거 매니저 1.subscribe Tickers를 탐색하고, BTCUSDT의 판매 가격 매니저 1.subscribe Tickers[i].ask1를 찾아보세요. 문제는 선물 시장 매트리거에서 BTCUSDT 현금 가격의 1을 추출하는 방법입니다.

제이미를 사랑해요저는 미래에셋대우와 현금 거래의 차이점을 의미하지만, 미래에셋대우 또는 현금 거래의 차이점을 의미하지는 않습니다. 문제는 동일한 거래에 대해 미래에셋대우의 구매 가격과 현금 거래의 판매 가격을 동시에 얻을 수 없다는 것입니다. 예를 들어: BTCUSDT 현금 거래와 BTCUSDT 미래에셋대우의 판매 가격의 차이점을 어떻게 얻을 수 있습니까? function GetBAspot ((syboml, tickerspot, BA) { for (var i = 0; i < tickerspot.length; i++) { if ((tickerspot[i].syboml!==syboml) { 계속하세요 }else if ((tickerspot[i].syboml===syboml) { var bidspot=tickerspot[i].bid1 var askspot=tickerspot[i].ask1 ♪ ♪ ♪ ♪ if ((BA==="bid") return bidspot 이므로 if(BA==="ask")return askspot (이번 문장과 같은 문장) ♪ ♪ function main ((() { _.each(manager1.subscribe 티커, 함수 티커) { var symb=ticker.symbol var symb1=manager1.symFuturesToSpot (symb) tbl1.rows.push (([ticker.symbol, ticker.bid1, ticker.ask1, manager1.Getfundingrate ((symb), manager1.Getrealrate ((symb, 50), GetBAspot ((symb1, SpotTickers, "ask")))) ]) }) ♪ ♪

작은 꿈이 구체적인 기록은 작동합니다, 구매 한 번 판매 한 번, 가격 차이점은 서로를 덜어주지 않습니다.

제이미를 사랑해요이 기사에서 파견된 가격 차이에 대한 그림의 소스 코드가 공개되지 않은 이유는 무엇입니까?

작은 꿈이 글은 제가 이 글을 쓰는 동안 쓴 글입니다.

제이미를 사랑해요하지만 같은 트랜잭션 쌍을 지정하는 것은 통일되지 않습니다.

작은 꿈이 코드는 구매와 판매에 대한 데이터를 포함하고 있습니다.