Обработка данных по линии K в количественной торговле

Автор:Доброта, Создано: 2019-09-03 11:15:30, Обновлено: 2023-11-07 20:43:41

img

Как K Line обрабатывает данные в количественной торговле?

При написании количественной торговой стратегии, используя данные K-линии, часто бывают случаи, когда требуются нестандартные циклические K-линейные данные. например, требуются 12-минутные циклические K-линейные данные и 4-часовые K-линейные циклические данные. Обычно такие нестандартные циклы непосредственно недоступны. Итак, как мы справляемся с такими потребностями?

Нестандартные данные о цикле K можно получить путем объединения данных меньшего цикла. Представьте, что самая высокая цена в нескольких циклах считается самой высокой ценой после синтеза линии K многочисленного цикла, а самая низкая цена рассчитывается как самая низкая цена после синтеза, и цена открытия не меняется. Первая цена открытия сырьевых данных K-линии синтезируется. Цена закрытия соответствует цене закрытия последних сырьевых данных K-линии. Время использует время линии цены открытия k. Объем транзакции использует сырьевые данные, которые суммировались и рассчитывались.

Как показано на рисунке:

  • Мысль

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

img img img img

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

Данные четырех одночасовых циклов объединяются в единые четырехчасовые данные.

Цена открытия - это цена открытия первой линии K в 00:00 время: 11382.57 Цена закрытия - это цена закрытия последней линии k в 03:00: 11384.71 Самая высокая цена - это найти самую высокую цену среди них: 11447,07 Самая низкая цена - это найти самую низкую цену среди них: 11365,51

Примечание: Китайский товарный фьючерсный рынок закрывается в 15:00 в обычный торговый день

Время начала 4-часового цикла - это время начала первой 1-часовой K-линии, т.е. 2019.8.12 00:00

Сумма объема всех 1-часовых k линий используется в качестве этого 4-часового k объема линий.

Выделяется 4-часовая K-линия:

High: 11447.07
Open: 11382.57
Low: 11365.51
Close: 11384.71
Time: 209.8.12 00:00

img

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

  • Внедрение кода

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

Эти коды предназначены только для справки:

function GetNewCycleRecords (sourceRecords, targetCycle) { // K line synthesis function
      var ret = []
      
      // First get the source K line data cycle
      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++) {
          // Get the time zone offset value
          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
  }

  // test
  function main () {
      while (true) {
          var r = exchange.GetRecords() // Raw data, as the basic K-line data of the synthesize K line. for example, to synthesize a 4-hour K-line, you can use the 1-hour K-line as the raw data.
          var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4) // Pass the original K-line data r through the GetNewCycleRecords function, and the target cycles, 1000 * 60 * 60 * 4, ie the target synthesis cycle is 4 hours K-line data .

          $.PlotRecords(r2, "r2") // The strategy class library bar can be selected by check the line class library, and calling the $.PlotRecords line drawing class library to export the function drawing.
          Sleep(1000) // Each cycle is separated by 1000 milliseconds, preventing access to the K-line interface too much, resulting in transaction restrictions.
      }
  }

На самом деле, чтобы синтезировать K-линию, вам нужны две вещи. Первая - это данные о сырье, то есть данные K-линии меньшего цикла.var r = exchange.GetRecords()чтобы получить более мелкие данные цикла K линии.

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

Пожалуйста, обратите внимание:

  1. Целевой цикл не может быть меньше цикла K-линии, которую вы прошли в функции GetNewCycleRecords в качестве сырья для данных.

  2. Целевой цикл должен быть настроен на закрытый цикл. Что такое закрытый цикл? Проще говоря, в течение одного часа или в течение дня, целевые промежутки времени цикла объединяются, образуя закрытую петлю.

Например:

К-линия 12-минутного цикла начинается с 0:0 каждый час, первый цикл - 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, которые составляют ровно один час.

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

Запустите его на реальном рынке:

img

Диаграмма контрастного обмена

img

  • Создать требуемую структуру данных с использованием данных K-линии

Я хочу вычислить скользящую среднюю наивысшей цены для всех K-линий.

Обычно мы рассчитываем скользящие средние, используя средние цены закрытия, но иногда есть спрос на использование самой высокой цены, самой низкой цены, цены открытия и так далее.

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

Например: Вtalib.MAФункция расчета показателя скользящей средней имеет два параметра, первый из которых - данные, которые необходимо передать, а второй - параметр цикла показателя.

Например, мы должны рассчитать показатели, как показано ниже.

img

Цикл К-линии длится 4 часа.

На диаграмме котировок на биржевых рынках установлена средняя линия с параметром цикла 9.

В рассчитанном источнике данных используется самая высокая цена за бар.

img

То есть, эта скользящая средняя линия состоит из средней наивысшей средней цены девяти 4-часовых циклов K-линии.

Давайте построим данные сами, чтобы увидеть, если это то же самое с данными обмена.

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

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

Вы можете видеть, чтоhighsпеременная изначально является пустым массивом, затем мы пересекаем переменную данных k-линии r2 (не помните r2? Посмотрите на код в основной функции, которая синтезирует 4-часовую K-линию выше).

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

В данный момент,highsВы можете пройтиtalib.MAфункция для расчета скользящей средней.

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

function main () {
     while (true) {
         var r = exchange.GetRecords()
         var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
         if (!r2) {
             Continue
         }
        
         $.PlotRecords(r2, "r2") // Draw the K line
        
         var highs = []
         for (var i = 0 ; i < r2.length ; i++) {
             Highs.push(r2[i].High)
         }
        
         var ma = talib.MA(highs, 9) // use the moving average function "talib.MA" to calculate the moving average indicator
         $.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time) // Use the line drawing library to draw the moving average indicator on the chart
        
         Sleep(1000)
     }
}

Проверка на обратном пути:

img

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

Вышеуказанный код можно скопировать в стратегию для выполнения теста, не забудьте проверить Draw Line Library и сохранить его!

  • Метод сбора данных K-линии для рынка криптовалют

Платформа FMZ Quant уже имеет пакетный интерфейс, а именноexchange.GetRecordsФункция, чтобы получить данные K-линии.

Следующее сосредоточено на прямом доступе к интерфейсу данных K-линии обмена для получения данных, потому что иногда вам нужно указать параметры, чтобы получить больше K-линий, пакетGetRecordsИнтерфейс обычно возвращает 100 к линий. Если вы столкнетесь со стратегией, которая поначалу требует более 100 к линий, вам нужно подождать процесс сбора.

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

Используя торговую пару BTC_USDT на бирже Huobi в качестве примера, мы реализуем следующее требование:

Найдите документацию обмена API и посмотрите описание интерфейса K-line:

img

https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles

параметры:

Имя Тип Это необходимо? Описание Стоимость
символ строка Истинно Торговая пара БТКУСД, ЭТКУСД...
Период строка Истинно Возвращает временную гранулярность данных, которая является временным интервалом каждой k строки 1 минута, 5 минут, 15 минут, 30 минут, 60 минут, 1 день, 1 месяц, 1 неделя, 1 год
Размер цельное число ложный Возвращает количество 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")
}

img img

Вы можете увидеть это на дневнике, отпечатокrecords.length300, то есть количествоrecordsК-линейная панель данных - 300.img


Связанные

Больше