Digital Currency Futures Double-EMA Turning Point Strategy (Tutorial-1)

in fmz •  last year 

In this article, we will explain how to design a simple trending strategy, only at the strategy design level, to help beginners learn how to design a simple strategy and understand the strategy execution process. The performance of the strategy is largely related to the strategy parameters (as is the case with almost all trending strategies).

Strategy design

We use two EMA indicators when both EMA averages have turning points. The turning point is used as a signal to open positions (or sell the opening position) for opening long, opening short positions, and a fixed target profit differential position closing is designed. The comments are written directly in the strategy code for convenient reading. The strategy code is generally very short and suitable for beginners to learn.

Strategy code

/*backtest
start: 2021-09-01 00:00:00
end: 2021-12-02 00:00:00
period: 1h
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

// The above /**/ is the default setting for backtesting, you can reset it on the backtesting page by using the relevant controls

var LONG = 1       // Markers for holding long positions, enum constant
var SHORT = -1     // Markers for holding short positions, enum constant
var IDLE = 0       // Markers without holding positions, enum constant

// Obtain positions in the specified direction. Positions is the position data, and direction is the position direction to be obtained
function getPosition(positions, direction) {
    var ret = {Price : 0, Amount : 0, Type : ""}    // Define a structure when no position is held
    // Iterate through the positions and find the positions that match the direction
    _.each(positions, function(pos) {
        if (pos.Type == direction) {
            ret = pos
        }
    })
    // Return to found positions
    return ret 
}

// Cancel all makers of current trading pairs and contracts
function cancellAll() {
    // Dead loop, keep detecting until break is triggered
    while (true) {
        // Obtain the makers' data of the current trading pair and contract, i.e. orders
        var orders = _C(exchange.GetOrders)
        if (orders.length == 0) {
            // When orders is an empty array, i.e. orders.length == 0, break is executed to exit the while loop
            break
        } else {
            // Iterate through all current makers and cancel them one by one
            for (var i = 0 ; i < orders.length ; i++) {
                // The function to cancel the specific order, cancel the order with ID: orders[i].Id
                exchange.CancelOrder(orders[i].Id, orders[i])
                Sleep(500)
            }
        }
        Sleep(500)
    }
}

// The closing function, used for closing positions according to the trading function-tradeFunc and direction passed in
function cover(tradeFunc, direction) {
    var mapDirection = {"closebuy": PD_LONG, "closesell": PD_SHORT}
    var positions = _C(exchange.GetPosition)  //Obtain the position data of the current trading pair and contract
    var pos = getPosition(positions, mapDirection[direction])  // Find the position information in the specified closing position direction
    // When the position is greater than 0 (the position can be closed only when there is a position)
    if (pos.Amount > 0) {
        // Cancel all possible makers
        cancellAll()
        // Set the trading direction
        exchange.SetDirection(direction)
        // Execute closing position trade functions
        if (tradeFunc(-1, pos.Amount)) {
            // Return to true if the order is placed
            return true 
        } else {
            // Return to false if the order is failed to place
            return false 
        }
    }
    // Return to true if there is no position
    return true 
}

// Strategy main functions
function main() {
    // For switching to OKEX V5 Demo
    if (okexSimulate) {
        exchange.IO("simulate", true) // Switch to OKEX V5 Demo for a test 
        Log("Switch to OKEX V5 Demo")
    }    
    
    // Set the contract code, if ct is swap, set the current contract to be a perpetual contract
    exchange.SetContractType(ct)
    // Initialization status is open position
    var state = IDLE
    // The initialized position price is 0
    var holdPrice = 0
    // Timestamp for initialization comparison, used to compare whether the current K-Line BAR has changed
    var preTime = 0

To be continued...

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!