avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

Được tạo ra trong: 2021-05-28 09:50:12, cập nhật trên: 2023-09-21 21:06:08
comments   14
hits   2533

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

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. Trong bài viết này, chúng tôi sẽ tiếp tục hoàn thiện thiết kế của 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 đã đề cập rằng miễn là chúng ta di chuyển qua từng đường lưới và xác định xem giá hiện tại có vượt lên trên hay xuống dưới đường lưới hay không thì hành động giao dịch có thể được kích hoạt. Nhưng trên thực tế, vẫn còn nhiều chi tiết logic. Những người mới không hiểu về chiến lược viết thường hình thành nhận thức sai lầm rằng “logic rất đơn giản và mã chỉ nên có vài dòng, nhưng trong thực tế viết vẫn còn nhiều chi tiết.”

Chi tiết đầu tiên chúng ta cần xem xét là thiết kế của lưới vô hạn. Hãy nhớ rằng trong bài viết trước chúng ta đã thiết kế một hàm để tạo cấu trúc dữ liệu lưới ban đầucreateNetCái gì? Hàm này tạo ra một cấu trúc dữ liệu lưới với số lượng đường lưới hữu hạn. Vậy thì sao nếu giá vượt quá ranh giới của cấu trúc dữ liệu lưới này (vượt qua đường lưới trên cùng có giá cao nhất và đường lưới dưới cùng có giá thấp nhất) khi chiến lược đang chạy? Vì vậy, trước tiên chúng ta cần thêm một cơ chế mở rộng vào cấu trúc dữ liệu lưới.

Bắt đầu viết hàm chính của chiến lược, đây là đoạn mã bắt đầu thực thi chiến lược.

  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ã khiến cấu trúc dữ liệu lưới có thể mở rộng được là mã sau (trích từ mã trên):

        // 检查网格范围
        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,
            })
        }

Bước tiếp theo là xem xét cách triển khai kích hoạt giao dịch một cách chi tiết.

  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:

  • Vượt qua điều kiện đường lưới:preTicker.Last < p.price && ticker.Last > p.price
  • Vượt qua điều kiện đường lưới:preTicker.Last > p.price && ticker.Last < p.price

Đây là những gì chúng ta đã nói ở bài viết trước:

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

Việc đi lên hay đi xuống chỉ là bước đầu tiên để xác định xem có thể thực hiện giao dịch hay không, điều này cũng đòi hỏi phải xác định các điểm trong dữ liệu đường lưới.

Nếu là giao cắt hướng lên, giá được đánh giá là thấp hơn đường lưới hiện tại và dấu mua trên đường lưới gần nhất. Nếu giá trị của dấu mua là đúng, điều đó có nghĩa là đường lưới trước đó đã được mua, và đường lưới trước đó được thiết lập lại. Dấu mua của gốc là sai và dấu bán của đường lưới hiện tại được thiết lập lại thành sai.

Sau khi phán đoán điều kiện trước đó, nếu không được kích hoạt, hãy tiếp tục phán đoán. Nếu các dấu mua/bán trên đường lưới hiện tại đều sai, điều đó có nghĩa là đường lưới hiện tại có thể được giao dịch. Vì đây là một giao cắt hướng lên, chúng ta thực hiện lệnh bán ở đây. Sau khi thực hiện, đánh dấu cờ bán trên lưới hiện tại là đúng.

Logic xử lý đường hầm cũng tương tự (điều này dành cho người mới bắt đầu suy nghĩ).

Kiểm tra lại chiến lược hoàn chỉnh

Để xem một số dữ liệu kiểm tra ngược, một hàm được viếtshowTblHiể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())
}

Mã chiến lược hoàn chỉnh:

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

Kiểm tra lại chiến lược:

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

Những người mới tham gia Giao dịch định lượng trong các Vòng tròn tiền điện tử, vui lòng xem qua bài viết này - Đưa bạn đến gần hơn với Giao dịch định lượng trong các Vòng tròn tiền điện tử (V)

Có thể thấy rằng đặc điểm của chiến lược lưới là sẽ có những khoản lỗ lớn khi thị trường có xu hướng và lợi nhuận chỉ phục hồi trong thị trường biến động. Do đó, chiến lược lưới không phải là không có rủi ro. Chiến lược giao ngay vẫn có thể được duy trì, nhưng chiến lược lưới hợp đồng tương lai rủi ro hơn và đòi hỏi các thiết lập thận trọng cho các tham số lưới.