Strategi Arbitraj Perpindahan Tempoh Mata Wang Digital Berdasarkan Bollinger Band

Penulis:Lydia, Dicipta: 2022-12-02 16:58:27, Dikemas kini: 2023-09-20 09:33:29

img

Strategi Arbitraj Perpindahan Tempoh Mata Wang Digital Berdasarkan Bollinger Band

I. Ringkasan

George Soros mengemukakan proposisi penting dalam The Alchemy of Finance yang ditulis pada tahun 1987: Saya percaya harga pasaran selalu salah dalam erti kata bahawa mereka membentangkan pandangan yang bias terhadap masa depan. Hipotesis kecekapan pasaran hanyalah hipotesis teori. Sebenarnya, peserta pasaran tidak selalu rasional, dan pada setiap titik masa, peserta tidak dapat memperoleh dan menafsirkan semua maklumat secara objektif. Selain itu, walaupun ia adalah maklumat yang sama, maklum balas semua orang adalah berbeza. Maksudnya, harga itu sendiri sudah mengandungi jangkaan yang salah daripada peserta pasaran, jadi pada dasarnya, harga pasaran selalu salah. Ini mungkin menjadi sumber keuntungan para arbitrager.

II. Prinsip-prinsip strategik

Menurut prinsip-prinsip di atas, kita dapat mengetahui bahawa dalam pasaran niaga hadapan yang tidak berkesan, sebab mengapa kesan pasaran pada kontrak penghantaran dalam tempoh yang berbeza tidak selalu serentak, dan penetapan harga tidak sepenuhnya berkesan. Kemudian, berdasarkan harga kontrak penghantaran objek transaksi yang sama dalam tempoh yang berbeza, jika terdapat perbezaan harga yang besar antara kedua harga, kita boleh membeli dan menjual kontrak niaga hadapan dalam tempoh yang berbeza pada masa yang sama untuk arbitrage lintas tempoh. Seperti niaga hadapan komoditi, mata wang digital juga mempunyai portfolio kontrak arbitrage lintas tempoh. Sebagai contoh, di bursa OKEX, terdapat: ETC minggu ini, ETC minggu depan, suku ETC. Sebagai contoh, anggaplah perbezaan harga antara minggu semasa ETC dan suku ETC kekal sekitar 5 untuk masa yang lama. Jika perbezaan harga mencapai 7 satu hari, kita mengharapkan bahawa perbezaan harga akan kembali ke 5 pada masa akan datang. Kemudian kita boleh menjual ETC minggu itu dan membeli suku ETC pada masa yang sama untuk memendekkan perbezaan harga, dan sebaliknya. Walaupun perbezaan harga ini wujud, terdapat banyak ketidakpastian dalam arbitraj manual kerana operasi manual yang memakan masa, ketepatan yang buruk dan kesan perubahan harga. Pesona arbitraj kuantitatif terletak pada menangkap peluang arbitraj melalui model kuantitatif dan merumuskan strategi perdagangan arbitraj, serta meletakkan pesanan perdagangan secara automatik ke bursa melalui algoritma yang diprogram, untuk menangkap peluang dengan cepat dan tepat dan membuat keuntungan dengan cekap dan stabil.

III. Logik Strategi

Artikel ini akan mengajar anda cara menggunakan Platform Dagangan Kuantum FMZ dan kontrak niaga hadapan ETC di bursa OKEX untuk menunjukkan cara menangkap peluang arbitraj segera, merebut keuntungan yang dapat dilihat setiap kali, dan melindungi risiko yang mungkin berlaku dalam perdagangan mata wang digital dengan strategi arbitraj yang mudah.

Membuat strategi arbitrage lintas tempoh untuk mata wang digital

Kesukaran: Biasa

Kawasan strategi

  • Objek urus niaga: Ether Classic (ETC)
  • Data penyebaran: minggu semasa ETC - suku ETC (mengecualikan ujian kointegrasi)
  • Tempoh transaksi: 5 minit
  • Persamaan kedudukan: 1:1
  • Jenis urus niaga: tempoh silang jenis yang sama

Logik strategi

  • Syarat untuk membuka kedudukan dengan pergi panjang perbezaan harga: jika akaun semasa tidak mempunyai kedudukan dan perbezaan harga adalah kurang daripada batas bawah boll, maka pergi panjang perbezaan harga. iaitu, membeli kedudukan pembukaan ETC untuk minggu, menjual kedudukan pembukaan ETC untuk suku.
  • Syarat untuk membuka kedudukan dengan pergi pendek perbezaan harga: jika tidak ada kedudukan dalam akaun semasa, dan perbezaan harga adalah lebih besar daripada batas atas boll, maka pergi pendek perbezaan harga. iaitu, menjual kedudukan pembukaan ETC untuk minggu, membeli kedudukan pembukaan ETC untuk suku.
  • Syarat untuk menutup kedudukan dengan pergi panjang perbezaan harga: jika akaun semasa memegang pesanan panjang ETC dalam minggu semasa dan memegang pesanan pendek ETC suku, dan perbezaan harga lebih besar daripada batas tengah bol, maka tutup panjang perbezaan harga. iaitu, jual kedudukan penutupan ETC untuk minggu, beli kedudukan penutupan ETC untuk suku.
  • Syarat untuk menutup kedudukan dengan pergi pendek perbezaan harga: jika akaun semasa memegang pergi pesanan pendek ETC dalam minggu semasa, dan memegang pergi pesanan panjang ETC suku, dan perbezaan harga adalah kurang daripada batas tengah boll, kemudian menutup pendek perbezaan harga. iaitu, membeli kedudukan penutupan ETC untuk minggu, menjual kedudukan penutupan ETC untuk suku.

IV. Menulis kerangka strategi

Yang di atas adalah penerangan logik yang mudah strategi arbitrage cross-period mata wang digital. jadi bagaimana untuk melaksanakan idea-idea kami dalam program? kami cuba untuk membina kerangka kerja pada FMZ Quant Trading Platform.

function Data() {}  // Basic data function
Data.prototype.mp = function () {}  // Position function
Data.prototype.boll = function () {}  // Indicator function
Data.prototype.trade = function () {}  // Order placement function
Data.prototype.cancelOrders = function () {}  // Order withdrawal function
Data.prototype.isEven = function () {}  // Processing single contract function
Data.prototype.drawingChart = function () {}  // Drawing function

// Trading conditions
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB);  // Create a basic data object
    var accountStocks = data.accountData.Stocks;  // Account balance
    var boll = data.boll(dataLength, timeCycle);  // Calculate the technical indicators of boll
    data.trade();  // Calculate trading conditions to place an order
    data.cancelOrders();  // Cancel orders
    data.drawingChart(boll);  // drawing
    data.isEven();  // Processing of holding individual contract
}

//Entry function
function main() {
    while (true) {  // Enter the polling mode
        onTick();  // Execute onTick function
        Sleep(500);  // Sleep for 0.5 seconds
    }
}

V. Strategi Penulisan

Rangka strategi boleh dengan mudah ditubuhkan mengikut idea strategi dan proses transaksi. Pra-pemprosesan sebelum transaksi. Dapatkan dan mengira data. Buat pesanan dan selesaikan nanti. Seterusnya, kita perlu mengisi kod butiran yang diperlukan dalam rangka strategi mengikut proses transaksi sebenar dan butiran transaksi.

Pemprosesan pra sebelum urus niaga Langkah 1: Nyatakan pembolehubah global yang diperlukan dalam skop global.

//Declare a chart object for the configuration chart
var chart = { }

//Call Chart function and initialize the chart
var ObjChart = Chart ( chart )

//Declare an empty array to store price difference series
var bars = [ ]

//Declare a record history data timestamp variable
var oldTime = 0

Langkah 2: Sesuaikan parameter luaran strategi.

// parameters
var tradeTypeA = "this_week"; // Arbitrage A Contract
var tradeTypeB = "quarter"; // Arbitrage B Contract
var dataLength = 10; //Indicator period length
var timeCycle = 1; // K-line period
var name = "ETC"; // Currencies
var unit = 1; // Order quantity

Langkah 3: Tentukan fungsi pemprosesan data Fungsi data asas: Data Buat pembina, Data, dan tentukan sifat dalamannya. Termasuk: data akaun, data kedudukan, cap masa data K-line, harga beli / jual kontrak arbitrage A / B, dan perbezaan harga arbitrage positif / negatif.

// Basic data
function Data(tradeTypeA, tradeTypeB) { // Pass in arbitrage A contract and arbitrage B contract
    this.accountData = _C(exchange.GetAccount); // Get account information
    this.positionData = _C(exchange.GetPosition); // Get position information
    var recordsData = _C(exchange.GetRecords); // Get K-line data
    exchange.SetContractType(tradeTypeA); // Subscription arbitrage A contract
    var depthDataA = _C(exchange.GetDepth); // Depth data of arbitrage A contract
    exchange.SetContractType(tradeTypeB); // Subscription arbitrage B contract
    var depthDataB = _C(exchange.GetDepth); // Depth data of arbitrage B contract
    this.time = recordsData[recordsData.length - 1].Time; // Time of obtaining the latest data
    this.askA = depthDataA.Asks[0].Price; // Sell one price of Arbitrage A contract
    this.bidA = depthDataA.Bids[0].Price; // Buy one price of Arbitrage A contract
    this.askB = depthDataB.Asks[0].Price; // Sell one price of Arbitrage B contract
    this.bidB = depthDataB.Bids[0].Price; // Buy one price of Arbitrage B contract
    // Positive arbitrage price differences (Sell one price of contract A - Buy one price of contract B)
    this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
    // Negative arbitrage price differences (Buy one price of contract A - Sell one price of contract B)
    this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}

Dapatkan fungsi kedudukan: mp ()) Melalui seluruh array kedudukan dan kembali kuantiti kedudukan kontrak dan arah yang ditentukan.

// Get positions
Data.prototype.mp = function (tradeType, type) {
    var positionData = this.positionData; // Get position information
    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;
}

K-garis dan fungsi penunjuk: boll() Satu urutan K-line baru disintesis mengikut data perbezaan harga arbitraj positif / negatif. Data trek atas, trek tengah dan trek bawah yang dikira oleh penunjuk boll dikembalikan.

// Synthesis of new K-line data and boll indicator data
Data.prototype.boll = function (num, timeCycle) {
    var self = {}; // Temporary objects
    // Median value of positive arbitrage price difference and negative arbitrage price difference
    self.Close = (this.basb + this.sabb) / 2;
    if (this.timeA == this.timeB) {
        self.Time = this.time;
    } // Compare two depth data timestamps
    if (this.time - oldTime > timeCycle * 60000) {
        bars.push(self);
        oldTime = this.time;
    } // Pass in the price difference data object into the K-line array according to the specified time period
    if (bars.length > num * 2) {
        bars.shift(); // Control the length of the K-line array
    } 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], // boll indicator upper track
        middle: boll[1][boll[1].length - 1], // boll indicator middle track
        down: boll[2][boll[2].length - 1] // boll indicator down track
    } // Return a processed boll indicator data
}

Fungsi pesanan: perdagangan Mempindahkan dalam nama kontrak pesanan dan jenis pesanan, kemudian meletakkan pesanan dengan pertimbangan, dan mengembalikan hasil selepas meletakkan pesanan.

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

Batalkan Perintah Fungsi: Batalkan Perintah Dapatkan satu susunan semua pesanan yang belum selesai dan batalkan satu demi satu.

// Cancel order
Data.prototype.cancelOrders = function () {
    Sleep(500); // Delay before cancellation, because some exchanges, you know what I mean
    var orders = _C(exchange.GetOrders); // Get an array of unfilled orders
    if (orders.length > 0) { // If there are unfilled orders
        for (var i = 0; i < orders.length; i++) { //Iterate through the array of unfilled orders
            exchange.CancelOrder(orders[i].Id); //Cancel unfilled orders one by one
            Sleep(500); //Delay 0.5 seconds
        }
        return false; // Return false if an unfilled order is cancelled
    }
    return true; // Return true if there are no unfilled orders
}

Mengurus memegang kontrak tunggal: isEven() Dalam kes kaki tunggal dalam urus niaga arbitraj, kita hanya akan menutup semua kedudukan.

// Handle holding a single contract
Data.prototype.isEven = function () {
    var positionData = this.positionData; // Get position information
    var type = null; // Switch position direction
    // If the remaining 2 of the position array length is not equal to 0 or the position array length is not equal to 2
    if (positionData.length % 2 != 0 || positionData.length != 2) {
        for (var i = 0; i < positionData.length; i++) { // Iterate through the position array
            if (positionData[i].Type == 0) { // If it is a long order
                type = 10; // Set order parameters
            } else if (positionData[i].Type == 1) { // If it is a short order
                type = -10; // Set order parameters
            }
            // Close all positions
            this.trade(positionData[i].ContractType, type, positionData[i].Amount);
        }
    }
}

Fungsi lukisan: lukisanGambar ()) Panggil kaedah ObjChart Add (), lukis data pasaran dan data penunjuk yang diperlukan dalam carta: trek atas, trek tengah, trek bawah, perbezaan harga arbitraj positif / negatif.

// Drawing
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);
}

Langkah 4: Dalam fungsi kemasukan utama ((), jalankan kod pra-pemprosesan pra-transaksi, yang hanya akan dijalankan sekali selepas program dimulakan, termasuk:

  • SetErrorFilter (()) untuk menapis maklumat yang tidak penting dalam konsol
  • exchange.IO ( https://www.squadhelp.com/name/exchange.io?lp=dUntuk menetapkan mata wang digital yang akan didagangkan
  • ObjChart reset ( ) untuk membersihkan carta sebelumnya yang digambar sebelum memulakan program
  • LogProfitReset (()) untuk membersihkan maklumat bar status sebelum memulakan program
//entry function
function main() {
    // Filter the unimportant information in the console
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //Set the digital currency to be traded
    ObjChart.reset(); // Clear the previous chart drawn before starting the program
    LogProfitReset(); // Clear the status bar information before starting the program
}

Selepas pra-pemprosesan pra-transaksi di atas ditakrifkan, langkah seterusnya adalah untuk memasuki mod pengundian dan melaksanakan fungsi onTick ()) berulang kali. Ia juga menetapkan masa tidur untuk pengundian Sleep (), kerana API beberapa pertukaran mata wang digital mempunyai had akses terbina dalam untuk tempoh masa tertentu.

//entry function
function main() {
    // Filter the unimportant information in the console
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //Set the digital currency to be traded
    ObjChart.reset(); //Clear the previous chart drawn before starting the program
    LogProfitReset(); //Clear the status bar information before starting the program
    while (true) { // Enter the polling mode
        onTick(); // Execute onTick function
        Sleep(500); // Sleep for 0.5 seconds
    }
}

Dapatkan dan mengira data Langkah 1: Dapatkan objek data asas, baki akaun, dan data penunjuk boll untuk digunakan dalam logik perdagangan.

// Trading conditions
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // Create a basic 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
}

Buat pesanan dan urus susulan Langkah 1: Melakukan operasi membeli dan menjual mengikut logik strategik di atas. Pertama, menilai sama ada harga dan keadaan penunjuk adalah sah, kemudian menilai sama ada keadaan kedudukan adalah sah, dan akhirnya melaksanakan fungsi pesanan perdagangan ()

// Trading conditions
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // Create a basic 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
    // Explanation of the price difference
    // basb = (Sell one price of contract A - Buy one price of contract B)
    // sabb = (Buy one price of contract A - Sell one price of contract B)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // If sabb is higher than the middle track
        if (data.mp(tradeTypeA, 0)) { // Check whether contract A has long orders before placing an order
            data.trade(tradeTypeA, "closebuy"); // Contract A closes long position
        }
        if (data.mp(tradeTypeB, 1)) { // Check whether contract B has short orders before placing an order
            data.trade(tradeTypeB, "closesell"); // Contract B closes short position
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // If basb is lower than the middle track
        if (data.mp(tradeTypeA, 1)) { // Check whether contract A has short orders before placing an order
            data.trade(tradeTypeA, "closesell"); // Contract A closes short position
        }
        if (data.mp(tradeTypeB, 0)) { // Check whether contract B has long orders before placing an order
            data.trade(tradeTypeB, "closebuy"); // Contract B closes long position
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // If there is balance in the account
        if (data.basb < boll.down) { // If basb price difference is lower than the down track
            if (!data.mp(tradeTypeA, 0)) { // Check whether contract A has long orders before placing an order
                data.trade(tradeTypeA, "buy"); // Contract A opens long position
            }
            if (!data.mp(tradeTypeB, 1)) { // Check whether contract B has short orders before placing an order
                data.trade(tradeTypeB, "sell"); // Contract B opens short position
            }
        } else if (data.sabb > boll.up) { // If sabb price difference is higher than the upper track
            if (!data.mp(tradeTypeA, 1)) { // Check whether contract A has short orders before placing an order
                data.trade(tradeTypeA, "sell"); // Contract A opens short position
            }
            if (!data.mp(tradeTypeB, 0)) { // Check whether contract B has long orders before placing an order
                data.trade(tradeTypeB, "buy"); // Contract B opens long position
            }
        }
    }
}

Langkah 2: Selepas pesanan diletakkan, adalah perlu untuk menangani situasi yang tidak normal seperti pesanan yang tidak diselesaikan dan memegang kontrak tunggal.

// Trading conditions
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // Create a basic 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
    // Explanation of the price difference
    //basb = (Sell one price of contract A - Buy one price of contract B)
    // sabb = (Buy one price of contract A - Sell one price of contract B)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // If sabb is higher than the middle track
        if (data.mp(tradeTypeA, 0)) { // Check whether contract A has long orders before placing an order
            data.trade(tradeTypeA, "closebuy"); // Contract A closes long position
        }
        if (data.mp(tradeTypeB, 1)) { // Check whether contract B has short orders before placing an order
            data.trade(tradeTypeB, "closesell"); // Contract B closes short position
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // If basb is lower than the middle track
        if (data.mp(tradeTypeA, 1)) { // Check whether contract A has short orders before placing an order
            data.trade(tradeTypeA, "closesell"); // Contract A closes short position
        }
        if (data.mp(tradeTypeB, 0)) { // Check whether contract B has long orders before placing an order
            data.trade(tradeTypeB, "closebuy"); // Contract B closes long position
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // If there is balance in the account
        if (data.basb < boll.down) { // If basb price difference is lower than the down track
            if (!data.mp(tradeTypeA, 0)) { // Check whether contract A has long orders before placing an order
                data.trade(tradeTypeA, "buy"); // Contract A opens long position
            }
            if (!data.mp(tradeTypeB, 1)) { // Check whether contract B has short orders before placing an order
                data.trade(tradeTypeB, "sell"); // Contract B opens short position
            }
        } else if (data.sabb > boll.up) { // If sabb price difference is higher than the upper track
            if (!data.mp(tradeTypeA, 1)) { // Check whether contract A has short orders before placing an order
                data.trade(tradeTypeA, "sell"); // Contract A opens short position
            }
            if (!data.mp(tradeTypeB, 0)) { // Check whether contract B has long orders before placing an order
                data.trade(tradeTypeB, "buy"); // Contract B opens long position
            }
        }
    }
    data.cancelOrders(); // cancel orders
    data.drawingChart(boll); // drawing
    data.isEven(); // Handle holding individual contracts
}

VI. Strategi Lengkap

Seperti di atas, kami telah mencipta strategi arbitrage cross-period mudah mata wang digital sepenuhnya melalui lebih daripada 200 baris kod.

// Global variable
// Declare a chart object for the configuration chart
var chart = {
    __isStock: true,
    tooltip: {
        xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
    },
    title: {
        text: 'transaction profit and loss curve (detailed)'
    },
    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: 'price difference'
        },
        opposite: false,
    },
    series: [{
        name: "upper track",
        id: "line1,up",
        data: []
    }, {
        name: "middle track",
        id: "line2,middle",
        data: []
    }, {
        name: "down track",
        id: "line3,down",
        data: []
    }, {
        name: "basb",
        id: "line4,basb",
        data: []
    }, {
        name: "sabb",
        id: "line5,sabb",
        data: []
    }]
};
var ObjChart = Chart(chart); // Drawing object
var bars = []; // Storage price difference series
var oldTime = 0; // Record historical data timestamp

// parameters
var tradeTypeA = "this_week"; // Arbitrage A contract
var tradeTypeB = "quarter"; // Arbitrage B contract
var dataLength = 10; //Indicator period length
var timeCycle = 1; // K-line period
var name = "ETC"; // Currencies
var unit = 1; // Order quantity

// basic data
function Data(tradeTypeA, tradeTypeB) { // Pass in arbitrage A contract and arbitrage B contract
    this.accountData = _C(exchange.GetAccount); // Get account information
    this.positionData = _C(exchange.GetPosition); // Get position information
    var recordsData = _C(exchange.GetRecords); //Get K-line data
    exchange.SetContractType(tradeTypeA); // Subscribe to arbitrage A contract
    var depthDataA = _C(exchange.GetDepth); // Arbitrage A contract depth data
    exchange.SetContractType(tradeTypeB); // Subscribe to arbitrage B contract
    var depthDataB = _C(exchange.GetDepth); // Arbitrage B contract depth data
    this.time = recordsData[recordsData.length - 1].Time; // Time to get the latest data
    this.askA = depthDataA.Asks[0].Price; // Sell one price of arbitrage A contract
    this.bidA = depthDataA.Bids[0].Price; // Buy one price of arbitrage A contract
    this.askB = depthDataB.Asks[0].Price; // Sell one price of arbitrage B contract
    this.bidB = depthDataB.Bids[0].Price; // Buy one price of arbitrage B contract
    // Positive arbitrage price difference (Sell one price of contract A - Buy one price of contract B)
    this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
    // Negative arbitrage price difference (Buy one price of contract A - Sell one price of contract B)
    this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}

// Get position
Data.prototype.mp = function (tradeType, type) {
    var positionData = this.positionData; // Get position information
    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;
}

// Synthesis of new K-line data and boll indicator data
Data.prototype.boll = function (num, timeCycle) {
    var self = {}; // Temporary objects
    // Median value of between positive arbitrage price difference and negative arbitrage price difference
    self.Close = (this.basb + this.sabb) / 2;
    if (this.timeA == this.timeB) {
        self.Time = this.time;
    } // Compare two depth data timestamps
    if (this.time - oldTime > timeCycle * 60000) {
        bars.push(self);
        oldTime = this.time;
    } // Pass in the price difference data object into the K-line array according to the specified time period
    if (bars.length > num * 2) {
        bars.shift(); // Control the length of the K-line array
    } 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], // boll indicator upper track
        middle: boll[1][boll[1].length - 1], // boll indicator middle track
        down: boll[2][boll[2].length - 1] // boll indicator down track
    } // Return a processed boll indicator data
}

// Place an order
Data.prototype.trade = function (tradeType, type) {
    exchange.SetContractType(tradeType); // Resubscribe to a contract before placing an order
    var askPrice, bidPrice;
    if (tradeType == tradeTypeA) { // If the order is placed in contract A
        askPrice = this.askA; // Set askPrice
        bidPrice = this.bidA; // Set bidPrice
    } else if (tradeType == tradeTypeB) { // If the order is placed in contract B
        askPrice = this.askB; // Set askPrice
        bidPrice = this.bidB; // Set bidPrice
    }
    switch (type) { // Match order placement mode
        case "buy":
            exchange.SetDirection(type); // Set order placement mode
            return exchange.Buy(askPrice, unit);
        case "sell":
            exchange.SetDirection(type); // Set order placement mode
            return exchange.Sell(bidPrice, unit);
        case "closebuy":
            exchange.SetDirection(type); // Set order placement mode
            return exchange.Sell(bidPrice, unit);
        case "closesell":
            exchange.SetDirection(type); // Set order placement mode
            return exchange.Buy(askPrice, unit);
        default:
            return false;
    }
}

// Cancel orders
Data.prototype.cancelOrders = function () {
    Sleep(500); // Delay before cancellation, because some exchanges, you know what I mean
    var orders = _C(exchange.GetOrders); //Get an array of unfilled orders
    if (orders.length > 0) { // If there are unfilled orders
        for (var i = 0; i < orders.length; i++) { //Iterate through the array of unfilled orders
            exchange.CancelOrder(orders[i].Id); //Cancel unfilled orders one by one
            Sleep(500); //Sleep for 0.5 seconds
        }
        return false; // Return false if an unfilled order is cancelled
    }
    return true; //Return true if there are no unfilled orders
}

// Handle holding individual contracts
Data.prototype.isEven = function () {
    var positionData = this.positionData; // Get position information
    var type = null; // Switch position direction
    // If the remaining 2 of the position array length is not equal to 0 or the position array length is not equal to 2
    if (positionData.length % 2 != 0 || positionData.length != 2) {
        for (var i = 0; i < positionData.length; i++) { // Iterate through the position array
            if (positionData[i].Type == 0) { // If it is a long order
                type = 10; // Set order parameters
            } else if (positionData[i].Type == 1) { // If it is a short order
                type = -10; // Set order parameters
            }
            // Close all positions
            this.trade(positionData[i].ContractType, type, positionData[i].Amount);
        }
    }
}

// Drawing
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 conditions
function onTick() {
    var data = new Data(tradeTypeA, tradeTypeB); // Create a basic 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
    // Explanation of price difference
    // basb = (Sell one price of contract A - Buy one price of contract B)
    // sabb = (Buy one price of contract A - Sell one price of contract B)
    if (data.sabb > boll.middle && data.sabb < boll.up) { // If sabb is higher than the middle track
        if (data.mp(tradeTypeA, 0)) { // Check whether contract A has long orders before placing an order
            data.trade(tradeTypeA, "closebuy"); // Contract A closes long position
        }
        if (data.mp(tradeTypeB, 1)) { // Check whether contract B has short orders before placing an order
            data.trade(tradeTypeB, "closesell"); // Contract B closes short position
        }
    } else if (data.basb < boll.middle && data.basb > boll.down) { // If basb is lower than the middle track
        if (data.mp(tradeTypeA, 1)) { // Check whether contract A has short orders before placing an order
            data.trade(tradeTypeA, "closesell"); // Contract A closes short position
        }
        if (data.mp(tradeTypeB, 0)) { // Check whether contract B has long orders before placing an order
            data.trade(tradeTypeB, "closebuy"); // Contract B closes long position
        }
    }
    if (accountStocks * Math.max(data.askA, data.askB) > 1) { // If there is a balance in the account
        if (data.basb < boll.down) { // If basb price difference is lower than the down track
            if (!data.mp(tradeTypeA, 0)) { // Check whether contract A has long orders before placing an order
                data.trade(tradeTypeA, "buy"); // Contract A opens long position
            }
            if (!data.mp(tradeTypeB, 1)) { // Check whether contract B has short orders before placing an order
                data.trade(tradeTypeB, "sell"); // Contract B opens short position
            }
        } else if (data.sabb > boll.up) { // If sabb price difference is higher than the upper track
            if (!data.mp(tradeTypeA, 1)) { // Check whether contract A has short orders before placing an order
                data.trade(tradeTypeA, "sell"); // Contract A opens short position
            }
            if (!data.mp(tradeTypeB, 0)) { // Check whether contract B has long orders before placing an order
                data.trade(tradeTypeB, "buy"); // Contract B opens long position
            }
        }
    }
    data.cancelOrders(); // Cancel orders
    data.drawingChart(boll); // Drawing
    data.isEven(); // Handle holding individual contracts
}

//Entry function
function main() {
    // Filter unimportant information in the console
    SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
    exchange.IO("currency", name + '_USDT'); //Set the digital currency to be traded
    ObjChart.reset(); //Clear the previous chart drawn before starting the program
    LogProfitReset(); //Clear the status bar information before starting the program
    while (true) { // Enter polling mode
        onTick(); // Execute the onTick function
        Sleep(500); // Sleep for 0.5 seconds
    }
}

Alamat strategi:https://www.fmz.com/strategy/104964

VII. Ringkasan

Strategi dalam artikel ini hanyalah contoh. Bot sebenar tidak mudah, tetapi anda boleh mengikuti contohnya dan menggunakan imaginasi liar anda sendiri Perlu diingatkan bahawa, berdasarkan pengalaman terhad saya, di pasaran mata wang digital semasa, hampir semua strategi arbitraj niaga hadapan-masa depan murni tidak layak dijalankan, sama ada ia adalah arbitraj segitiga bebas risiko atau arbitraj rentas pasaran. Sebabnya adalah bahawa tidak kira pasaran niaga hadapan pertukaran mata wang digital mana, marginnya bukan mata wang sah. Pada masa ini, hampir semua mata wang digital telah jatuh kira-kira 70% sejak awal tahun ini. Maksudnya, strategi selalu untuk memperoleh mata wang, tetapi harga mata wang menurun. Secara keseluruhan, pasaran mata wang digital nampaknya telah terlepas dari blockchain. Seperti bunga tulip pada masa itu, harga selalu berasal dari harapan dan keyakinan orang, dan keyakinan berasal dari harga...


Berkaitan

Lebih lanjut