Tangan mengajarkan Anda menulis strategi -- mentransfer strategi bahasa saya.

Penulis:Mimpi kecil, Dibuat: 2019-10-21 14:59:12, Diperbarui: 2023-10-17 21:22:56

img

Tangan mengajarkan Anda menulis strategi dan mentransplantasikan strategi bahasa saya.

Saya baru-baru ini berbicara dengan teman-teman tentang strategi. Saya belajar bahwa ada banyak masalah dengan strategi menulis bahasa saya yang sulit untuk fleksibel. Dalam banyak kasus, Anda perlu menggunakan siklus K-line standar yang disediakan oleh non-sistem, misalnya, yang paling banyak diajukan adalah menggunakan 4 jam K-line. Masalah ini telah diselesaikan dalam sebuah artikel, yang menarik untuk dilihat terlebih dahulu:TautanNamun dalam strategi bahasa saya, masalah ini disebabkan oleh sifat kemasan bahasa saya yang tinggi dan tidak dapat memproses data secara mandiri secara fleksibel.

Untuk port strategi tren sangat sederhana, kita dapat menggunakan kode contoh untuk mengisi bagian kode perhitungan data yang mendorong strategi, mengisi kondisi pemicu sinyal perdagangan.

Kode contoh yang dapat digunakan kembali:

Strategi yang digunakan untuk futures OKEX adalah contohnya.

// 全局变量
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: Transplantasi strategi dua garis lurus

Dia mengatakan, "Saya tidak tahu apa yang terjadi".img

Kode strategi bahasa Melayu:

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

Port ke kebijakan JavaScript

Pertama-tama, isi kode contoh yang dapat digunakan kembali di bagian Pengadaan Pasar, Perhitungan Indikator:

// 驱动策略的行情处理部分
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 dapat melihat bahwa strategi dua garis lurus sangat sederhana, hanya mengambil data garis K terlebih dahulu.recordsDan kemudian gunakanTA函数库Fungsi rata-rataTA.MAMenghitung garis rata-rata 5 hari, garis rata-rata 15 hari (lihat pada antarmuka retrograde bahwa siklus garis K diatur sebagai garis rata-rata K hari, jadiTA.MA(records, 5)Perhitungan yang dilakukan adalah garis rata-rata 5 hari.TA.MA(records, 15)"Saya tidak tahu apa yang terjadi. Kemudian mendapatkanma5Ini adalah titik negatif kedua dari data indikator.ma5_curr(nilai indikator), titik negatif ketiga.ma5_pre(nilai indikator)ma15Data indikator adalah simetris. Kemudian data indikator dapat digunakan untuk menilai apa yang terjadi, seperti gambar:imgJika kondisi seperti ini terjadi, maka sudah pasti golden fork akan mati.

Jika Anda tidak tahu apa yang terjadi, maka bagian dari penilaian sinyal dapat ditulis sebagai 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
}

Setelah transplantasi selesai, Anda bisa kembali dan melakukan tes: Pengujian kembali kebijakan JavaScript Periksa kembali konfigurasi:img

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

My bahasaimg

Hasil retesting dapat dilihat pada dasarnya sama, sehingga jika Anda ingin menambahkan lebih banyak fitur interaktif untuk kebijakan, menambahkan pemrosesan data (misalnya, sintesis K-line), menambahkan tampilan gambar grafik khusus, maka itu bisa dilakukan.

Jika Anda tertarik, cobalah.


Berkaitan

Lebih banyak

Si KecilBelajar