4
Подписаться
1271
Подписчики

Краткое обсуждение обработки данных K-line в программируемой торговле

Создано: 2019-08-13 11:11:38, Обновлено: 2023-10-20 20:06:13
comments   8
hits   4631

Краткое обсуждение обработки данных K-line в программируемой торговле

Краткое обсуждение обработки данных K-line в программируемой торговле

При написании программных торговых стратегий с использованием данных K-line часто возникает необходимость использовать некоторые нестандартные периоды данных K-line, например, данные K-line за 12-минутный период, данные K-line за 4-часовой период, обычно этот вид нестандартного периода не может быть получен напрямую. Так как же нам реагировать на такие требования? Ответ: способ, безусловно, есть. Нестандартные циклы могут быть получены путем слияния и синтеза данных из меньших циклов. Вы можете представить, что самая высокая цена в нескольких циклах считается самой высокой ценой после синтеза, а самая низкая цена считается самой низкой ценой после синтеза. Открытие цена не изменится. , используется первая цена открытия исходных данных синтезированной K-линии, цена закрытия соответствует последней цене закрытия исходных данных синтезированной K-линии, время - это время от цены открытия, а объем торгов рассчитывается путем суммирования объемов транзакций с данными о сырьевых материалах. Как показано на рисунке:

  • ### Идеи

В качестве примера мы возьмем рынок блокчейн-активов BTC_USDT и синтезируем 1 час в 4 часа.

Краткое обсуждение обработки данных K-line в программируемой торговле

Краткое обсуждение обработки данных K-line в программируемой торговле

Краткое обсуждение обработки данных K-line в программируемой торговле

Краткое обсуждение обработки данных K-line в программируемой торговле

|Время|Высокий|Открытый|Низкий|Закрытый| |- |- |- |- |-| |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|

Данные этих четырех 1-часовых циклов объединяются в данные 4-часового цикла. Цена открытия — это цена открытия первого времени 00:00: 11382.57 Цена закрытия — последняя, ​​то есть цена закрытия в 03:00: 11384.71 Самая высокая цена здесь самая высокая цена: 11447.07 Самая низкая цена здесь: 11365.51 Время начала 4-часового цикла - 00:00, время начала 1-часовой К-линии, то есть 2019.8.12 00:00 Объем торгов можно суммировать каждый час (в основном для того, чтобы посмотреть, как синтезируется цена, которая не отображается в данных по объему торгов). Я не буду здесь вдаваться в подробности.

Синтезированная 4-часовая К-линия: Максимум: 11447.07 Открыто: 11382.57 Низкий: 11365.51 Получено: 11384.71 Время: 2019.8.12 00:00

Краткое обсуждение обработки данных K-line в программируемой торговле

Вы можете видеть, что данные согласуются.

  • ### Написать код для реализации

После проверки предварительных идей можно приступить к написанию кода для предварительной реализации этого требования.

Опубликуйте код напрямую, код предназначен только для справки:

    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线接口获取数据过于频繁,导致交易所限制。
        }
    }

На самом деле, для синтеза K-line необходимы две вещи. Первая — это данные о сырье, то есть данные K-line малого периода.var r = exchange.GetRecords() Получены данные по К-линии с малым периодом. Во-вторых, необходимо четко определить период синтеза, то есть целевой период для синтеза данных K-line. Затем с помощью алгоритма функции GetNewCycleRecords можно окончательно вернуть данные синтезированной структуры массива K-строк. Следует отметить, что:

    1. Целевой цикл не может быть меньше цикла K-линии, которую вы передаете в функцию GetNewCycleRecords в качестве исходных данных. Это связано с тем, что невозможно использовать малый цикл для синтеза данных из меньшего цикла.
    1. Установленный целевой период должен быть закрытым периодом. Что такое замыкание цикла? Проще говоря, в течение часа или дня целевые диапазоны времени цикла объединяются, образуя замкнутый цикл. Пример: Например, линия К 12-минутного цикла начинается в 0:00 каждого часа (возьмем 0:00 в качестве примера), а первый цикл —00:00:00 ~ 00:12:00, второй цикл -00:12:00 ~ 00:24:00, третий цикл - это00:24:00 ~ 00:36:00, четвертый цикл - это00:36:00 ~ 00:48:00, пятый цикл - это00:48:00 ~ 01:00:00 , что составляет целый 1 час.

    Если это 13-минутный цикл, то это открытый цикл, и данные, рассчитанные в таком цикле, не являются уникальными, поскольку синтезированные данные будут отличаться в зависимости от начальной точки синтезированных данных.

Реальный диск был запущен: Краткое обсуждение обработки данных K-line в программируемой торговле

Сравните графики обмена Краткое обсуждение обработки данных K-line в программируемой торговле

  • ## Использовать данные K-line для построения требуемой структуры данных

Участники группы часто задают вопросы: Я хочу рассчитать скользящую среднюю самой высокой цены каждой К-линии, что мне делать?

Обычно мы рассчитываем скользящую среднюю путем вычисления среднего значения цен закрытия для формирования скользящей средней, но иногда возникает необходимость рассчитать самую высокую цену, самую низкую цену, цену открытия и т. д. В это время вы не можете простоexchange.GetRecords() Данные K-линии, возвращаемые функцией, напрямую передаются в функцию расчета индикатора.

Например: Функция расчета индикатора скользящей средней talib.MA имеет два параметра. Первый параметр — это данные, которые необходимо передать, а второй параметр — это параметр периода индикатора. Например, мы хотим рассчитать следующие показатели Краткое обсуждение обработки данных K-line в программируемой торговле

Цикл К-линии составляет 4 часа. На биржевом графике установлена ​​скользящая средняя с параметром периода скользящей средней 9. Источником данных для расчета является максимальная цена каждого бара. Краткое обсуждение обработки данных K-line в программируемой торговле То есть эта скользящая средняя представляет собой среднее значение самых высоких цен 9 4-часовых баров K-линии, которые составляют скользящую среднюю индикатора.

Давайте построим некоторые данные самостоятельно и посмотрим, совпадают ли они с теми, которые рассчитаны по графику биржи.

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

Так как нам необходимо рассчитать среднее значение самых высоких цен каждого бара, чтобы вывести индикатор скользящей средней. Затем вам необходимо сначала построить массив, в котором каждый элемент данных соответствует максимальной цене каждого бара. Вы можете видеть, что переменная highs изначально представляет собой пустой массив, а затем мы обходим переменную данных свечи r2 (не помните r2? Посмотрите на код в основной функции синтеза 4-часовой свечи выше). Прочитайте самую высокую цену каждого бара r2 (т.е. r2[i].High, i находится в диапазоне от 0 до r2.length - 1), а затем переходит в highs. Таким образом, создается структура данных, которая один к одному соответствует данным K-линии Bar.

На этом этапе максимумы можно передать в функцию talib.MA для расчета скользящей средней.

Полный пример:

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

Тестирование на исторических данных:

Краткое обсуждение обработки данных K-line в программируемой торговле

Вы можете видеть, что значения индикатора скользящей средней в позиции мыши на рисунке равны11466.9289

Вышеуказанный код можно скопировать в стратегию для запуска теста. Не забудьте проверить “Библиотеку рисования линий” и сохранить его!

  • ## Как получить данные K-line на рынке цифровой валюты

Платформа количественной торговли Inventor уже имеет упакованный интерфейс, а именно функцию exchange.GetRecords, которая может получать данные K-line. Далее основное внимание уделяется прямому доступу к интерфейсу данных K-line обмена для получения данных, поскольку иногда необходимо указать параметры для получения большего количества K-строк, инкапсулированный интерфейс GetRecords. Обычно возвращается 100. Если изначально стратегия требует более 100 К-линий, нужно собраться и подождать. Чтобы стратегия выполнялась как можно быстрее, вы можете самостоятельно инкапсулировать функцию, напрямую получить доступ к интерфейсу K-line обмена и указать параметры для получения дополнительных данных K-line.

Взяв в качестве примера торговую пару BTC_USDT Huobi, мы реализуем это требование:

Найдите API-документ биржи и просмотрите описание интерфейса K-line: Краткое обсуждение обработки данных K-line в программируемой торговле

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

параметр: |Имя параметра|Тип|Обязательно|Описание|Значение| |-|-|-|-|-| |символ|строка|истина|Торговая пара|btcusdt, ethbtc…| |period|string|true|Возвращает временную гранулярность данных, то есть временной интервал каждой свечи|1мин, 5мин, 15мин, 30мин, 60мин, 1день, 1мес, 1неделя, 1год| |size|integer|false|Возвращает количество данных K-линии|[1, 2000]|

Тестовый код:

  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")
  }

Версия Python, пример доступа к интерфейсу биржи Huobi:

#!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画线类库


Версия Python, пример доступа к интерфейсу K-line биржи 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画线类库


Краткое обсуждение обработки данных K-line в программируемой торговле

Краткое обсуждение обработки данных K-line в программируемой торговле

В журнале мы видим, что длина записей равна 300, что означает, что имеется 300 столбцов данных K-линии. Краткое обсуждение обработки данных K-line в программируемой торговле