Xây dựng chiến lược đa dạng bằng cách sử dụng giao dịch tiền kỹ thuật số để tích hợp giao diện thị trường

Tác giả:Giấc mơ nhỏ, Tạo: 2021-03-17 18:38:47, Cập nhật: 2023-09-26 20:58:11

img

Xây dựng chiến lược đa dạng bằng cách sử dụng giao dịch tiền kỹ thuật số để tích hợp giao diện thị trường

FMZ sàn giao dịch định lượngChiến lược bao quátBài viết này sẽ hướng dẫn bạn cách sử dụng giao diện giao dịch tổng hợp để xây dựng chiến lược đa dạng.

Trong khi đó, một số sàn giao dịch khác cũng có giao diện giao dịch tổng hợp, như Bitcoin và Token.

Giao diện giao tiếp

  • Các nhà lãnh đạo của các nước khác cũng đã đồng ý.https://fapi.binance.com/fapi/v1/ticker/bookTickerGiao diện trả về dữ liệu

    [
        {
            "symbol": "BTCUSDT", // 交易对
            "bidPrice": "4.00000000", //最优买单价
            "bidQty": "431.00000000", //挂单量
            "askPrice": "4.00000200", //最优卖单价
            "askQty": "9.00000000", //挂单量
            "time": 1589437530011   // 撮合引擎时间
        }
        ...
    ]
    
  • Tiền mặt:https://api.huobi.pro/market/tickersGiao diện trả về dữ liệu

    [  
        {  
            "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
        }, 
        ...
    ]
    

    Tuy nhiên, thực tế không phải như vậy, cấu trúc mà giao diện token thực sự trả về là:

    {
        "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
        }, ...]
    }
    

    Cần phải cẩn thận khi xử lý dữ liệu được trả về bởi giao diện.

Xây dựng khuôn khổ quy trình chiến lược

Làm thế nào để bao gồm hai giao diện này trong chiến lược và làm thế nào để xử lý dữ liệu? Chúng ta hãy cùng nhau xem nó từ từ nhé.

Trước tiên, hãy viết một hàm xây dựng để xây dựng các đối tượng điều khiển.

// 参数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 
}

Các hàm API sử dụng FMZHttpQueryChức năng gửi yêu cầu, truy cập giao diện giao dịch.HttpQueryKhi cần xử lý ngoại lệtry...catchXử lý các trường hợp bất thường như sự thất bại của giao diện trả về. Một số học sinh có thể sẽ hỏi: "Cách xử lý các cấu trúc dữ liệu được trả về từ các giao diện giao dịch nhôm khác nhau là gì? Đúng vậy, không chỉ cấu trúc dữ liệu của giao diện giao dịch trở lại khác nhau, thậm chí tên của các trường dữ liệu trở lại cũng khác nhau. Một ý nghĩa tương tự có thể là tên khác nhau. Ví dụ như giao diện chúng tôi liệt kê ở trên.bidPriceTrong token được gọi làbid

Chúng ta sử dụng các hàm gọi lại để giải quyết và tách các phần xử lý đặc biệt này ra. Sau khi khởi tạo đối tượng trên, nó sẽ được sử dụng như sau: (Chữ mã sau đã bỏ qua hàm xây dựng)createManager:) Các hợp đồng này được theo dõi bằng các hợp đồng tương lai:["BTCUSDT", "ETHUSDT", "EOSUSDT", "LTCUSDT", "ETCUSDT", "XRPUSDT"]Trong khi đó, các nhà đầu tư khác cũng có thể tham gia vào các hoạt động này.["btcusdt", "ethusdt", "eosusdt", "etcusdt", "ltcusdt", "xrpusdt"]Ví dụ:

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)
    }
}

Thử chạy: Đối tượng đầu tiên của sàn giao dịch thêm tiền tương lai và đối tượng thứ hai thêm tiền mặt của sàn giao dịchimg

img

Như bạn có thể thấy, ở đây, các hoạt động như lấy dữ liệu được trả lại bởi giao diện được xử lý đặc biệt cho các sàn giao dịch khác nhau bằng cách sử dụng các hàm trả lại.

    	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}})

Các giao dịch mua tài sản trên sàn giao dịch thường trả về toàn bộ dữ liệu tài sản.

Xây dựng hàmcreateManagerThêm phương pháp để có được tài sản

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

Cũng do định dạng giao diện giao dịch trả về, tên trường khác nhau, điều này cũng cần xử lý đặc biệt bằng cách sử dụng chức năng gọi lại.

Ví dụ như token cash, bitcoin futures, bạn có thể viết hàm gọi lại như sau:

    // 获取账户资产的回调函数
    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 
    }

Hoạt động một khuôn khổ chiến lược có chức năng tiếp cận thị trường, tài sản

Vụ việc:img

Tài sản:img

Bạn có thể xem dữ liệu thị trường được truy cập, sau đó có thể xử lý dữ liệu tính toán chênh lệch của các loại khác nhau, theo dõi chênh lệch giao dịch trên nhiều cặp giao dịch. Sau đó, bạn có thể thiết kế một chiến lược bảo hiểm tương lai đa dạng.

Theo cách thiết kế này, các sàn giao dịch khác có thể được mở rộng và các sinh viên quan tâm có thể thử.


Có liên quan

Thêm nữa

Tình yêu Jimmy.CallBackFuncGetAcc trong tài sản là một tham số hay một hàm? Ngoài ra có hai hàm gọi lại để truy cập tài khoản tài sản là callBackFuncGetHuobiAcc và callBackFuncGetFutures_BinanceAcc.

Tình yêu Jimmy.Làm thế nào để lấy giá Bid1 và Ask1 của một cặp giao dịch ngay lập tức?

zltimThật tuyệt vời.

Giấc mơ nhỏPhương thức gọi lại Baidu.

Giấc mơ nhỏCó thể nói là hai vòng tròn được nối lại và đi qua nhau.

Giấc mơ nhỏTôi đã nói với bạn về sự khác biệt giữa giá hiện tại và giá tương lai, không phải tất cả trong bài viết, giá tương lai. Có dữ liệu, cụ thể như thế nào, bạn giảm một chút hay không?

Tình yêu Jimmy.Nếu bạn muốn lấy sự khác biệt giữa giá mua và giá bán giao dịch tương lai BTCUSDT: trước tiên hãy đi qua trình quản lý thị trường tương lai 1.subscribeTickers, tìm ra trình quản lý bán và giá bán của BTCUSDT 1.subscribeTickers[i].ask1, câu hỏi là làm thế nào để lấy giá thầu của BTCUSDT tại thời điểm giao dịch tương lai được thực hiện, liệu bạn có thể theo dõi lại trình quản lý thị trường tương lai 1.subscribeTickers?

Tình yêu Jimmy.Tôi có nghĩa là chênh lệch giữa giá mua và giá bán của giao dịch tương lai, chứ không phải giá mua và giá bán của giao dịch tương lai hoặc giao dịch tương lai; vấn đề gặp phải là không thể có được giá mua và giá bán của giao dịch tương lai cùng một lúc. Ví dụ: Làm thế nào để có được chênh lệch giữa giá mua và giá bán giao dịch tương lai BTCUSDT. Tôi đã viết, câu hỏi mã dưới đây không biết xuất hiện ở đâu? function GetBAspot ((syboml, tickerspot, BA) { for (var i = 0; i < tickerspot.length; i++) { if ((tickerspot[i].syboml!==syboml) { tiếp tục }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 Tickers, function ((ticker)) { 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")]))) ) ♪ ♪

Giấc mơ nhỏTrong khi đó, một số nhà đầu tư khác cũng cho rằng, việc mua bán một cái là tốt hơn cả việc mua bán một cái, và giá cả khác nhau không phải là giảm một chút.

Tình yêu Jimmy.Tại sao mã nguồn của các hình ảnh thu được giá tương lai trong bài viết không được công bố?

Giấc mơ nhỏTôi không hiểu ý anh ấy là gì.

Tình yêu Jimmy.Tôi đã thấy, nhưng không có sự thống nhất trong việc chỉ định cùng một cặp giao dịch

Giấc mơ nhỏBạn có thể tìm thấy dữ liệu mua và bán trong mã.