डिजिटल मुद्राओं के लिए हाथ से वायदा किए गए हेजिंग रणनीति

लेखक:छोटे सपने, बनाया गयाः 2021-09-08 14:47:33, अद्यतन किया गयाः 2023-09-20 10:28:44

img

डिजिटल मुद्राओं के लिए हाथ से वायदा किए गए हेजिंग रणनीति

चूंकि फ्यूचर्स हेजिंग रणनीतियों की हेजिंग आवृत्ति विशेष रूप से उच्च नहीं है, वास्तव में इसे मैन्युअल रूप से संचालित किया जा सकता है। लेकिन यदि आप इसे पूरी तरह से मैन्युअल रूप से संचालित करते हैं, तो विभिन्न एक्सचेंज पृष्ठों को स्विच करते हैं, कीमतों को देखते हैं, अंतर की गणना करते हैं, यह बहुत असुविधाजनक है, और कभी-कभी आप कुछ और किस्मों को देखना चाह सकते हैं, कुछ प्रदर्शनियों को बाजार की स्थिति दिखाने के लिए भी बहुत जरूरी नहीं है। क्या यह एक अर्ध-स्वचालित रणनीति के साथ मैन्युअल संचालन को पूरा करने की आवश्यकता है? यह सबसे अच्छा है कि यह किस्म है, ओह! हाँ, सबसे अच्छा एक बटन भी है, स्टॉप, स्टॉप। ओह! हाँ, और एक स्टॉप दिखाएं...

अगर जरूरत है, तो तुरंत कार्रवाई करें!

डिजिटल मुद्राओं के लिए मैन्युअल रूप से वायदा किए गए हेजिंग के लिए एक रणनीति डिजाइन करें

यह एक बहुत ही कठिन लेख है, कोड की 600 लाइनों से कम है।

function createManager(fuEx, spEx, symbolPairs, cmdHedgeAmount, fuMarginLevel, fuMarginReservedRatio) {
    var self = {}
    self.fuEx = fuEx
    self.spEx = spEx
    self.symbolPairs = symbolPairs
    self.pairs = []                        
    self.fuExTickers = null                
    self.spExTickers = null                
    self.tickerUpdateTS = 0                
    self.fuMarginLevel = fuMarginLevel     
    self.fuMarginReservedRatio = fuMarginReservedRatio 
    self.cmdHedgeAmount = cmdHedgeAmount   
    self.preUpdateAccTS = 0                
    self.accAndPosUpdateCount = 0          
    self.profit = []                       
    self.allPairs = []                     

    self.PLUS = 0          
    self.MINUS = 1         
    self.COVER_PLUS = 2    
    self.COVER_MINUS = 3   
    self.arrTradeTypeDesc = ["正套", "反套", "平正套", "平反套"]

    self.updateTickers = function() {
        self.fuEx.goGetTickers()
        self.spEx.goGetTickers()
        var fuExTickers = self.fuEx.getTickers()
        var spExTickers = self.spEx.getTickers()

        if (!fuExTickers || !spExTickers) {
            return null
        }
        self.fuExTickers = fuExTickers
        self.spExTickers = spExTickers
        self.tickerUpdateTS = new Date().getTime()
        return true 
    }

    self.hedge = function(index, fuSymbol, spSymbol, tradeType, amount) {
        var fe = self.fuEx
        var se = self.spEx
        var pair = self.pairs[index]
        var timeStamp = new Date().getTime()

        var fuDirection = null 
        var spDirection = null     
        var fuPrice = null 
        var spPrice = null 

        if (tradeType == self.PLUS) {
            fuDirection = fe.OPEN_SHORT
            spDirection = se.OPEN_LONG
            fuPrice = pair.fuTicker.bid1
            spPrice = pair.spTicker.ask1
        } else if (tradeType == self.MINUS) {
            fuDirection = fe.OPEN_LONG
            spDirection = se.OPEN_SHORT
            fuPrice = pair.fuTicker.ask1
            spPrice = pair.spTicker.bid1
        } else if (tradeType == self.COVER_PLUS) {
            fuDirection = fe.COVER_SHORT
            spDirection = se.COVER_LONG
            fuPrice = pair.fuTicker.ask1
            spPrice = pair.spTicker.bid1            
        } else if (tradeType == self.COVER_MINUS) {
            fuDirection = fe.COVER_LONG
            spDirection = se.COVER_SHORT
            fuPrice = pair.fuTicker.bid1
            spPrice = pair.spTicker.ask1
        } else {
            throw "unknow tradeType!"
        }

        fe.goGetAcc(fuSymbol, timeStamp)              
        se.goGetAcc(spSymbol, timeStamp)
        var nowFuAcc = fe.getAcc(fuSymbol, timeStamp)
        var nowSpAcc = se.getAcc(spSymbol, timeStamp)
        if (!nowFuAcc || !nowSpAcc) {
            Log(fuSymbol, spSymbol, ",获取账户数据失败")
            return 
        }
        pair.nowFuAcc = nowFuAcc           
        pair.nowSpAcc = nowSpAcc

        var nowFuPos = fe.getFuPos(fuSymbol, timeStamp)
        var nowSpPos = se.getSpPos(spSymbol, spPrice, pair.initSpAcc, pair.nowSpAcc)
        if (!nowFuPos || !nowSpPos) {
            Log(fuSymbol, spSymbol, ",获取持仓数据失败")
            return 
        }
        pair.nowFuPos = nowFuPos
        pair.nowSpPos = nowSpPos

        var fuAmount = amount 
        var spAmount = amount
        if (tradeType == self.PLUS || tradeType == self.MINUS) {
            if (nowFuAcc.Balance < (pair.initFuAcc.Balance + pair.initFuAcc.FrozenBalance) * self.fuMarginReservedRatio + (fuAmount * fuPrice / self.fuMarginLevel)) {
                Log(pair.fuSymbol, "保证金不足!", "本次计划使用", (fuAmount * fuPrice / self.fuMarginLevel), "当前可用:", nowFuAcc.Balance, 
                    "计划预留:", (pair.initFuAcc.Balance + pair.initFuAcc.FrozenBalance) * self.fuMarginReservedRatio)
                return 
            }
            if ((tradeType == self.PLUS && nowSpAcc.Balance < spAmount * spPrice)) {  
                Log(pair.spSymbol, "资金不足!", "本次买入计划使用", spAmount * spPrice, "当前可用:", nowSpAcc.Balance)
                return 
            } else if (tradeType == self.MINUS && nowSpAcc.Stocks < spAmount) {       
                Log(pair.spSymbol, "资金不足!", "本次卖出计划使用", spAmount, "当前可用:", nowSpAcc.Stocks)
                return 
            }
        } else {
            var fuLongPos = self.getLongPos(nowFuPos)
            var fuShortPos = self.getShortPos(nowFuPos)
            var spLongPos = self.getLongPos(nowSpPos)
            var spShortPos = self.getShortPos(nowSpPos)
            if ((tradeType == self.COVER_PLUS && !fuShortPos) || (tradeType == self.COVER_MINUS && !fuLongPos)) {  
                Log(fuSymbol, spSymbol, ",期货没有对应持仓!")
                return 
            } else if (tradeType == self.COVER_PLUS && Math.abs(fuShortPos.amount) < fuAmount) {
                fuAmount = Math.abs(fuShortPos.amount)
            } else if (tradeType == self.COVER_MINUS && Math.abs(fuLongPos.amount) < fuAmount) {
                fuAmount = Math.abs(fuLongPos.amount)
            }
            if ((tradeType == self.COVER_PLUS && !spLongPos) || (tradeType == self.COVER_MINUS && !spShortPos)) {  
                Log(fuSymbol, spSymbol, ",现货没有对应持仓!")
                return 
            } else if (tradeType == self.COVER_PLUS && Math.min(Math.abs(spLongPos.amount), nowSpAcc.Stocks) < spAmount) {               
                spAmount = Math.min(Math.abs(spLongPos.amount), nowSpAcc.Stocks)
            } else if (tradeType == self.COVER_MINUS && Math.min(Math.abs(spShortPos.amount), nowSpAcc.Balance / spPrice) < spAmount) {  
                spAmount = Math.min(Math.abs(spShortPos.amount), nowSpAcc.Balance / spPrice)
            }
        }

        fuAmount = fe.calcAmount(fuSymbol, fuDirection, fuPrice, fuAmount)  
        spAmount = se.calcAmount(spSymbol, spDirection, spPrice, spAmount)
        if (!fuAmount || !spAmount) {
            Log(fuSymbol, spSymbol, "下单量计算错误:", fuAmount, spAmount)
            return 
        } else {
            fuAmount = fe.calcAmount(fuSymbol, fuDirection, fuPrice, fuAmount[1])
            spAmount = se.calcAmount(spSymbol, spDirection, spPrice, Math.min(fuAmount[1], spAmount[1]))
            if (!fuAmount || !spAmount) {
                Log(fuSymbol, spSymbol, "下单量计算错误:", fuAmount, spAmount)
                return 
            }
        }
        Log("合约代码:", fuSymbol + "/" + spSymbol, "方向:", self.arrTradeTypeDesc[tradeType], "差价:", fuPrice - spPrice, "期货数量:", fuAmount, "现货数量:", spAmount, "@")  

        fe.goGetTrade(fuSymbol, fuDirection, fuPrice, fuAmount[0])
        se.goGetTrade(spSymbol, spDirection, spPrice, spAmount[0])

        var feIdMsg = fe.getTrade()
        var seIdMsg = se.getTrade()
        return [feIdMsg, seIdMsg]
    }

    self.process = function() {
        var nowTS = new Date().getTime()
        if(!self.updateTickers()) {
            return 
        }

        _.each(self.pairs, function(pair, index) {
            var fuTicker = null 
            var spTicker = null
            _.each(self.fuExTickers, function(ticker) {
                if (ticker.originalSymbol == pair.fuSymbol) {
                    fuTicker = ticker
                }
            })
            _.each(self.spExTickers, function(ticker) {
                if (ticker.originalSymbol == pair.spSymbol) {
                    spTicker = ticker
                }
            })
            if (fuTicker && spTicker) {
                pair.canTrade = true 
            } else {
                pair.canTrade = false
            }
            fuTicker = fuTicker ? fuTicker : {}
            spTicker = spTicker ? spTicker : {}
            pair.fuTicker = fuTicker
            pair.spTicker = spTicker
            pair.plusDiff = fuTicker.bid1 - spTicker.ask1
            pair.minusDiff = fuTicker.ask1 - spTicker.bid1
            if (pair.plusDiff && pair.minusDiff) {
                pair.plusDiff = _N(pair.plusDiff, Math.max(self.fuEx.judgePrecision(fuTicker.bid1), self.spEx.judgePrecision(spTicker.ask1)))
                pair.minusDiff = _N(pair.minusDiff, Math.max(self.fuEx.judgePrecision(fuTicker.ask1), self.spEx.judgePrecision(spTicker.bid1)))
            }
            
            if (nowTS - self.preUpdateAccTS > 1000 * 60 * 5) {    
                self.fuEx.goGetAcc(pair.fuSymbol, nowTS)
                self.spEx.goGetAcc(pair.spSymbol, nowTS)
                var fuAcc = self.fuEx.getAcc(pair.fuSymbol, nowTS)   
                var spAcc = self.spEx.getAcc(pair.spSymbol, nowTS)
                if (fuAcc) {
                    pair.nowFuAcc = fuAcc
                }
                if (spAcc) {
                    pair.nowSpAcc = spAcc
                }
                var nowFuPos = self.fuEx.getFuPos(pair.fuSymbol, nowTS)
                var nowSpPos = self.spEx.getSpPos(pair.spSymbol, (pair.spTicker.ask1 + pair.spTicker.bid1) / 2, pair.initSpAcc, pair.nowSpAcc)

                if (nowFuPos && nowSpPos) {
                    pair.nowFuPos = nowFuPos
                    pair.nowSpPos = nowSpPos                    
                    self.keepBalance(pair)
                } else {
                    Log(pair.fuSymbol, pair.spSymbol, "组合仓位更新失败,nowFuPos:", nowFuPos, " nowSpPos:", nowSpPos)
                }
                self.accAndPosUpdateCount++    
            }
        })

        if (nowTS - self.preUpdateAccTS > 1000 * 60 * 5) {       
            self.preUpdateAccTS = nowTS
            self.profit = self.calcProfit()
            LogProfit(self.profit[0], "期货:", self.profit[1], "现货:", self.profit[2], "&")    // 打印总收益曲线,使用&字符不打印收益日志
        }

        var cmd = GetCommand()
        if(cmd) {
            Log("交互命令:", cmd)
            var arr = cmd.split(":") 
            if(arr[0] == "plus") {
                var pair = self.pairs[parseFloat(arr[1])]
                self.hedge(parseFloat(arr[1]), pair.fuSymbol, pair.spSymbol, self.PLUS, self.cmdHedgeAmount)
            } else if (arr[0] == "cover_plus") {
                var pair = self.pairs[parseFloat(arr[1])]
                self.hedge(parseFloat(arr[1]), pair.fuSymbol, pair.spSymbol, self.COVER_PLUS, self.cmdHedgeAmount)
            }
        }

        LogStatus("当前时间:", _D(), "  数据更新时间:", _D(self.tickerUpdateTS), "持仓账户更新计数:", self.accAndPosUpdateCount, "\n", "盈亏:", self.profit[0], "    期货盈亏:", self.profit[1],
            "    现货盈亏:", self.profit[2], "\n`" + JSON.stringify(self.returnTbl()) + "`", "\n`" + JSON.stringify(self.returnPosTbl()) + "`")
    }

    self.keepBalance = function (pair) {
        var nowFuPos = pair.nowFuPos
        var nowSpPos = pair.nowSpPos
        var fuLongPos = self.getLongPos(nowFuPos)
        var fuShortPos = self.getShortPos(nowFuPos)
        var spLongPos = self.getLongPos(nowSpPos)
        var spShortPos = self.getShortPos(nowSpPos)

        if (fuLongPos || spShortPos) {    
            Log("不支持反套") 
        }
        if (fuShortPos || spLongPos) {    
            var fuHoldAmount = fuShortPos ? fuShortPos.amount : 0
            var spHoldAmount = spLongPos ? spLongPos.amount : 0
            var sum = fuHoldAmount + spHoldAmount
            if (sum > 0) {            
                var spAmount = self.spEx.calcAmount(pair.spSymbol, self.spEx.COVER_LONG, pair.spTicker.bid1, Math.abs(sum), true)
                if (spAmount) {
                    Log(pair.fuSymbol, pair.spSymbol, "现货头寸多出", Math.abs(sum), "fuShortPos:", fuShortPos, "spLongPos:", spLongPos)
                    self.spEx.goGetTrade(pair.spSymbol, self.spEx.COVER_LONG, pair.spTicker.bid1, spAmount[0])
                    var seIdMsg = self.spEx.getTrade()                    
                }
            } else if (sum < 0) {     
                var fuAmount = self.fuEx.calcAmount(pair.fuSymbol, self.fuEx.COVER_SHORT, pair.fuTicker.ask1, Math.abs(sum), true)
                if (fuAmount) {
                    Log(pair.fuSymbol, pair.spSymbol, "期货头寸多出", Math.abs(sum), "fuShortPos:", fuShortPos, "spLongPos:", spLongPos)
                    self.fuEx.goGetTrade(pair.fuSymbol, self.fuEx.COVER_SHORT, pair.fuTicker.ask1, fuAmount[0])
                    var feIdMsg = self.fuEx.getTrade()
                }
            }
        }
    }

    self.getLongPos = function (positions) {
        return self.getPosByDirection(positions, PD_LONG)
    }

    self.getShortPos = function (positions) {
        return self.getPosByDirection(positions, PD_SHORT)
    }

    self.getPosByDirection = function (positions, direction) {
        var ret = null
        if (positions.length > 2) {
            Log("持仓错误,检测到三个持仓:", JSON.stringify(positions))
            return ret 
        }
        _.each(positions, function(pos) {
            if ((direction == PD_LONG && pos.amount > 0) || (direction == PD_SHORT && pos.amount < 0)) {
                ret = pos
            }
        })
        return ret 
    }

    self.calcProfit = function() {   
        var arrInitFuAcc = []
        var arrNowFuAcc = []
        _.each(self.pairs, function(pair) {
            arrInitFuAcc.push(pair.initFuAcc)
            arrNowFuAcc.push(pair.nowFuAcc)
        })
        var fuProfit = self.fuEx.calcProfit(arrInitFuAcc, arrNowFuAcc)
        var spProfit = 0
        var deltaBalance = 0
        _.each(self.pairs, function(pair) {
            var nowSpAcc = pair.nowSpAcc
            var initSpAcc = pair.initSpAcc
            var stocksDiff = nowSpAcc.Stocks + nowSpAcc.FrozenStocks - (initSpAcc.Stocks + initSpAcc.FrozenStocks)
            var price = stocksDiff > 0 ? pair.spTicker.bid1 : pair.spTicker.ask1
            spProfit += stocksDiff * price
            deltaBalance = nowSpAcc.Balance + nowSpAcc.FrozenBalance - (initSpAcc.Balance + initSpAcc.FrozenBalance)
        })
        spProfit += deltaBalance
        return [fuProfit + spProfit, fuProfit, spProfit]    
    }

    self.returnPosTbl = function() {
        var posTbl = {
            type : "table", 
            title : "positions", 
            cols : ["索引", "期货", "期货杠杆", "数量", "现货", "数量"], 
            rows : []
        }
        _.each(self.pairs, function(pair, index) {
            var nowFuPos = pair.nowFuPos
            var nowSpPos = pair.nowSpPos
            for (var i = 0 ; i < nowFuPos.length ; i++) {
                if (nowSpPos.length > 0) {
                    posTbl.rows.push([index, nowFuPos[i].symbol, nowFuPos[i].marginLevel, nowFuPos[i].amount, nowSpPos[0].symbol, nowSpPos[0].amount])
                } else {
                    posTbl.rows.push([index, nowFuPos[i].symbol, nowFuPos[i].marginLevel, nowFuPos[i].amount, "--", "--"])
                }               
            }
        })

        return posTbl
    }

    self.returnTbl = function() {
        var fuExName = "[" + self.fuEx.getExName() + "]"
        var spExName = "[" + self.spEx.getExName() + "]"
        var combiTickersTbl = {
            type : "table", 
            title : "combiTickersTbl", 
            cols : ["期货", "代码" + fuExName, "卖一", "买一", "现货", "代码" + spExName, "卖一", "买一", "正对冲差价", "反对冲差价", "正对冲", "正对冲平仓"], 
            rows : []
        }
        _.each(self.pairs, function(pair, index) {
            var spSymbolInfo = self.spEx.getSymbolInfo(pair.spTicker.originalSymbol)  
            combiTickersTbl.rows.push([
                pair.fuTicker.symbol, 
                pair.fuTicker.originalSymbol, 
                pair.fuTicker.ask1, 
                pair.fuTicker.bid1, 
                pair.spTicker.symbol, 
                pair.spTicker.originalSymbol, 
                pair.spTicker.ask1, 
                pair.spTicker.bid1,
                pair.plusDiff,
                pair.minusDiff,
                {'type':'button', 'cmd': 'plus:' + String(index), 'name': '正套'},
                {'type':'button', 'cmd': 'cover_plus:' + String(index), 'name': '平正套'}
            ])
        })

        var accsTbl = {
            type : "table", 
            title : "accs",
            cols : ["代码" + fuExName, "初币", "初冻币", "初钱", "初冻钱", "币", "冻币", "钱", "冻钱",
                "代码" + spExName, "初币", "初冻币", "初钱", "初冻钱", "币", "冻币", "钱", "冻钱"], 
            rows : []
        }
        _.each(self.pairs, function(pair) {
            var arr = [pair.fuTicker.originalSymbol, pair.initFuAcc.Stocks, pair.initFuAcc.FrozenStocks, pair.initFuAcc.Balance, pair.initFuAcc.FrozenBalance, pair.nowFuAcc.Stocks, pair.nowFuAcc.FrozenStocks, pair.nowFuAcc.Balance, pair.nowFuAcc.FrozenBalance,
                pair.spTicker.originalSymbol, pair.initSpAcc.Stocks, pair.initSpAcc.FrozenStocks, pair.initSpAcc.Balance, pair.initSpAcc.FrozenBalance, pair.nowSpAcc.Stocks, pair.nowSpAcc.FrozenStocks, pair.nowSpAcc.Balance, pair.nowSpAcc.FrozenBalance]
            for (var i = 0 ; i < arr.length ; i++) {
                if (typeof(arr[i]) == "number") {
                    arr[i] = _N(arr[i], 6)  
                }
            }
            accsTbl.rows.push(arr)
        })

        var symbolInfoTbl = {
            type : "table", 
            title : "symbolInfos", 
            cols : ["合约代码" + fuExName, "量精度", "价格精度", "乘数", "最小下单量", "现货代码" + spExName, "量精度", "价格精度", "乘数", "最小下单量"], 
            rows : []
        }
        _.each(self.pairs, function(pair) {
            var fuSymbolInfo = self.fuEx.getSymbolInfo(pair.fuTicker.originalSymbol)
            var spSymbolInfo = self.spEx.getSymbolInfo(pair.spTicker.originalSymbol)
            symbolInfoTbl.rows.push([fuSymbolInfo.symbol, fuSymbolInfo.amountPrecision, fuSymbolInfo.pricePrecision, fuSymbolInfo.multiplier, fuSymbolInfo.min, 
                spSymbolInfo.symbol, spSymbolInfo.amountPrecision, spSymbolInfo.pricePrecision, spSymbolInfo.multiplier, spSymbolInfo.min])
        })
        
        var allPairs = []
        _.each(self.fuExTickers, function(fuTicker) {
            _.each(self.spExTickers, function(spTicker) {
                if (fuTicker.symbol == spTicker.symbol) {
                    allPairs.push({symbol: fuTicker.symbol, fuSymbol: fuTicker.originalSymbol, spSymbol: spTicker.originalSymbol, plus: fuTicker.bid1 - spTicker.ask1})
                }
            })
        })
        _.each(allPairs, function(pair) {
            var findPair = null 
            _.each(self.allPairs, function(selfPair) {
                if (pair.fuSymbol == selfPair.fuSymbol && pair.spSymbol == selfPair.spSymbol) {
                    findPair = selfPair
                }
            })
            if (findPair) {  
                findPair.minPlus = pair.plus < findPair.minPlus ? pair.plus : findPair.minPlus
                findPair.maxPlus = pair.plus > findPair.maxPlus ? pair.plus : findPair.maxPlus
                pair.minPlus = findPair.minPlus
                pair.maxPlus = findPair.maxPlus
            } else {        
                self.allPairs.push({symbol: pair.symbol, fuSymbol: pair.fuSymbol, spSymbol: pair.spSymbol, plus: pair.plus, minPlus: pair.plus, maxPlus: pair.plus})
                pair.minPlus = pair.plus
                pair.maxPlus = pair.plus
            }
        })
        return [combiTickersTbl, accsTbl, symbolInfoTbl]
    }

    self.onexit = function() {        
        _G("pairs", self.pairs)
        _G("allPairs", self.allPairs)
        Log("执行扫尾处理,数据保存", "#FF0000")
    }

    self.init = function() {
        var fuExName = self.fuEx.getExName()
        var spExName = self.spEx.getExName()
        var gFuExName = _G("fuExName")
        var gSpExName = _G("spExName")
        if ((gFuExName && gFuExName != fuExName) || (gSpExName && gSpExName != spExName)) {
            throw "交易所对象发生变化,需要重置数据"
        }
        if (!gFuExName) {
            _G("fuExName", fuExName)
        }
        if (!gSpExName) {
            _G("spExName", spExName)
        }

        self.allPairs = _G("allPairs")
        if (!self.allPairs) {
            self.allPairs = []
        }

        var arrPair = _G("pairs")
        if (!arrPair) {
            arrPair = []
        }
        var arrStrPair = self.symbolPairs.split(",")
        var timeStamp = new Date().getTime()
        _.each(arrStrPair, function(strPair) {
            var arrSymbol = strPair.split("|")
            var recoveryPair = null 
            _.each(arrPair, function(pair) {
                if (pair.fuSymbol == arrSymbol[0] && pair.spSymbol == arrSymbol[1]) {
                    recoveryPair = pair
                }
            })

            if (!recoveryPair) {
                var pair = {
                    fuSymbol : arrSymbol[0],
                    spSymbol : arrSymbol[1],
                    fuTicker : {}, 
                    spTicker : {},
                    plusDiff : null,
                    minusDiff : null,
                    canTrade : false,        
                    initFuAcc : null,        
                    initSpAcc : null,        
                    nowFuAcc : null,         
                    nowSpAcc : null,         
                    nowFuPos : null,         
                    nowSpPos : null,         
                    fuMarginLevel : null     
                }
                self.pairs.push(pair)
                Log("初始化:", pair)
            } else {
                self.pairs.push(recoveryPair)
                Log("恢复:", recoveryPair)
            }
            self.fuEx.pushSubscribeSymbol(arrSymbol[0])
            self.spEx.pushSubscribeSymbol(arrSymbol[1])
            if (!self.pairs[self.pairs.length - 1].initFuAcc) {
                self.fuEx.goGetAcc(arrSymbol[0], timeStamp)
                var nowFuAcc = self.fuEx.getAcc(arrSymbol[0], timeStamp)
                self.pairs[self.pairs.length - 1].initFuAcc = nowFuAcc
                self.pairs[self.pairs.length - 1].nowFuAcc = nowFuAcc
            }
            if (!self.pairs[self.pairs.length - 1].initSpAcc) {
                self.spEx.goGetAcc(arrSymbol[1], timeStamp)
                var nowSpAcc = self.spEx.getAcc(arrSymbol[1], timeStamp)
                self.pairs[self.pairs.length - 1].initSpAcc = nowSpAcc
                self.pairs[self.pairs.length - 1].nowSpAcc = nowSpAcc
            }
            Sleep(300)
        })
        Log("self.pairs:", self.pairs)
        _.each(self.pairs, function(pair) {
            var fuSymbolInfo = self.fuEx.getSymbolInfo(pair.fuSymbol)
            if (!fuSymbolInfo) {
                throw pair.fuSymbol + ",品种信息获取失败!"
            } else {
                Log(pair.fuSymbol, fuSymbolInfo)
            }
            var spSymbolInfo = self.spEx.getSymbolInfo(pair.spSymbol)
            if (!spSymbolInfo) {
                throw pair.spSymbol + ",品种信息获取失败!"
            } else {
                Log(pair.spSymbol, spSymbolInfo)
            }
        })

        _.each(self.pairs, function(pair) {
            pair.fuMarginLevel = self.fuMarginLevel
            var ret = self.fuEx.setMarginLevel(pair.fuSymbol, self.fuMarginLevel)
            Log(pair.fuSymbol, "杠杆设置:", ret)
            if (!ret) {
                throw "初始设置杠杆失败!"
            }
        })
    }

    self.init()
    return self
}

var manager = null 
function main() {
    if(isReset) {        
        _G(null)
        LogReset(1)
        LogProfitReset()
        LogVacuum()
        Log("重置所有数据", "#FF0000")
    }

    if (isOKEX_V5_Simulate) {
        for (var i = 0 ; i < exchanges.length ; i++) {
            if (exchanges[i].GetName() == "Futures_OKCoin" || exchanges[i].GetName() == "OKEX") {
                var ret = exchanges[i].IO("simulate", true)
                Log(exchanges[i].GetName(), "切换模拟盘")
            }
        }
    }

    var fuConfigureFunc = null 
    var spConfigureFunc = null 
    if (exchanges.length != 2) {
        throw "需要添加两个交易所对象!"
    } else {
        var fuName = exchanges[0].GetName()
        if (fuName == "Futures_OKCoin" && isOkexV5) {
            fuName += "_V5"
            Log("使用OKEX V5接口")
        }
        var spName = exchanges[1].GetName()
        fuConfigureFunc = $.getConfigureFunc()[fuName]
        spConfigureFunc = $.getConfigureFunc()[spName]
        if (!fuConfigureFunc || !spConfigureFunc) {
            throw (fuConfigureFunc ? "" : fuName) + " " +  (spConfigureFunc ? "" : spName) + " not support!"
        }
    }
    var fuEx = $.createBaseEx(exchanges[0], fuConfigureFunc)
    var spEx = $.createBaseEx(exchanges[1], spConfigureFunc)
    manager = createManager(fuEx, spEx, symbolPairs, cmdHedgeAmount, fuMarginLevel, fuMarginReservedRatio)

    while(true) {
        manager.process()
        Sleep(interval)
    }
}

function onerror() {
    if (manager) {
        manager.onexit()
    }    
}

function onexit() {
    if (manager) {
        manager.onexit()
    }
}

क्योंकि बहु-प्रजाति रणनीति आईओ के साथ डिजाइन करने के लिए अधिक उपयुक्त है, इसलिए कोड में इसका उपयोग किया जाता है।MultiSymbolCtrlLibएक टेम्पलेट श्रेणी संग्रह ((पैक, आईओ के माध्यम से एक्सचेंज इंटरफेस को कॉल करें) । इसलिए रणनीति वापस नहीं की जा सकती है, लेकिन एनालॉग डिस्क के साथ परीक्षण किया जा सकता है ((हालांकि वास्तविक डिस्क भी 2 महीने से चल रही है, परीक्षण, परिचित चरण अभी भी एनालॉग डिस्क के साथ चल रहा है) ।)

पैरामीटर

हाथों से परीक्षण करने से पहले, पहले पैरामीटर डिजाइन के बारे में बात करें।

img

इस तरह की रणनीति के लिए बहुत कम पैरामीटर हैं, लेकिन महत्वपूर्ण पैरामीटर हैंः

  • हेफिंग कंट्रोल टेबल

    LTC-USDT-211231|LTC_USDT,BTC-USDT-211231|BTC_USDT
    

    यहाँ पर सेटअप की रणनीति है जो उन सभी संयोजनों की निगरानी करती है, उदाहरण के लिए ऊपर दी गई सेटिंग्स फ्यूचर्स एक्सचेंजों के लिए लाइटकॉइन कॉन्ट्रैक्ट्स ((LTC-USDT-211231) और ओवरहेड एक्सचेंजों के लिए लाइटकॉइन ((LTC_USDT) की निगरानी करती हैं। एक संयोजन फ्यूचर्स कॉन्ट्रैक्ट्स और ओवरहेड ट्रेडिंग का उपयोग करता है।|प्रतीक को अलग करके एक संयोजन बनाना; विभिन्न संयोजनों का उपयोग करना,चिह्नों को अलग करें. ध्यान दें कि यहां चिह्न अंग्रेजी टाइपिंग स्टेटस टैग हैं! आप मुझसे पूछ सकते हैं कि कॉन्ट्रैक्ट कोड कैसे ढूंढें, ये कॉन्ट्रैक्ट कोड, जिनका उपयोग एक्सचेंज द्वारा किया जाता है, एफएमजेड प्लेटफॉर्म पर नहीं। उदाहरण के लिएLTC-USDT-211231यह अनुबंध वर्तमान में दूसरी तिमाही के लिए है, एफएमजेड पर कहा जाता है।next_quarterओकेएक्स का इंटरफेस सिस्टम है।LTC-USDT-211231◎ WexApp एनालॉग डिस्क के लिएLitecoin/USDTलेन-देन लिखना है।LTC_USDTइस तरह के एक नाम के बारे में बात करने के लिए, आप एक नाम के बारे में बात कर सकते हैं जो एक्सचेंज में परिभाषित है।

  • इंटरएक्टिव कंट्रोल के लिए हेजिंग स्थिति नियंत्रण बटन पर क्लिक करें, प्रतिभूति की मात्रा। इकाई सिक्का संख्या है, नीति स्वचालित रूप से अनुबंध संख्या में परिवर्तित हो जाती है।

    img

बाकी सब कुछ, जैसे कि एनालॉग डिस्क सेट करना, डेटा रीसेट करना, OKEX V5 इंटरफ़ेस का उपयोग करना (क्योंकि यह V3 के साथ भी संगत है), बहुत महत्वपूर्ण नहीं है।

परीक्षण

पहला एक्सचेंज ऑब्जेक्ट उस एक्सचेंज में जोड़ा जाता है जहां वायदा होता है, दूसरा एक्सचेंज ऑब्जेक्ट उस एक्सचेंज में जोड़ा जाता है जहां नकदी होता है।

फ्यूचर्स एक्सचेंज ओकेईएक्स के वी5 इंटरफेस एनालॉग का उपयोग करता है, जबकि ओवरहेड एक्सचेंज वेक्सएपी एनालॉग का उपयोग करता है।

एक बार जब आप BTC के सही सेट बटन पर क्लिक करते हैं, तो आप एक व्यापार खोलते हैं।

img

img

img

एक बार फिर से, हम एक अच्छा पोजीशन बनाते हैं।

img

img

यह लगता है कि जब लाभ का अंतर छोटा होता है, तो प्वॉइज़िंग प्रसंस्करण शुल्क को कवर नहीं कर सकती है, इसलिए आपको प्रसंस्करण शुल्क की गणना करने की आवश्यकता होती है, शायद स्लाइड पॉइंट, और फिर प्वॉइज़िंग के अंतर की उचित योजना बनाना, फिर प्वॉइज़िंग।

रणनीति का स्रोत कोडःhttps://www.fmz.com/strategy/314352

दिलचस्प है, उपयोग किया जा सकता है, जादू कर सकते हैं।


संबंधित

अधिक

लुडविग570 पंक्तियों में त्रुटि, क्या कोई टेम्पलेट गायब है?

मैगा क्वांटिफाइंगaicoin के पास यह सुविधा है।

छोटे सपनेयह टेम्पलेट सार्वजनिक नहीं है, लेकिन इस टेम्पलेट को सीधे संदर्भित करने के लिए इस पूरी नीति को कॉपी करना संभव है।