볼링거 밴드 기반의 디지털 화폐의 횡단 기간 중재 전략

저자:리디아, 창작: 2022-12-02 16:58:27, 업데이트: 2023-09-20 09:33:29

img

볼링거 밴드 기반의 디지털 화폐의 횡단 기간 중재 전략

요약

조지 소로스는 1987년에 쓴?? 금융의 화학?? 에서 중요한 주장을 내놓았다. 나는 시장 가격이 미래에 대한 편향된 시각을 제시한다는 점에서 항상 틀린다고 믿는다. 시장 효율성 가설은 이론적인 가설에 불과하다. 실제로 시장 참여자는 항상 합리적이지 않으며, 각 시점에서 참가자는 모든 정보를 완전히 얻고 객관적으로 해석할 수 없다. 게다가, 동일한 정보일지라도 모든 사람들의 피드백은 다르다. 즉, 가격 자체는 이미 시장 참여자의 잘못된 기대를 포함하고 있기 때문에 본질적으로 시장 가격은 항상 틀린다. 이것은 중재자의 수익원일 수 있다.

전략적 원칙

위의 원칙에 따르면, 비효율적인 선물 시장에서, 시장의 영향이 서로 다른 기간의 배달 계약에 미치는 이유는 항상 동기화되지 않으며, 가격 결정도 완전히 효과적이지 않다는 것을 알 수 있습니다. 그런 다음, 서로 다른 기간의 동일한 거래 대상의 배달 계약 가격에 따라 두 가격 사이에 큰 가격 차이가있는 경우, 우리는 기간 중재를 위해 서로 다른 기간의 선물 계약을 동시에 구매하고 판매 할 수 있습니다. 상품 선물과 마찬가지로 디지털 화폐에도 기간 중재 계약 포트폴리오가 있습니다. 예를 들어, OKEX 거래소에는: ETC 현재 주, ETC 다음 주, ETC 분기. 예를 들어, 현재 주 ETC와 ETC의 분기 사이의 가격 차이는 오랫동안 5에 가깝다고 가정합니다. 가격 차이는 어느 날 7에 도달하면 가격 차이는 미래에 5으로 돌아갈 것으로 예상됩니다. 그 다음 우리는 그 주 ETC를 판매하고 동시에 ETC 분기를 구입하여 가격 차이를 단축시킬 수 있습니다. 이러한 가격 차이는 존재하지만 시간이 많이 걸리는 수동 작업, 정확도가 떨어지고 가격 변화의 영향으로 인해 수동 중재에 많은 불확실성이 있습니다. 양적 중재의 매력은 양적 모델과 중재 거래 전략을 수립하여 중재 기회를 포착하고 프로그래밍 알고리즘을 통해 거래소에 자동으로 거래 명령을 배치하여 기회를 빠르고 정확하게 포착하고 효율적이고 안정적으로 수익을 창출하는 데 있습니다.

III. 전략 논리

이 기사에서는 FMZ 퀀트 트레이딩 플랫폼과 OKEX 거래소에서 ETC 선물 계약을 사용하는 방법을 알려줍니다. 간단한 중재 전략으로 즉각적인 중재 기회를 포착하고 매번 볼 수있는 이익을 포착하고 디지털 통화 거래에서 발생할 수있는 위험을 헤지하는 방법을 보여줍니다.

디지털 화폐를 위한 횡단 기간 중재 전략을 만들자

어려움: 정상

전략 환경

  • 거래 대상: 이더 클래식 (ETC)
  • 스프레드 데이터: 현재 주 ETC - ETC 분기 (동결합 테스트를 생략)
  • 거래 기간: 5분
  • 위치 일치: 1:1
  • 거래 유형: 같은 유형의 크로스 기간

전략 논리

  • 가격 차이로 긴 지점을 개설하는 조건: 현재 계좌에 지점이 없으며 가격 차이가 볼의 하위 경계보다 작으면 가격 차이를 길게합니다. 즉, 주간 개설 지점을 구매하고 분기 개설 지점을 판매합니다.
  • 가격 차이에 짧은 지점을 개설하는 조건: 현재 계좌에 지점이 없다면 가격 차이가 볼의 상위 경계보다 크다면 가격 차이에 짧은 지점을 개설합니다. 즉, 주간 개설 지점을 판매하고, 분기 개설 지점을 구매합니다.
  • 가격 차이로 긴 포지션을 닫는 조건: 현재 주에서 주류 계좌가 ETC의 긴 장기 주문을 보유하고 있고 ETC 분기에 짧은 장기 주문을 보유하고 있으며 가격 차이는 볼의 중간 경계보다 크다면 가격 차이를 긴 기간 동안 닫습니다. 즉, 일주일 동안 ETC의 폐쇄 포지션을 판매하고 분기에 ETC의 폐쇄 포지션을 구매하십시오.
  • 가격 차이를 짧게하는 포지션 폐쇄 조건: 주류 계좌가 현재 주에 ETC의 짧은 주문을 유지하고, ETC 분기에 긴 주문을 유지하고, 가격 차이는 볼의 중간 경계보다 작으면 가격 차이를 짧게 닫습니다. 즉, 일주일 동안 ETC를 닫는 포지션을 구입하고, 분기에 ETC를 닫는 포지션을 판매하십시오.

IV. 전략 프레임워크를 작성

위의 것은 디지털 화폐의 크로스 기간 중재 전략의 간단한 논리적 설명입니다. 그래서 프로그램에 우리의 아이디어를 구현하는 방법? 우리는 FMZ 양자 거래 플랫폼에 프레임워크를 구축하려고합니다.

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. 전략 작성

전략 프레임워크는 전략 아이디어와 거래 프로세스에 따라 쉽게 설정 될 수 있습니다. 전체 전략은 세 단계로 단순화 될 수 있습니다. 거래 전에 사전 처리. 데이터를 수집하고 계산합니다. 주문하고 나중에 처리해 다음으로, 우리는 실제 거래 과정과 거래 세부 사항에 따라 전략 프레임워크에 필요한 세부 코드를 작성해야합니다.

거래 전 사전 처리 단계 1: 글로벌 범위에 필요한 글로벌 변수를 선언합니다.

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

단계 2: 전략의 외부 매개 변수를 구성합니다.

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

단계 3: 데이터 처리 기능을 정의 기본 데이터 함수: 데이터 생성자, 데이터, 및 내부 속성을 정의합니다. 포함: 계정 데이터, 위치 데이터, K-라인 데이터 시간표, 중재 A / B 계약의 구매 / 판매 가격, 그리고 긍정적 / 부정적인 중재 가격 차이.

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

위치 함수를 얻으십시오: mp ()) 전체 위치 배열을 통과 하 고 지정 된 계약 및 방향의 위치 양을 반환 합니다. 그렇지 않으면 false를 반환

// 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선 및 표시기 기능: boll ((() 새로운 K-라인 염기서열은 긍정적 인 중재 / 부정적 중재 가격 차이 데이터에 따라 합성됩니다. 볼 표시기로 계산된 상단 트랙, 중단 트랙 및 하단 트랙의 데이터가 반환됩니다.

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

오더 기능: 거래 주문 계약 이름과 주문 유형을 입력 하 고, 그 다음 대조로 주문을 배치 하 고, 주문을 배치 한 후 결과를 반환 합니다. 동시에 다른 방향으로 두 주문을 배치 할 필요가 있기 때문에, 구매 / 판매 한 가격은 주문의 계약 이름에 따라 함수 내에서 변환 됩니다.

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

주문 취소 기능: 주문 취소() 모든 미수 주문을 배열하고 하나씩 취소합니다. 또한, 미수 주문이 있으면 거짓이 반환되고, 미수 주문이 없다면 진실이 반환됩니다.

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

단일 계약을 보유하는 핸들: isEven ((() 중재 거래의 단일 다리의 경우, 우리는 단순히 모든 포지션을 닫을 것입니다. 물론, 그것은 또한 추적 방법에 변경 될 수 있습니다.

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

도면 함수: 도면 도표 ()) ObjChart Add () 방법을 호출하고, 그래프에 필요한 시장 데이터와 지표 데이터를 그리십시오: 상단 트랙, 중단 트랙, 하단 트랙, 긍정적 / 부정적인 중재 가격 차이.

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

단계 4: 입력 함수 main(에서, 프로그램을 시작 한 후에 한 번만 실행되는 전 거래 전 처리 코드를 실행합니다.

  • SetErrorFilter (()) 콘솔에서 중요하지 않은 정보를 필터링
  • exchange.IO ( https://www.squadhelp.com/name/exchange.io?lp=d거래될 디지털 화폐를 설정하기 위해
  • ObjChart 재설정 ()) 프로그램을 시작하기 전에 그려진 이전 차트를 삭제
  • LogProfitReset (()) 프로그램을 시작하기 전에 상태 표시줄 정보를 삭제
//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
}

위 트랜잭션 전 사전 처리가 정의 된 후 다음 단계는 투표 모드에 들어가 onTick ()) 함수를 반복적으로 실행하는 것입니다. 일부 디지털 통화 거래소의 API가 특정 기간 동안 액세스 제한을 내장하고 있기 때문에 Sleep () 투표의 수면 시간을 설정합니다.

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

데이터를 얻고 계산합니다 단계 1: 거래 논리에서 사용하기 위해 기본 데이터 객체, 계좌 잔금 및 boll 지표 데이터를 얻으십시오.

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

주문하고 후속 작업을 처리합니다. 단계 1: 위의 전략적 논리에 따라 구매 및 판매 작업을 실행하십시오. 먼저 가격 및 지표 조건이 유효하는지 판단하고 위치 조건이 유효하는지 판단하고 마지막으로 거래 () 주문 기능을 실행하십시오.

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

단계 2: 주문이 배치 된 후, 해결되지 않은 주문과 단일 계약의 보유와 같은 비정상적인 상황을 처리해야합니다. 그리고 차트를 그리십시오.

// 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. 전체 전략

위와 같이, 우리는 200 줄 이상의 코드를 통해 디지털 화폐의 간단한 크로스 기간 중재 전략을 완전히 만들었습니다. 전체 코드는 다음과 같습니다.

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

전략 주소:https://www.fmz.com/strategy/104964

VII. 요약

이 문서의 전략은 단지 한 예입니다. 실제 봇은 간단하지 않지만 예를 따라 자신의 야생 상상력을 사용할 수 있습니다. 현재의 디지털 통화 시장에서 제 제한된 경험에 따라 거의 모든 순수한 선물-미래 중재 전략이 위험 없는 삼각형 중재 또는 크로스 마켓 중재이든 실행할 가치가 없다는 것을 상기시켜야합니다. 그 이유는 어떤 디지털 화폐 교환 선물 시장이든, 그 마진이 합법적인 화폐가 아니라는 것입니다. 현재, 거의 모든 디지털 화폐는 올해 초부터 약 70% 감소했습니다. 즉, 전략은 항상 화폐를 얻는 것이지만 통화 가격이 감소하고 있습니다. 전반적으로, 디지털 화폐 시장은 블록체인에서 분리 된 것 같습니다. 그 당시의 툴립과 마찬가지로 가격은 항상 사람들의 기대와 신뢰에서 비롯되며 신뢰는 가격에서 발생합니다.


관련

더 많은