Kursus Siri Pelaburan Kuantitatif Blockchain (3) Arbitraj Spread Kalender

Penulis:rubi, Dicipta: 2018-08-27 16:49:50, Dikemas kini:

NO.1 Dalam buku Financial Alchemy yang ditulis oleh Soros pada tahun 1987, satu proposisi penting dikemukakan: Saya percaya harga pasaran sentiasa salah dalam erti kata bahawa mereka membentangkan pandangan yang berat sebelah tentang masa depan. Hipotesis kesahihan pasaran hanyalah satu andaian teoritis. Sebenarnya, peserta pasaran tidak selalu rasional, dan pada setiap titik masa, peserta tidak dapat memperoleh sepenuhnya dan menafsirkan semua maklumat secara objektif. Walaupun ia adalah maklumat yang sama, maklum balas setiap orang adalah berbeza.

Dengan kata lain, harga itu sendiri sudah mengandungi jangkaan yang salah daripada peserta pasaran, jadi pada dasarnya harga pasaran sentiasa salah.

img

NO.2 Berdasarkan prinsip-prinsip di atas, kita juga tahu bahawa dalam pasaran niaga hadapan yang tidak berkesan, kesan pasaran kontrak penghantaran dalam tempoh yang berbeza tidak selalu diselaraskan, dan penetapan harga tidak menjadi sebab untuk sepenuhnya berkesan.

Kemudian, berdasarkan harga kontrak penghantaran pada masa yang berlainan sasaran urus niaga yang sama, jika terdapat perbezaan besar antara kedua-dua harga, adalah mungkin untuk memperdagangkan kontrak niaga hadapan pada masa yang sama dari tempoh yang berlainan dan menjalankan arbitrage intertemporal. Seperti komoditi niaga hadapan, mata wang digital juga mempunyai portfolio kontrak arbitrase intertemporal yang berkaitan dengan mereka.

Sebagai contoh, anggap spread antara minggu ETC dan suku ETC dikekalkan pada sekitar 5 untuk masa yang lama. Jika spread mencapai 7, kita menjangkakan spread akan kembali ke 5 pada suatu masa di masa depan. Kemudian anda boleh menjual minggu ETC dan membeli suku ETC untuk pendekkan spread. sebaliknya.

NO.3 Walaupun spread ini wujud, sering terdapat banyak ketidakpastian dalam arbitrage manual kerana memakan masa, operasi manual yang kurang tepat dan kesan perubahan harga.

Melalui model kuantitatif untuk menangkap peluang arbitrase dan membangunkan strategi perdagangan arbitrase, serta algoritma programatik secara automatik melepaskan pesanan perdagangan ke bursa, untuk menangkap peluang dengan cepat dan tepat dan memperoleh pendapatan dengan cekap, yang merupakan daya tarikan arbitrase kuantitatif.

img

Artikel ini akan mengajar anda cara menggunakan platform perdagangan kuantitatif FMZ dan kontrak niaga hadapan ETC di bursa OkEX dalam perdagangan mata wang digital, dengan strategi arbitrase yang mudah untuk menunjukkan cara menangkap peluang arbitrase serta-merta, dan merebut setiap keuntungan yang kelihatan sambil menyelamatkan risiko yang mungkin dihadapi.

NO.4 Buat strategi arbitrage intertemporal mata wang digital Kesukaran: tahap biasa Kawasan strategik: Sasaran urus niaga: Ethereum klasik (ETC) Data penyebaran: ETC mingguan - ETC suku tahunan Tempoh dagangan: 5 minit Persamaan kedudukan: 1:1 Jenis urus niaga: pelbagai yang sama antara masa Logik strategi: Syarat-syarat kedudukan spread panjang: Jika akaun semasa tidak mempunyai kedudukan, dan spread adalah kurang daripada jejak penurunan penunjuk boll, letakkan pesanan spread, iaitu: membeli ETC panjang mingguan, menjual ETC pendek suku tahunan.

Keadaan kedudukan jual pendek: Jika akaun semasa tidak mempunyai kedudukan dan perbezaan lebih tinggi daripada rel ke atas penunjuk boll, letakkan pesanan spread, iaitu: menjual ETC pendek setiap minggu, membeli ETC panjang setiap suku tahun.

Penutupan syarat kedudukan jual panjang: Jika akaun semasa memegang kedudukan mingguan ETC panjang dan memegang kedudukan suku tahunan ETC pendek, dan perbezaan lebih tinggi daripada rel tengah penunjuk boll, letakkan pesanan jual dekat, iaitu: menjual ETC mingguan, membeli untuk menampung ETC suku tahunan.

Penutupan syarat kedudukan Spread Jualan Pendek: Jika akaun semasa memegang kedudukan mingguan ETC pendek dan memegang kedudukan suku tahunan ETC panjang, dan spreadnya lebih rendah daripada rel tengah penunjuk boll, letakkan pesanan spread dekat, iaitu: beli untuk menampung ETC mingguan, menjual ETC suku tahunan.

NO.5 Yang di atas adalah penerangan mudah dari mata wang digital intertemporal arbitrage strategi logik, maka bagaimana untuk melaksanakan idea anda sendiri dalam program? Rangka strategi:

img

Kerangka strategi boleh dengan mudah dibina mengikut pemikiran strategik dan proses transaksi.

  1. Pra-pemprosesan sebelum transaksi.
  2. Dapatkan dan mengira data.
  3. Buat pesanan dan tindak lanjut.

NO.6 Seterusnya, kita perlu mengisi butiran yang diperlukan dalam rangka strategi berdasarkan proses transaksi sebenar dan butiran transaksi.

Pertama, pra-proses sebelum transaksi Langkah 1: Dalam persekitaran global, nyatakan pembolehubah global yang diperlukan. Mengisytiharkan objek carta yang mengkonfigurasi carta Carta Var = { } Panggil fungsi Chart untuk memulakan carta Var ObjChart = carta (grafik) Mengisytiharkan array kosong untuk menyimpan urutan penyebaran Var bar = [ ] Mengisytiharkan pembolehubah cap masa yang merakam data sejarah Var oldTime = 0 Langkah 2: Sesuaikan parameter luaran untuk strategi.

img

Langkah 3: Tentukan fungsi pemprosesan data Fungsi data asas: Data ()) Buat data pembina dan tentukan sifatnya, termasuk: data akaun, data kedudukan, data cap masa K-line, harga beli/jual terakhir kontrak arbitraj A/B, spread arbitraj positif/balik

img

Dapatkan fungsi kedudukan: mp ()) Semak melalui seluruh susunan kedudukan, kembali kontrak yang ditentukan dan bilangan kedudukan dalam arah yang ditentukan.

img

Garis K dan fungsi penunjuk: boll ()) Menyintesis urutan K-garis baru berdasarkan data penyebaran arbitrage positif / terbalik. Dan kembali data atas / tengah / bawah rel dikira oleh penunjuk bol.

img

Fungsi pesanan: perdagangan () Masukkan nama kontrak pesanan dan jenis perdagangan, kemudian letakkan pesanan dalam harga beli / jual terkini dan kembali hasilnya selepas meletakkan pesanan.

img

Fungsi Batalkan Perintah: Batalkan Perintah ()) Dapatkan semua pesanan yang belum selesai dan batalkan satu demi satu. dan jika ada pesanan yang belum selesai, kembali palsu, dan jika tidak ada, kembali benar.

img

Proses memegang kontrak tunggal: isEven ()) Dalam kes situasi kaki tunggal dalam perdagangan arbitrage, ia secara langsung ditangani dengan hanya menutup semua kedudukan.

img

Fungsi carta lukisan: gambarGambar ()) Panggil kaedah ObjChart.add ( ) untuk menarik data pasaran dan data penunjuk yang diperlukan dalam carta: naik, tengah, bawah rel, spread arbitrage positif / terbalik.

img

Langkah 4: Dalam fungsi kemasukan utama (), jalankan kod pra-pemprosesan sebelum urus niaga, yang hanya dijalankan sekali selepas program bermula, termasuk:

menapis maklumat yang tidak penting dalam konsol SetErrorFilter ()) Tetapkan jenis mata wang digital yang akan didagangkanexchange.IO()) Kosongkan carta yang digambar sebelum program bermula ObjChart.reset ()) Kosongkan maklumat bar status sebelum program memulakan LogProfitReset ())

img

NO.7 Selepas menentukan pra-pemprosesan di atas sebelum transaksi, adalah perlu untuk meneruskan ke langkah seterusnya, masukkan mod pengundian, dan ulangi fungsi onTick (). Dan tetapkan waktu tidur semasa mengundi, kerana beberapa API pertukaran mata wang digital mempunyai had akses terbina dalam untuk jangka masa tertentu.

img

Kedua, mendapatkan dan mengira data Langkah 1: Dapatkan objek data asas, baki akaun dan data penunjuk boll untuk logika perdagangan.

img

Ketiga, buat pesanan dan tindak lanjut Langkah 1: Melakukan operasi membeli dan menjual mengikut logik strategi di atas. Pertama, lihat sama ada harga dan keadaan penunjuk benar, dan kemudian lihat sama ada keadaan kedudukan benar, dan akhirnya melaksanakan fungsi pesanan perdagangan ().

img

Langkah 2: Selepas meletakkan pesanan, adalah perlu untuk menangani situasi yang tidak normal seperti pesanan yang menunggu dan memegang kontrak tunggal, dan membuat carta.

img

NO.8 Di atas, kami telah mencipta strategi arbitrage intertemporal mata wang digital yang mudah melalui lebih daripada 200 baris.

img

NO.9 Strategi ini hanya berfungsi sebagai pencetus. pasaran sebenar tidak begitu mudah, tetapi anda boleh menggunakan contoh ini untuk bermain dengan imaginasi anda.

Apa yang perlu diingatkan ialah, berdasarkan pengalaman saya yang terhad, strategi arbitraj tempoh murni pada dasarnya tidak layak dijalankan dalam keadaan pasaran mata wang digital semasa, sama ada ia adalah arbitraj segitiga bebas risiko atau arbitraj rentas pasaran.

Sebabnya adalah tidak kira di mana bursa mata wang digitals pasaran niaga hadapan, margin tidak fiat. Hampir semua mata wang digital telah jatuh kira-kira 70% sejak awal tahun. Dengan kata lain, strategi sentiasa membuat mata wang, tetapi harga mata wang jatuh.

Lihat secara luas, pasaran mata wang digital telah meninggalkan blockchain. sama seperti bunga tulip, harga selalu datang dari harapan dan keyakinan orang, dan keyakinan datang dari harga...

Di sini untuk mendapatkan kod 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 lanjut

Mimpi kecilBaguslah!