avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada Pesan pribadi
4
fokus pada
1271
Pengikut

Penerapan fungsi __Thread dalam desain strategi JavaScript

Dibuat di: 2023-07-04 16:35:42, diperbarui pada: 2024-11-11 22:41:32
comments   3
hits   1076

Penerapan fungsi __Thread dalam desain strategi JavaScript

Penerapan fungsi __Thread dalam desain strategi JavaScript

Dalam desain strategi FMZ asli, jika Anda perlu menggunakan operasi bersamaan yang tidak sinkron, Anda hanya dapat menggunakanexchange.Go()Fungsi ini digunakan untuk mengimplementasikan konkurensi antarmuka enkapsulasi FMZ, dan beberapa operasi kustom (fungsi) tidak dapat dieksekusi secara bersamaan. Meskipun desain ini sangat meningkatkan efisiensi pelaksanaan program kebijakan, desain ini masih sangat asing bagi siswa yang memiliki pengalaman dalam desain serentak dalam bahasa pemrograman asli.

Bahkan beberapa mahasiswa baru yang baru mengenal perdagangan kuantitatif menggunakan FMZ tidak mengertiexchange.Go()Penggunaan fungsi, penggunaanexchange.Go()Masih terlihat seperti pernyataan dieksekusi satu per satu dalam kode yang dieksekusi berurutan. Dalam artikel ini, mari kita jelajahi fitur threading bersamaan baru dari platform FMZ:__Thread()Penggunaan serangkaian fungsi dan program strategi desain asinkron.

1. Desain konkuren sederhana

Jika kita ingin menjalankan thread anak secara bersamaan untuk mengeksekusi fungsi kustom yang kita tulis saat thread strategi utama sedang berjalan, kita dapat menggunakan desain yang mirip dengan kode berikut. Sesuaikan fungsi dalam kode strategiGetTickerAsync(), tuliskan fungsionalitas spesifik dari fungsi ini. Fungsi ini menjalankan perulangan tak terhingga.whileAntarmuka API FMZ dipanggil terus-menerus dalam satu lingkaran:GetTicker()Untuk mendapatkan data pasar.

Kemudian gunakan__threadSetData(0, "ticker", t)Kalimat ini menuliskan sebuah data ke thread utama. Nama datanya adalahticker, nilai datanya adalahtSekarangGetTicker()Nilai pengembalian .

__threadSetData(0, "ticker", t)

Setelah merancang fungsi khusus untuk eksekusi thread secara bersamaan, kita dapat menulismain()Kode dalam fungsi tersebut adalahmain()Pada awal fungsi, kita menggunakan:

__Thread(GetTickerAsync, 0)   // GetTickerAsync为需要并发执行的自定义函数,0为这个传入GetTickerAsync函数的参数

Buat thread bersamaan, yang mulai mengeksekusiGetTickerAsync()fungsi. Kemudianmain()Fungsi mulai menjalankan tugasnyawhileLoop, terima dalam loopGetTickerAsync()Fungsi ini memperbarui data dan kemudian mencetak:

var t = __threadGetData(0, "ticker")
Log(t)

Contoh kode lengkap:

function GetTickerAsync(index) {
    while (true) {
        var t = exchanges[index].GetTicker()
        __threadSetData(0, "ticker", t)
        Sleep(500)
    }
}

function main() {
    __Thread(GetTickerAsync, 0)

    while(true) {
        var t = __threadGetData(0, "ticker")
        Log(t)
        Sleep(1000)
    }
}

Uji operasi disk nyata:

Penerapan fungsi __Thread dalam desain strategi JavaScript

Ini adalah desain aplikasi yang paling sederhana. Selanjutnya, mari kita lihat beberapa desain permintaan lainnya.

2. Desain pesanan serentak

Suatu fungsi dapat dirancang untuk membuat 10 utas pada saat yang sama, dan setiap utas mengeksekusi fungsi operasi perintah. adamain()Mendesain suatu fungsiwhileLoop, instruksi interaksi strategi deteksi. Terima instruksi interaktif:placeMultipleOrdersPanggil saja fungsi order bersamaan initestPlaceMultipleOrders()

if (cmd == "placeMultipleOrders") {
    // ...
}

Tambahkan desain interaksi strategi pada halaman pengeditan strategi dan atur tombol dengan perintah: placeMultipleOrders

Penerapan fungsi __Thread dalam desain strategi JavaScript

Contoh kode lengkap:

function placeOrder(exIndex, type, price, amount) {
    var id = null 
    if (type == "Buy") {
        id = exchanges[exIndex].Buy(price, amount)
    } else if (type == "Sell") {
        id = exchanges[exIndex].Sell(price, amount)
    } else {
        throw "type error! type:" + type
    }
}

function testPlaceMultipleOrders(index, beginPrice, endPrice, step, type, amount) {
    Log("beginPrice:", beginPrice, ", endPrice:", endPrice, ", step:", step, ", type:", type, ", amount:", amount)
    var tids = []
    for (var p = beginPrice; p <= endPrice; p += step) {
        var tid = __Thread(placeOrder, index, type, p, amount)
        tids.push(tid)
        Sleep(10)
    }
    Sleep(1000)
    for (var i = 0; i < tids.length; i++) {
        __threadTerminate(tids[i])
    }
}

function main() {
    while(true) {
        LogStatus(_D())
        var cmd = GetCommand()
        if (cmd) {
            if (cmd == "placeMultipleOrders") {
                var t = _C(exchange.GetTicker)
                var beginPrice = t.Last * 0.8
                var endPrice = t.Last * 0.9
                var step = t.Last * 0.01
                testPlaceMultipleOrders(0, beginPrice, endPrice, step, "Buy", 0.01)
                var orders = exchange.GetOrders()
                for (var i = 0; i < orders.length; i++) {
                    Log(orders[i])
                }
            }
        }
        Sleep(1000)
    }
}
  • Pengujian ini menggunakan metode pending order, meningkat dari 80% menjadi 90% dari harga saat ini, menggunakan simulasi pengujian lingkungan disk, dan mengklik tombol interaktif untuk memicu pending order:

Penerapan fungsi __Thread dalam desain strategi JavaScript

  • Setelah mengklik tombol “placeMultipleOrders”, pesan promptnya adalah:

Penerapan fungsi __Thread dalam desain strategi JavaScript

  • Log strategi menunjukkan operasi order bersamaan:

Penerapan fungsi __Thread dalam desain strategi JavaScript

3. Buat koneksi WebSocket dalam fungsi eksekusi utas bersamaan

Persyaratan ini diajukan oleh pengguna FMZ yang menginginkan contoh sederhana untuk menunjukkan cara menggunakannya pada thread bersamaan.WebSocketHubungkan dan rancang cara meneruskan data ke utas utamamain()fungsi.

Sebenarnya ini sangat sederhana, dan mirip dengan pembuatan thread serentak pada contoh sebelumnya. Hanya komunikasi antar thread yang digunakan__threadPeekMessage()Fungsi dan__threadPostMessage()fungsi. Mengambil contoh panggilan antarmuka API WebSocket dari Binance Exchange, kita juga perlu memperhatikan operasi penutupan koneksi WebSocket dalam desain. Contoh berikut juga menunjukkan cara memberi tahu thread bersamaan untuk menghentikannya.

Contoh kode lengkap:

var tid = null 

function createWS() {
    // wss://stream.binance.com:9443/ws/<streamName> , <symbol>@ticker
    
    var stream = "wss://stream.binance.com:9443/ws/btcusdt@ticker"    
    var ws = Dial(stream)
    Log("创建WS连接:", stream)
    
    while (true) {
        var data = ws.read()
        if (data) {            
            __threadPostMessage(0, data)
        }
        Log("接收到WS链接推送的数据,data:", data)
        
        // __threadPeekMessage 超时参数设置-1,不阻塞
        var msg = __threadPeekMessage(-1)
        if (msg) {
            if (msg == "stop") {
                Log("并发线程Id:", __threadId(), "接收到stop指令")
                break
            }
        }
    }

    Log("并发线程执行完毕,关闭ws连接")
    ws.close()
}

function main() {
    tid = __Thread(createWS)
    Log("创建并发线程,线程Id:", tid)

    while(true) {
        // __threadPeekMessage 的超时参数设置为0,阻塞等待数据
        var data = __threadPeekMessage(0)
        Log("接收到并发线程", ", Id:", tid, ", 发送的数据,data:", data, "#FF0000")
        
        var tbl = {
            type : "table", 
            title : "<symbol>@ticker频道推送消息",
            cols : ["事件类型", "事件时间", "交易对", "24小时价格变化", "24小时价格变化百分比", "平均价格", "最新成交价格", "24小时内成交量", "24小时内成交额"],
            rows : []
        }

        try {
            data = JSON.parse(data)
            tbl.rows.push([data.e, _D(data.E), data.s, data.p, data.P, data.w, data.c, data.v, data.q])
        } catch (e) {
            Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
        }
        LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
    }
}

function onexit() {
    Log("扫尾函数,向Id为", tid, "的并发线程发送stop指令")
    __threadPostMessage(tid, "stop")
    Log("等待Id为", tid, "的并发线程停止")
    __threadJoin(tid)
    Log("扫尾函数执行完毕")
}

Uji operasi disk nyata:

Penerapan fungsi __Thread dalam desain strategi JavaScript

Kamu bisa melihatmain()Fungsi ini terus menerima data pasar dari koneksi WebSocket yang dibuat oleh utas bersamaan.

Ketika strategi dihentikan, fungsi sapuan akan mulai bekerja:

Penerapan fungsi __Thread dalam desain strategi JavaScript