
क्या आपने कभी सोचा है कि आप आसानी से मात्रात्मक व्यापार शुरू कर सकते हैं और फ्रेमवर्क बनाने, यूआई डिजाइन करने और विभिन्न डिजाइन विवरण और तंत्र बनाने के लिए पूरी रात कोड लिखने के बिना तुरंत शुरू कर सकते हैं? एफएमजेड मात्रात्मक मंच पर सब कुछ संभव हो जाता है। आपको उन्नत प्रोग्रामिंग पृष्ठभूमि की आवश्यकता नहीं है, न ही आपको जटिल परिनियोजन प्रक्रियाओं के बारे में चिंता करने की आवश्यकता है - आपको अपनी “कहीं भी जाने वाली” मात्रात्मक यात्रा शुरू करने के लिए केवल एक कंप्यूटर और एक खाते की आवश्यकता है। यह लेख आपको शुरुआत से लेकर, FMZ के साथ शीघ्रता से शुरुआत करने, स्वचालित ट्रेडिंग के आकर्षण का अनुभव करने, तथा बाजार की लय में महारत हासिल करने के लिए डेटा और रणनीतियों का उपयोग करने में मदद करेगा। चाहे आप एक शुरुआती हों या एक अनुभवी जो दक्षता में सुधार करना चाहते हैं, यह यात्रा प्रयास करने लायक है।
मैं अक्सर इस मंच के शुरुआती लोगों के साथ संवाद और चैट करता हूं। मात्रात्मक व्यापार के शुरुआती लोग आमतौर पर पूरी डिजाइन प्रक्रिया से भ्रमित हो जाते हैं। जब मेरे पास ट्रेडिंग के विचार आते हैं, तो मैं अक्सर यह नहीं जान पाता कि कहां से शुरू करूं और मैं परेशान हो जाता हूं।
इस बात को लेकर असमंजस में:
आइये, उपरोक्त उलझन को मिलकर सुलझाएं।
मात्रात्मक व्यापार की दुनिया में, रणनीति डिजाइन अक्सर अन्वेषण की एक यात्रा होती है जिसका कोई अंत नहीं होता। आपने संकेतक लिखने की कोशिश की होगी, या खरीद और बिक्री के संकेतों का आँख मूंदकर अनुसरण करने की कोशिश की होगी, लेकिन जो वास्तव में दूर तक जा सकते हैं वे वे रणनीति प्रणालियाँ हैं जो “दृश्यमान, समायोज्य और स्थिर” हो सकती हैं। एफएमजेड मात्रात्मक मंच के आधार पर, आप “समय पर चलने” का व्यावहारिक अनुभव प्राप्त कर सकते हैं। किसी रणनीति की डिजाइन आवश्यकताओं को पूरी तरह से पूरा करने के लिए, पैरामीटर सेटिंग, चार्ट डिस्प्ले से लेकर इंटरैक्टिव फ़ंक्शन और लाभ और हानि की गणना तक एक सरल रणनीति बनाएं।
रणनीति का विचार एटीआर, चरण-दर-चरण ग्रिड स्थिति निर्माण तर्क (दीर्घ और लघु द्विदिशात्मक), एटीआर अनुकूली अस्थिरता गणना, और स्थिति परिसमापन तर्क (जब बाजार केंद्रीय अक्ष पर उलट जाता है) पर आधारित एक चरण-दर-चरण स्थिति-वृद्धि की रणनीति है।
यह रणनीति निम्नलिखित डिज़ाइन आवश्यकताओं पर आधारित है:
पदों की क्रमिक वृद्धि को नियंत्रित करने के लिए दो सरणियाँ स्थापित करें।
var arrUp = null
var arrDown = null
हर बार जब आप कोई स्थिति जोड़ते हैं, तो स्थिति की जानकारी सरणी में डाल दी जाती है, जिससे स्थिति को नियंत्रित करना और रणनीति वास्तविक समय इंटरफ़ेस पर डेटा प्रदर्शित करना आसान हो जाता है।
मूल्य सफलता स्तर के अनुसार पोजीशन खोलें और बंद करें। सरलता के लिए, आरंभिक और अंतिम दोनों स्थितियों में बाजार आदेशों का उपयोग किया जाता है, जो सरल और प्रभावी होते हैं।
if (close > up && i >= arrUp.length && !isPaused) {
var id = exchange.CreateOrder(symbol, "sell", -1, tradeAmount)
if (!id) {
Log("下单失败")
continue
}
arrUp.push({"symbol": symbol, "ratio": (i + 1), "amount": tradeAmount, "price": close})
_G("arrUp", arrUp)
arrSignal.push([r[r.length - 1].Time, "short", close, tradeAmount])
Log([r[r.length - 1].Time, "short", close, tradeAmount], "@")
} else if (close < down && i >= arrDown.length && !isPaused) {
var id = exchange.CreateOrder(symbol, "buy", -1, tradeAmount)
if (!id) {
Log("下单失败")
continue
}
arrDown.push({"symbol": symbol, "ratio": (i + 1), "amount": tradeAmount, "price": close})
_G("arrDown", arrDown)
arrSignal.push([r[r.length - 1].Time, "long", close, tradeAmount])
Log([r[r.length - 1].Time, "long", close, tradeAmount], "@")
} else if (((arrUp.length > 0 && close < mid) || (arrDown.length > 0 && close > mid)) && !isPaused) {
clear(pos, r)
}
इन्वेंटरी साफ़ करें और इसे संभालने के लिए फ़ंक्शन का उपयोग करें। कुछ डेटा संरचनाओं को प्रत्येक बार इन्वेंट्री साफ़ करने पर रीसेट करने की आवश्यकता होती है, इसलिए क्लियरिंग फ़ंक्शन को इंटरैक्टिव मॉड्यूल में पुनः उपयोग के लिए फ़ंक्शन में समाहित करने की आवश्यकता होती है।
function clear(positions, r) {
var close = r[r.length - 1].Close
for (var p of positions) {
if (p.Type == PD_LONG) {
var id = exchange.CreateOrder(symbol, "closebuy", -1, p.Amount)
if (!id) {
Log("下单失败")
continue
}
arrSignal.push([r[r.length - 1].Time, "closelong", close, p.Amount])
Log([r[r.length - 1].Time, "closelong", close, p.Amount], "@")
} else if (p.Type == PD_SHORT) {
var id = exchange.CreateOrder(symbol, "closesell", -1, p.Amount)
if (!id) {
Log("下单失败")
continue
}
arrSignal.push([r[r.length - 1].Time, "closeshort", close, p.Amount])
Log([r[r.length - 1].Time, "closeshort", close, p.Amount], "@")
}
}
arrUp = []
arrDown = []
_G("arrUp", arrUp)
_G("arrDown", arrDown)
var profit = calcProfit()
LogProfit(profit)
}
इसे कई स्तरों में विभाजित किया गया है, और अधिकतम स्तर है: maxRatio. प्रत्येक स्तर पर अलग-अलग मूल्य सीमा की गणना की जाती है।
for (var i = 0; i < maxRatio; i++) {
var up = open + atr[atr.length - 1] * (i + 1)
var mid = open
var down = open - atr[atr.length - 1] * (i + 1)
atrs.push([open, (i + 1), atr])
var tradeAmount = baseAmount * Math.pow(2, i)
if (isAmountForUSDT) {
tradeAmount = tradeAmount * 1.05 / close
}
tradeAmount = _N(tradeAmount, amountPrecision)
var balance = acc.Balance
if (balance - initAcc.Equity * reserve < tradeAmount * close) {
continue
}
// ...
}
इंटरैक्टिव फ़ंक्शन डिज़ाइन करें, इन्वेंट्री साफ़ करें, रोकें, अनपॉज़ करें, पैरामीटर संशोधित करें, आदि। FMZ पर इंटरैक्शन डिज़ाइन करना बहुत सुविधाजनक है, और प्लेटफ़ॉर्म कई इंटरैक्टिव नियंत्रण प्रदान करता है। हमें केवल रणनीति में इंटरैक्टिव नियंत्रण जोड़ने की जरूरत है, और फिर रणनीति कोड में संदेश प्राप्त करते समय विभिन्न पहचान और प्रसंस्करण कोड लिखना होगा।
var cmd = GetCommand()
if (cmd) {
Log("交互指令:", cmd)
var arrCmd = cmd.split(":")
if (arrCmd.length == 2) {
var strCmd = arrCmd[0]
var param = parseFloat(arrCmd[1])
if (strCmd == "atrPeriod") {
atrPeriod = param
Log("修改ATR参数:", atrPeriod)
}
} else {
if (cmd == "isPaused" && !isPaused) {
isPaused = true
Log("暂停交易")
} else if (cmd == "isPaused" && isPaused) {
isPaused = false
Log("取消暂停交易")
} else if (cmd == "clearAndPaused") {
clear(pos, r)
isPaused = true
Log("清仓、暂停交易")
}
}
}
किसी रणनीति को खोलते या बंद करते समय, आप आसानी से संदेश भेज सकते हैंमेल, FMZ एपीपी, तृतीय-पक्ष इंटरफ़ेस, आदि।
Log([r[r.length - 1].Time, "long", close, tradeAmount], "@") // 消息推送
पुश नोटिफिकेशन प्राप्त करें (FMZ ऐप और अन्य ऐप्स को भी पुश नोटिफिकेशन प्राप्त होंगे):

लाभ और हानि की गणना करने के लिए फ़ंक्शन को हर बार स्थिति बंद होने पर बुलाया जाता है ताकि लाभ और हानि की गणना की जा सके और लाभ और हानि वक्र को आउटपुट किया जा सके।
function calcProfit() {
var initAcc = _G("initAcc")
var nowAcc = _C(exchange.GetAccount)
var profit = nowAcc.Equity - initAcc.Equity
return profit
}
FMZ का उपयोग करें_G()फ़ंक्शन, एक रणनीति प्रगति वसूली तंत्र डिजाइन करना आसान है।
if (isReset) {
_G(null)
LogProfitReset()
LogReset(1)
c.reset()
}
arrUp = _G("arrUp")
if (!arrUp) {
arrUp = []
_G("arrUp", arrUp)
}
arrDown = _G("arrDown")
if (!arrDown) {
arrDown = []
_G("arrDown", arrDown)
}
अनुबंधों का व्यापार करते समय, ऑर्डर इंटरफ़ेस में ऑर्डर मात्रा अनुबंधों की संख्या होती है, इसलिए उपयोगकर्ता अक्सर पूछते हैं कि हमारे द्वारा ऑर्डर की संख्या में ऑर्डर कैसे रखा जाए:
if (isAmountForUSDT) {
tradeAmount = tradeAmount * 1.05 / close
}
tradeAmount = _N(tradeAmount, amountPrecision)
यह वास्तव में बहुत सरल है, बस राशि को कीमत से विभाजित करें।
यदि आप जोखिम नियंत्रण के रूप में अपने खाते में हमेशा एक निश्चित राशि आरक्षित रखना चाहते हैं, तो आप यह सरल तंत्र डिजाइन कर सकते हैं।
var balance = acc.Balance
if (balance - initAcc.Equity * reserve < tradeAmount * close) {
continue
}
वास्तविक बाजार चलाते समय, रणनीति का निरीक्षण करना निश्चित रूप से आवश्यक है, जिसमें खाता इक्विटी, रणनीति की स्थिति, रणनीति की स्थिति, ऑर्डर की जानकारी, बाजार चार्ट आदि शामिल हैं। इन्हें निम्नानुसार डिज़ाइन किया गया है:
if (isShowPlot) {
r.forEach(function(bar, index) {
c.begin(bar)
for (var i in atrs) {
var arr = atrs[i]
var up = arr[0] + arr[2][index] * arr[1]
var mid = arr[0]
var down = arr[0] - arr[2][index] * arr[1]
c.plot(up, 'up_' + (i + 1))
c.plot(mid, 'mid_' + (i + 1))
c.plot(down, 'down_' + (i + 1))
}
for (var signal of arrSignal) {
if (signal[0] == bar.Time) {
c.signal(signal[1], signal[2], signal[3])
}
}
c.close()
})
}
// ...
var orderTbl = {"type": "table", "title": "order", "cols": ["symbol", "type", "ratio", "price", "amount"], "rows": []}
for (var i = arrUp.length - 1; i >= 0; i--) {
var order = arrUp[i]
orderTbl["rows"].push([order["symbol"], "short", order["ratio"], order["price"], order["amount"]])
}
for (var i = 0; i < arrDown.length; i++) {
var order = arrDown[i]
orderTbl["rows"].push([order["symbol"], "long", order["ratio"], order["price"], order["amount"]])
}
var posTbl = {"type": "table", "title": "pos", "cols": ["symbol", "type", "price", "amount"], "rows": []}
for (var i = 0; i < pos.length; i++) {
var p = pos[i]
posTbl["rows"].push([p.Symbol, p.Type == PD_LONG ? "long" : "short", p.Price, p.Amount])
}
LogStatus(_D(), "初始权益:" + initAcc.Equity, ", 当前权益:" + acc.Equity, ", 运行状态:" + (isPaused ? "暂停交易" : "运行中"),
"\n`" + JSON.stringify(orderTbl) + "`\n", "`" + JSON.stringify(posTbl) + "`")
अंत में, 200 से अधिक कोड लाइनों ने एक पूर्ण रणनीति को कार्यान्वित किया, जिसका बैकटेस्ट किया जा सकता है और वास्तविक ट्रेडिंग में कार्यान्वित किया जा सकता है। हमने अपना अंतिम लक्ष्य हासिल कर लिया है: FMZ पर एक ऑल-इन-वन मात्रात्मक ट्रेडिंग सिस्टम बनाना जो “विज़ुअलाइज़ेशन + इंटरैक्शन + ऑटोमेशन” को जोड़ता है।
बैकटेस्टिंग केवल संदर्भ के लिए है। जो लोग मात्रात्मक व्यापार करते हैं, वे जानते हैं कि “बैकटेस्टिंग” वास्तविक परिदृश्य का 100% अनुकरण नहीं कर सकता। बैकटेस्टिंग का मुख्य उद्देश्य रणनीति के तर्क का परीक्षण करना, रणनीति की मजबूती का परीक्षण करना और बुनियादी कार्यों का परीक्षण करना है।


पैरामीटर डिज़ाइन:

इंटरेक्शन डिज़ाइन:

रणनीति स्रोत कोड:
/*backtest
start: 2024-04-27 18:40:00
end: 2025-04-10 00:00:00
period: 15m
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":100}]
*/
var atrPeriod = 20
var arrUp = null
var arrDown = null
var arrSignal = []
function calcProfit() {
var initAcc = _G("initAcc")
var nowAcc = _C(exchange.GetAccount)
var profit = nowAcc.Equity - initAcc.Equity
return profit
}
function clear(positions, r) {
var close = r[r.length - 1].Close
for (var p of positions) {
if (p.Type == PD_LONG) {
var id = exchange.CreateOrder(symbol, "closebuy", -1, p.Amount)
if (!id) {
Log("下单失败")
continue
}
arrSignal.push([r[r.length - 1].Time, "closelong", close, p.Amount])
Log([r[r.length - 1].Time, "closelong", close, p.Amount], "@")
} else if (p.Type == PD_SHORT) {
var id = exchange.CreateOrder(symbol, "closesell", -1, p.Amount)
if (!id) {
Log("下单失败")
continue
}
arrSignal.push([r[r.length - 1].Time, "closeshort", close, p.Amount])
Log([r[r.length - 1].Time, "closeshort", close, p.Amount], "@")
}
}
arrUp = []
arrDown = []
_G("arrUp", arrUp)
_G("arrDown", arrDown)
var profit = calcProfit()
LogProfit(profit)
}
function main() {
var symbolInfo = symbol.split(".")
if (symbolInfo.length != 2) {
throw "error symbol:" + symbol
} else {
exchange.SetCurrency(symbolInfo[0])
exchange.SetContractType(symbolInfo[1])
}
exchange.SetPrecision(pricePrecision, amountPrecision)
let c = KLineChart({
overlay: true
})
if (isReset) {
_G(null)
LogProfitReset()
LogReset(1)
c.reset()
}
arrUp = _G("arrUp")
if (!arrUp) {
arrUp = []
_G("arrUp", arrUp)
}
arrDown = _G("arrDown")
if (!arrDown) {
arrDown = []
_G("arrDown", arrDown)
}
var initAcc = _G("initAcc")
if (!initAcc) {
initAcc = _C(exchange.GetAccount)
_G("initAcc", initAcc)
}
var isPaused = false
while (true) {
var atrs = []
var r = _C(exchange.GetRecords, symbol)
var pos = _C(exchange.GetPositions, symbol)
var acc = _C(exchange.GetAccount)
var open = r[r.length - 1].Open
var close = r[r.length - 1].Close
var atr = TA.ATR(r, atrPeriod)
for (var i = 0; i < maxRatio; i++) {
var up = open + atr[atr.length - 1] * (i + 1)
var mid = open
var down = open - atr[atr.length - 1] * (i + 1)
atrs.push([open, (i + 1), atr])
var tradeAmount = baseAmount * Math.pow(2, i)
if (isAmountForUSDT) {
tradeAmount = tradeAmount * 1.05 / close
}
tradeAmount = _N(tradeAmount, amountPrecision)
var balance = acc.Balance
if (balance - initAcc.Equity * reserve < tradeAmount * close) {
continue
}
if (close > up && i >= arrUp.length && !isPaused) {
var id = exchange.CreateOrder(symbol, "sell", -1, tradeAmount)
if (!id) {
Log("下单失败")
continue
}
arrUp.push({"symbol": symbol, "ratio": (i + 1), "amount": tradeAmount, "price": close})
_G("arrUp", arrUp)
arrSignal.push([r[r.length - 1].Time, "short", close, tradeAmount])
Log([r[r.length - 1].Time, "short", close, tradeAmount], "@")
} else if (close < down && i >= arrDown.length && !isPaused) {
var id = exchange.CreateOrder(symbol, "buy", -1, tradeAmount)
if (!id) {
Log("下单失败")
continue
}
arrDown.push({"symbol": symbol, "ratio": (i + 1), "amount": tradeAmount, "price": close})
_G("arrDown", arrDown)
arrSignal.push([r[r.length - 1].Time, "long", close, tradeAmount])
Log([r[r.length - 1].Time, "long", close, tradeAmount], "@")
} else if (((arrUp.length > 0 && close < mid) || (arrDown.length > 0 && close > mid)) && !isPaused) {
clear(pos, r)
}
}
if (isShowPlot) {
r.forEach(function(bar, index) {
c.begin(bar)
for (var i in atrs) {
var arr = atrs[i]
var up = arr[0] + arr[2][index] * arr[1]
var mid = arr[0]
var down = arr[0] - arr[2][index] * arr[1]
c.plot(up, 'up_' + (i + 1))
c.plot(mid, 'mid_' + (i + 1))
c.plot(down, 'down_' + (i + 1))
}
for (var signal of arrSignal) {
if (signal[0] == bar.Time) {
c.signal(signal[1], signal[2], signal[3])
}
}
c.close()
})
}
var cmd = GetCommand()
if (cmd) {
Log("交互指令:", cmd)
var arrCmd = cmd.split(":")
if (arrCmd.length == 2) {
var strCmd = arrCmd[0]
var param = parseFloat(arrCmd[1])
if (strCmd == "atrPeriod") {
atrPeriod = param
Log("修改ATR参数:", atrPeriod)
}
} else {
if (cmd == "isPaused" && !isPaused) {
isPaused = true
Log("暂停交易")
} else if (cmd == "isPaused" && isPaused) {
isPaused = false
Log("取消暂停交易")
} else if (cmd == "clearAndPaused") {
clear(pos, r)
isPaused = true
Log("清仓、暂停交易")
}
}
}
var orderTbl = {"type": "table", "title": "order", "cols": ["symbol", "type", "ratio", "price", "amount"], "rows": []}
for (var i = arrUp.length - 1; i >= 0; i--) {
var order = arrUp[i]
orderTbl["rows"].push([order["symbol"], "short", order["ratio"], order["price"], order["amount"]])
}
for (var i = 0; i < arrDown.length; i++) {
var order = arrDown[i]
orderTbl["rows"].push([order["symbol"], "long", order["ratio"], order["price"], order["amount"]])
}
var posTbl = {"type": "table", "title": "pos", "cols": ["symbol", "type", "price", "amount"], "rows": []}
for (var i = 0; i < pos.length; i++) {
var p = pos[i]
posTbl["rows"].push([p.Symbol, p.Type == PD_LONG ? "long" : "short", p.Price, p.Amount])
}
LogStatus(_D(), "初始权益:" + initAcc.Equity, ", 当前权益:" + acc.Equity, ", 运行状态:" + (isPaused ? "暂停交易" : "运行中"),
"\n`" + JSON.stringify(orderTbl) + "`\n", "`" + JSON.stringify(posTbl) + "`")
Sleep(5000)
}
}
यह रणनीति केवल शिक्षण प्रयोजन के लिए है। यद्यपि इसका उपयोग वास्तविक व्यापार में किया जा सकता है और वर्तमान में यह लाभदायक भी है, फिर भी इसकी दीर्घकालिक प्रभावशीलता का परीक्षण करने में समय लगेगा। रणनीति तैयार करने वाले भाग में अभी भी अनुकूलन की गुंजाइश है, जिससे कुछ दोहराव वाले कार्यों से बचा जा सकता है और कार्यक्रम की दक्षता में सुधार किया जा सकता है। रणनीति तर्क को भी और अधिक अनुकूलित किया जा सकता है।

जीपीटी से एक काव्यात्मक सारांश:
वास्तविक व्यापार एक लंबी यात्रा है। चाहे आप कब भी लौटें, आप केवल मन की शांति चाहते हैं। हर बार जब आप कोई पोजीशन खोलते हैं, तो आप विशाल बाजार में आशा की रोशनी बोते हैं; हर बार जब आप नुकसान रोकते हैं, तो आप हवा और बारिश में अधिक दृढ़ता से आगे बढ़ना सीखते हैं। बाजार ज्वार की तरह है और लाभ-हानि स्वप्न की तरह है। हम संख्याओं की लहरों के शिखर पर नृत्य करते हैं और रणनीति के प्रकाश स्तंभ के नीचे देखते हैं। आप और मैं, इस लम्बी यात्रा में, न तो अपना रास्ता खोएं, न ही अकेलेपन से डरें, और अंततः उस प्रकाश तक पहुंचें जो हमारा है।
यह आलेख न केवल एक सम्पूर्ण रणनीति प्रस्तुत करता है, बल्कि इससे भी अधिक महत्वपूर्ण बात यह है कि यह एक “व्यवस्थित” रणनीति विकास विचार प्रस्तुत करता है। रणनीति डिजाइन, स्थिति प्रबंधन, जोखिम नियंत्रण, चार्ट इंटरैक्शन से लेकर वास्तविक कार्यान्वयन तक, यह टेम्पलेट्स का एक सेट है जिसे बार-बार पुन: उपयोग किया जा सकता है, और यह मात्रात्मक व्यापार के लिए व्यावसायिकता की ओर बढ़ने का एकमात्र तरीका भी है।
मुझे आशा है कि आप FMZ प्लेटफॉर्म का उपयोग करके अपना स्वयं का स्वचालित ट्रेडिंग सिस्टम बना सकेंगे, जिससे आप कभी भी कोई सिग्नल नहीं चूकेंगे।
आपके पढ़ने और समर्थन के लिए धन्यवाद। यह रणनीति केवल शिक्षण उद्देश्यों के लिए है। कृपया वास्तविक व्यापार में इसका उपयोग सावधानी से करें।