Trong bài viết trước, chúng tôi đã giải thích về phân tích logic giao dịch của một chiến lược lưới đơn giản, và bài viết này sẽ tiếp tục để hoàn thiện thiết kế chiến lược giảng dạy này.
Phân tích logic giao dịch Trong bài viết trước, chúng tôi đã nói rằng chỉ cần đi qua mỗi đường lưới lưới, đánh giá giá hiện tại qua đường lưới, bạn có thể kích hoạt các hành động giao dịch. Nhưng thực tế, vẫn có rất nhiều chi tiết logic, thường không hiểu chiến lược viết những người mới có thể dễ dàng hình thành một nhận thức sai lầm là lập logic rất đơn giản, mã cũng nên chỉ trong một vài dòng, thực tế viết ra tìm thấy chi tiết là rất nhiều.
Trước tiên, chi tiết đầu tiên chúng ta cần xem xét là thiết kế về mạng lưới vô hạn.createNet
Vậy? Chức năng này tạo ra một cấu trúc dữ liệu lưới với một số lượng lưới giới hạn. Vậy nếu giá vượt quá ranh giới của cấu trúc dữ liệu lưới này (trên đường lưới ở trên cùng là giá cao nhất, dưới cùng là giá thấp nhất) khi chiến lược được thực hiện?
Vì vậy, điều đầu tiên chúng ta cần làm là thêm một cơ chế mở rộng cho cấu trúc dữ liệu lưới.
Bạn bắt đầu viết chính sách main function, chính là mã mà chính sách bắt đầu thực hiện.
var diff = 50 // 全局变量,网格间距,可以设计成参数,方便讲解,我们把这个参数写死在代码里。
function main() {
// 实盘开始运行后,从这里开始执行策略代码
var ticker = _C(exchange.GetTicker) // 获取市场最新的行情数据ticker,ticker这个数据的结构参看FMZ API文档:https://www.fmz.com/api#ticker
var net = createNet(ticker.Last, diff) // 我们上篇设计的初始构造网格数据结构的函数,这里构造一个网格数据结构net
while (true) { // 然后程序逻辑就进入了这个while死循环,策略执行到此将不停的循环执行这里{}符号之内的代码
ticker = _C(exchange.GetTicker) // 死循环代码部分的第一行,获取最新的行情数据,更新给ticker变量
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) {
net.push({
buy : false,
sell : false,
price : net[net.length - 1].price + diff,
})
}
while (ticker.Last <= net[0].price) {
var price = net[0].price - diff
if (price <= 0) {
break
}
net.unshift({
buy : false,
sell : false,
price : price,
})
}
// 还有其它代码...
}
}
Để mở rộng cấu trúc dữ liệu lưới, đoạn mã này (được chọn từ mã trên) là:
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) { // 如果价格超过网格最高价格的网格线
net.push({ // 就在网格最高价格的网格线之后加入一个新的网格线
buy : false, // 初始化卖出标记
sell : false, // 初始化买入标记
price : net[net.length - 1].price + diff, // 在之前最高价格的基础上再加一个网格间距
})
}
while (ticker.Last <= net[0].price) { // 如果价格低于网格最低价格的网格线
var price = net[0].price - diff // 区别于向上添加,要注意向下添加新网格线的价格不能小于等于0,所以这里要判断
if (price <= 0) { // 小于等于0就不添加了,跳出这层循环
break
}
net.unshift({ // 就在网格最低价格的网格线之前添加一个新的网格线
buy : false,
sell : false,
price : price,
})
}
Sau đó, chúng ta sẽ xem xét cách cụ thể để kích hoạt giao dịch.
var diff = 50
var amount = 0.002 // 增加一个全局变量,也可以设计成参数,当然为了简便讲解,我们也写死在策略代码,
// 这个参数控制每次网格线上触发交易时的交易量
function main() {
var ticker = _C(exchange.GetTicker)
var net = createNet(ticker.Last, diff)
var preTicker = ticker // 在主循环(死循环)开始前,设置一个变量,记录上一次的行情数据
while (true) {
ticker = _C(exchange.GetTicker)
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) {
net.push({
buy : false,
sell : false,
price : net[net.length - 1].price + diff,
})
}
while (ticker.Last <= net[0].price) {
var price = net[0].price - diff
if (price <= 0) {
break
}
net.unshift({
buy : false,
sell : false,
price : price,
})
}
// 检索网格
for (var i = 0 ; i < net.length ; i++) { // 遍历网格数据结构中的所有网格线
var p = net[i]
if (preTicker.Last < p.price && ticker.Last > p.price) { // 上穿,卖出,当前节点已经交易过不论SELL BUY ,都不再交易
if (i != 0) {
var downP = net[i - 1]
if (downP.buy) {
exchange.Sell(-1, amount, ticker)
downP.buy = false
p.sell = false
continue
}
}
if (!p.sell && !p.buy) {
exchange.Sell(-1, amount, ticker)
p.sell = true
}
} else if (preTicker.Last > p.price && ticker.Last < p.price) { // 下穿,买入
if (i != net.length - 1) {
var upP = net[i + 1]
if (upP.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
upP.sell = false
p.buy = false
continue
}
}
if (!p.buy && !p.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
p.buy = true
}
}
}
preTicker = ticker // 把当前的行情数据记录在preTicker中,在下一次循环中,作为“上一次”行情数据和最新的对比,判断上穿下穿
Sleep(500)
}
}
Bạn có thể thấy:
preTicker.Last < p.price && ticker.Last > p.price
preTicker.Last > p.price && ticker.Last < p.price
Điều này có nghĩa là chúng ta đã nói trong bài viết trước:
Đi lên xuống chỉ là bước đầu tiên để quyết định liệu có thể đặt hàng hay không, trong đó cũng cần phải xác định các dấu hiệu trong dữ liệu lưới.
Nếu là trên, giá sẽ được đánh giá thấp hơn so với đường lưới hiện tại và dấu buy trên đường lưới gần nhất, nếu giá trị của dấu buy là true, thì chỉ ra rằng đường lưới trước đã được mua, đặt lại dấu buy trên đường lưới hiện tại là false, đặt lại dấu sell hiện tại là false.
Sau khi đánh giá các điều kiện vừa được đưa ra, nếu không có kích hoạt thì tiếp tục đánh giá, nếu các dấu buy/sell trên đường lưới hiện tại đều là false, thì cho thấy đường lưới hiện tại có thể giao dịch.
Trong khi đó, một số người cho rằng, việc sử dụng các phương pháp này là một cách đơn giản và dễ dàng, nhưng không có nghĩa là bạn phải sử dụng các phương pháp này.
Để có thể nhìn thấy một số dữ liệu trong quá trình kiểm tra lại, hãy viết một hàm.showTbl
Hiển thị dữ liệu.
function showTbl(arr) {
var tbl = {
type : "table",
title : "网格",
cols : ["网格信息"],
rows : []
}
var arrReverse = arr.slice(0).reverse()
_.each(arrReverse, function(ele) {
var color = ""
if (ele.buy) {
color = "#FF0000"
} else if (ele.sell) {
color = "#00FF00"
}
tbl.rows.push([JSON.stringify(ele) + color])
})
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`", "\n 账户信息:", exchange.GetAccount())
}
Có thể bạn có thể tìm hiểu thêm về chiến lược này.
/*backtest
start: 2021-04-01 22:00:00
end: 2021-05-22 00:00:00
period: 1d
basePeriod: 1m
exchanges: [{"eid":"OKEX","currency":"ETH_USDT","balance":100000}]
*/
var diff = 50
var amount = 0.002
function createNet(begin, diff) {
var oneSideNums = 10
var up = []
var down = []
for (var i = 0 ; i < oneSideNums ; i++) {
var upObj = {
buy : false,
sell : false,
price : begin + diff / 2 + i * diff,
}
up.push(upObj)
var j = (oneSideNums - 1) - i
var downObj = {
buy : false,
sell : false,
price : begin - diff / 2 - j * diff,
}
if (downObj.price <= 0) { // 价格不能小于等于0
continue
}
down.push(downObj)
}
return down.concat(up)
}
function showTbl(arr) {
var tbl = {
type : "table",
title : "网格",
cols : ["网格信息"],
rows : []
}
var arrReverse = arr.slice(0).reverse()
_.each(arrReverse, function(ele) {
var color = ""
if (ele.buy) {
color = "#FF0000"
} else if (ele.sell) {
color = "#00FF00"
}
tbl.rows.push([JSON.stringify(ele) + color])
})
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`", "\n 账户信息:", exchange.GetAccount())
}
function main() {
var ticker = _C(exchange.GetTicker)
var net = createNet(ticker.Last, diff)
var preTicker = ticker
while (true) {
ticker = _C(exchange.GetTicker)
// 检查网格范围
while (ticker.Last >= net[net.length - 1].price) {
net.push({
buy : false,
sell : false,
price : net[net.length - 1].price + diff,
})
}
while (ticker.Last <= net[0].price) {
var price = net[0].price - diff
if (price <= 0) {
break
}
net.unshift({
buy : false,
sell : false,
price : price,
})
}
// 检索网格
for (var i = 0 ; i < net.length ; i++) {
var p = net[i]
if (preTicker.Last < p.price && ticker.Last > p.price) { // 上穿,卖出,当前节点已经交易过不论SELL BUY ,都不再交易
if (i != 0) {
var downP = net[i - 1]
if (downP.buy) {
exchange.Sell(-1, amount, ticker)
downP.buy = false
p.sell = false
continue
}
}
if (!p.sell && !p.buy) {
exchange.Sell(-1, amount, ticker)
p.sell = true
}
} else if (preTicker.Last > p.price && ticker.Last < p.price) { // 下穿,买入
if (i != net.length - 1) {
var upP = net[i + 1]
if (upP.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
upP.sell = false
p.buy = false
continue
}
}
if (!p.buy && !p.sell) {
exchange.Buy(-1, amount * ticker.Last, ticker)
p.buy = true
}
}
}
showTbl(net)
preTicker = ticker
Sleep(500)
}
}
Các chiến lược được xem xét lại:
Bạn có thể thấy đặc điểm của chiến lược lưới, khi gặp một thị trường có xu hướng sẽ có lỗ lớn hơn, thu nhập sẽ hồi phục sau khi thị trường sốc. Do đó, chiến lược lưới không phải là không có rủi ro, chiến lược hiện tại vẫn có thể nằm yên và cứng rắn, chiến lược lưới hợp đồng tương lai có rủi ro lớn hơn, cần thiết phải đặt các tham số lưới một cách bảo thủ.
husr12345Đây là ngôn ngữ C++.
Tony233Bạn có thể chọn một số từ trong các câu hỏi của bạn, nhưng bạn sẽ không thể tìm ra một số từ trong các câu hỏi của bạn. Bạn có thể tìm thấy một số từ trong các câu hỏi của bạn, nhưng bạn sẽ không tìm thấy một số từ trong các câu hỏi của bạn. Bạn có thể tìm thấy một số từ trong các câu hỏi của bạn, nhưng bạn sẽ không tìm thấy một số từ trong các câu hỏi của bạn.
Tony233Thật khó.
thảKhi đi lên và đi xuống, exchange.Buy ((-1, amount * ticker.Last, ticker), amount * ticker.Last là ngớ ngẩn, tại sao không bán?
CYZWXhttps://www.fmz.com/strategy/291160 last_tick = [] đường = [] grid_buy_list = [] Định giá ròng ((now_price): đường dây toàn cầu print ((now_price) Đường = [now_price*(1+0.003*i) cho i trong phạm vi ((-1000,1000) ] Đăng ký (đường) def ontick ((): Global last_tick đường dây toàn cầu Global grid_buy_list tài khoản = trao đổi.GetAccount() ticker = exchange.GetTicker() last_tick.append ((ticker['Last']) if len ((last_tick) == 1:return elif len ((last_tick) == 100:del last_tick[1] Đối với i trong phạm vi ((len))): if last_tick[-1] > line[i] and last_tick[-2] < line[i] and len(grid_buy_list)!= 0 và i > min(grid_buy_list) and account['Stock'] >= 0,001: trao đổi.Bán ((lần cuối_tick[-1],0.01) del grid_buy_list[grid_buy_list.index(min(grid_buy_list))] Log ((exchange.GetAccount)) elif last_tick[-1] < line[i] và last_tick[-2] > line[i] và i không có trong grid_buy_list: giao dịch.Buy ((last_tick[-1],0.01) grid_buy_list.append (i) Log ((exchange.GetAccount)) defin main ((): net ((exchange.GetTicker() ['Last']) Log ((exchange.GetAccount)) while ((true): ontick ((() Giấc ngủ ((1000)
CYZWXNhờ đó, chúng tôi đã có được một số thông tin chi tiết, và chúng tôi đã giải thích mọi thứ để mua lại, giống như một phiên bản py.
Những nhà phát minh định lượng - những giấc mơ nhỏChiến lược là ngôn ngữ JavaScript.
Tony233Có phải hợp đồng lâu dài trong văn bản là hợp đồng tương lai không?
Những nhà phát minh định lượng - những giấc mơ nhỏCác hợp đồng tương lai là số lượng hợp đồng, giá thị trường hiện tại là số tiền thanh toán; các đơn hàng bán hiện tại là số tiền tệ.
Tony233Ơ, xin hỏi thêm một câu hỏi nữa, ý nghĩa của điều này là gì. Lưu ý: cần giao dịch giao diện đặt hàng dưới hỗ trợ bảng giá thị trường ((như loại đặt hàng là thanh toán, các tham số đơn vị dưới là số tiền được tính theo đơn vị tiền tệ) ‒ các phương thức đặt hàng thị trường tiền tệ tương lai kỹ thuật số, các đơn vị của các tham số đơn vị dưới là số lượng hợp đồng. Tôi thấy bài viết này của bạn kiểm tra lại hợp đồng vĩnh viễn USdt của etokex, nó không tính theo phương thức đặt hàng của đơn vị thị trường tiền mặt?
Tony233Ồ, tôi hiểu rồi.
Những nhà phát minh định lượng - những giấc mơ nhỏCác hàm API của FMZ có thể tạo ra các hàm đầu ra nhật ký như: Log ((...)), exchange.Buy ((Price, Amount), exchange.CancelOrder ((Id) v.v. với một số tham số đầu ra kèm theo các tham số cần thiết.