कई उपयोगकर्ताओं की जरूरतों के जवाब में, एफएमजेड प्लेटफॉर्म ने हाल ही में विकेन्द्रीकृत प्लेटफॉर्म 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("reset all data", "#FF0000")
}
exchange.SetContractType(ct)
var initPos = _C(exchange.GetPosition)
if (initPos.length != 0) {
throw "Position detected when starting the strategy!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("setPrecision", 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 "fail to obtain the initial equity"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// update account information, and calculate the profit
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("place", direction > 50 ? "buy order" : "sell order", ",price:", 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
}
// detect close positions
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
// plot
$.PlotLine("bid", depth.Bids[0].Price)
$.PlotLine("ask", depth.Asks[0].Price)
// stop loss
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
}
// stop profit
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
}
// detect pending orders
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 {
// cancel pending orders
cancelAll()
Sleep(2000)
pos = _C(exchange.GetPosition)
// after canceling, update positions, which needs to be detected again
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 {
// cancel pending orders
// reset openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
रणनीतिक मापदंडः
ठीक है! रणनीति का एक नाम की जरूरत है, और चलो इसे कॉल "अनुमान लगाओ जो बड़ा है (dYdX संस्करण) ।
बैकटेस्ट केवल संदर्भ के लिए है! यह मुख्य रूप से यह जांचने के लिए है कि क्या रणनीति में कोई बग हैं; बिनेंस फ्यूचर्स के साथ बैकटेस्ट।
बैकटेस्ट खत्म हो गया है, कोई बग नहीं है. लेकिन मुझे लगता है कि बैकटेस्ट प्रणाली मेल खाया गया था... चलो इसे एक वास्तविक बॉट में निरीक्षण के लिए चलाते हैं.
यह रणनीति केवल सीखने और संदर्भ के लिए है।मत करो!! मत करोइसे एक असली बॉट में इस्तेमाल करें!