Kursus Seri Investasi Kuantitatif Blockchain (3) Arbitrase Spread Kalender

Penulis:rubi, Dibuat: 2018-08-27 16:49:50, Diperbarui:

No. 1 Dalam buku Financial Alchemy yang ditulis oleh Soros pada tahun 1987, sebuah proposisi penting dikemukakan: Saya percaya harga pasar selalu salah dalam arti bahwa mereka menyajikan pandangan bias tentang masa depan. Hipotesis validitas pasar hanyalah asumsi teoritis. Faktanya, peserta pasar tidak selalu rasional, dan pada setiap titik waktu, peserta tidak dapat sepenuhnya memperoleh dan secara obyektif menafsirkan semua informasi. Bahkan jika itu adalah informasi yang sama, umpan balik setiap orang berbeda.

Dengan kata lain, harga itu sendiri sudah mengandung harapan yang salah dari peserta pasar, sehingga pada dasarnya harga pasar selalu salah.

img

No. 2 Berdasarkan prinsip-prinsip di atas, kita juga tahu bahwa di pasar berjangka yang tidak efektif, dampak pasar dari kontrak pengiriman dalam periode yang berbeda tidak selalu disinkronkan, dan penetapan harga tidak menjadi alasan untuk sepenuhnya efektif.

Kemudian, berdasarkan harga kontrak pengiriman pada waktu yang berbeda dari target transaksi yang sama, jika ada perbedaan besar antara kedua harga, dimungkinkan untuk secara bersamaan memperdagangkan kontrak berjangka dari periode yang berbeda dan melakukan arbitrase intertemporal. Seperti komoditas berjangka, mata uang digital juga memiliki portofolio kontrak arbitrase intertemporal yang terkait dengan mereka.

Sebagai contoh, misalkan spread antara minggu ETC dan kuartal ETC dipertahankan sekitar 5 untuk waktu yang lama. Jika spread mencapai 7, kita mengharapkan spread untuk kembali ke 5 di beberapa waktu di masa depan. Kemudian Anda dapat menjual minggu ETC dan membeli kuartal ETC untuk short spread. sebaliknya.

No.3 Meskipun spread ini ada, sering ada banyak ketidakpastian dalam arbitrage manual karena memakan waktu, tidak akurat dari operasi manual dan efek perubahan harga.

Melalui model kuantitatif untuk menangkap peluang arbitrage dan mengembangkan strategi perdagangan arbitrage, serta algoritma programatik secara otomatis melepaskan pesanan perdagangan ke bursa, untuk dengan cepat dan akurat menangkap peluang dan secara efisien menghasilkan pendapatan, yang merupakan pesona arbitrage kuantitatif.

img

Artikel ini akan mengajarkan Anda cara menggunakan platform perdagangan kuantitatif FMZ dan kontrak berjangka ETC di bursa OkEX dalam perdagangan mata uang digital, dengan strategi arbitrage sederhana untuk menunjukkan cara menangkap peluang arbitrage instan, dan merebut setiap keuntungan yang terlihat sambil sekaligus lindung nilai risiko yang mungkin terjadi.

NO.4 Membuat strategi arbitrage intertemporal mata uang digital Kesulitan: tingkat biasa Lingkungan strategis: Target transaksi: Ethereum klasik (ETC) Data spread: ETC mingguan - ETC triwulanan Periode perdagangan: 5 menit Persamaan posisi: 1:1 Jenis transaksi: varietas yang sama intertemporal Logika strategi: Kondisi posisi spread panjang: Jika akun arus tidak memiliki posisi, dan spreadnya lebih kecil dari jejak penurunan indikator boll, tempatkan spread order, yaitu: membeli ETC panjang mingguan, menjual ETC pendek triwulanan.

Kondisi posisi spread short selling: Jika akun arus tidak memiliki posisi dan spreadnya lebih tinggi dari up rail dari indikator boll, tempatkan spread order, yaitu: menjual ETC short mingguan, membeli ETC long triwulanan.

Penutupan kondisi posisi jual spread panjang: Jika akun saat ini memiliki posisi mingguan ETC panjang dan posisi ETC kuartal pendek, dan spreadnya lebih tinggi dari rel tengah indikator boll, tempatkan pesanan jual spread dekat, yaitu: menjual ETC mingguan, membeli untuk menutupi ETC kuartal.

Penutupan kondisi Posisi Spread Penjualan Singkat: Jika akun arus memegang posisi ETC mingguan pendek dan memegang posisi ETC kuartal panjang, dan spreadnya lebih rendah dari rel tengah indikator boll, tempatkan pesanan spread dekat, yaitu: beli untuk menutupi ETC mingguan, menjual ETC kuartal.

NO.5 Di atas adalah deskripsi sederhana dari logika strategi arbitrage intertemporal mata uang digital, lalu bagaimana menerapkan ide Anda sendiri dalam program? Kerangka strategi:

img

Kerangka kerja strategi dapat dengan mudah dibangun sesuai dengan pemikiran strategis dan proses transaksi.

  1. Pemrosesan pra sebelum transaksi.
  2. Dapatkan dan hitung data.
  3. Tempatkan pesanan dan tindak lanjut.

NO.6 Selanjutnya, kita perlu mengisi rincian yang diperlukan dalam kerangka strategi berdasarkan proses transaksi yang sebenarnya dan rincian transaksi.

Pertama, pra-pengolahan sebelum transaksi Langkah 1: Dalam lingkungan global, deklarasikan variabel global yang diperlukan. Deklarasikan objek grafik yang mengkonfigurasi grafik Diagram Var = { } Panggilan fungsi Chart untuk menginisialisasi grafik Var ObjChart = Grafik (grafik) Mengumumkan array kosong untuk menyimpan urutan penyebaran Var bar = [ ] Mengisyaratkan variabel timestamp yang mencatat data historis Var oldTime = 0 Langkah 2: Mengkonfigurasi parameter eksternal untuk strategi.

img

Langkah 3: Mendefinisikan fungsi pemrosesan data Fungsi data dasar: Data ()) Buat constructor Data dan tentukan sifat internalnya, termasuk: data akun, data posisi, data K-line timestamp, harga beli/penjualan terbaru dari kontrak arbitrage A/B, spread arbitrage positif/reverse

img

Dapatkan fungsi posisi: mp ()) Periksa seluruh array posisi, kembalikan kontrak yang ditentukan dan jumlah posisi di arah yang ditentukan.

img

K line dan fungsi indikator: boll ()) Sintesis urutan K-line baru berdasarkan data spread arbitrage positif / terbalik. Dan kembali data up / middle / down rail dihitung oleh indikator bol.

img

Fungsi pesanan: perdagangan () Masukkan nama kontrak order dan jenis perdagangan, kemudian menempatkan order di harga beli/jual terbaru dan mengembalikan hasilnya setelah menempatkan order.

img

Fungsi membatalkan pesanan: cancelOrders ()) Dapatkan array semua pesanan tertunda dan membatalkan mereka satu per satu. dan jika ada pesanan tertunda, kembali palsu, dan jika tidak ada, kembali benar.

img

Proses memegang kontrak tunggal: isEven ()) Dalam kasus situasi single-leg dalam perdagangan arbitrage, hal ini langsung ditangani dengan hanya menutup semua posisi.

img

Fungsi menggambar grafik: menggambarGambar ()) Menggunakan metode ObjChart.add () untuk menarik data pasar dan data indikator yang diperlukan dalam grafik: naik, tengah, turun rel, spread arbitrage positif/balik.

img

Langkah 4: Dalam fungsi entri utama (), eksekusi kode pra-pemrosesan sebelum transaksi, yang hanya dijalankan sekali setelah program dimulai, termasuk:

saring informasi yang tidak terlalu penting di konsol SetErrorFilter ()) Atur jenis mata uang digital yang akan diperdagangkanexchange.IO() Kosongkan grafik yang ditarik sebelum program dimulai ObjChart.reset ()) Kosongkan informasi bilah status sebelum program memulai LogProfitReset ())

img

NO.7 Setelah menentukan pra-pemrosesan di atas sebelum transaksi, perlu untuk melanjutkan ke langkah berikutnya, masuk ke mode pemungutan suara, dan ulangi fungsi onTick (). Dan atur waktu tidur saat polling, karena beberapa API pertukaran mata uang digital memiliki batas akses bawaan untuk jangka waktu tertentu.

img

Kedua, mendapatkan dan menghitung data Langkah 1: Dapatkan objek data yang mendasari, saldo akun dan data indikator boll untuk logika perdagangan.

img

Ketiga, membuat pesanan dan tindak lanjut Langkah 1: Melakukan operasi pembelian dan penjualan sesuai dengan logika strategi di atas. Pertama, periksa apakah kondisi harga dan indikator benar, dan kemudian periksa apakah kondisi posisi benar, dan akhirnya pelaksanaan fungsi pesanan perdagangan ().

img

Langkah 2: Setelah pemesanan, perlu untuk menangani situasi yang tidak normal seperti pesanan yang menunggu dan memegang kontrak tunggal, dan membuat grafik.

img

No. 8 Di atas, kami telah membuat strategi arbitrage intertemporal mata uang digital sederhana melalui lebih dari 200 baris.

img

NO.9 Strategi ini hanya berfungsi sebagai pemicu. pasar nyata tidak begitu sederhana, tapi Anda dapat menggunakan contoh ini untuk bermain dengan imajinasi Anda.

Apa yang perlu diingat adalah bahwa, berdasarkan pengalaman terbatas saya, strategi arbitrage periode murni pada dasarnya tidak layak dijalankan dalam situasi pasar mata uang digital saat ini, apakah itu risiko bebas arbitrage segitiga atau cross-market arbitrage.

Alasan adalah bahwa tidak peduli di pasar futures pertukaran mata uang digital mana, margin tidak fiat. Hampir semua mata uang digital telah turun sekitar 70% sejak awal tahun. Dengan kata lain, strategi selalu menghasilkan mata uang, tetapi harga mata uang menurun.

Jika dilihat secara luas, pasar mata uang digital sudah meninggalkan blockchain. sama seperti bunga tulip saat itu, harga selalu berasal dari harapan dan kepercayaan orang, dan kepercayaan berasal dari harga...

Di sini untuk mendapatkan kode lengkap:

// global variable
// Declare a chart object that configures the chart
var chart = {
    __isStock: true,
    tooltip: {
        xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
    },
    title: {
        text: 'Profit and loss chart(detail)'
    },
    rangeSelector: {
        buttons: [{
            type: 'hour',
            count: 1,
            text: '1h'
        }, {
            type: 'hour',
            count: 2,
            text: '3h'
        }, {
            type: 'hour',
            count: 8,
            text: '8h'
        }, {
            type: 'all',
            text: 'All'
        }],
        selected: 0,
        inputEnabled: false
    },
    xAxis: {
        type: 'datetime'
    },
    yAxis: {
        title: {
            text: 'spread'
        },
        opposite: false,
    },
    series: [{
        name: "up",
        id: "line1,up",
        data: []
    }, {
        name: "middle",
        id: "line2,middle",
        data: []
    }, {
        name: "down",
        id: "line3,down",
        data: []
    }, {
        name: "basb",
        id: "line4,basb",
        data: []
    }, {
        name: "sabb",
        id: "line5,sabb",
        data: []
    }]
};
var ObjChart = Chart(chart); // Drawing object
var bars = []; // Store spread sequence
var oldTime = 0; // Record historical data timestamp

// Parameter
var tradeTypeA = "this_week"; // Arbitrage contract A
var tradeTypeB = "quarter"; // Arbitrage contract B
var dataLength = 10; //Length of indicator cycle
var timeCycle = 1; // The cycle of K-line
var name = "ETC"; // Currency type
var unit = 1; // Quantity of orders

// Basic data
function Data(tradeTypeA, tradeTypeB) { // input arbitrage contract A&B
    this.accountData = _C(exchange.GetAccount); // get account data
    this.positionData = _C(exchange.GetPosition); // get position data
    var recordsData = _C(exchange.GetRecords); //get k-line data
    exchange.SetContractType(tradeTypeA); // subscribe arbitrage contract A
    var depthDataA = _C(exchange.GetDepth); // deep data of arbitrage contract A
    exchange.SetContractType(tradeTypeB); // subscribe arbitrage contract B
    var depthDataB = _C(exchange.GetDepth); // deep data of arbitrage contract B
    this.time = recordsData[recordsData.length - 1].Time; // get the latest time data
    this.askA = depthDataA.Asks[0].Price; // the latest selling price of arbitrage contract A
    this.bidA = depthDataA.Bids[0].Price; // the latest buying price of arbitrage contract A
    this.askB = depthDataB.Asks[0].Price; // the latest selling price of arbitrage contract B
    this.bidB = depthDataB.Bids[0].Price; // the latest buying price of arbitrage contract B
    // Positive arbitrage spread(the latest selling price of contract A -the latest buying price of contract B )
    this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
    // Reverse arbitrage spread(the latest buying price of contract A -the latest selling price of contract B )
    this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}

// get position information
Data.prototype.mp = function (tradeType, type) {
    var positionData = this.positionData; // get position data
    for (var i = 0; i < positionData.length; i++) {
        if (positionData[i].ContractType == tradeType) {
            if (positionData[i].Type == type) {
                if (positionData[i].Amount > 0) {
                    return positionData[i].Amount;
                }
            }
        }
    }
    return false;
}

// Synthetize new K-line data and boll indicator data
Data.prototype.boll = function (num, timeCycle) {
    var self = {}; // Temporary object
    // the median of Positive arbitrage spread and reverse arbitrage spread
    self.Close = (this.basb + this.sabb) / 2;
    if (this.timeA == this.timeB) {
        self.Time = this.time;
    } // Comparing two depth data timestamps
    if (this.time - oldTime > timeCycle * 60000) {
        bars.push(self);
        oldTime = this.time;
    } // According to the specified time period, insert the spread data object in the K-line array.
    if (bars.length > num * 2) {
        bars.shift(); // Control K-line array length
    } else {
        return;
    }
    var boll = TA.BOLL(bars, num, 2); // Call the boll indicator in the Talib Library
    return {
        up: boll[0][boll[0].length - 1], // up rail of boll indicator
        middle: boll[1][boll[1].length - 1], // middle rail of boll indicator
        down: boll[2][boll[2].length - 1] // down rail of boll indicator
    } // Return a processed boll indicator data.
}

// place order
Data.prototype.trade = function (tradeType, type) {
    exchange.SetContractType(tradeType); // Resubscribe contract before placing order
    var askPrice, bidPrice;
    if (tradeType == tradeTypeA) { // if it's contract A
        askPrice = this.askA; // set askPrice
        bidPrice = this.bidA; // set bidPrice
    } else if (tradeType == tradeTypeB) { // if it's contract B
        askPrice = this.askB; // set askPrice
        bidPrice = this.bidB; // set bidPrice
    }
    switch (type) { // Match order mode
        case "buy":
            exchange.SetDirection(type); // Set order mode
            return exchange.Buy(askPrice, unit);
        case "sell":
            exchange.SetDirection(type); // Set order mode
            return exchange.Sell(bidPrice, unit);
        case "closebuy":
            exchange.SetDirection(type); // Set order mode
            return exchange.Sell(bidPrice, unit);
        case "closesell":
            exchange.SetDirection(type); // Set order mode
            return exchange.Buy(askPrice, unit);
        default:
            return false;
    }
}

// cancel order
Data.prototype.cancelOrders = function () {
    Sleep(500); // delay before canceling, because some exchanges you know...
    var orders = _C(exchange.GetOrders); // Get the array of pending orders
    if (orders.length > 0) { // if there is pending order
        for (var i = 0; i < orders.length; i++) { //check through the array of pending orders
            exchange.CancelOrder(orders[i].Id); //cancel pending orders one by one
            Sleep(500); //Delay 0.5 seconds
        }
        return false; // return false if pending orders have been cancelled
    }
    return true; //return true if there is no pending order
}

// handle holding single contract
Data.prototype.isEven = function () {
    var positionData = this.positionData; // get position data
    var type = null; // converse position direction 
    // If the length of the position array divided by some number and the remainder is 2, the result is not equal to 0 or the length of the position array is not equal to 2
    if (positionData.length % 2 != 0 || positionData.length != 2) {
        for (var i = 0; i < positionData.length; i++) { // check through the array of positions
            if (positionData[i].Type == 0) { // if it's long position
                type = 10; // Set order parameters
            } else if (positionData[i].Type == 1) { // if it's short position
                type = -10; // Set order parameters
            }
            // close all positions
            this.trade(positionData[i].ContractType, type, positionData[i].Amount);
        }
    }
}

// drawing chart
Data.prototype.drawingChart = function (boll) {
    var nowTime = new Date().getTime();
    ObjChart.add([0, [nowTime, boll.up]]);
    ObjChart.add([1, [nowTime, boll.middle]]);
    ObjChart.add([2, [nowTime, boll.down]]);
    ObjChart.add([3, [nowTime, this.basb]]);
    ObjChart.add([4, [nowTime, this.sabb]]);
    ObjChart.update(chart);
}

// trading condition
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // Create a base data object
    var accountStocks = data.accountData.Stocks; // account balance
    var boll = data.boll(dataLength, timeCycle); // get boll indicator data
    if (!boll) return; // return if there is no boll data
    // Spread description
    // basb = (the latest selling price of contract A - the latest buying price of contract B)
    // sabb = (the latest buying price of contract A - the latest selling price of contract B)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // if sabb is higher than the middle rail
        if (data.mp(tradeTypeA, 0)) { // check if contract A has long positon before placing order
            data.trade(tradeTypeA, "closebuy"); // close long position of contract A
        }
        if (data.mp(tradeTypeB, 1)) { // check if contract B has short positon before placing order
            data.trade(tradeTypeB, "closesell"); // close short position of contract B
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // if basb is lower than the middle rail
        if (data.mp(tradeTypeA, 1)) { // check if contract A has short positon before placing order
            data.trade(tradeTypeA, "closesell"); // close short position of contract A
        }
        if (data.mp(tradeTypeB, 0)) { // check if contract B has long positon before placing order
            data.trade(tradeTypeB, "closebuy"); // close long position of contract B
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // If there is balance in the account
        if (data.basb < boll.down) { // if basb spread is lower than the down rail
            if (!data.mp(tradeTypeA, 0)) { // check if contract A has long positon before placing order
                data.trade(tradeTypeA, "buy"); // open long position of contract A
            }
            if (!data.mp(tradeTypeB, 1)) { // check if contract B has short positon before placing order
                data.trade(tradeTypeB, "sell"); // open short position of contract B
            }
        } else if (data.sabb > boll.up) { // if sabb spread is higher than the up rail
            if (!data.mp(tradeTypeA, 1)) { // check if contract A has short positon before placing order
                data.trade(tradeTypeA, "sell"); // open short position of contract A
            }
            if (!data.mp(tradeTypeB, 0)) { // check if contract B has long positon before placing order
                data.trade(tradeTypeB, "buy"); // open long position of contract B
            }
        }
    }
    data.cancelOrders(); // cancel orders
    data.drawingChart(boll); // drawing chart
    data.isEven(); // process holding single contract
}

//enter function
function main() {
    // filter the information that is not very important in the console
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //Set the cryptocurrency type to be traded
    ObjChart.reset(); //Empty the drawn charts before the program starts
    LogProfitReset(); //Empty the status bar information before the program starts
    while (true) { // Enter polling mode
        onTick(); // Execute onTick function
        Sleep(500); // sleep for o.5 seconds
    }
}


Lebih banyak

Mimpi kecilBagus sekali!