রিসোর্স লোড হচ্ছে... লোডিং...

ডিজিটাল মুদ্রা স্পট মাল্টি-ভেরিটি ডাবল-ইএমএ কৌশল (টিউটোরিয়াল)

লেখক:এফএমজেড-লিডিয়া, সৃষ্টিঃ ২০২২-১১-০৮ ১২ঃ৫০ঃ৫৬, আপডেটঃ ২০২৩-০৯-১৫ ২০ঃ৫৭ঃ২৫

img

কমিউনিটি ব্যবহারকারীদের অনুরোধে যারা নকশা রেফারেন্সের জন্য একটি মাল্টি-ভেরিয়েটি ডাবল-ইএমএ কৌশল থাকতে চান। এই নিবন্ধে, আমরা একটি মাল্টি-ভেরিয়েটি ডাবল-ইএমএ কৌশল বাস্তবায়ন করব। কৌশল কোড সম্পর্কে মন্তব্যগুলি সুবিধাজনক বোঝার এবং শেখার জন্য লেখা হবে। প্রোগ্রামিং এবং পরিমাণগত ট্রেডিংয়ের আরও নতুনদের দ্রুত শুরু করতে দিন।

কৌশলগত ধারণা

ডাবল-ইএমএ কৌশলটির যুক্তি খুব সহজ, অর্থাৎ, দুটি ইএমএ। একটি ছোট প্যারামিটার সময়ের সাথে একটি ইএমএ (দ্রুত লাইন) এবং একটি বড় প্যারামিটার সময়ের সাথে একটি ইএমএ (ধীর লাইন) । যদি দুটি লাইনের একটি সোনার ক্রস থাকে (দ্রুত লাইনটি নীচে থেকে উপরের দিকে ধীর লাইনের মধ্য দিয়ে যায়), তবে আমরা কিনব এবং দীর্ঘ যাই; এবং যদি দুটি লাইনের একটি মৃত ক্রস থাকে (দ্রুত লাইনটি উপরে থেকে নীচে ধীর লাইনের মধ্য দিয়ে যায়), তবে আমরা বিক্রি করি এবং সংক্ষিপ্ত যাই। আমরা এখানে ইএমএ ব্যবহার করি।

যাইহোক, কৌশলটি মাল্টি-বৈচিত্র্য হিসাবে ডিজাইন করা উচিত, তাই প্রতিটি জাতের পরামিতি ভিন্ন হতে পারে (বিভিন্ন জাতের বিভিন্ন EMA পরামিতি ব্যবহার করে), তাই একটি প্যারামিটার গ্রুপ পদ্ধতি ব্যবহার করা উচিত পরামিতি ডিজাইন করতে।

img

প্যারামিটারগুলি স্ট্রিং ফর্মে ডিজাইন করা হয়েছে, প্রতিটি প্যারামিটার কমা পৃথক করে। কৌশলটি চালানো শুরু করার সময় এই স্ট্রিংগুলি বিশ্লেষণ করুন। কার্যকরকরণ যুক্তি প্রতিটি বৈচিত্র্যের সাথে মেলে (ট্রেডিং জোড়া) । কৌশল ঘোরানো প্রতিটি বৈচিত্র্যের বাজার সনাক্ত করে, ট্রেডিং শর্তগুলির ট্রিগার, চার্ট মুদ্রণ ইত্যাদি। সমস্ত বৈচিত্র্য একবার ঘোরানোর পরে, ডেটা সংক্ষিপ্ত করুন এবং স্থিতি বারে টেবিলের তথ্য প্রদর্শন করুন।

কৌশলটি খুব সহজ এবং নতুনদের শেখার জন্য উপযুক্ত, মোট মাত্র 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) + "`")
    }
}

কৌশল ব্যাকটেস্ট

img

img

img

এটা দেখা যাচ্ছে যে ইটিএইচ, এলটিসি এবং ইটিসি ইএমএর গোল্ডেন ক্রস এবং ডেড ক্রস অনুসারে ট্রিগার করা হয় এবং ট্রেডিং হয়েছে।

আমরা পরীক্ষার জন্য সিমুলেশন বটও নিতে পারি।

কৌশল উৎস কোডঃhttps://www.fmz.com/strategy/333783

কৌশলটি ব্যাকটেস্টিং, শেখার কৌশল ডিজাইনের জন্য ব্যবহার করা হয়, এবং এটি বাস্তব বটে সতর্কতার সাথে ব্যবহার করা উচিত।


আরো