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

जिन मित्रों के पास खनन रणनीति के अच्छे विचार हैं, वे भी संदेश छोड़ने के लिए स्वागत हैं!
आइये “खुले तौर पर सोचें”! मैं ऐसी रणनीति बनाने की योजना बना रहा हूँ जो संकेतक या कीमतों को देखे बिना यादृच्छिक रूप से ऑर्डर दे। ऑर्डर लॉन्ग या शॉर्ट जाने से ज़्यादा कुछ नहीं है, और आपको बस संभावनाओं का अनुमान लगाना है। फिर हम लंबी और छोटी स्थिति निर्धारित करने के लिए 1 से 100 तक की यादृच्छिक संख्याओं का उपयोग करते हैं।
लंबी शर्तें: यादृच्छिक संख्या 1~50. शॉर्ट सेलिंग की शर्तें: यादृच्छिक संख्या 51~100.
लंबी और छोटी दोनों स्थितियों के लिए संख्याएं 50 हैं। इसके बाद, आइए इस बारे में सोचें कि स्थिति को कैसे बंद किया जाए। चूंकि यह एक जुआ है, इसलिए जीतने और हारने का एक मानक होना चाहिए। फिर लेनदेन में हम जीत या हार के मानक के रूप में निश्चित लाभ-हानि और हानि-विराम निर्धारित करते हैं। यदि आप लाभ रोकते हैं तो आप जीतते हैं; यदि आप हानि रोकते हैं तो आप हारते हैं। जहां तक उचित लाभ-लेने और हानि-रोक सेटिंग का सवाल है, यह वास्तव में लाभ और हानि अनुपात को प्रभावित करता है, अरे हां! इससे जीतने की दर भी प्रभावित होती है! (क्या यह डिज़ाइन रणनीति प्रभावी है? क्या यह सकारात्मक गणितीय अपेक्षा की गारंटी दे सकती है? आइए पहले इसे करें! आखिरकार, यह सीखने और शोध के लिए है!)
ट्रेडिंग लागत-मुक्त नहीं है। स्लिपेज और हैंडलिंग फीस जैसे कारक हमारी रैंडम ट्रेडिंग जीत दर को 50% से कम करने के लिए पर्याप्त हैं। मुझे इस बात को ध्यान में रखते हुए डिजाइनिंग कैसे जारी रखनी चाहिए? कई पोजीशन बढ़ाने का डिज़ाइन बनाना बेहतर है। चूंकि यह एक जुआ है, इसलिए लगातार 10 में से 8 यादृच्छिक लेनदेन खोने की संभावना बहुत अधिक नहीं होनी चाहिए। इसलिए मैं पहले लेनदेन को बहुत छोटे ऑर्डर आकार के साथ डिजाइन करना चाहता हूं, जितना संभव हो सके उतना छोटा। फिर यदि आप शर्त हार जाते हैं, तो ऑर्डर की मात्रा बढ़ाएं और यादृच्छिक ऑर्डर देना जारी रखें।
ठीक है, रणनीति का डिज़ाइन बहुत सरल है।
डिज़ाइन स्रोत कोड:
var openPrice = 0
var ratio = 1
var totalEq = null
var nowEq = null
function cancelAll() {
while (1) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
exchange.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
Sleep(500)
}
}
function main() {
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("重置所有数据", "#FF0000")
}
exchange.SetContractType(ct)
var initPos = _C(exchange.GetPosition)
if (initPos.length != 0) {
throw "策略启动时有持仓!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("设置精度", pricePrecision, amountPrecision)
if (!IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = _C(exchange.GetAccount).Balance // equity
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "获取初始权益失败"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// 更新账户信息,计算收益
var nowAcc = _C(exchange.GetAccount)
nowEq = IsVirtual() ? nowAcc.Balance : nowAcc.Balance // equity
LogProfit(nowEq - totalEq, nowAcc)
var direction = Math.floor((Math.random()*100)+1) // 1~50 , 51~100
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
if (direction > 50) {
// long
openPrice = depth.Bids[1].Price
exchange.SetDirection("buy")
exchange.Buy(Math.abs(openPrice) + slidePrice, amount * ratio)
} else {
// short
openPrice = -depth.Asks[1].Price
exchange.SetDirection("sell")
exchange.Sell(Math.abs(openPrice) - slidePrice, amount * ratio)
}
Log("下", direction > 50 ? "买单" : "卖单", ",价格:", Math.abs(openPrice))
continue
}
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
var pos = _C(exchange.GetPosition)
if (pos.length == 0) {
openPrice = 0
continue
}
// 平仓检测
while (1) {
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
var stopLossPrice = openPrice > 0 ? Math.abs(openPrice) - stopLoss : Math.abs(openPrice) + stopLoss
var stopProfitPrice = openPrice > 0 ? Math.abs(openPrice) + stopProfit : Math.abs(openPrice) - stopProfit
var winOrLoss = 0 // 1 win , -1 loss
// 画线
$.PlotLine("bid", depth.Bids[0].Price)
$.PlotLine("ask", depth.Asks[0].Price)
// 止损
if (openPrice > 0 && depth.Bids[0].Price < stopLossPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = -1
} else if (openPrice < 0 && depth.Asks[0].Price > stopLossPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = -1
}
// 止盈
if (openPrice > 0 && depth.Bids[0].Price > stopProfitPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = 1
} else if (openPrice < 0 && depth.Asks[0].Price < stopProfitPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = 1
}
// 检测挂单
Sleep(2000)
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
pos = _C(exchange.GetPosition)
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
} else {
// 撤销挂单
cancelAll()
Sleep(2000)
pos = _C(exchange.GetPosition)
// 撤销后更新持仓,需要再次检查
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
}
var tbl = {
"type" : "table",
"title" : "info",
"cols" : ["totalEq", "nowEq", "openPrice", "bid1Price", "ask1Price", "ratio", "pos.length"],
"rows" : [],
}
tbl.rows.push([totalEq, nowEq, Math.abs(openPrice), depth.Bids[0].Price, depth.Asks[0].Price, ratio, pos.length])
tbl.rows.push(["pos", "type", "amount", "price", "--", "--", "--"])
for (var j = 0 ; j < pos.length ; j++) {
tbl.rows.push([j, pos[j].Type, pos[j].Amount, pos[j].Price, "--", "--", "--"])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
}
} else {
// 撤销挂单
// 重置openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
रणनीति मापदंड:

ओह हां! इस रणनीति को एक नाम की आवश्यकता है, आइए इसे “आकार का अनुमान लगाएं (dYdX संस्करण)” कहें।
बैकटेस्टिंग केवल संदर्भ के लिए है।_<! इसका मुख्य उद्देश्य यह जांचना है कि क्या रणनीति में कोई बग है और बिनेंस फ्यूचर्स बैकटेस्टिंग का उपयोग करना है।




बैकटेस्टिंग पूर्ण हो गई है, कोई बग नहीं है। लेकिन मुझे लगता है कि मैंने बैकटेस्ट सिस्टम को ओवरफिट कर दिया है…T_T, मुझे इसे वास्तविक समय में आज़माने दें।



यह रणनीति केवल सीखने और संदर्भ के लिए है।सौ लाख~सौ लाखइसका वास्तविक उपयोग न करें! !