Khóa học Blockchain Quantitative Investment Series (3) Calender Spread Arbitrage

Tác giả:màu đỏ, Tạo: 2018-08-27 16:49:50, Cập nhật:

NO.1 Trong cuốn sách Financial Alchemy được Soros viết năm 1987, một đề xuất quan trọng đã được đưa ra: Tôi tin rằng giá thị trường luôn luôn sai trong ý nghĩa rằng chúng trình bày một cái nhìn thiên vị về tương lai. Giả thuyết giá trị thị trường chỉ là một giả định lý thuyết. Trên thực tế, những người tham gia thị trường không phải lúc nào cũng hợp lý, và tại mỗi thời điểm, những người tham gia không thể hoàn toàn có được và giải thích khách quan tất cả các thông tin. Ngay cả khi đó là cùng một thông tin, phản hồi của mọi người là khác nhau.

Nói cách khác, giá bản thân nó đã chứa những kỳ vọng sai lầm của những người tham gia thị trường, vì vậy về bản chất giá thị trường luôn luôn sai.

img

NO.2 Dựa trên các nguyên tắc trên, chúng tôi cũng biết rằng trong một thị trường tương lai không hiệu quả, tác động của thị trường của các hợp đồng giao hàng trong các giai đoạn khác nhau không phải lúc nào cũng đồng bộ và giá cả không phải là lý do cho hiệu quả hoàn toàn.

Sau đó, dựa trên giá của hợp đồng giao hàng tại các thời điểm khác nhau của cùng một mục tiêu giao dịch, nếu có sự chênh lệch lớn giữa hai giá, có thể đồng thời giao dịch các hợp đồng tương lai của các giai đoạn khác nhau và thực hiện sự phân phối giữa thời gian. Giống như hợp đồng tương lai hàng hóa, các loại tiền kỹ thuật số cũng có danh mục hợp đồng trọng tài liên tục liên quan đến chúng.

Ví dụ, giả sử chênh lệch giữa tuần ETC và quý ETC được duy trì ở khoảng 5 trong một thời gian dài. Nếu chênh lệch đạt 7, chúng ta mong đợi chênh lệch sẽ trở lại 5 vào một thời điểm nào đó trong tương lai. Sau đó bạn có thể bán tuần ETC và mua quý ETC để rút ngắn chênh lệch. ngược lại.

Số 3 Mặc dù chênh lệch này tồn tại, nhưng thường có nhiều sự không chắc chắn trong sự điều chỉnh thủ công do mất nhiều thời gian, không chính xác của các hoạt động thủ công và tác động thay đổi giá.

Thông qua mô hình định lượng để nắm bắt các cơ hội trọng tài và phát triển các chiến lược giao dịch trọng tài, cũng như các thuật toán lập trình tự động phát hành lệnh giao dịch cho sàn giao dịch, để nhanh chóng và chính xác nắm bắt các cơ hội và thu nhập hiệu quả, đó là nét quyến rũ của trọng tài định lượng.

img

Bài viết này sẽ dạy bạn cách sử dụng nền tảng giao dịch định lượng FMZ và hợp đồng tương lai ETC trong sàn giao dịch OkEX trong giao dịch tiền tệ kỹ thuật số, với một chiến lược trọng tài đơn giản để chứng minh cách nắm bắt các cơ hội trọng tài ngay lập tức và nắm bắt mọi lợi nhuận có thể nhìn thấy trong khi đồng thời bảo hiểm rủi ro có thể gặp phải.

Số 4 Tạo ra một chiến lược điều khoản giữa thời gian và tiền tệ kỹ thuật số Khó khăn: mức bình thường Môi trường chiến lược: Mục tiêu giao dịch: Ethereum classic (ETC) Dữ liệu chênh lệch: ETC hàng tuần - ETC hàng quý Thời gian giao dịch: 5 phút Khớp vị trí: 1:1 Loại giao dịch: cùng một loại giữa thời gian Chiến lược logic: Điều kiện mua vị trí chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch bán hàng.

Điều kiện vị trí bán ngắn: Nếu tài khoản vãng lai không có vị trí và chênh lệch cao hơn đường ray tăng của chỉ số boll, đặt lệnh chênh lệch, đó là: bán ETC ngắn hàng tuần, mua ETC dài hàng quý.

Khóa điều kiện vị trí mua chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch chênh lệch

Khóa điều kiện vị trí bán ngắn: Nếu tài khoản vãng lai giữ một vị trí ngắn hàng tuần ETC và giữ một vị trí dài hàng quý ETC, và chênh lệch thấp hơn đường sắt giữa của chỉ số boll, đặt lệnh bán gần, đó là: mua để trang trải ETC hàng tuần, bán ETC hàng quý.

NO.5 Điều trên là một mô tả đơn giản về chiến lược phân phối tiền kỹ thuật số, sau đó làm thế nào để thực hiện ý tưởng của riêng bạn trong chương trình? Khung chiến lược:

img

Khung chiến lược có thể dễ dàng được xây dựng theo suy nghĩ chiến lược và quá trình giao dịch. Toàn bộ chiến lược có thể được đơn giản hóa thành ba bước:

  1. Xử lý trước trước giao dịch.
  2. Nhận và tính toán dữ liệu.
  3. Đặt đơn đặt hàng và theo dõi.

NO.6 Tiếp theo, chúng ta cần phải điền vào các chi tiết cần thiết trong khuôn khổ chiến lược dựa trên quy trình giao dịch thực tế và chi tiết giao dịch.

Thứ nhất, xử lý trước giao dịch Bước 1: Trong môi trường toàn cầu, khai báo các biến toàn cầu cần thiết. Xác định đối tượng biểu đồ cấu hình biểu đồ Biểu đồ Var = { } Gọi hàm Chart để khởi tạo biểu đồ Var ObjChart = Biểu đồ (biểu đồ) Xác định một mảng trống để lưu trữ chuỗi phân bố Var bar = [ ] Xác định một biến dấu thời gian ghi lại dữ liệu lịch sử Var oldTime = 0 Bước 2: Thiết lập các tham số bên ngoài cho chiến lược.

img

Bước 3: Xác định chức năng xử lý dữ liệu Chức năng dữ liệu cơ bản: Dữ liệu ()) Tạo một cấu trúc dữ liệu và xác định thuộc tính nội bộ của nó, bao gồm: dữ liệu tài khoản, dữ liệu vị trí, dấu thời gian dữ liệu K-line, giá mua / bán mới nhất của hợp đồng phân phối A / B, chênh lệch phân phối tích cực / đảo ngược

img

Nhận chức năng vị trí: mp ()) Kiểm tra qua toàn bộ mảng các vị trí, trả về hợp đồng được chỉ định và số lượng các vị trí theo hướng được chỉ định. trả về sai nếu không có.

img

Dòng K và chức năng chỉ số: boll ()) Kết hợp một chuỗi K-line mới dựa trên dữ liệu của chênh lệch chênh lệch tích cực / đảo ngược. Và trả lại dữ liệu đường ray lên / giữa / xuống được tính bằng chỉ số boll.

img

Chức năng lệnh: giao dịch ()) Nhập tên hợp đồng lệnh và loại giao dịch, sau đó đặt lệnh ở mức giá mua/bán gần nhất và trả lại kết quả sau khi đặt lệnh.

img

Chức năng hủy lệnh: cancelOrders ()) Nhận hàng loạt tất cả các đơn đặt hàng đang chờ và hủy bỏ chúng một một. và nếu có đơn đặt hàng đang chờ, trả về sai, và nếu không có, trả về đúng.

img

Hợp đồng duy nhất: isEven ()) Trong trường hợp tình huống một chân trong giao dịch chênh lệch giá, nó được xử lý trực tiếp bằng cách chỉ đơn giản là đóng tất cả các vị trí.

img

Chức năng vẽ biểu đồ: vẽBản đồ ()) Gọi phương pháp ObjChart.add ( ) để vẽ dữ liệu thị trường và dữ liệu chỉ số cần thiết trong biểu đồ: tăng, trung bình, giảm đường ray, chênh lệch tỷ lệ chênh lệch tích cực / đảo ngược.

img

Bước 4: Trong hàm nhập main (), thực hiện mã xử lý trước trước giao dịch, chỉ chạy một lần sau khi chương trình bắt đầu, bao gồm:

lọc thông tin không quan trọng trong bảng điều khiển SetErrorFilter ()) Thiết lập loại tiền tệ kỹ thuật số để giao dịchexchange.IO()) Xóa biểu đồ được vẽ trước khi chương trình bắt đầu ObjChart.reset ()) Xóa thông tin thanh trạng thái trước khi chương trình bắt đầu LogProfitReset ())

img

NO.7 Sau khi xác định quá trình xử lý trước trước giao dịch ở trên, cần phải chuyển sang bước tiếp theo, nhập chế độ thăm dò và lặp lại hàm onTick (). Và đặt thời gian ngủ khi bỏ phiếu, bởi vì một số API của sàn giao dịch tiền kỹ thuật số có giới hạn truy cập tích hợp trong một khoảng thời gian nhất định.

img

Thứ hai, lấy và tính toán dữ liệu Bước 1: Nhận đối tượng dữ liệu cơ bản, số dư tài khoản và dữ liệu chỉ số boll cho logic giao dịch.

img

Thứ ba, đặt hàng và theo dõi Bước 1: Thực hiện giao dịch mua và bán theo logic chiến lược ở trên. Đầu tiên, kiểm tra xem các điều kiện giá và chỉ số có đúng không, sau đó kiểm tra xem các điều kiện vị trí có đúng không, và cuối cùng thực hiện chức năng lệnh giao dịch ().

img

Bước 2: Sau khi đặt hàng, cần phải giải quyết các tình huống bất thường như các đơn đặt hàng đang chờ và giữ hợp đồng duy nhất, và vẽ biểu đồ.

img

Số 8 Ở trên, chúng tôi đã tạo ra một chiến lược điều khoản tiền kỹ thuật số đơn giản thông qua hơn 200 dòng.

img

NO.9 Thị trường thực sự không đơn giản như vậy, nhưng bạn có thể sử dụng ví dụ này để chơi với trí tưởng tượng của bạn.

Điều cần được nhắc nhở là, dựa trên kinh nghiệm hạn chế của tôi, chiến lược điều chỉnh thời gian thuần túy về cơ bản không đáng để chạy trong tình hình thị trường tiền kỹ thuật số hiện tại, cho dù đó là điều chỉnh tam giác không rủi ro hoặc điều chỉnh thị trường chéo.

Lý do là bất kể thị trường tương lai của sàn giao dịch tiền kỹ thuật số nào, biên không phải là fiat. Hầu như tất cả các loại tiền kỹ thuật số đã giảm khoảng 70% kể từ đầu năm. Nói cách khác, chiến lược luôn tạo ra tiền tệ, nhưng giá của tiền tệ đang giảm.

Nhìn rộng hơn, thị trường tiền kỹ thuật số đã rời khỏi blockchain. Cũng giống như hoa tulip, giá luôn luôn xuất phát từ sự kỳ vọng và niềm tin của mọi người, và niềm tin xuất phát từ giá...

ở đây để có được mã đầy đủ:

// 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
    }
}


Thêm nữa

Giấc mơ nhỏTốt lắm!