조지 소로스는 1987년에 쓴?? 금융의 화학?? 에서 중요한 주장을 내놓았다. 나는 시장 가격이 미래에 대한 편향된 시각을 제시한다는 점에서 항상 틀린다고 믿는다. 시장 효율성 가설은 이론적인 가설에 불과하다. 실제로 시장 참여자는 항상 합리적이지 않으며, 각 시점에서 참가자는 모든 정보를 완전히 얻고 객관적으로 해석할 수 없다. 게다가, 동일한 정보일지라도 모든 사람들의 피드백은 다르다. 즉, 가격 자체는 이미 시장 참여자의 잘못된 기대를 포함하고 있기 때문에 본질적으로 시장 가격은 항상 틀린다. 이것은 중재자의 수익원일 수 있다.
위의 원칙에 따르면, 비효율적인 선물 시장에서, 시장의 영향이 서로 다른 기간의 배달 계약에 미치는 이유는 항상 동기화되지 않으며, 가격 결정도 완전히 효과적이지 않다는 것을 알 수 있습니다. 그런 다음, 서로 다른 기간의 동일한 거래 대상의 배달 계약 가격에 따라 두 가격 사이에 큰 가격 차이가있는 경우, 우리는 기간 중재를 위해 서로 다른 기간의 선물 계약을 동시에 구매하고 판매 할 수 있습니다. 상품 선물과 마찬가지로 디지털 화폐에도 기간 중재 계약 포트폴리오가 있습니다. 예를 들어, OKEX 거래소에는: ETC 현재 주, ETC 다음 주, ETC 분기. 예를 들어, 현재 주 ETC와 ETC의 분기 사이의 가격 차이는 오랫동안 5에 가깝다고 가정합니다. 가격 차이는 어느 날 7에 도달하면 가격 차이는 미래에 5으로 돌아갈 것으로 예상됩니다. 그 다음 우리는 그 주 ETC를 판매하고 동시에 ETC 분기를 구입하여 가격 차이를 단축시킬 수 있습니다. 이러한 가격 차이는 존재하지만 시간이 많이 걸리는 수동 작업, 정확도가 떨어지고 가격 변화의 영향으로 인해 수동 중재에 많은 불확실성이 있습니다. 양적 중재의 매력은 양적 모델과 중재 거래 전략을 수립하여 중재 기회를 포착하고 프로그래밍 알고리즘을 통해 거래소에 자동으로 거래 명령을 배치하여 기회를 빠르고 정확하게 포착하고 효율적이고 안정적으로 수익을 창출하는 데 있습니다.
이 기사에서는 FMZ 퀀트 트레이딩 플랫폼과 OKEX 거래소에서 ETC 선물 계약을 사용하는 방법을 알려줍니다. 간단한 중재 전략으로 즉각적인 중재 기회를 포착하고 매번 볼 수있는 이익을 포착하고 디지털 통화 거래에서 발생할 수있는 위험을 헤지하는 방법을 보여줍니다.
어려움: 정상
위의 것은 디지털 화폐의 크로스 기간 중재 전략의 간단한 논리적 설명입니다. 그래서 프로그램에 우리의 아이디어를 구현하는 방법? 우리는 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
}
}
전략 프레임워크는 전략 아이디어와 거래 프로세스에 따라 쉽게 설정 될 수 있습니다. 전체 전략은 세 단계로 단순화 될 수 있습니다. 거래 전에 사전 처리. 데이터를 수집하고 계산합니다. 주문하고 나중에 처리해 다음으로, 우리는 실제 거래 과정과 거래 세부 사항에 따라 전략 프레임워크에 필요한 세부 코드를 작성해야합니다.
거래 전 사전 처리 단계 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(에서, 프로그램을 시작 한 후에 한 번만 실행되는 전 거래 전 처리 코드를 실행합니다.
//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
}
위와 같이, 우리는 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
이 문서의 전략은 단지 한 예입니다. 실제 봇은 간단하지 않지만 예를 따라 자신의 야생 상상력을 사용할 수 있습니다. 현재의 디지털 통화 시장에서 제 제한된 경험에 따라 거의 모든 순수한 선물-미래 중재 전략이 위험 없는 삼각형 중재 또는 크로스 마켓 중재이든 실행할 가치가 없다는 것을 상기시켜야합니다. 그 이유는 어떤 디지털 화폐 교환 선물 시장이든, 그 마진이 합법적인 화폐가 아니라는 것입니다. 현재, 거의 모든 디지털 화폐는 올해 초부터 약 70% 감소했습니다. 즉, 전략은 항상 화폐를 얻는 것이지만 통화 가격이 감소하고 있습니다. 전반적으로, 디지털 화폐 시장은 블록체인에서 분리 된 것 같습니다. 그 당시의 툴립과 마찬가지로 가격은 항상 사람들의 기대와 신뢰에서 비롯되며 신뢰는 가격에서 발생합니다.