संसाधन लोड हो रहा है... लोड करना...

नोट्स और फ्यूचर्स रिवर्स डबलिंग एल्गोरिथ्म रणनीति की व्याख्या

लेखक:निनाबादास, बनाया गयाः 2022-04-27 15:44:04, अद्यतन किया गयाः 2022-04-28 12:05:02

नोट्स और फ्यूचर्स रिवर्स डबलिंग एल्गोरिथ्म रणनीति की व्याख्या

यह रणनीति एक रणनीति है जो बहुत पहले क्रिप्टोक्यूरेंसी 796 फ्यूचर्स एक्सचेंज पर लागू थी। वायदा अनुबंध क्रिप्टो-मार्जिन है, अर्थात, मार्जिन मुद्रा से घटाया जाता है (उदाहरण के लिए, बीटीसी अनुबंधों में, यह बीटीसी से घटाया जाता है), और अनुबंध आदेश राशि दशमलव हो सकती है, जो कि बिनेंस क्रिप्टो-मार्जिन अनुबंध के समान है। रणनीति को रणनीति डिजाइन अध्ययन के लिए लिया जाता है, तर्क प्रसंस्करण अभी भी बहुत अच्छा है, इसलिए रणनीति मुख्य रूप से सीखने के लिए है।

रणनीति कोड नोट्सः

var FirstTradeType = [ORDER_TYPE_BUY, ORDER_TYPE_SELL][OpType];   // the opening direction of the first trade is determined by the opening direction of the parameter OpType, and the value of the global variable FirstTradeType is ORDER_TYPE_BUY or ORDER_TYPE_SELL
var OrgAccount = null;                                            // the global variable, to record the account assets  
var Counter = {s : 0, f: 0};                                      // declare the variable Counter; its value is initialized as an object (similar structure in Python is called dictionary); "s" represents the number of win, and "f" represents the number of failure
var LastProfit = 0;                                               // the recent profit and loss 
var AllProfit = 0;                                                // the total rofit and loss 
var _Failed = 0;                                                  // the number of stop loss 

// Cancel all orders except the order of a certain ID in the pending order list. When the orderId parameter is not passed, all pending orders of the current trading pair are cancelled. The parameter "e" is the reference of the exchange object. For example, import exchange as parameter, "e" is now the alias of exchange
function StripOrders(e, orderId) {                                
    var order = null;                               // the initialization variable "order" is null  
    if (typeof(orderId) == 'undefined') {           // If the parameter orderId is not written, then typeof(orderId) == 'undefined' is true, and the code block of the if statement is executed, and the orderId is assigned to null
        orderId = null;
    }
    while (true) {                                  // processing loop 
        var dropped = 0;                            // the number of processing marks 
        var orders = _C(e.GetOrders);               // call GetOrders to obtain the current pending orders (not executed orders), and assign to orders
        for (var i = 0; i < orders.length; i++) {   // traverse the list of unexecuted orders "orders"
            if (orders[i].Id == orderId) {          // if the order ID is the same as the ID in the parameter "orderId", the local variable "order" assign a value to orders[i], which is the current order structure when traversing 
                order = orders[i];
            } else {                                // if the order ID is not the same as the ID in the parameter "orderId", execute the cancellation operation  
                var extra = "";                     // according to part of executed situation, set the extending information "extra"
                if (orders[i].DealAmount > 0) {
                    extra = "Executed:" + orders[i].DealAmount;
                } else {
                    extra = "Unexecuted:";
                }
                e.SetDirection(orders[i].Type == ORDER_TYPE_BUY ? "buy" : "sell");
                e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "buy order" : "sell order", extra);    // cancellation operation along with exporting "extra" information, which will be displayed in logs 
                dropped++;                           // dropped, accumulated counts
            }
        }
        if (dropped == 0) {                          // when the traverse is done, "dropped" is equal to 0, namely no cancellation processing during the traverse (which means no order to be canceled); that is to say the cancellation processing is done, and break out of the loop 
            break;
        }
        Sleep(300);                                  // prevent over fast rotating frequency; create a time interval 
    }
    return order;                                    // return the order that needs to be found 
}


var preMsg = "";                                      // the variable to record the cached information 
function GetAccount(e, waitFrozen) {                  // to get account asset information; parameter e is also a reference to exchange, and parameter waitFrozen controls whether to wait for freezing
    if (typeof(waitFrozen) == 'undefined') {          // if the parameter waitFrozen is not passed in the call, assign false to the parameter waitFrozen, that is, the default is no waiting for freezing
        waitFrozen = false;
    }
    var account = null;
    var alreadyAlert = false;                         // the varibale to mark whether it already alerted 
    while (true) {                                    // to obtain the account information and detect frozen; if no wait for freezing, break the while loop directly 
        account = _C(e.GetAccount);
        if (!waitFrozen || account.FrozenStocks < MinStock) {
            break;
        }
        if (!alreadyAlert) {
            alreadyAlert = true;                      // trigger the alert once, and then reset alreadyAlert to avoid repeating alert 
            Log("frozen assets or symbols are found in the account", account);       // export the alert log 
        }
        Sleep(Interval);
    }
    msg = "Success: " + Counter.s + " times, failure: " + Counter.f + " times, the current account symbols: " + account.Stocks;
    if (account.FrozenStocks > 0) {
        msg += " frozen symbols: " + account.FrozenStocks;
    }

    if (msg != preMsg) {                              // detect whether the current information is the same as that last time; if not, update the informtaion on the status bar 
        preMsg = msg;
        LogStatus(msg, "#ff0000");
    }
    return account;                                   // the function returns the account stucture of the account information 
}

function GetPosition(e, orderType) {                  // obtain positions, or obtain the positions with specified direction (orderType)
    var positions = _C(e.GetPosition);                // obtain positions 
    if (typeof(orderType) == 'undefined') {           // the parameter orderType is to specify the position type; if the parameter is not imported, directly return all positions
        return positions;
    }
    for (var i = 0; i < positions.length; i++) {      // traverse the list of positions 
        if (positions[i].Type == orderType) {         // if the traversed current position data is the direction (orderType) we need 
            return positions[i];                      // return positions of orderType
        }
    }
    return null;
}

function GetTicker(e) {                               // obtain ticker market data 
    while (true) {
        var ticker = _C(e.GetTicker);                 // obtain tick market data
        if (ticker.Buy > 0 && ticker.Sell > 0 && ticker.Sell > ticker.Buy) {   // detect the reliability of the market data 
            return ticker;                            // return ticker data 
        }
        Sleep(100);
    }
}
// mode = 0 : direct buy, 1 : buy as buy1
function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxSpace, retryDelay) {      // trading function 
    // e for exchange object reference, tradeType for trade direction (buy/sell), tradeAmount for the trading amount, mode for trading mode, slidePrice for slippoint price, maxSpace for maximum pending order distance, and retryDelay for retry interval
    var initPosition = GetPosition(e, tradeType);      // obtain the position data with a specified direction, recorded as initPosition
    var nowPosition = initPosition;                    // declare another variable "nowPosition", assigned by "initPosition
    var orderId = null;
    var prePrice = 0;            // the ordering price in the loop last time 
    var dealAmount = 0;          // executed trading amount 
    var diffMoney = 0;           
    var isFirst = true;          // mark of initially executing the loop 
    var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell;     // the function of placing orders; according to the parameter tradeType, determine to call e.Buy or e.Sell
    var isBuy = tradeType == ORDER_TYPE_BUY;                          // whether it is the buy mark
    while (true) {                                                    // while loop
        var account = _C(e.GetAccount);                               // obtain the current account asset data 
        var ticker = GetTicker(e);                                    // obtain the current market data 
        var tradePrice = 0;                                           // determine a trading price based on the parameter mode
        if (isBuy) {
            tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4);
        } else {
            tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4);
        }
        if (orderId == null) {
            if (isFirst) {                                            // according to the  mark variable isFirst to judge, if it is the first execution, nothing will be done 
                isFirst = false;                                      // if the mark isFirst is set to false, it means it is not the first execution 
            } else {                                                  // not the first executin, so update the position data 
                nowPosition = GetPosition(e, tradeType);
            }
            dealAmount = _N((nowPosition ? nowPosition.Amount : 0) - (initPosition ? initPosition.Amount : 0), 6);   // by the initial position data and the current position data, calculate the executed amount 
            var doAmount = Math.min(tradeAmount - dealAmount, account.Stocks * MarginLevel, 4);      // by the executed amount and the account available assets, calculate the rest amount that needs to be traded 
            if (doAmount < MinStock) {                                                               // if the calculated trading amount is less than the minimum of the executed amount, terminate the logic and break the while loop 
                break;
            }
            prePrice = tradePrice;                                                                   // cache the trading price in the current round of loop 
            e.SetDirection(tradeType == ORDER_TYPE_BUY ? "buy" : "sell");                            // set futures trading direction 
            orderId = tradeFunc(tradePrice, doAmount);                                               // trade of placing orders; its parameters are the calculated price and the order amount of this time
        } else {                                                                                     // when the order recording variable "orderId" is not null, it means the orders has been placed  
            if (mode == 0 || Math.abs(tradePrice - prePrice) > maxSpace) {                           // if it is the mode of pending orders, the current price and the price cached last time exceed the maximum pending order range  
                orderId = null;                                                                      // reset orderId to null, and restart to place orders in next round of loop 
            }
            var order = StripOrders(exchange, orderId);                                              // call StripOrders to find the order with ID of orderId in the pending order list 
            if (order == null) {                                                                     // if not found, reset orderId to null, and continue the next round of placing orders  
                orderId = null;
            }
        }
        Sleep(retryDelay);                                                                           // temporarily specify a certain time, to control the loop frequency 
    }

    if (dealAmount <= 0) {                                                                           // after the while loop is finished, if the executed amount "dealAmount" is less than or equal to 0, that means the trade is a failure, and return null
        return null;
    }

    return nowPosition;                                                                              // under normal circumstances, return the latest position data 
}

function coverFutures(e, orderType) {                               // function of closing positions 
    var coverAmount = 0;                                            // declare a variable coverAmount, with the default of 0, to record the amount already closed 
    while (true) {
        var positions = _C(e.GetPosition);                          // obtain positions 
        var ticker = GetTicker(e);                                  // obtain the current market quotes 
        var found = 0;                                              // search for marks 
        for (var i = 0; i < positions.length; i++) {                // traverse the array of holding positions, namely "positions"
            if (positions[i].Type == orderType) {                   // find the positions that are needed 
                if (coverAmount == 0) {                             
                    coverAmount = positions[i].Amount;              // initially record the position amount, namely the amount to be closed 
                }
                if (positions[i].Type == ORDER_TYPE_BUY) {          // execute the operation of closing positions, according to position type 
                    e.SetDirection("closebuy");                     // set the futures trading direction 
                    e.Sell(ticker.Buy, positions[i].Amount);        // function of placing orders 
                } else {
                    e.SetDirection("closesell");
                    e.Buy(ticker.Sell, positions[i].Amount);
                }
                found++;                                            // mark the accumulation 
            }
        }
        if (found == 0) {                                           // if the mark variable found is 0, it means no position to be processed, and then break out of the while loop
            break;
        }
        Sleep(2000);                                                // interval time of 2 seconds
        StripOrders(e);                                             // cancel all pending orders 
    }
    return coverAmount;                                             // return the amount of closing positions 
}


function loop(pos) {
    var tradeType = null;                         // initialize the trading direction 
    if (typeof(pos) == 'undefined' || !pos) {     //judge whether it is the initial round of execution
        tradeType = FirstTradeType;
        pos = Trade(exchange, tradeType, OpAmount, OpMode, SlidePrice, MaxSpace, Interval);     // initial trade 
        if (!pos) {
            throw "Rough start, fail to open positions";
        } else {
            Log(tradeType == ORDER_TYPE_BUY ? "opening long positions completed" : "Opening short positions completed", "Average price:", pos.Price, "Amount:", pos.Amount);
        }
    } else {
        tradeType = pos.Type;        // continue to specify the trading direction according to position direction 
    }
    var holdPrice = pos.Price;       // position price 
    var holdAmount = pos.Amount;     // position amount 

    var openFunc = tradeType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell;     // long positions; open positions to buy; if not, open positions to sell
    var coverFunc = tradeType == ORDER_TYPE_BUY ? exchange.Sell : exchange.Buy;    // long positions; close positions to sell; if not, close positions to buy 

    var reversePrice = 0;           // reverse price
    var coverPrice = 0;             // closing position price
    var canOpen = true;             //  mark for enabling opening positions 

    if (tradeType == ORDER_TYPE_BUY) {                         
        reversePrice = _N(holdPrice * (1 - StopLoss), 4);     // stop loss price
        coverPrice = _N(holdPrice * (1 + StopProfit), 4);     // take profit price
    } else {
        reversePrice = _N(holdPrice * (1 + StopLoss), 4);
        coverPrice = _N(holdPrice * (1 - StopProfit), 4);
    }

    var coverId = null;
    var msg = "position price:" + holdPrice + " stopLoss price:" + reversePrice;

    for (var i = 0; i < 10; i++) {               // control to order 10 times maximum
        if (coverId) {                           // when the order ID is null, and break will not be triggered, continue the loop, until to the maximum of 10 times 
            break;
        }
        if (tradeType == ORDER_TYPE_BUY) {       // according to the order direction, pend orders to close, namely the take profit orders 
            exchange.SetDirection("closebuy");
            coverId = exchange.Sell(coverPrice, holdAmount, msg);
        } else {
            exchange.SetDirection("closesell");
            coverId = exchange.Buy(coverPrice, holdAmount, msg);
        }

        Sleep(Interval);
    }

    if (!coverId) {                // raise the error after 10 times of order failure, and stop the strategy 
        StripOrders(exchange);     // cancel all pending orders
        Log("fail to order", "@")        // add push alert 
        throw "fail to order";           // raise the error, and stop the bot 
    }


    while (true) {                 // enter to detect the reverse loop
        Sleep(Interval);           
        var ticker = GetTicker(exchange);                                // obtain the latest market quotes 
        if ((tradeType == ORDER_TYPE_BUY && ticker.Last < reversePrice) || (tradeType == ORDER_TYPE_SELL && ticker.Last > reversePrice)) {   // detect the trigger of stoploss, namely reverse 
            StripOrders(exchange);                                       // cancel all pending orders 
            var coverAmount = coverFutures(exchange, tradeType);         // close all positions 
            if (_Failed >= MaxLoss) {                                    // if the maximum number of stoploss (reverse times) is exceeded, break the loop and restart again  
                Counter.f++;                                             // counted as one failure 
                Log("exceed the maximum number of failures", MaxLoss);
                break;                                                   // break out of the loop
            }
            var reverseAmount = _N(coverAmount * ReverseRate, 4);        // according to the closing position amount, double the trading amount  

            var account = GetAccount(exchange, true);                    // update the account information, and here frozen assets are forbidden  
            // detect whether the assets are enough; if not, break the loop, and restart, such as _Failed >= MaxLoss
            if (_N(account.Stocks * MarginLevel, 4) < reverseAmount) {   // detect whether the assets are enough 
                Log("open positions without currency, need to open positions:", reverseAmount, "currency symbols, and there are only ", account.Stocks, "currency symbols");
                Counter.f++;
                break;
            }
            var reverseType = tradeType;                                 // record the type of the reverse operation; the default is forward
            if (ReverseMode == 0) {                                      // the adjustment of the reverse mode, that is, if the parameter is set to reverse, the adjustment is needed here  
                reverseType = tradeType == ORDER_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; // reverse indicates if the positions just now are long, the reverse now will do short; if the positions just now are short, the reverse now will do long 
            }
            var pos = Trade(exchange, reverseType, reverseAmount, OpMode, SlidePrice, MaxSpace, Interval);    // double the operation of placing orders 
            if (pos) {                                                                                        // detect the positions after the execution of the trading logic  
                Log(reverseType == ORDER_TYPE_BUY ? "long position" : "short position", "double open positions completed");
            }
            return pos;                                                                                       // return the position structure 
        } else {                                          // the trading logic executed when the reverse is not triggered 
            var orders = _C(exchange.GetOrders);          // when the take-profit pending orders are executed, add 1 to the number of win 
            if (orders.length == 0) {
                Counter.s++;
                var account = GetAccount(exchange, true); // update the account assets 
                LogProfit(account.Stocks, account);       // print the account assets 
                break;
            }
        }
    }

    // if the return is normal in a non-while loop, null is returned, such as successful take-profit, exceeding the number of failures, insufficient assets
    return null;
}

function onexit() {          // when the bot is stopped, execute the onexit function
    StripOrders(exchange);   // cancel all pending orders 
    Log("Exit");
}

function main() {
    if (exchange.GetName().indexOf("Futures") == -1) {    // detect whether the currently first added exchange object is a futures platform 
        throw "only support futures, and spot not supported temporarily";
    }
    // EnableLogLocal(SaveLocal);
    if (exchange.GetRate() != 1) {                        // disable the exchange rateconverting  
        Log("disable exchange rate converting");
        exchange.SetRate(1);
    }

    StopProfit /= 100;                                    // the parameter is processed to be decimal; assuming that StopProfit is 1, namely 1% of take-profit, recalculate the assignment and the value of StopProfit is 0.01, namely 1%.
    StopLoss /= 100;                                      // stop loss (reverse), as above 

    var eName = exchange.GetName();
    if (eName == "Futures_CTP") {                         // detect whether the currently first added exchange object is commodity futures ; if it is, raise an error to stop the bot 
        throw "temporarily only support cryptocurrency futures"
    }
    exchange.SetContractType(Symbol);                     // set the code of the cryptocurrency contract, namely the contract to be traded and operated 
    exchange.SetMarginLevel(MarginLevel);                 // set margin level 
    Interval *= 1000;                                     // change the polling interval parameter from second to millisecond 
    SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF");    // set the type of the error filtered 
    StripOrders(exchange);                                // cancel all pending orders 
    OrgAccount = GetAccount(exchange, true);              // obtain the current account information 
    LogStatus("start successfully");                                 // update the status bar information 
    var pos = null;                                       // initialize the variable pos to null in the main function, to record the position data structure 
    var positions = GetPosition(exchange);                // obtaining the current positions is to call the encapsulated GetPosition without orderType, to obtain all positions held; note that here the called function is not "exchange.GetPosition" of API interface 
    if (positions.length == 1) {                          // if there are positions at the beginning, assign the value to the variable pos 
        pos = positions[0];
        Log("found 1 position, and already rcovered the process automatically");
    } else if (positions.length > 1) {                    // when there are multiple positions, that is, the status in which the strategy cannot run, the strategy raises an error to make the bot stop  
        throw "found over 1 position ";
    }
    while (true) {                                        // strategy main loop 
        pos = loop(pos);                                  // execute the main function loop in the trading logic; take pos as parameter; return the new position data structure 
        if (!pos) {                                       // under the circumstance if the condition is triggered, and return null, such as the success of take-profit, exceeding the number of failures, and inadequate assets 
            _Failed = 0;                                  // reset the number of stop loss to 0, and restart it 
        } else {
            _Failed++;                                    // the accumulated number of stop loss
        }
        Sleep(Interval);
    }
}

रणनीति तर्क

रणनीति कोड पढ़ने के बाद, आप पा सकते हैं कि रणनीति तर्क जटिल नहीं है, और कोड बहुत ज्यादा नहीं है, लेकिन डिजाइन सरल है और इसके कई हिस्सों का उपयोग संदर्भ के लिए किया जा सकता है। रणनीति व्यापार तर्क का मुख्य कार्य हैloopसमारोह है, जो बार-बार मुख्य लूप में बुलाया जाता हैmainकार्य।loopफ़ंक्शन शुरू होता है, पहले पदों को पकड़ने के लिए ऑर्डर रखें, और फिर लाभ लेने के आदेशों को पेंड करें और स्टॉप-प्रॉफिट ऑर्डर के निष्पादन की प्रतीक्षा करें। फिर, निम्नलिखित दो सामग्री का पता लगाने के लिए पता लगाने की स्थिति दर्ज करें।

  • यह पता लगाने के लिए कि क्या लंबित लाभ लेने के आदेश निष्पादित किए जाते हैं; यदि लाभ लेने के आदेश निष्पादित किए जाते हैं, तो इसका मतलब है कि लाभ अर्जित किया गया है, इसलिए पता लगाने के लूप से बाहर निकलें, तर्क को रीसेट करें, और फिर से शुरू करें।
  • यह पता लगाने के लिए कि क्या स्टॉप-लॉस (रिवर्स) ट्रिगर किया गया है; यह यह ट्रिगर किया गया है, जिसका अर्थ है सभी लंबित आदेशों को रद्द करना, और पदों को बंद करना, और फिर रिवर्स ऑर्डर ट्रेडों को दोगुना करना, यह देखते हुए कि क्या पैरामीटर रिवर्स या फॉरवर्ड पर सेट किया गया है। पद हैं, लंबित ले-प्रॉफिट ऑर्डर जारी रखें, और फिर से पता लगाने की स्थिति दर्ज करें (ले-प्रॉफिट, रिवर्स की निगरानी) ।

रणनीतिक तर्क का वर्णन सरलता से किया गया है, लेकिन अभी भी कुछ अन्य विवरण हैं, जैसे कि अधिकतम रिवर्स की संख्या निर्धारित करना, उपलब्ध खाता परिसंपत्तियों का पता लगाना और अधिकतम विफलताओं की संख्या को 10 गुना तक संसाधित करना। रणनीति में कुछ कार्यों को विभिन्न मापदंडों के अनुसार अलग-अलग प्रदर्शन करने के लिए डिज़ाइन किया गया है, जैसेःStripOrdersकार्य,GetAccountकार्य,GetPositionइन कार्यों में आयातित मापदंडों के अंतर के आधार पर अलग-अलग क्रियाएं होती हैं। यह कोड का अच्छा उपयोग करता है, और कोड अतिरेक से बचता है, और रणनीति डिजाइन को संक्षिप्त और समझने में आसान बनाता है।

मूल रणनीति:https://www.fmz.com/strategy/3648

दोगुनी रिवर्स में कुछ जोखिम हैं, विशेष रूप से वायदा में; रणनीति केवल अध्ययन के लिए है, और कृपया इसे सावधानी से उपयोग करें। चर्चा के लिए संदेश छोड़ने के लिए आपका स्वागत है।


अधिक