चूंकि फ्यूचर्स हेजिंग रणनीतियों की हेजिंग आवृत्ति विशेष रूप से उच्च नहीं है, वास्तव में इसे मैन्युअल रूप से संचालित किया जा सकता है। लेकिन यदि आप इसे पूरी तरह से मैन्युअल रूप से संचालित करते हैं, तो विभिन्न एक्सचेंज पृष्ठों को स्विच करते हैं, कीमतों को देखते हैं, अंतर की गणना करते हैं, यह बहुत असुविधाजनक है, और कभी-कभी आप कुछ और किस्मों को देखना चाह सकते हैं, कुछ प्रदर्शनियों को बाजार की स्थिति दिखाने के लिए भी बहुत जरूरी नहीं है। क्या यह एक अर्ध-स्वचालित रणनीति के साथ मैन्युअल संचालन को पूरा करने की आवश्यकता है? यह सबसे अच्छा है कि यह किस्म है, ओह! हाँ, सबसे अच्छा एक बटन भी है, स्टॉप, स्टॉप। ओह! हाँ, और एक स्टॉप दिखाएं...
अगर जरूरत है, तो तुरंत कार्रवाई करें!
यह एक बहुत ही कठिन लेख है, कोड की 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 महीने से चल रही है, परीक्षण, परिचित चरण अभी भी एनालॉग डिस्क के साथ चल रहा है) ।)
हाथों से परीक्षण करने से पहले, पहले पैरामीटर डिजाइन के बारे में बात करें।
इस तरह की रणनीति के लिए बहुत कम पैरामीटर हैं, लेकिन महत्वपूर्ण पैरामीटर हैंः
हेफिंग कंट्रोल टेबल
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
इस तरह के एक नाम के बारे में बात करने के लिए, आप एक नाम के बारे में बात कर सकते हैं जो एक्सचेंज में परिभाषित है।
इंटरएक्टिव कंट्रोल के लिए हेजिंग स्थिति नियंत्रण बटन पर क्लिक करें, प्रतिभूति की मात्रा। इकाई सिक्का संख्या है, नीति स्वचालित रूप से अनुबंध संख्या में परिवर्तित हो जाती है।
बाकी सब कुछ, जैसे कि एनालॉग डिस्क सेट करना, डेटा रीसेट करना, OKEX V5 इंटरफ़ेस का उपयोग करना (क्योंकि यह V3 के साथ भी संगत है), बहुत महत्वपूर्ण नहीं है।
पहला एक्सचेंज ऑब्जेक्ट उस एक्सचेंज में जोड़ा जाता है जहां वायदा होता है, दूसरा एक्सचेंज ऑब्जेक्ट उस एक्सचेंज में जोड़ा जाता है जहां नकदी होता है।
फ्यूचर्स एक्सचेंज ओकेईएक्स के वी5 इंटरफेस एनालॉग का उपयोग करता है, जबकि ओवरहेड एक्सचेंज वेक्सएपी एनालॉग का उपयोग करता है।
एक बार जब आप BTC के सही सेट बटन पर क्लिक करते हैं, तो आप एक व्यापार खोलते हैं।
एक बार फिर से, हम एक अच्छा पोजीशन बनाते हैं।
यह लगता है कि जब लाभ का अंतर छोटा होता है, तो प्वॉइज़िंग प्रसंस्करण शुल्क को कवर नहीं कर सकती है, इसलिए आपको प्रसंस्करण शुल्क की गणना करने की आवश्यकता होती है, शायद स्लाइड पॉइंट, और फिर प्वॉइज़िंग के अंतर की उचित योजना बनाना, फिर प्वॉइज़िंग।
रणनीति का स्रोत कोडःhttps://www.fmz.com/strategy/314352
दिलचस्प है, उपयोग किया जा सकता है, जादू कर सकते हैं।
लुडविग570 पंक्तियों में त्रुटि, क्या कोई टेम्पलेट गायब है?
मैगा क्वांटिफाइंगaicoin के पास यह सुविधा है।
आविष्कारक मात्रा - छोटे सपनेयह टेम्पलेट सार्वजनिक नहीं है, लेकिन इस टेम्पलेट को सीधे संदर्भित करने के लिए इस पूरी नीति को कॉपी करना संभव है।