Mengajar anda untuk menulis strategi - menanam strategi MyLanguage

Penulis:Lydia, Dicipta: 2022-12-26 15:23:08, Dikemas kini: 2023-09-13 19:44:28

img

Mengajar anda menulis strategi menanam strategi MyLanguage

Baru-baru ini, ketika bercakap tentang strategi dengan rakan-rakan saya, saya belajar bahawa banyak strategi yang ditulis dalam MyLanguage mengalami fleksibiliti. Dalam banyak kes, adalah perlu untuk menggunakan tempoh K-line standard yang tidak disediakan oleh sistem. Sebagai contoh, keperluan maksimum adalah untuk menggunakan K-line selama 4 jam. Masalah ini telah diselesaikan dalam satu artikel. Jika anda berminat, sila lihat:Pautan. Walau bagaimanapun, dalam strategi MyLanguage, kerana ciri encapsulation tinggi MyLanguage, ia tidak fleksibel untuk memproses data sendiri. Pada masa ini, adalah perlu untuk memindahkan idea strategi ke bahasa lain.

Ia adalah sangat mudah untuk pemindahan strategi trend. kita boleh menggunakan kod contoh untuk mengisi dalam bahagian pengiraan data kod yang memandu strategi, dan mengisi dalam keadaan pencetus isyarat perdagangan.

Kod sampel yang boleh digunakan semula:

Ambil strategi untuk masa hadapan OKX sebagai contoh.

// Global variables
var IDLE = 0
var LONG = 1
var SHORT = 2
var OPENLONG = 3
var OPENSHORT = 4
var COVERLONG = 5
var COVERSHORT = 6  

var BREAK = 9
var SHOCK = 10  

var _State = IDLE
var Amount = 0                 // Record the number of positions
var TradeInterval = 500        // Polling intervals
var PriceTick = 1              // Price per jump
var Symbol = "this_week"  

function OnTick(){
    // Ticker processing part of the driving strategy
    // To be filled...
     
    // Trading signal trigger processing section
    // To be filled...  

    // Execution of trading logic
    var pos = null
    var price = null
    var currBar = records[records.length - 1]
    if(_State == OPENLONG){
        pos = GetPosition(PD_LONG)
        // Determine whether the state is satisfied, and if so, modify the state.
        if(pos[1] >= Amount){
            _State = LONG
            Amount = pos[1]   // Update the actual volume.
            return
        }
        price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2
        Trade(OPENLONG, price, Amount - pos[1], pos, PriceTick)                // (Type, Price, Amount, CurrPos, PriceTick)
    }  

    if(_State == OPENSHORT){
        pos = GetPosition(PD_SHORT)
        if(pos[1] >= Amount){
            _State = SHORT
            Amount = pos[1]   // Update the actual volume.
            return
        }
        price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
        Trade(OPENSHORT, price, Amount - pos[1], pos, PriceTick)
    }  

    if(_State == COVERLONG){
        pos = GetPosition(PD_LONG)
        if(pos[1] == 0){
            _State = IDLE
            return
        }
        price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
        Trade(COVERLONG, price, pos[1], pos, PriceTick)
    }
    
    if(_State == COVERSHORT){
        pos = GetPosition(PD_SHORT)
        if(pos[1] == 0){
            _State = IDLE
            return
        }
        price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2
        Trade(COVERSHORT, price, pos[1], pos, PriceTick)
    }
}  

// Trading logic section
function GetPosition(posType) {
    var positions = _C(exchange.GetPosition)
    var count = 0
    for(var j = 0; j < positions.length; j++){
        if(positions[j].ContractType == Symbol){
            count++
        }
    }  

    if(count > 1){
        throw "positions error:" + JSON.stringify(positions)
    }  

    for (var i = 0; i < positions.length; i++) {
        if (positions[i].ContractType == Symbol && positions[i].Type === posType) {
            return [positions[i].Price, positions[i].Amount];
        }
    }
    Sleep(TradeInterval);
    return [0, 0];
}  

function CancelPendingOrders() {
    while (true) {
        var orders = _C(exchange.GetOrders)
        for (var i = 0; i < orders.length; i++) {
            exchange.CancelOrder(orders[i].Id);
            Sleep(TradeInterval);
        }
        if (orders.length === 0) {
            break;
        }
    }
}  

function Trade(Type, Price, Amount, CurrPos, OnePriceTick){    // Processing transactions
    if(Type == OPENLONG || Type == OPENSHORT){                 // Processing of opening positions
        exchange.SetDirection(Type == OPENLONG ? "buy" : "sell")
        var pfnOpen = Type == OPENLONG ? exchange.Buy : exchange.Sell
        var idOpen = pfnOpen(Price, Amount, CurrPos, OnePriceTick, Type)
        Sleep(TradeInterval)
        if(idOpen) {
            exchange.CancelOrder(idOpen)
        } else {
            CancelPendingOrders()
        }
    } else if(Type == COVERLONG || Type == COVERSHORT){        // Processing of closing positions
        exchange.SetDirection(Type == COVERLONG ? "closebuy" : "closesell")
        var pfnCover = Type == COVERLONG ? exchange.Sell : exchange.Buy
        var idCover = pfnCover(Price, Amount, CurrPos, OnePriceTick, Type)
        Sleep(TradeInterval)
        if(idCover){
            exchange.CancelOrder(idCover)
        } else {
            CancelPendingOrders()
        }
    } else {
        throw "Type error:" + Type
    }
}  

function main() { 
    // Set up the contract
    exchange.SetContractType(Symbol)  

    while(1){
        OnTick()
        Sleep(1000)
    }
}

Contoh: Pemindahan strategi EMA berganda

Ujian belakang MyLanguage:

img

Kod strategi MyLanguage:

MA5^^MA(C,5);
MA15^^MA(C,15);
CROSSUP(MA5,MA15),BPK;
CROSSDOWN(MA5,MA15),SPK;

Memindahkan ke Strategi JavaScript

Pertama, isi bahagian pemerolehan ticker dan pengiraan penunjuk untuk kod sampel yang boleh digunakan semula:

// The ticker processing part of the driving strategy
var records = _C(exchange.GetRecords)  

if (records.length < 15) {
    return 
}  

var ma5 = TA.MA(records, 5)
var ma15 = TA.MA(records, 15)
var ma5_pre = ma5[ma5.length - 3]
var ma15_pre = ma15[ma15.length - 3]
var ma5_curr = ma5[ma5.length - 2]
var ma15_curr = ma15[ma15.length - 2]

Seperti yang anda lihat, strategi EMA berganda adalah sangat mudah.records, dan kemudian gunakan fungsi EMATA.MAdaripadaTA function libraryuntuk mengira 5-hari EMA dan 15-hari EMA (seperti yang kita boleh lihat dalam antara muka backtest, tempoh K-garis ditetapkan kepada harian K-garis, jadiTA.MA(records, 5)adalah untuk mengira EMA 5 hari,TA.MA(records, 15)adalah untuk mengira EMA 15 hari). Kemudian mendapatkan titik penutupma5_curr(nilai penunjuk), titik ketiga terakhirma5_pre(nilai petunjuk) data petunjukma5, dan sama juga untukma15Kemudian kita boleh menggunakan data penunjuk ini untuk menilai Golden Cross dan Bearish Crossover, seperti yang ditunjukkan dalam gambar:

img

Setiap kali keadaan seperti itu terbentuk, ia adalah Golden Cross atau Bearish Crossover yang pasti.

Kemudian bahagian menilai isyarat boleh ditulis seperti berikut:

if(_State == IDLE && ma5_pre < ma15_pre && ma5_curr > ma15_curr){     
    _State = OPENLONG
    Amount = 1
}  

if(_State == IDLE && ma5_pre > ma15_pre && ma5_curr < ma15_curr){     
    _State = OPENSHORT
    Amount = 1
}  

if(_State == LONG && ma5_pre > ma15_pre && ma5_curr < ma15_curr){     
    _State = COVERLONG
    Amount = 1
}  

if(_State == SHORT && ma5_pre < ma15_pre && ma5_curr > ma15_curr){     
    _State = COVERSHORT
    Amount = 1
}

Dengan cara ini, pemindahan OK. Ujian balik strategi JavaScript Konfigurasi pengujian balik:

img

Hasil ujian semula:

img

Ujian balik MyLanguage

img

Ia dapat dilihat bahawa hasil backtest hampir sama. Dengan cara ini, jika anda ingin terus menambah fungsi interaktif, pemprosesan data (seperti sintesis K-line), dan paparan carta tersuai kepada strategi, anda boleh mencapai ini.

Jika anda berminat, sila cuba.


Berkaitan

Lebih lanjut