Les ressources ont été chargées... Je charge...

Stratégie du point de basculement des contrats à terme sur devises numériques à double EMA (tutoriel)

Auteur:FMZ~Lydia, Créé à: 2022-11-09 09:44:38, Mis à jour à: 2023-09-20 10:25:53

img

Dans cet article, nous expliquerons comment concevoir une stratégie de tendance simple, uniquement au niveau de la conception de la stratégie, pour aider les débutants à apprendre à concevoir une stratégie simple et à comprendre le processus d'exécution de la stratégie.

Conception de la stratégie

Nous utilisons deux indicateurs EMA lorsque les deux moyennes EMA ont des points tournants. Le point tournant est utilisé comme un signal pour ouvrir des positions (ou vendre la position d'ouverture) pour ouvrir des positions longues, ouvrir des positions courtes, et une position de clôture différentielle de profit cible fixe est conçue. Les commentaires sont écrits directement dans le code de stratégie pour une lecture pratique.

Code de stratégie

/*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
    
    // Strategy main loop
    while (true) {
        // Obtain the K-line data for current trading pairs and contracts
        var r = _C(exchange.GetRecords)
        // Obtain the length of the K-line data, i.e. l
        var l = r.length
        // Judge the K-line length that l must be greater than the indicator period (if not, the indicator function cannot calculate valid indicator data), or it will be recycled
        if (l < Math.max(ema1Period, ema2Period)) {
            // Wait for 1,000 milliseconds, i.e. 1 second, to avoid rotating too fast
            Sleep(1000)
            // Ignore the code after the current if, and execute while loop again
            continue
        }
        
        // Calculate ema indicator data
        var ema1 = TA.EMA(r, ema1Period)
        var ema2 = TA.EMA(r, ema2Period)
        
        // Drawing chart
        $.PlotRecords(r, 'K-Line')    // Drawing the K-line chart
        // When the last BAR timestamp changes, i.e. when a new K-line BAR is created
        if(preTime !== r[l - 1].Time){
            // The last update of the last BAR before the new BAR appears
            $.PlotLine('ema1', ema1[l - 2], r[l - 2].Time)
            $.PlotLine('ema2', ema2[l - 2], r[l - 2].Time)
            
            // Draw the indicator line of the new BAR, i.e. the indicator data on the current last BAR
            $.PlotLine('ema1', ema1[l - 1], r[l - 1].Time)
            $.PlotLine('ema2', ema2[l - 1], r[l - 1].Time)
            
            // Update the timestamp used for comparison
            preTime = r[l - 1].Time
        } else {
            // When no new BARs are generated, only the indicator data of the last BAR on the chart is updated
            $.PlotLine('ema1', ema1[l - 1], r[l - 1].Time)
            $.PlotLine('ema2', ema2[l - 1], r[l - 1].Time)
        }
        
        // Conditions for opening long positions, turning points
        var up = (ema1[l - 2] > ema1[l - 3] && ema1[l - 4] > ema1[l - 3]) && (ema2[l - 2] > ema2[l - 3] && ema2[l - 4] > ema2[l - 3])
        // Conditions for opening short positions, turning points
        var down = (ema1[l - 2] < ema1[l - 3] && ema1[l - 4] < ema1[l - 3]) && (ema2[l - 2] < ema2[l - 3] && ema2[l - 4] < ema2[l - 3])
        
        // The condition of opening a long position is triggered and the current short position is held, or the condition of opening a long position is triggered and no position is held
        if (up && (state == SHORT || state == IDLE)) {
            // If you have a short position, close it first
            if (state == SHORT && cover(exchange.Buy, "closesell")) {
                // Mark open positions after closing them
                state = IDLE
                // The price of reset position is 0
                holdPrice = 0
                // Mark on the chart
                $.PlotFlag(r[l - 1].Time, 'coverShort', 'CS')
            }
            // Open a long position after closing the position
            exchange.SetDirection("buy")
            if (exchange.Buy(-1, amount)) {
                // Mark the current status
                state = LONG
                // Record the current price
                holdPrice = r[l - 1].Close
                $.PlotFlag(r[l - 1].Time, 'openLong', 'L')
            }
        } else if (down && (state == LONG || state == IDLE)) {
            // The same as the judgment of up condition
            if (state == LONG && cover(exchange.Sell, "closebuy")) {
                state = IDLE
                holdPrice = 0
                $.PlotFlag(r[l - 1].Time, 'coverLong', 'CL')
            }
            exchange.SetDirection("sell")
            if (exchange.Sell(-1, amount)) {
                state = SHORT
                holdPrice = r[l - 1].Close
                $.PlotFlag(r[l - 1].Time, 'openShort', 'S')
            }
        }
        
        // Stop profits
        if (state == LONG && r[l - 1].Close - holdPrice > profitTarget && cover(exchange.Sell, "closebuy")) {            
            state = IDLE
            holdPrice = 0
            $.PlotFlag(r[l - 1].Time, 'coverLong', 'CL')
        } else if (state == SHORT && holdPrice - r[l - 1].Close > profitTarget && cover(exchange.Buy, "closesell")) {            
            state = IDLE
            holdPrice = 0
            $.PlotFlag(r[l - 1].Time, 'coverShort', 'CS')
        }
        // Display time on the status bar
        LogStatus(_D())
        Sleep(500)        
    }
}

img

img

Le code source de la stratégie:https://www.fmz.com/strategy/333269

La stratégie est pour le tutoriel de conception de programme seulement, s'il vous plaît ne l'utilisez pas dans le vrai bot.


Relationnée

Plus de