پچھلے مضمون میں ، ہم نے مل کر ایک کثیر قسم کے معاہدے کی قیمتوں کی نگرانی کی حکمت عملی تیار کی ، اور اس مضمون میں ہم اس خیال کو بہتر بناتے ہیں۔ آئیے دیکھتے ہیں کہ آیا یہ خیال قابل عمل ہے ، اور OKEX V5 کے ایک الیکٹرانک رن کے ساتھ اس حکمت عملی کے ڈیزائن کی توثیق کریں۔ یہ عمل بھی ڈیجیٹل کرنسیوں کے عمل کی تجارت ، مقداری تجارت کے عمل میں تجربہ کرنے کی ضرورت ہے ، امید ہے کہ نئے آنے والوں کو قیمتی تجربہ حاصل ہوگا۔
اس سے پہلے کہ آپ اسکرپٹ میں داخل ہوں ، حکمت عملی چل رہی ہے ، تھوڑا سا جوش و خروش!
حکمت عملی کا مجموعی ڈیزائن سب سے آسان طریقے سے کیا گیا ہے ، اگرچہ اس کی تفصیلات کو سنبھالنے کے لئے بہت زیادہ نہیں ہے ، لیکن پھر بھی کوڈ سے کچھ چھوٹی چھوٹی چالیں سیکھنے کے قابل ہیں۔ حکمت عملی کا کوڈ پوری طرح سے 400 لائنوں سے بھی کم ہے ، اسے پڑھنا اور سمجھنا بہت بور نہیں ہوگا۔ یقینا یہ صرف ایک ٹیسٹ ڈیمو ہے ، اس کے لئے کچھ وقت کی جانچ پڑتال کی ضرورت ہے۔ لہذا میں یہ کہوں گا: موجودہ حکمت عملی صرف کامیاب پوزیشن کھولنے کے لئے ہے ، اور فلیش پوزیشن وغیرہ کی طرح مختلف حالات کو عملی طور پر ٹیسٹ ٹیسٹ کرنے کے لئے ، پروگرامنگ ڈیزائن میں BUG ناگزیر ہے ، لہذا ٹیسٹ ، DEBUG (غلطی کی قطار) بہت اہم ہے!
اس کے علاوہ ، ہم نے اس کوڈ کو بھی شامل کیا ہے جو پچھلے مضمون کی بنیاد پر ہے:
اس کے علاوہ ، یہ ایک اضافی خصوصیت ہے۔ ڈیزائن کو آسان بنانے کے ل the ، حکمت عملی صرف مثبت ہیجنگ کے لئے ڈیزائن کی گئی ہے۔ موجودہ مستقل معاہدے (قریبی مدت) منفی شرح پر ہیں ، ٹھیک ہے ، زیادہ مستقل معاہدے کریں ، دیکھیں کہ کیا آپ پوائنٹ کی شرح میں اضافہ کرکے منافع حاصل کرسکتے ہیں۔
ایک لمحے کے لئے اسٹریٹجی چلنے دو
ہم نے تقریباً تین دن تک ٹیسٹ کیا اور قیمتوں میں اتار چڑھاؤ ٹھیک ہے۔
اس کے علاوہ ، آپ کو کچھ فنڈز کی شرح میں منافع مل سکتا ہے۔
اس کی حکمت عملی کا ماخذ کوڈ ذیل میں شیئر کریں:
var arrNearContractType = strNearContractType.split(",")
var arrFarContractType = strFarContractType.split(",")
var nets = null
var initTotalEquity = null
var OPEN_PLUS = 1
var COVER_PLUS = 2
function createNet(begin, diff, initAvgPrice, diffUsagePercentage) {
if (diffUsagePercentage) {
diff = diff * initAvgPrice
}
var oneSideNums = 3
var up = []
var down = []
for (var i = 0 ; i < oneSideNums ; i++) {
var upObj = {
sell : false,
price : begin + diff / 2 + i * diff
}
up.push(upObj)
var j = (oneSideNums - 1) - i
var downObj = {
sell : false,
price : begin - diff / 2 - j * diff
}
if (downObj.price <= 0) { // 价格不能小于等于0
continue
}
down.push(downObj)
}
return down.concat(up)
}
function createCfg(symbol) {
var cfg = {
extension: {
layout: 'single',
height: 300,
col: 6
},
title: {
text: symbol
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'plus',
data: []
}]
}
return cfg
}
function formatSymbol(originalSymbol) {
var arr = originalSymbol.split("-")
return [arr[0] + "_" + arr[1], arr[0], arr[1]]
}
function main() {
if (isSimulate) {
exchange.IO("simulate", true) // 切换为模拟环境
Log("仅支持OKEX V5 API,切换为OKEX V5 模拟盘:")
} else {
exchange.IO("simulate", false) // 切换为实盘
Log("仅支持OKEX V5 API,切换为OKEX V5 实盘:")
}
if (exchange.GetName() != "Futures_OKCoin") {
throw "支持OKEX期货"
}
// 初始化
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("重置所有数据", "#FF0000")
}
// 初始化标记
var isFirst = true
// 收益打印周期
var preProfitPrintTS = 0
// 总权益
var totalEquity = 0
var posTbls = [] // 持仓表格数组
// 声明arrCfg
var arrCfg = []
_.each(arrNearContractType, function(ct) {
arrCfg.push(createCfg(formatSymbol(ct)[0]))
})
var objCharts = Chart(arrCfg)
objCharts.reset()
// 创建对象
var exName = exchange.GetName() + "_V5"
var nearConfigureFunc = $.getConfigureFunc()[exName]
var farConfigureFunc = $.getConfigureFunc()[exName]
var nearEx = $.createBaseEx(exchange, nearConfigureFunc)
var farEx = $.createBaseEx(exchange, farConfigureFunc)
// 预先写入需要订阅的合约
_.each(arrNearContractType, function(ct) {
nearEx.pushSubscribeSymbol(ct)
})
_.each(arrFarContractType, function(ct) {
farEx.pushSubscribeSymbol(ct)
})
while (true) {
var ts = new Date().getTime()
// 获取行情数据
nearEx.goGetTickers()
farEx.goGetTickers()
var nearTickers = nearEx.getTickers()
var farTickers = farEx.getTickers()
if (!farTickers || !nearTickers) {
Sleep(2000)
continue
}
var tbl = {
type : "table",
title : "远期-近期差价",
cols : ["交易对", "远期", "近期", "正对冲", "反对冲"],
rows : []
}
var subscribeFarTickers = []
var subscribeNearTickers = []
_.each(farTickers, function(farTicker) {
_.each(arrFarContractType, function(symbol) {
if (farTicker.originalSymbol == symbol) {
subscribeFarTickers.push(farTicker)
}
})
})
_.each(nearTickers, function(nearTicker) {
_.each(arrNearContractType, function(symbol) {
if (nearTicker.originalSymbol == symbol) {
subscribeNearTickers.push(nearTicker)
}
})
})
var pairs = []
_.each(subscribeFarTickers, function(farTicker) {
_.each(subscribeNearTickers, function(nearTicker) {
if (farTicker.symbol == nearTicker.symbol) {
var pair = {symbol: nearTicker.symbol, nearTicker: nearTicker, farTicker: farTicker, plusDiff: farTicker.bid1 - nearTicker.ask1, minusDiff: farTicker.ask1 - nearTicker.bid1}
pairs.push(pair)
tbl.rows.push([pair.symbol, farTicker.originalSymbol, nearTicker.originalSymbol, pair.plusDiff, pair.minusDiff])
for (var i = 0 ; i < arrCfg.length ; i++) {
if (arrCfg[i].title.text == pair.symbol) {
objCharts.add([i, [ts, pair.plusDiff]])
}
}
}
})
})
// 初始化
if (isFirst) {
isFirst = false
var recoveryNets = _G("nets")
var recoveryInitTotalEquity = _G("initTotalEquity")
if (!recoveryNets) {
// 检查持仓
_.each(subscribeFarTickers, function(farTicker) {
var pos = farEx.getFuPos(farTicker.originalSymbol, ts)
if (pos.length != 0) {
Log(farTicker.originalSymbol, pos)
throw "初始化时有持仓"
}
})
_.each(subscribeNearTickers, function(nearTicker) {
var pos = nearEx.getFuPos(nearTicker.originalSymbol, ts)
if (pos.length != 0) {
Log(nearTicker.originalSymbol, pos)
throw "初始化时有持仓"
}
})
// 构造nets
nets = []
_.each(pairs, function (pair) {
farEx.goGetAcc(pair.farTicker.originalSymbol, ts)
nearEx.goGetAcc(pair.nearTicker.originalSymbol, ts)
var obj = {
"symbol" : pair.symbol,
"farSymbol" : pair.farTicker.originalSymbol,
"nearSymbol" : pair.nearTicker.originalSymbol,
"initPrice" : (pair.nearTicker.ask1 + pair.farTicker.bid1) / 2,
"prePlus" : pair.farTicker.bid1 - pair.nearTicker.ask1,
"net" : createNet((pair.farTicker.bid1 - pair.nearTicker.ask1), diff, (pair.nearTicker.ask1 + pair.farTicker.bid1) / 2, true),
"initFarAcc" : farEx.getAcc(pair.farTicker.originalSymbol, ts),
"initNearAcc" : nearEx.getAcc(pair.nearTicker.originalSymbol, ts),
"farTicker" : pair.farTicker,
"nearTicker" : pair.nearTicker,
"farPos" : null,
"nearPos" : null,
}
nets.push(obj)
})
var currTotalEquity = getTotalEquity()
if (currTotalEquity) {
initTotalEquity = currTotalEquity
} else {
throw "初始化获取总权益失败!"
}
} else {
// 恢复
nets = recoveryNets
initTotalEquity = recoveryInitTotalEquity
}
}
// 检索网格,检查是否触发交易
_.each(nets, function(obj) {
var currPlus = null
_.each(pairs, function(pair) {
if (pair.symbol == obj.symbol) {
currPlus = pair.plusDiff
obj.farTicker = pair.farTicker
obj.nearTicker = pair.nearTicker
}
})
if (!currPlus) {
Log("没有查询到", obj.symbol, "的差价")
return
}
// 检查网格,动态添加
while (currPlus >= obj.net[obj.net.length - 1].price) {
obj.net.push({
sell : false,
price : obj.net[obj.net.length - 1].price + diff * obj.initPrice,
})
}
while (currPlus <= obj.net[0].price) {
var price = obj.net[0].price - diff * obj.initPrice
if (price <= 0) {
break
}
obj.net.unshift({
sell : false,
price : price,
})
}
// 检索网格
for (var i = 0 ; i < obj.net.length - 1 ; i++) {
var p = obj.net[i]
var upP = obj.net[i + 1]
if (obj.prePlus <= p.price && currPlus > p.price && !p.sell) {
if (hedge(nearEx, farEx, obj.nearSymbol, obj.farSymbol, obj.nearTicker, obj.farTicker, hedgeAmount, OPEN_PLUS)) { // 正对冲开仓
p.sell = true
}
} else if (obj.prePlus >= p.price && currPlus < p.price && upP.sell) {
if (hedge(nearEx, farEx, obj.nearSymbol, obj.farSymbol, obj.nearTicker, obj.farTicker, hedgeAmount, COVER_PLUS)) { // 正对冲平仓
upP.sell = false
}
}
}
obj.prePlus = currPlus // 记录本次差价,作为缓存,下次用于判断上穿下穿
// 增加其它表格输出
})
if (ts - preProfitPrintTS > 1000 * 60 * 5) { // 5分钟打印一次
var currTotalEquity = getTotalEquity()
if (currTotalEquity) {
totalEquity = currTotalEquity
LogProfit(totalEquity - initTotalEquity, "&") // 打印动态权益收益
}
// 检查持仓
posTbls = [] // 重置,更新
_.each(nets, function(obj) {
var currFarPos = farEx.getFuPos(obj.farSymbol)
var currNearPos = nearEx.getFuPos(obj.nearSymbol)
if (currFarPos && currNearPos) {
obj.farPos = currFarPos
obj.nearPos = currNearPos
}
var posTbl = {
"type" : "table",
"title" : obj.symbol,
"cols" : ["合约代码", "数量", "价格"],
"rows" : []
}
_.each(obj.farPos, function(pos) {
posTbl.rows.push([pos.symbol, pos.amount, pos.price])
})
_.each(obj.nearPos, function(pos) {
posTbl.rows.push([pos.symbol, pos.amount, pos.price])
})
posTbls.push(posTbl)
})
preProfitPrintTS = ts
}
// 显示网格
var netTbls = []
_.each(nets, function(obj) {
var netTbl = {
"type" : "table",
"title" : obj.symbol,
"cols" : ["网格"],
"rows" : []
}
_.each(obj.net, function(p) {
var color = ""
if (p.sell) {
color = "#00FF00"
}
netTbl.rows.push([JSON.stringify(p) + color])
})
netTbl.rows.reverse()
netTbls.push(netTbl)
})
LogStatus(_D(), "总权益:", totalEquity, "初始总权益:", initTotalEquity, " 浮动盈亏:", totalEquity - initTotalEquity,
"\n`" + JSON.stringify(tbl) + "`" + "\n`" + JSON.stringify(netTbls) + "`" + "\n`" + JSON.stringify(posTbls) + "`")
Sleep(interval)
}
}
function getTotalEquity() {
var totalEquity = null
var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
if (ret) {
try {
totalEquity = parseFloat(ret.data[0].details[0].eq)
} catch(e) {
Log("获取账户总权益失败!")
return null
}
}
return totalEquity
}
function hedge(nearEx, farEx, nearSymbol, farSymbol, nearTicker, farTicker, amount, tradeType) {
var farDirection = null
var nearDirection = null
if (tradeType == OPEN_PLUS) {
farDirection = farEx.OPEN_SHORT
nearDirection = nearEx.OPEN_LONG
} else {
farDirection = farEx.COVER_SHORT
nearDirection = nearEx.COVER_LONG
}
var nearSymbolInfo = nearEx.getSymbolInfo(nearSymbol)
var farSymbolInfo = farEx.getSymbolInfo(farSymbol)
nearAmount = nearEx.calcAmount(nearSymbol, nearDirection, nearTicker.ask1, amount * nearSymbolInfo.multiplier)
farAmount = farEx.calcAmount(farSymbol, farDirection, farTicker.bid1, amount * farSymbolInfo.multiplier)
if (!nearAmount || !farAmount) {
Log(nearSymbol, farSymbol, "下单量计算错误:", nearAmount, farAmount)
return
}
nearEx.goGetTrade(nearSymbol, nearDirection, nearTicker.ask1, nearAmount[0])
farEx.goGetTrade(farSymbol, farDirection, farTicker.bid1, farAmount[0])
var nearIdMsg = nearEx.getTrade()
var farIdMsg = farEx.getTrade()
return [nearIdMsg, farIdMsg]
}
function onexit() {
Log("执行扫尾函数", "#FF0000")
_G("nets", nets)
_G("initTotalEquity", initTotalEquity)
Log("保存数据:", _G("nets"), _G("initTotalEquity"))
}
اس حکمت عملی کا پبلک ایڈریس:https://www.fmz.com/strategy/288559
یہ پالیسی ایک ٹیمپلیٹ کلاس لائبریری کا استعمال کرتی ہے جو میں نے خود لکھی ہے ، اور چونکہ لکھا ہوا ٹیبلیٹ عوامی نہیں ہے ، لہذا اس پالیسی کا منبع کوڈ اس ٹیمپلیٹ کا استعمال کیے بغیر تبدیل کیا جاسکتا ہے۔
دلچسپی رکھنے والوں کے لیے OKEX V5 سمیلیٹر ٹیسٹ کروا سکتے ہیں۔ اوہ! ٹھیک ہے، یہ حکمت عملی دوبارہ نہیں کی جا سکتی۔
N95دو سال کے وقفے سے، ڈرامہ کی حکمت عملی مختلف تجارت کے جوڑوں، مختلف پوزیشنوں کی تعداد قائم کرنے کے لئے کس طرح ہے
چاؤاور اس کے بعد، میں نے اسے تبدیل کر دیا ہے، لیکن میں نے اسے تبدیل نہیں کیا ہے، اور میں نے اسے تبدیل نہیں کیا ہے.
ٹریک حیاتیاتمیں نے اس پلگ ان کے ساتھ کام نہیں کر رہا ہوں.
ایجاد کاروں کی مقدار - خواب`` //arrCfg کا اعلان کریں var arrCfg = [] _.each ((arrNearContractType, function ((ct) { arrCfg.push ((createCfg ((formatSymbol ((ct) [0])) }) `` اس طرح ہیج ایمونٹ کو بھی اسی طرح سے کیا جاتا ہے، اس کو ایک سٹرنگ کی طرح ڈیزائن کیا جاتا ہے: 100، 200، 330۔ اس طرح 100 ہیجنگ کے پہلے مجموعے کے مطابق ہوتا ہے، اور پھر اس کا استعمال کیا جاتا ہے۔
ایجاد کاروں کی مقدار - خواباس کے علاوہ، آپ کو اپنے آپ کو ایک ٹیمپلیٹ لائبریری کا استعمال کرتے ہوئے، اور اس کے ساتھ ساتھ آپ کو اپنے آپ کو بھی احاطہ کر سکتے ہیں.
ایجاد کاروں کی مقدار - خوابکیا پلگ ان؟