Xử lý dữ liệu tuyến K trong giao dịch có tính toán

Tác giả:Giấc mơ nhỏ, Tạo: 2019-08-13 11:11:38, Cập nhật: 2023-10-20 20:06:13

img

Xử lý dữ liệu tuyến K trong giao dịch có tính toán

Trong việc viết các chiến lược giao dịch lập trình, sử dụng dữ liệu K-line thường có nhu cầu sử dụng một số dữ liệu K-line không chuẩn, ví dụ như sử dụng dữ liệu K-line 12 phút, dữ liệu K-line 4 giờ, thường không thể truy cập trực tiếp. Vậy làm thế nào để đối phó với nhu cầu như vậy? Câu trả lời chắc chắn là có cách nào đó. Các chu kỳ phi tiêu chuẩn có thể được thu thập tổng hợp thông qua dữ liệu từ các chu kỳ nhỏ hơn, bạn có thể tưởng tượng, giá cao nhất trong nhiều chu kỳ, được tính là giá cao nhất sau khi tổng hợp, giá thấp nhất được tính là giá thấp nhất sau khi tổng hợp, giá mở không thay đổi, giá mở đầu tiên được tính bằng dữ liệu nguyên liệu của đường K, giá đóng tương ứng với giá đóng cuối cùng của dữ liệu nguyên liệu của đường K, thời gian là thời gian của giá mở, khối lượng giao dịch được tính toán và tìm kiếm dữ liệu nguyên liệu. Những người bị ảnh hưởng là:

  • Ý nghĩ

    Ví dụ như trên thị trường tài sản blockchain BTC_USDT, một giờ trở thành 4 giờ.

    img

    img

    img

    img

    Thời gian cao Mở thấp Lưu ý
    2019.8.12 00:00 11447.07 11382.57 11367.2 11406.92
    2019.8.12 01:00 11420 11405.65 11366.6 11373.83
    2019.8.12 02:00 11419.24 11374.68 11365.51 11398.19
    2019.8.12 03:00 11407.88 11398.59 11369.7 11384.71

    Bốn chu kỳ 1 giờ này, tổng hợp dữ liệu của một chu kỳ 4 giờ gốc, giá mở là giá mở đầu tiên vào 00:00:11382.57 Giá đóng là giá đóng cuối cùng, tức là lúc 03:00: 11384.71 Giá cao nhất là giá cao nhất ở đây: 11447.07 Giá thấp nhất tìm giá thấp nhất ở đây: 11365.51 Thời gian bắt đầu của dòng K 1 giờ này là 2019.8.12 00:00 Số lượng giao dịch mỗi giờ (chỉ cần xem giá được tổng hợp như thế nào, không được hiển thị trong dữ liệu giao dịch) không được mô tả ở đây.

    Một dòng K dài 4 giờ được tổng hợp: Cao: 114477 Mở: 11382.57 Giảm: 11365.51 Lưu ý: 11384.71 Thời gian: 19.8.12 00:00

    img

    Bạn có thể thấy dữ liệu phù hợp.

  • Viết mã thực hiện

    Một khi ý tưởng ban đầu đã được xác minh, bạn có thể tự viết mã để thực hiện nhu cầu ban đầu.

    Có thể bạn sẽ thấy một số hình ảnh của những người đang sử dụng ứng dụng này.

      function GetNewCycleRecords (sourceRecords, targetCycle) {    // K线合成函数
          var ret = []
          
          // 首先获取源K线数据的周期
          if (!sourceRecords || sourceRecords.length < 2) {
              return null
          }
          var sourceLen = sourceRecords.length
          var sourceCycle = sourceRecords[sourceLen - 1].Time - sourceRecords[sourceLen - 2].Time
    
          if (targetCycle % sourceCycle != 0) {
              Log("targetCycle:", targetCycle)
              Log("sourceCycle:", sourceCycle)
              throw "targetCycle is not an integral multiple of sourceCycle."
          }
    
          if ((1000 * 60 * 60) % targetCycle != 0 && (1000 * 60 * 60 * 24) % targetCycle != 0) {
              Log("targetCycle:", targetCycle)
              Log("sourceCycle:", sourceCycle)
              Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle)
              throw "targetCycle cannot complete the cycle."
          }
    
          var multiple = targetCycle / sourceCycle
    
    
          var isBegin = false 
          var count = 0
          var high = 0 
          var low = 0 
          var open = 0
          var close = 0 
          var time = 0
          var vol = 0
          for (var i = 0 ; i < sourceLen ; i++) {
              // 获取 时区偏移数值
              var d = new Date()
              var n = d.getTimezoneOffset()
    
              if (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) {
                  isBegin = true
              }
    
              if (isBegin) {
                  if (count == 0) {
                      high = sourceRecords[i].High
                      low = sourceRecords[i].Low
                      open = sourceRecords[i].Open
                      close = sourceRecords[i].Close
                      time = sourceRecords[i].Time
                      vol = sourceRecords[i].Volume
    
                      count++
                  } else if (count < multiple) {
                      high = Math.max(high, sourceRecords[i].High)
                      low = Math.min(low, sourceRecords[i].Low)
                      close = sourceRecords[i].Close
                      vol += sourceRecords[i].Volume
    
                      count++
                  }
    
                  if (count == multiple || i == sourceLen - 1) {
                      ret.push({
                          High : high,
                          Low : low,
                          Open : open,
                          Close : close,
                          Time : time,
                          Volume : vol,
                      })
                      count = 0
                  }
              }
          }
    
          return ret 
      }
    
      // 测试
      function main () {
          while (true) {
              var r = exchange.GetRecords()                           // 原始数据,作为合成K线的基础K线数据,例如要合成4小时K线,可以用1小时K线作为原始数据。
              var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)      // 通过 GetNewCycleRecords 函数 传入 原始K线数据 r , 和目标周期, 1000 * 60 * 60 * 4 即 目标合成的周期 是4小时K线数据。
    
              $.PlotRecords(r2, "r2")                                 // 策略类库栏 可以勾选画线类库,调用 $.PlotRecords 画线类库 导出函数 画图。
              Sleep(1000)                                             // 每次循环间隔 1000 毫秒,防止访问K线接口获取数据过于频繁,导致交易所限制。
          }
      }
    

    Thực tế là để tổng hợp các đường k, bạn cần hai thứ, thứ nhất là bạn cần dữ liệu nguyên liệu, dữ liệu đường k trong chu kỳ nhỏ, ví dụ như trong ví dụ này.var r = exchange.GetRecords()Dữ liệu đường K chu kỳ nhỏ được thu thập. Thứ hai, cần phải xác định rõ ràng các chu kỳ lớn như thế nào, đó là các chu kỳ mục tiêu để tổng hợp dữ liệu đường K. Sau đó, các thuật toán của hàm GetNewCycleRecords có thể trả về dữ liệu của một cấu trúc matrix K-line tổng hợp. Những điều cần lưu ý:

    • 1, chu kỳ mục tiêu không thể nhỏ hơn chu kỳ của K dòng của hàm GetNewCycleRecords như là dữ liệu nguyên liệu. Vì không thể tổng hợp dữ liệu từ các chu kỳ nhỏ hơn với các chu kỳ nhỏ hơn.

    • 2, Các chu kỳ mục tiêu được đặt phải đóng chu kỳ. Đó là một sự kết thúc của một chu kỳ. Nói một cách đơn giản, trong một giờ hoặc trong một ngày, các phạm vi thời gian của chu kỳ mục tiêu được kết hợp với nhau để tạo thành một vòng tròn khép kín. Ví dụ: Ví dụ, đường K có chu kỳ 12 phút, bắt đầu từ 0 phút 0 giây trong mỗi giờ (ví dụ như 0 giờ), và chu kỳ đầu tiên là00:00:00 ~ 00:12:00Và chu kỳ thứ hai là00:12:00 ~ 00:24:00Và chu kỳ thứ ba là00:24:00 ~ 00:36:00Chu kỳ thứ tư là00:36:00 ~ 00:48:00Và chu kỳ thứ năm là00:48:00 ~ 01:00:00Trong khi đó, một người đàn ông người Việt Nam có thể nói rằng:

      Nếu là chu kỳ 13 phút, hay là chu kỳ không đóng, dữ liệu được tính toán theo chu kỳ như vậy không phải là duy nhất, bởi vì dữ liệu tổng hợp khác nhau tùy thuộc vào điểm bắt đầu của dữ liệu tổng hợp.

    Một người đàn ông người Việt Nam nói với một người đàn ông khác:img

    Biểu đồ giao dịch so sánhimg

  • Cấu trúc dữ liệu cần thiết để xây dựng dữ liệu K-line

    Một câu hỏi thường được đặt ra là tôi muốn tính giá trung bình cao nhất cho mỗi đường K.

    Thông thường, chúng ta tính đường trung bình là giá trung bình của giá đóng, tạo thành đường trung bình, nhưng đôi khi cũng có nhu cầu tính giá cao nhất, giá thấp nhất, giá mở, v.v. Không thể nói trực tiếp.exchange.GetRecords()Dữ liệu đường K mà hàm trả về được truyền trực tiếp vào hàm tính chỉ số.

    Ví dụ:talib.MAChức năng tính toán chỉ số đường thẳng có hai tham số, tham số đầu tiên là dữ liệu cần được truyền và tham số thứ hai là tham số chu kỳ chỉ số. Ví dụ, chúng ta sẽ tính các chỉ số như trên.img

    Một số người nói rằng, "K-line là một hệ thống máy tính có thể hoạt động trong vòng 4 giờ". Trên biểu đồ giao dịch, một đường trung bình đã được thiết lập với tham số chu kỳ đường trung bình là 9. Và các nguồn dữ liệu được tính toán là giá cao nhất cho mỗi Bar.imgĐường trung bình này là đường trung bình được tính trung bình giá cao nhất của 9 chu kỳ 4 giờ K-LineBar, bao gồm đường trung bình của chỉ số.

    Chúng tôi tự xây dựng một số liệu để xem liệu nó có giống như các biểu đồ trên sàn giao dịch hay không.

    var highs = []
    for (var i = 0 ; i < r2.length ; i++) {
        highs.push(r2[i].High)
    }
    

    Vì vậy, để tính toán giá cao nhất cho mỗi Bar, giá trung bình được đưa ra chỉ số đường thẳng. Sau đó, bạn cần phải tạo ra một mảng mà mỗi phần tử dữ liệu là giá trị cao nhất của mỗi Bar. Bạn có thể thấy rằng các biến highs bắt đầu như một mảng trống, sau đó chúng ta đi qua biến dữ liệu đường K này r2 (không nhớ r2? Xem mã trong hàm chính của đường K tổng hợp 4 giờ ở trên). Đọc giá trị cao nhất của r2 trên mỗi Bar (tức là r2[i].High, i lấy giá trị trong phạm vi từ 0 đến r2.length-1), và đẩy vào highs.

    Khi đó, các highs có thể được truyền vào talib.

    Một ví dụ hoàn chỉnh:

    function main () {
        while (true) {
            var r = exchange.GetRecords()
            var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
            if (!r2) {
                continue
            }
            
            $.PlotRecords(r2, "r2")                                               // 画出K线
            
            var highs = []
            for (var i = 0 ; i < r2.length ; i++) {
                highs.push(r2[i].High)
            }
            
            var ma = talib.MA(highs, 9)                                           // 用均线指标函数 talib.MA 计算 均线指标
            $.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time)     // 使用画线类库把均线指标画在图表上
            
            Sleep(1000)
        }
    }
    

    Khả năng kiểm tra lại:

    img

    Bạn có thể thấy ở trên biểu đồ, các chỉ số đường trung tuyến của vị trí chuột dừng lại là11466.9289

    Mã trên có thể được sao chép để chạy thử nghiệm trong chính sách, hãy nhớ chọn "Draw Line Library" để lưu!

  • Cách thu thập dữ liệu K-line của thị trường tiền kỹ thuật số

    Các nhà phát minh của nền tảng giao dịch định lượng đã có một giao diện được đóng gói sẵn, đó là chức năng exchange.GetRecords, có thể lấy dữ liệu từ K-line. Dưới đây là một giải thích về việc truy cập trực tiếp vào giao dịch K-line giao diện dữ liệu để lấy dữ liệu, vì đôi khi cần phải chỉ định các tham số để lấy nhiều hơn K-line, bao gồm giao diện GetRecords Thông thường trả về 100 thẻ. Nếu gặp phải một chiến lược yêu cầu ban đầu hơn 100 thẻ, bạn cần phải thu thập chờ. Để làm cho chính sách hoạt động càng nhanh càng tốt, bạn có thể tự đóng gói một hàm, truy cập trực tiếp vào giao diện K-Line của sàn giao dịch, chỉ định tham số để lấy nhiều dữ liệu K-Line hơn.

    Với cặp giao dịch BTC_USDT, chúng tôi thực hiện nhu cầu này:

    Tìm tài liệu API của sàn giao dịch và xem mô tả giao diện K-Line:img

    https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt
    

    Các thông số:

    Tên tham số Loại Phải không? Mô tả Lấy giá trị
    biểu tượng chuỗi đúng Giao dịch Btcusdt, ethbtc...
    thời gian chuỗi đúng Trả về độ phân tử thời gian dữ liệu, tức là khoảng thời gian của mỗi đoạn. 1 phút, 5 phút, 15 phút, 30 phút, 60 phút, 1 ngày, 1 tháng, 1 tuần, 1 năm
    kích thước số nguyên sai Trả về các đoạn dữ liệu đường K [1, 2000]

    Mã kiểm tra:

    function GetRecords_Huobi (period, size, symbol) {
        var url = "https://api.huobi.pro/market/history/kline?" + "period=" + period + "&size=" + size + "&symbol=" + symbol
        var ret = HttpQuery(url)
        
        try {
            var jsonData = JSON.parse(ret)
            var records = []
            for (var i = jsonData.data.length - 1; i >= 0 ; i--) {
                records.push({
                    Time : jsonData.data[i].id * 1000,
                    High : jsonData.data[i].high,
                    Open : jsonData.data[i].open,
                    Low : jsonData.data[i].low,
                    Close : jsonData.data[i].close,
                    Volume : jsonData.data[i].vol,
                })
            }
            return records
        } catch (e) {
            Log(e)
        }
    }  
    
    
    function main() {
        var records = GetRecords_Huobi("1day", "300", "btcusdt")
        Log(records.length)
        $.PlotRecords(records, "K")
    }
    

    Phiên bản Python, ví dụ về cách truy cập giao diện sàn giao dịch token:

#!python3
import json
import urllib2

def GetRecords_Huobi(period, size, symbol):
    headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    url = "https://api.huobi.pro/market/history/kline?" + "period=" + period + "&size=" + size + "&symbol=" + symbol
    request = urllib2.Request(url)  
    request.add_header('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')  
    opener = urllib2.build_opener()  
    f= opener.open(request)  
    ret = f.read().decode('utf-8')  
    
    try :
        jsonData = json.loads(ret)
        
        records = []
        for i in range(len(jsonData["data"]) - 1, -1, -1):
            records.append({
                "Time" : jsonData["data"][i]["id"] * 1000, 
                "High" : jsonData["data"][i]["high"], 
                "Open" : jsonData["data"][i]["open"], 
                "Low" : jsonData["data"][i]["low"], 
                "Close" : jsonData["data"][i]["close"], 
                "Volume" : jsonData["data"][i]["vol"], 
            })
        return records
    except Exception as e:
        Log(e)
        
def main():
    r = GetRecords_Huobi("1day", "300", "btcusdt")
    Log(len(r))
    ext.PlotRecords(r, "K")   # 需要引用Python画线类库


Phiên bản Python, ví dụ về giao diện K-Line để truy cập Binance:

#!python3
import json
import urllib2

def GetRecords_Huobi(period, size, symbol):
    headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    url = "https://api.binance.com/api/v3/klines?symbol=" + symbol + "&interval=" + period
    request = urllib2.Request(url)  
    request.add_header('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')  
    opener = urllib2.build_opener()  
    f= opener.open(request)  
    ret = f.read().decode('utf-8')  
    try :
        jsonData = json.loads(ret)
        
        records = []
        for i in range(len(jsonData)):
            records.append({
                "Time" : float(jsonData[i][0]),
                "High" : float(jsonData[i][2]), 
                "Open" : float(jsonData[i][1]), 
                "Low" : float(jsonData[i][3]), 
                "Close" : float(jsonData[i][4]), 
                "Volume" : float(jsonData[i][5]), 
            })
        return records
    except Exception as e:
        Log(e)
        
def main():
    r = GetRecords_Huobi("1m", "300", "BTCUSDT")
    Log(len(r))
    ext.PlotRecords(r, "K")   # 需要引用Python画线类库


img

img

Bạn có thể thấy trên nhật ký, in records.length là 300, nghĩa là records K là số lượng các thanh dữ liệu trên dòng có 300.img


Có liên quan

Thêm nữa

BamsmenBạn có thể sửa được vấn đề này không? Bạn không thể tổng hợp k ngày trong 3 giờ hoặc 6 giờ.

Bamsmenif (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) { isBegin = true Câu này có vấn đề, bạn không thể tổng hợp ngày k trong 3 hoặc 6 giờ, bạn chỉ có thể tổng hợp ngày k trong 1 giờ, 2 giờ, 4 giờ.

xis2004Nếu bạn muốn leo lên tất cả các dữ liệu lịch sử của một giống, bạn có thể leo lên không?

willzhangCảm ơn bạn đã trả lời.

willzhangXin hỏi, làm thế nào để xử lý tốt hơn nếu bạn muốn hơn 300 bit? ví dụ: 1000 K-line dữ liệu.

Giấc mơ nhỏĐược rồi, hãy thay đổi thời gian nhé.

Giấc mơ nhỏĐây là số lượng dữ liệu mà giao dịch cung cấp cho bạn.

Giấc mơ nhỏNếu vượt quá số lượng trả về tối đa được hỗ trợ bởi giao diện giao dịch, chỉ có thể thu thập dữ liệu, và như vậy đủ dữ liệu K-line.