
Trong cuốn sách The Alchemy of Finance được viết năm 1987, Soros đã từng đưa ra một đề xuất quan trọng: Tôi tin rằng giá thị trường luôn sai theo nghĩa là chúng thể hiện quan điểm thiên vị về tương lai. Giả thuyết thị trường hiệu quả chỉ là một lý thuyết. Trong thực tế, những người tham gia thị trường không phải lúc nào cũng lý trí, và tại mọi thời điểm, người tham gia không thể có được đầy đủ và diễn giải khách quan mọi thông tin. Hơn nữa, ngay cả khi thông tin giống nhau, phản hồi của mọi người cũng khác nhau. Thay đổi. Nói cách khác, bản thân giá cả đã bao gồm những kỳ vọng sai lầm của những người tham gia thị trường, do đó về bản chất, giá thị trường luôn sai. Đây có thể là nguồn lợi nhuận cho những người kinh doanh chênh lệch giá.
Dựa trên các nguyên tắc trên, chúng ta 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 lên 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ủa chúng không hoàn toàn hiệu quả. Sau đó, dựa trên giá hợp đồng giao dịch của cùng một đối tượng giao dịch ở các thời điểm khác nhau, nếu có sự chênh lệch giá lớn giữa hai mức giá, bạn có thể mua và bán hợp đồng tương lai của các thời điểm khác nhau cùng một lúc để tiến hành giao dịch chênh lệch giá chéo thời điểm. Giống như hợp đồng tương lai hàng hóa, tiền kỹ thuật số cũng có sự kết hợp của các hợp đồng chênh lệch giá xuyên thời kỳ liên quan đến chúng. Ví dụ, trên sàn giao dịch OkEX, có: ETC Weekly, ETC Biweekly và ETC Quarterly.
Ví dụ, giả sử chênh lệch giá giữa ETC hàng tuần và ETC hàng quý vẫn ở mức khoảng 5 trong một thời gian dài. Nếu mức chênh lệch đạt 7 vào một ngày nào đó, chúng tôi dự kiến mức chênh lệch sẽ trở lại mức 5 vào một thời điểm nào đó trong tương lai. Sau đó, bạn có thể bán ETC hàng tuần và mua ETC hàng quý để bán khống chênh lệch. ngược lại. Mặc dù có sự chênh lệch giá này, nhưng hoạt động kinh doanh chênh lệch giá thủ công thường tiềm ẩn nhiều yếu tố không chắc chắn do thao tác thủ công tốn thời gian, độ chính xác kém và tác động của những thay đổi về giá. Sự hấp dẫn của giao dịch chênh lệch giá định lượng nằm ở việc nắm bắt cơ hội chênh lệch giá thông qua các mô hình định lượng và xây dựng chiến lược giao dịch chênh lệch giá, cũng như tự động đặt lệnh giao dịch vào các sàn giao dịch thông qua các thuật toán được lập trình, nhằm nắm bắt cơ hội một cách nhanh chóng và chính xác, đồng thời kiếm lợi nhuận một cách hiệu quả và ổn định.
Bài viết này sẽ hướng dẫn bạn cách sử dụng Nền tảng giao dịch định lượng Inventor và hợp đồng tương lai ETC trên sàn giao dịch OkEX trong giao dịch tiền kỹ thuật số, sử dụng chiến lược chênh lệch giá đơn giản để chứng minh cách nắm bắt cơ hội chênh lệch giá tức thời và nắm bắt mọi cơ hội để thấy Lợi nhuận trong khi phòng ngừa rủi ro những rủi ro có thể xảy ra.
Tạo chiến lược chênh lệch giá xuyên thời kỳ tiền điện tử Độ khó: Bình thường
Môi trường chiến lược
Chiến lược Logic
Trên đây là mô tả đơn giản về logic của chiến lược chênh lệch giá xuyên thời kỳ tiền kỹ thuật số. Vậy bạn triển khai ý tưởng của mình vào chương trình như thế nào? Đầu tiên, chúng tôi đã thử xây dựng khuôn khổ trên Nền tảng giao dịch định lượng Inventor.
function Data() {} // 基础数据函数
Data.prototype.mp = function () {} // 持仓函数
Data.prototype.boll = function () {} // 指标函数
Data.prototype.trade = function () {} // 下单函数
Data.prototype.cancelOrders = function () {} // 撤单函数
Data.prototype.isEven = function () {} // 处理单只合约函数
Data.prototype.drawingChart = function () {} // 画图函数
// 交易条件
function onTick() {
var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
var accountStocks = data.accountData.Stocks; // 账户余额
var boll = data.boll(dataLength, timeCycle); // 计算boll技术指标
data.trade(); // 计算交易条件下单
data.cancelOrders(); // 撤单
data.drawingChart(boll); // 画图
data.isEven(); // 处理持有单个合约
}
//入口函数
function main() {
while (true) { // 进入轮询模式
onTick(); // 执行onTick函数
Sleep(500); // 休眠0.5秒
}
}
Bằng cách so sánh các ý tưởng chiến lược và quy trình giao dịch, bạn có thể dễ dàng xây dựng một khuôn khổ chiến lược. Toàn bộ chiến lược có thể được đơn giản hóa thành ba bước:
Tiếp theo, chúng ta cần điền mã chi tiết cần thiết vào khung chiến lược dựa trên quy trình giao dịch thực tế và thông tin chi tiết về giao dịch.
Xử lý trước giao dịch Bước 1: Trong môi trường toàn cục, khai báo các biến toàn cục cần thiết.
//声明一个配置图表的 chart 对象
var chart = { }
//调用 Chart 函数,初始化图表
var ObjChart = Chart ( chart )
//声明一个空数组,用来存储价差序列
var bars = [ ]
//声明一个记录历史数据时间戳变量
var oldTime = 0
Bước 2: Cấu hình các tham số bên ngoài của chiến lược.
// 参数
var tradeTypeA = "this_week"; // 套利A合约
var tradeTypeB = "quarter"; // 套利B合约
var dataLength = 10; //指标周期长度
var timeCycle = 1; // K线周期
var name = "ETC"; // 币种
var unit = 1; // 下单量
Bước 3: Xác định các chức năng xử lý dữ liệu Hàm dữ liệu cơ bản: Data ( ) Tạo một hàm tạo Data và xác định các thuộc tính bên trong của nó. Bao gồm: dữ liệu tài khoản, dữ liệu vị thế, dấu thời gian dữ liệu K-line, giá mua/bán hợp đồng A/B chênh lệch giá và chênh lệch giá kỳ hạn/ngược lại.
// 基础数据
function Data(tradeTypeA, tradeTypeB) { // 传入套利A合约和套利B合约
this.accountData = _C(exchange.GetAccount); // 获取账户信息
this.positionData = _C(exchange.GetPosition); // 获取持仓信息
var recordsData = _C(exchange.GetRecords); //获取K线数据
exchange.SetContractType(tradeTypeA); // 订阅套利A合约
var depthDataA = _C(exchange.GetDepth); // 套利A合约深度数据
exchange.SetContractType(tradeTypeB); // 订阅套利B合约
var depthDataB = _C(exchange.GetDepth); // 套利B合约深度数据
this.time = recordsData[recordsData.length - 1].Time; // 获取最新数据时间
this.askA = depthDataA.Asks[0].Price; // 套利A合约卖一价
this.bidA = depthDataA.Bids[0].Price; // 套利A合约买一价
this.askB = depthDataB.Asks[0].Price; // 套利B合约卖一价
this.bidB = depthDataB.Bids[0].Price; // 套利B合约买一价
// 正套价差(合约A卖一价 - 合约B买一价)
this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
// 反套价差(合约A买一价 - 合约B卖一价)
this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}
Hàm lấy vị trí: mp ( ) Duyệt toàn bộ mảng vị trí và trả về số vị trí của hợp đồng và hướng đã chỉ định. Nếu không có, trả về false
// 获取持仓
Data.prototype.mp = function (tradeType, type) {
var positionData = this.positionData; // 获取持仓信息
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;
}
Chức năng của đường K và chỉ báo: boll ( ) Tổng hợp chuỗi K-line mới dựa trên dữ liệu chênh lệch giá thuận/ngược. Và trả về dữ liệu thanh ray trên, thanh ray giữa và thanh ray dưới được tính toán bởi chỉ báo boll.
// 合成新K线数据和boll指标数据
Data.prototype.boll = function (num, timeCycle) {
var self = {}; // 临时对象
// 正套价差和反套价差中间值
self.Close = (this.basb + this.sabb) / 2;
if (this.timeA == this.timeB) {
self.Time = this.time;
} // 对比两个深度数据时间戳
if (this.time - oldTime > timeCycle * 60000) {
bars.push(self);
oldTime = this.time;
} // 根据指定时间周期,在K线数组里面传入价差数据对象
if (bars.length > num * 2) {
bars.shift(); // 控制K线数组长度
} else {
return;
}
var boll = TA.BOLL(bars, num, 2); // 调用talib库中的boll指标
return {
up: boll[0][boll[0].length - 1], // boll指标上轨
middle: boll[1][boll[1].length - 1], // boll指标中轨
down: boll[2][boll[2].length - 1] // boll指标下轨
} // 返回一个处理好的boll指标数据
}
Hàm lệnh: trade ( ) Nhập tên hợp đồng lệnh và loại lệnh, sau đó đặt lệnh theo giá cần xem xét và trả về kết quả sau khi đặt lệnh. Vì cần phải đặt hai lệnh theo các hướng khác nhau cùng một lúc nên giá mua/bán được chuyển đổi trong hàm theo tên hợp đồng lệnh.
// 下单
Data.prototype.trade = function (tradeType, type) {
exchange.SetContractType(tradeType); // 下单前先重新订阅合约
var askPrice, bidPrice;
if (tradeType == tradeTypeA) { // 如果是A合约下单
askPrice = this.askA; // 设置askPrice
bidPrice = this.bidA; // 设置bidPrice
} else if (tradeType == tradeTypeB) { // 如果是B合约下单
askPrice = this.askB; // 设置askPrice
bidPrice = this.bidB; // 设置bidPrice
}
switch (type) { // 匹配下单模式
case "buy":
exchange.SetDirection(type); // 设置下单模式
return exchange.Buy(askPrice, unit);
case "sell":
exchange.SetDirection(type); // 设置下单模式
return exchange.Sell(bidPrice, unit);
case "closebuy":
exchange.SetDirection(type); // 设置下单模式
return exchange.Sell(bidPrice, unit);
case "closesell":
exchange.SetDirection(type); // 设置下单模式
return exchange.Buy(askPrice, unit);
default:
return false;
}
}
Hủy chức năng đơn hàng: cancelOrders() Lấy một mảng gồm tất cả các đơn hàng chưa hoàn thành và hủy từng đơn hàng một. Và nếu có lệnh chưa được thực hiện, nó sẽ trả về false, và nếu không có lệnh nào chưa được thực hiện, nó sẽ trả về true.
// 取消订单
Data.prototype.cancelOrders = function () {
Sleep(500); // 撤单前先延时,因为有些交易所你懂的
var orders = _C(exchange.GetOrders); // 获取未成交订单数组
if (orders.length > 0) { // 如果有未成交的订单
for (var i = 0; i < orders.length; i++) { //遍历未成交订单数组
exchange.CancelOrder(orders[i].Id); //逐个取消未成交的订单
Sleep(500); //延时0.5秒
}
return false; // 如果取消了未成交的单子就返回false
}
return true; //如果没有未成交的订单就返回true
}
Xử lý việc giữ một hợp đồng duy nhất: isEven() Khi xử lý tình huống một chân trong giao dịch chênh lệch giá, chúng ta chỉ cần đóng tất cả các vị thế để xử lý. Tất nhiên, bạn cũng có thể thay đổi sang phương thức đặt hàng tiếp theo.
// 处理持有单个合约
Data.prototype.isEven = function () {
var positionData = this.positionData; // 获取持仓信息
var type = null; // 转换持仓方向
// 如果持仓数组长度余2不等于0或者持仓数组长度不等于2
if (positionData.length % 2 != 0 || positionData.length != 2) {
for (var i = 0; i < positionData.length; i++) { // 遍历持仓数组
if (positionData[i].Type == 0) { // 如果是多单
type = 10; // 设置下单参数
} else if (positionData[i].Type == 1) { // 如果是空单
type = -10; // 设置下单参数
}
// 平掉所有仓位
this.trade(positionData[i].ContractType, type, positionData[i].Amount);
}
}
}
Hàm vẽ: drawingChart ( ) Gọi phương thức ObjChart.add() để vẽ dữ liệu thị trường và dữ liệu chỉ báo cần thiết trong biểu đồ: đường trên, đường giữa, đường dưới và chênh lệch dương/âm.
// 画图
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);
}
Bước 4: Trong hàm nhập main(), thực thi mã tiền xử lý trước giao dịch. Mã này chỉ chạy một lần sau khi chương trình bắt đầu. bao gồm:
//入口函数
function main() {
// 过滤控制台中不是很重要的信息
SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种
ObjChart.reset(); //程序启动前清空之前绘制的图表
LogProfitReset(); //程序启动前清空之前的状态栏信息
}
Sau khi xác định quá trình xử lý trước giao dịch ở trên, chúng ta sẽ chuyển sang bước tiếp theo, vào chế độ thăm dò và thực hiện hàm onTick() nhiều lần. Và đặt thời gian ngủ khi Sleep() thăm dò, vì một số API trao đổi tiền điện tử có giới hạn truy cập tích hợp trong một khoảng thời gian nhất định.
//入口函数
function main() {
// 过滤控制台中不是很重要的信息
SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种
ObjChart.reset(); //程序启动前清空之前绘制的图表
LogProfitReset(); //程序启动前清空之前的状态栏信息
while (true) { // 进入轮询模式
onTick(); // 执行onTick函数
Sleep(500); // 休眠0.5秒
}
}
Nhận và tính toán dữ liệu Bước 1: Lấy các đối tượng dữ liệu cơ bản, số dư tài khoản và dữ liệu chỉ báo boll để sử dụng trong logic giao dịch.
// 交易条件
function onTick() {
var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
var accountStocks = data.accountData.Stocks; // 账户余额
var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
if (!boll) return; // 如果没有boll数据就返回
}
Đặt hàng và theo dõi Bước 1: Thực hiện các hoạt động mua và bán theo logic chiến lược trên. Đầu tiên, nó xác định xem các điều kiện về giá và chỉ báo có được đáp ứng hay không, sau đó xác định xem các điều kiện về vị thế có được đáp ứng hay không và cuối cùng thực hiện lệnh trade ( )
// 交易条件
function onTick() {
var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
var accountStocks = data.accountData.Stocks; // 账户余额
var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
if (!boll) return; // 如果没有boll数据就返回
// 价差说明
// basb = (合约A卖一价 - 合约B买一价)
// sabb = (合约A买一价 - 合约B卖一价)
if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨
if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
data.trade(tradeTypeA, "closebuy"); // 合约A平多
}
if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
data.trade(tradeTypeB, "closesell"); // 合约B平空
}
} else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨
if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
data.trade(tradeTypeA, "closesell"); // 合约A平空
}
if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
data.trade(tradeTypeB, "closebuy"); // 合约B平多
}
}
if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额
if (data.basb < boll.down) { // 如果basb价差低于下轨
if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
data.trade(tradeTypeA, "buy"); // 合约A开多
}
if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
data.trade(tradeTypeB, "sell"); // 合约B开空
}
} else if (data.sabb > boll.up) { // 如果sabb价差高于上轨
if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
data.trade(tradeTypeA, "sell"); // 合约A开空
}
if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
data.trade(tradeTypeB, "buy"); // 合约B开多
}
}
}
}
Bước 2: Sau khi đặt hàng, cần xử lý các tình huống bất thường như đơn hàng chưa hoàn thành, giữ một hợp đồng duy nhất. và vẽ biểu đồ.
// 交易条件
function onTick() {
var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
var accountStocks = data.accountData.Stocks; // 账户余额
var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
if (!boll) return; // 如果没有boll数据就返回
// 价差说明
// basb = (合约A卖一价 - 合约B买一价)
// sabb = (合约A买一价 - 合约B卖一价)
if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨
if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
data.trade(tradeTypeA, "closebuy"); // 合约A平多
}
if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
data.trade(tradeTypeB, "closesell"); // 合约B平空
}
} else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨
if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
data.trade(tradeTypeA, "closesell"); // 合约A平空
}
if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
data.trade(tradeTypeB, "closebuy"); // 合约B平多
}
}
if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额
if (data.basb < boll.down) { // 如果basb价差低于下轨
if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
data.trade(tradeTypeA, "buy"); // 合约A开多
}
if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
data.trade(tradeTypeB, "sell"); // 合约B开空
}
} else if (data.sabb > boll.up) { // 如果sabb价差高于上轨
if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
data.trade(tradeTypeA, "sell"); // 合约A开空
}
if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
data.trade(tradeTypeB, "buy"); // 合约B开多
}
}
}
data.cancelOrders(); // 撤单
data.drawingChart(boll); // 画图
data.isEven(); // 处理持有单个合约
}
Ở trên, chúng tôi đã tạo ra một chiến lược chênh lệch giá liên thời kỳ tiền kỹ thuật số đơn giản chỉ trong hơn 200 dòng. Mã đầy đủ như sau:
// 全局变量
// 声明一个配置图表的 chart 对象
var chart = {
__isStock: true,
tooltip: {
xDateFormat: '%Y-%m-%d %H:%M:%S, %A'
},
title: {
text: '交易盈亏曲线图(详细)'
},
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: '价差'
},
opposite: false,
},
series: [{
name: "上轨",
id: "线1,up",
data: []
}, {
name: "中轨",
id: "线2,middle",
data: []
}, {
name: "下轨",
id: "线3,down",
data: []
}, {
name: "basb",
id: "线4,basb",
data: []
}, {
name: "sabb",
id: "线5,sabb",
data: []
}]
};
var ObjChart = Chart(chart); // 画图对象
var bars = []; // 存储价差序列
var oldTime = 0; // 记录历史数据时间戳
// 参数
var tradeTypeA = "this_week"; // 套利A合约
var tradeTypeB = "quarter"; // 套利B合约
var dataLength = 10; //指标周期长度
var timeCycle = 1; // K线周期
var name = "ETC"; // 币种
var unit = 1; // 下单量
// 基础数据
function Data(tradeTypeA, tradeTypeB) { // 传入套利A合约和套利B合约
this.accountData = _C(exchange.GetAccount); // 获取账户信息
this.positionData = _C(exchange.GetPosition); // 获取持仓信息
var recordsData = _C(exchange.GetRecords); //获取K线数据
exchange.SetContractType(tradeTypeA); // 订阅套利A合约
var depthDataA = _C(exchange.GetDepth); // 套利A合约深度数据
exchange.SetContractType(tradeTypeB); // 订阅套利B合约
var depthDataB = _C(exchange.GetDepth); // 套利B合约深度数据
this.time = recordsData[recordsData.length - 1].Time; // 获取最新数据时间
this.askA = depthDataA.Asks[0].Price; // 套利A合约卖一价
this.bidA = depthDataA.Bids[0].Price; // 套利A合约买一价
this.askB = depthDataB.Asks[0].Price; // 套利B合约卖一价
this.bidB = depthDataB.Bids[0].Price; // 套利B合约买一价
// 正套价差(合约A卖一价 - 合约B买一价)
this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price;
// 反套价差(合约A买一价 - 合约B卖一价)
this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price;
}
// 获取持仓
Data.prototype.mp = function (tradeType, type) {
var positionData = this.positionData; // 获取持仓信息
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指标数据
Data.prototype.boll = function (num, timeCycle) {
var self = {}; // 临时对象
// 正套价差和反套价差中间值
self.Close = (this.basb + this.sabb) / 2;
if (this.timeA == this.timeB) {
self.Time = this.time;
} // 对比两个深度数据时间戳
if (this.time - oldTime > timeCycle * 60000) {
bars.push(self);
oldTime = this.time;
} // 根据指定时间周期,在K线数组里面传入价差数据对象
if (bars.length > num * 2) {
bars.shift(); // 控制K线数组长度
} else {
return;
}
var boll = TA.BOLL(bars, num, 2); // 调用talib库中的boll指标
return {
up: boll[0][boll[0].length - 1], // boll指标上轨
middle: boll[1][boll[1].length - 1], // boll指标中轨
down: boll[2][boll[2].length - 1] // boll指标下轨
} // 返回一个处理好的boll指标数据
}
// 下单
Data.prototype.trade = function (tradeType, type) {
exchange.SetContractType(tradeType); // 下单前先重新订阅合约
var askPrice, bidPrice;
if (tradeType == tradeTypeA) { // 如果是A合约下单
askPrice = this.askA; // 设置askPrice
bidPrice = this.bidA; // 设置bidPrice
} else if (tradeType == tradeTypeB) { // 如果是B合约下单
askPrice = this.askB; // 设置askPrice
bidPrice = this.bidB; // 设置bidPrice
}
switch (type) { // 匹配下单模式
case "buy":
exchange.SetDirection(type); // 设置下单模式
return exchange.Buy(askPrice, unit);
case "sell":
exchange.SetDirection(type); // 设置下单模式
return exchange.Sell(bidPrice, unit);
case "closebuy":
exchange.SetDirection(type); // 设置下单模式
return exchange.Sell(bidPrice, unit);
case "closesell":
exchange.SetDirection(type); // 设置下单模式
return exchange.Buy(askPrice, unit);
default:
return false;
}
}
// 取消订单
Data.prototype.cancelOrders = function () {
Sleep(500); // 撤单前先延时,因为有些交易所你懂的
var orders = _C(exchange.GetOrders); // 获取未成交订单数组
if (orders.length > 0) { // 如果有未成交的订单
for (var i = 0; i < orders.length; i++) { //遍历未成交订单数组
exchange.CancelOrder(orders[i].Id); //逐个取消未成交的订单
Sleep(500); //延时0.5秒
}
return false; // 如果取消了未成交的单子就返回false
}
return true; //如果没有未成交的订单就返回true
}
// 处理持有单个合约
Data.prototype.isEven = function () {
var positionData = this.positionData; // 获取持仓信息
var type = null; // 转换持仓方向
// 如果持仓数组长度余2不等于0或者持仓数组长度不等于2
if (positionData.length % 2 != 0 || positionData.length != 2) {
for (var i = 0; i < positionData.length; i++) { // 遍历持仓数组
if (positionData[i].Type == 0) { // 如果是多单
type = 10; // 设置下单参数
} else if (positionData[i].Type == 1) { // 如果是空单
type = -10; // 设置下单参数
}
// 平掉所有仓位
this.trade(positionData[i].ContractType, type, positionData[i].Amount);
}
}
}
// 画图
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);
}
// 交易条件
function onTick() {
var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象
var accountStocks = data.accountData.Stocks; // 账户余额
var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据
if (!boll) return; // 如果没有boll数据就返回
// 价差说明
// basb = (合约A卖一价 - 合约B买一价)
// sabb = (合约A买一价 - 合约B卖一价)
if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨
if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
data.trade(tradeTypeA, "closebuy"); // 合约A平多
}
if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
data.trade(tradeTypeB, "closesell"); // 合约B平空
}
} else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨
if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
data.trade(tradeTypeA, "closesell"); // 合约A平空
}
if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
data.trade(tradeTypeB, "closebuy"); // 合约B平多
}
}
if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额
if (data.basb < boll.down) { // 如果basb价差低于下轨
if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单
data.trade(tradeTypeA, "buy"); // 合约A开多
}
if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单
data.trade(tradeTypeB, "sell"); // 合约B开空
}
} else if (data.sabb > boll.up) { // 如果sabb价差高于上轨
if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单
data.trade(tradeTypeA, "sell"); // 合约A开空
}
if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单
data.trade(tradeTypeB, "buy"); // 合约B开多
}
}
}
data.cancelOrders(); // 撤单
data.drawingChart(boll); // 画图
data.isEven(); // 处理持有单个合约
}
//入口函数
function main() {
// 过滤控制台中不是很重要的信息
SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP");
exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种
ObjChart.reset(); //程序启动前清空之前绘制的图表
LogProfitReset(); //程序启动前清空之前的状态栏信息
while (true) { // 进入轮询模式
onTick(); // 执行onTick函数
Sleep(500); // 休眠0.5秒
}
}
Địa chỉ chính sách: https://www.fmz.com/strategy/104964
Chiến lược này chỉ là điểm khởi đầu. Giao dịch thực tế không đơn giản như vậy, nhưng bạn có thể sử dụng các ví dụ để phát huy hết trí tưởng tượng của mình. Tôi cần nhắc nhở mọi người rằng, dựa trên kinh nghiệm hạn chế của tôi, xét theo điều kiện thị trường tiền điện tử hiện tại, các chiến lược chênh lệch giá thuần túy theo từng giai đoạn về cơ bản là không đáng để áp dụng, cho dù đó là chênh lệch giá tam giác không rủi ro hay chênh lệch giá liên thị trường.
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 thì biên độ cũng không phải là tiền tệ hợp pháp. Ngày nay, hầu hết các loại tiền kỹ thuật số đều giảm khoảng 70% kể từ đầu năm nay. Nói cách khác, chiến lược này luôn tạo ra tiền, nhưng giá của đồng tiền vẫn đang giảm. Nhìn xung quanh, thị trường tiền kỹ thuật số dường như đã tách khỏi blockchain. Giống như hoa tulip ngày xưa, giá cả luôn đến từ kỳ vọng và sự tự tin của mọi người, và sự tự tin đến từ giá cả…