کمیونٹی کے صارفین کی درخواست پر جو ڈیزائن حوالہ کے لئے کثیر اقسام کی ڈبل ای ایم اے حکمت عملی رکھنا چاہتے ہیں۔ اس مضمون میں ، ہم کثیر اقسام کی ڈبل ای ایم اے حکمت عملی کو نافذ کریں گے۔ حکمت عملی کوڈ پر تبصرے آسان تفہیم اور سیکھنے کے ل written لکھے جائیں گے۔ پروگرامنگ اور مقداری تجارت کے زیادہ نئے آنے والوں کو جلدی سے شروعات کرنے دیں۔
ڈبل ای ایم اے حکمت عملی کا منطق بہت آسان ہے ، یعنی دو ای ایم اے۔ ایک ای ایم اے (فاسٹ لائن) جس میں پیرامیٹر کی مدت چھوٹی ہے اور ایک ای ایم اے (سست لائن) جس میں پیرامیٹر کی مدت بڑی ہے۔ اگر دونوں لائنوں میں سنہری کراس ہے (فاسٹ لائن نیچے سے اوپر تک سست لائن سے گزرتی ہے) تو ہم خریدتے ہیں اور طویل ہوجاتے ہیں۔ اور اگر دونوں لائنوں میں مردہ کراس ہے (فاسٹ لائن اوپر سے نیچے تک سست لائن سے گزرتی ہے) تو ہم فروخت کرتے ہیں اور مختصر ہوجاتے ہیں۔ ہم یہاں ای ایم اے کا استعمال کرتے ہیں۔
تاہم ، حکمت عملی کو کثیر قسم کے طور پر ڈیزائن کیا جانا چاہئے ، لہذا ہر قسم کے پیرامیٹرز مختلف ہوسکتے ہیں (مختلف قسمیں مختلف EMA پیرامیٹرز استعمال کرتی ہیں) ، لہذا پیرامیٹرز کو ڈیزائن کرنے کے لئے
پیرامیٹرز کو اسٹرنگ کی شکل میں ڈیزائن کیا گیا ہے ، ہر پیرامیٹر کو کوما سے الگ کیا گیا ہے۔ جب حکمت عملی چلنا شروع ہوتی ہے تو ان تاروں کو تجزیہ کریں۔ عملدرآمد کا منطق ہر قسم (ٹریڈنگ جوڑی) سے ملتا ہے۔ گھومنے والی حکمت عملی ہر قسم کی مارکیٹ کا پتہ لگاتی ہے ، تجارتی حالات کو متحرک کرتی ہے ، چارٹ پرنٹنگ وغیرہ۔ تمام اقسام کو ایک بار گھومنے کے بعد ، اعداد و شمار کا خلاصہ کریں اور اسٹیٹس بار پر ٹیبل کی معلومات دکھائیں۔
یہ حکمت عملی بہت سادہ اور نئے آنے والوں کے لئے موزوں ہونے کے لئے ڈیزائن کی گئی ہے، مجموعی طور پر صرف 200+ کوڈ لائنوں کے ساتھ.
// Function: cancel all takers of the current trading pair
function cancelAll(e) {
while (true) {
var orders = _C(e.GetOrders)
if (orders.length == 0) {
break
} else {
for (var i = 0 ; i < orders.length ; i++) {
e.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
}
Sleep(500)
}
}
// Functionn: calculate the profit/loss in real-time
function getProfit(account, initAccount, lastPrices) {
// account is the current account information, initAccount is the initial account information, lastPrices is the latest price of all varieties
var sum = 0
_.each(account, function(val, key) {
// Iterate through all current assets, calculate the currency difference of assets other than USDT, and the amount difference
if (key != "USDT" && typeof(initAccount[key]) == "number" && lastPrices[key + "_USDT"]) {
sum += (account[key] - initAccount[key]) * lastPrices[key + "_USDT"]
}
})
// Return to the profit and loss of the asset based on the current prices
return account["USDT"] - initAccount["USDT"] + sum
}
// Function: generate chart configuration
function createChartConfig(symbol, ema1Period, ema2Period) {
// symbol is the trading pair, ema1Period is the first EMA period, ema2Period is the second EMA period
var chart = {
__isStock: true,
extension: {
layout: 'single',
height: 600,
},
title : { text : symbol},
xAxis: { type: 'datetime'},
series : [
{
type: 'candlestick', // K-line data series
name: symbol,
id: symbol,
data: []
}, {
type: 'line', // EMA data series
name: symbol + ',EMA1:' + ema1Period,
data: [],
}, {
type: 'line', // EMA data series
name: symbol + ',EMA2:' + ema2Period,
data: []
}
]
}
return chart
}
function main() {
// Reset all data
if (isReset) {
_G(null) // Clear data of all persistent records
LogReset(1) // Clear all logs
LogProfitReset() // Clear all return logs
LogVacuum() //Release the resources occupied by the real bot database
Log("Reset all data", "#FF0000") // Print messages
}
// Parameter analysis
var arrSymbols = symbols.split(",") // Comma-separated string of trading varieties
var arrEma1Periods = ema1Periods.split(",") // Parameter string for splitting the first EMA
var arrEma2Periods = ema2Periods.split(",") // Parameter string for splitting the second EMA
var arrAmounts = orderAmounts.split(",") // Splitting the amount of orders placed for each variety
var account = {} // Variables used for recording current asset messages
var initAccount = {} // Variables used for recording initial asset messages
var currTradeMsg = {} // Variables used for recording whether current BAR trades
var lastPrices = {} // Variables used for recording the latest price of monitored varieties
var lastBarTime = {} // Variable used for recording the time of the last BAR, used to judge the update of BAR when drawing
var arrChartConfig = [] // Used for recording chart configuration message and draw
if (_G("currTradeMsg")) { // For example, restore currTradeMsg data when restarting
currTradeMsg = _G("currTradeMsg")
Log("Restore records", currTradeMsg)
}
// Initialize account
_.each(arrSymbols, function(symbol, index) {
exchange.SetCurrency(symbol)
var arrCurrencyName = symbol.split("_")
var baseCurrency = arrCurrencyName[0]
var quoteCurrency = arrCurrencyName[1]
if (quoteCurrency != "USDT") {
throw "only support quoteCurrency: USDT"
}
if (!account[baseCurrency] || !account[quoteCurrency]) {
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
}
// Initialize chart-related data
lastBarTime[symbol] = 0
arrChartConfig.push(createChartConfig(symbol, arrEma1Periods[index], arrEma2Periods[index]))
})
if (_G("initAccount")) {
initAccount = _G("initAccount")
Log("Restore initial account records", initAccount)
} else {
// Initialize the initAccount variable with the current asset information
_.each(account, function(val, key) {
initAccount[key] = val
})
}
Log("account:", account, "initAccount:", initAccount) // Print asset information
// Initialize the chart object
var chart = Chart(arrChartConfig)
// Chart reset
chart.reset()
// Strategy main loop logic
while (true) {
// Iterate through all varieties and execute the double-EMA logic one by one
_.each(arrSymbols, function(symbol, index) {
exchange.SetCurrency(symbol) // Switch the trading pair to the trading pair of symbol string record
var arrCurrencyName = symbol.split("_") // Split the trading pairs with the "_" symbol
var baseCurrency = arrCurrencyName[0] // String for trading currencies
var quoteCurrency = arrCurrencyName[1] // String for denominated currency
// Obtain the EMA parameters of the current trading pair according to the index
var ema1Period = parseFloat(arrEma1Periods[index])
var ema2Period = parseFloat(arrEma2Periods[index])
var amount = parseFloat(arrAmounts[index])
// Obtain the K-line data of the current trading pair
var r = exchange.GetRecords()
if (!r || r.length < Math.max(ema1Period, ema2Period)) { // Return directly if K-line length is insufficient
Sleep(1000)
return
}
var currBarTime = r[r.length - 1].Time // Record the current BAR timestamp
lastPrices[symbol] = r[r.length - 1].Close // Record the latest current price
var ema1 = TA.EMA(r, ema1Period) // Calculate EMA indicators
var ema2 = TA.EMA(r, ema2Period) // Calculate EMA indicators
if (ema1.length < 3 || ema2.length < 3) { // The length of EMA indicator array is too short, return directly
Sleep(1000)
return
}
var ema1Last2 = ema1[ema1.length - 2] // EMA on the penultimate BAR
var ema1Last3 = ema1[ema1.length - 3] // EMA on the third from the last BAR
var ema2Last2 = ema2[ema2.length - 2]
var ema2Last3 = ema2[ema2.length - 3]
// Write data to the chart
var klineIndex = index + 2 * index
// Iterate through the K-line data
for (var i = 0 ; i < r.length ; i++) {
if (r[i].Time == lastBarTime[symbol]) { // Draw the chart, update the current BAR and indicators
// update
chart.add(klineIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close], -1)
chart.add(klineIndex + 1, [r[i].Time, ema1[i]], -1)
chart.add(klineIndex + 2, [r[i].Time, ema2[i]], -1)
} else if (r[i].Time > lastBarTime[symbol]) { // Draw the charts, add BARs and indicators
// add
lastBarTime[symbol] = r[i].Time // Update timestamp
chart.add(klineIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close])
chart.add(klineIndex + 1, [r[i].Time, ema1[i]])
chart.add(klineIndex + 2, [r[i].Time, ema2[i]])
}
}
if (ema1Last3 < ema2Last3 && ema1Last2 > ema2Last2 && currTradeMsg[symbol] != currBarTime) {
// Golden cross
var depth = exchange.GetDepth() // Obtain the depth data of current order book
var price = depth.Asks[Math.min(takeLevel, depth.Asks.length)].Price // Take the 10th grade price, taker
if (depth && price * amount <= account[quoteCurrency]) { // Obtain deep data normally with enough assets to place an order
exchange.Buy(price, amount, ema1Last3, ema2Last3, ema1Last2, ema2Last2) // Place a buy order
cancelAll(exchange) // Cancel all makers
var acc = _C(exchange.GetAccount) // Obtain account asset information
if (acc.Stocks != account[baseCurrency]) { // Detect changes in account assets
account[baseCurrency] = acc.Stocks // Update assets
account[quoteCurrency] = acc.Balance // Update assets
currTradeMsg[symbol] = currBarTime // Record that the current BAR has been traded
_G("currTradeMsg", currTradeMsg) // Persistent records
var profit = getProfit(account, initAccount, lastPrices) // Calculate profits
if (profit) {
LogProfit(profit, account, initAccount) // Print profits
}
}
}
} else if (ema1Last3 > ema2Last3 && ema1Last2 < ema2Last2 && currTradeMsg[symbol] != currBarTime) {
// dead cross
var depth = exchange.GetDepth()
var price = depth.Bids[Math.min(takeLevel, depth.Bids.length)].Price
if (depth && amount <= account[baseCurrency]) {
exchange.Sell(price, amount, ema1Last3, ema2Last3, ema1Last2, ema2Last2)
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
if (acc.Stocks != account[baseCurrency]) {
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
currTradeMsg[symbol] = currBarTime
_G("currTradeMsg", currTradeMsg)
var profit = getProfit(account, initAccount, lastPrices)
if (profit) {
LogProfit(profit, account, initAccount)
}
}
}
}
Sleep(1000)
})
// Table variables in the status bar
var tbl = {
type : "table",
title : "Account Information",
cols : [],
rows : []
}
// Write data into the status bar table structure
tbl.cols.push("--")
tbl.rows.push(["initial"])
tbl.rows.push(["current"])
_.each(account, function(val, key) {
if (typeof(initAccount[key]) == "number") {
tbl.cols.push(key)
tbl.rows[0].push(initAccount[key]) // initial
tbl.rows[1].push(val) // current
}
})
// Show status bar table
LogStatus(_D(), "\n", "profit:", getProfit(account, initAccount, lastPrices), "\n", "`" + JSON.stringify(tbl) + "`")
}
}
یہ دیکھا جا سکتا ہے کہ ETH، LTC اور ETC کو ای ایم اے کے گولڈن کراس اور ڈیڈ کراس کے مطابق ٹرگر کیا جاتا ہے، اور ٹریڈنگ ہوئی ہے۔
ہم ٹیسٹنگ کے لیے ایک سمیلیٹر روبوٹ بھی لے سکتے ہیں۔
حکمت عملی کا ماخذ کوڈ:https://www.fmz.com/strategy/333783
حکمت عملی backtesting کے لئے استعمال کیا جاتا ہے، سیکھنے کی حکمت عملی ڈیزائن صرف، اور یہ حقیقی بوٹ میں احتیاط کے ساتھ استعمال کیا جانا چاہئے.