Tangan mengajar anda menulis strategi -- mentransfer strategi dalam bahasa saya.

Penulis:Mimpi kecil, Dicipta: 2019-10-21 14:59:12, Dikemas kini: 2023-10-17 21:22:56

img

Tangan mengajar anda menulis strategi dan mentransplantasikan strategi bahasa saya.

Baru-baru ini, ketika berbual dengan rakan saya mengenai strategi, saya mendapati bahawa terdapat banyak masalah yang bermasalah dengan penggunaan strategi penulisan bahasa saya. Dalam banyak kes, anda perlu menggunakan kitaran K baris standard yang disediakan oleh bukan sistem, contohnya, yang paling banyak dikemukakan adalah penggunaan K baris 4 jam. Masalah ini telah diselesaikan dalam satu artikel, yang menarik untuk dilihat terlebih dahulu:PautanWalau bagaimanapun, masalah ini berlaku dalam strategi bahasa saya kerana sifat pembungkusan bahasa saya yang tinggi dan tidak dapat memproses data sendiri secara fleksibel. Pada masa ini, perlu memindahkan idea strategi ke bahasa lain.

Untuk mentransfer strategi trend adalah sangat mudah, kita boleh menggunakan sekumpulan kod contoh untuk mengisi sebahagian kod pengiraan data yang memandu strategi dan mengisi syarat pencetus isyarat dagangan.

Contoh kod yang boleh digunakan semula:

Sebagai contoh, strategi yang digunakan untuk OKEX berjangka.

// 全局变量
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                 // 记录持仓数量
var TradeInterval = 500        // 轮询间隔
var PriceTick = 1              // 价格一跳
var Symbol = "this_week"  

function OnTick(){
    // 驱动策略的行情处理部分
    // 待填充...
     
    // 交易信号触发处理部分
    // 待填充...  

    // 执行交易逻辑
    var pos = null
    var price = null
    var currBar = records[records.length - 1]
    if(_State == OPENLONG){
        pos = GetPosition(PD_LONG)
        // 判断是不是 满足状态,如果满足 修改状态
        if(pos[1] >= Amount){
            _State = LONG
            Amount = pos[1]   // 更新实际量
            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]   // 更新实际量
            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)
    }
}  

// 交易逻辑部分
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){    // 处理交易
    if(Type == OPENLONG || Type == OPENSHORT){                 // 处理开仓
        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){        // 处理平仓
        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() { 
    // 设置合约
    exchange.SetContractType(Symbol)  

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

Contoh: Pemindahan strategi dua garis lurus

Di sini, kita akan melihat apa yang berlaku.img

Kod strategi bahasa Melayu:

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

Memindahkan ke dasar JavaScript

Pertama, isi kod contoh yang boleh digunakan semula di bahagian Pemerolehan Pasaran, Pengiraan Penunjuk:

// 驱动策略的行情处理部分
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]

Jadi, anda boleh lihat, strategi dua garis lurus adalah sangat mudah, hanya mengambil data garis K terlebih dahulu.recordsKemudian gunakanTA函数库Fungsi rata-rataTA.MAMenghitung garis purata 5 hari, garis purata 15 hari (seperti yang dapat dilihat pada antara muka pengukuran semula, kitaran garis K ditetapkan sebagai garis purata K hari, jadiTA.MA(records, 5)Perkiraan yang dibuat ialah garis purata lima hari.TA.MA(records, 15)Perbandingan hari ke-15) ]. Kemudian mendapatkanma5Nilai negatif kedua dari data penunjukma5_curr(nilai penunjuk), titik negatif ketiga.ma5_pre(nilai penunjuk)ma15Data penunjuk adalah simetris. Kemudian data penunjuk boleh digunakan untuk menilai garpu emas, seperti dalam gambar:imgJika keadaan ini berlaku, maka ia adalah sebuah garpu emas yang pasti.

Jika anda tidak tahu apa yang berlaku, anda boleh menulis bahagian yang menilai isyarat:

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
}

Jika anda mempunyai masalah dengan pemindahan, maka anda boleh kembali untuk ujian: Kaedah Javascript yang diuji semula Perisian pengukuran semula:img

回测结果:
![img](/upload/asset/16baa65d35e034e06a58.png) 

my bahasaimg

Hasil retesting dapat dilihat sama, jika anda ingin menambah fungsi interaksi untuk dasar, menambah pemprosesan data (misalnya sintesis K-line), menambah paparan gambar grafik yang disesuaikan.

Pelajar yang berminat boleh cuba.


Berkaitan

Lebih lanjut

Si KecilBelajar