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

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я...

Создано: 2022-06-01 17:37:55, Обновлено: 2023-09-18 20:19:45
comments   6
hits   2992

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я…

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я…

На TradingView огромное количество стратегий с открытым исходным кодом. Жаль, что столько прекрасных стратегий, идей и индикаторов не могут быть реализованы на практике. Видя это, FMZ, которая стремится популяризировать технологию количественной торговли среди многих трейдеров, естественно, не может сдержать желание удовлетворить этот спрос!

Это требование совершенно невыносимо!

Итак, в мире программирования я путешествовал по горам и рекам и пережил 9*9=81 пит-стоп, после бесчисленных бессонных ночей, в углу скопилась гора пустых банок из-под Red Bull. Наконец, FMZ поддерживает язык Pine и совместим с ним, а также позволяет использовать различные скрипты TradingView Pine.

Говоря о языке сосны, я только недавно выучил его самостоятельно. Но, честно говоря, язык Pine для количественной торговли действительно прост, удобен в использовании и легок в изучении. Что? Не верите? Посмотрите, как я пишу для вас стратегию сетки~

/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="间距价格")
var dir = input.string("long", title="方向", options = ["long", "short", "both"])
var amount = input.float(-1, title="下单量")
var numbers = input.int(-1, title="网格数量")
var profit = input.int(-1, title="盈利价差") / syminfo.mintick

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("参数错误")

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

findTradeId(id) =>
    ret = "notFound"
    for i = 0 to strategy.opentrades - 1
        if strategy.opentrades.entry_id(i) == id 
            ret := strategy.opentrades.entry_id(i)
    ret 

// 实时K线阶段
if not barstate.ishistory
    // 检索网格
    for i = 1 to numbers
        // 做多
        direction = dir == "both" ? "long" : dir 
        plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
        if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.long,  qty=amount, limit=beginPrice-i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
        // 做空
        direction := dir == "both" ? "short" : dir 
        plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
        if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)

Торговля в реальном времени, инструменты бэктестинга, многочисленные функции FMZ и простота использования языка Pine — это как добавить крылья тигру! Включая настройки параметров и коды конфигурации бэктестинга, общее количество кодов не превышает 50 строк. Новичкам больше не придется беспокоиться о написании сетки…

Конечно, эта стратегия — стратегия сетки. Стратегии сетки также имеют свои недостатки, и это не гарантированный станок для печатания денег. Ключ кроется в его использовании и параметрах. Я не буду подробно останавливаться на этом моменте. Давайте больше сосредоточимся на том, как легко писать стратегии, внедрять собственную торговую логику и зарабатывать деньги, создавая собственные стратегии. Это так здорово, не прося никого о помощи! !

Пояснение кода

Позвольте мне объяснить вам, код прост и понятен. Если вы все еще не можете писать стратегии, используя простой в изучении и использовании язык Pine, то я буду…….. ……… …………………….Позвольте мне рассказать вам подробнее!

В начале/*backtestи*/Обернутое содержимое представляет собой код конфигурации бэктеста FMZ, который является функцией FMZ, а не содержимым языка Pine. Конечно, вы можете не писать эту часть. При бэктестинге вам нужно будет вручную щелкнуть элементы управления параметрами, чтобы задать конфигурацию и параметры бэктеста.

/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/

Следующий код:

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="间距价格")
var dir = input.string("long", title="方向", options = ["long", "short", "both"])
var amount = input.float(-1, title="下单量")
var numbers = input.int(-1, title="网格数量")
var profit = input.int(-1, title="盈利点数") / syminfo.mintick
  • strategy(overlay=true): Используется для установки некоторых опций скрипта, overlay=true, который задает параметрыoverlayПрисвойте значение true, чтобы отобразить изображение на основном изображении графика (график K-line является основным изображением, его можно понять так просто).
  • varip beginPrice = 0: Переменная beginPrice объявляется с использованием ключевого слова varip и изначально ей присваивается значение 0, которое используется в качестве начальной цены сетки.
  • var spacing = input.float(-1, title="间距价格"): Установите параметр стратегии. Имя параметра — «интервальная цена», которая представляет собой интервал между каждой точкой сетки. Если он установлен на 100, это означает, что транзакция будет совершаться каждый раз, когда цена превысит 100.
  • var dir = input.string("long", title="方向", options = ["long", "short", "both"]): Параметр стратегии установлен, называется “направление”. Этот параметр является опцией с раскрывающимся списком, и вы можете выбрать длинную, короткую или обе позиции. Они соответственно указывают на то, что сетка торгует только на длинные позиции, только на короткие позиции или торгует как на длинные, так и на короткие позиции.
  • var amount = input.float(-1, title="下单量"): Установите параметр для управления объемом транзакции в каждой точке сетки.
  • var numbers = input.int(-1, title="网格数量"): Количество точек сетки. Установка значения 20 означает, что в одном направлении будет 20 точек сетки.
  • var profit = input.int(-1, title="盈利价差") / syminfo.mintick: Установите параметр для управления разницей цен, при которой позиция в каждой точке сетки будет закрыта.

Далее смотрим на код:

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("参数错误")

Это означает, что если какой-либо из параметров, таких как интервал, сумма, числа и прибыль, не установлен, то значение по умолчанию равно -1, что означает, что стратегия остановится (вы не сможете бегать, не установив параметры ~ хаха!)

Go on !

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

Это означает, что когда стратегия находится на стадии K-линии в реальном времени и beginPrice == 0, измените значение beginPrice на текущую последнюю цену. Можно понять, что при официальном запуске стратегии начальная текущая цена является начальной ценой сетки. Поскольку сценарий имеет историческую стадию BAR линии K, стратегия будет выполнять логику на исторической стадии BAR. Определенно бессмысленно размещать сетку на исторической стадии BAR.

Что такое историческая фаза BAR?

Приведем простой пример: в текущий момент A стратегия начинает работать и получает данные со 100 BAR линии K. Со временем 100 BAR определенно превратятся в 101, 102… N. При отсчете от времени А 101-й БАР представляет собой стадию К-линии в реальном времени, которая представляет собой последние данные в реальном времени. Таким образом, с 1-го по 100-й БАРЫ все эти исторические рыночные условия уже прошли, но стратегия также будет работать на этих исторических рыночных условиях, поэтому этот этап является этапом исторической К-линии.

barstate.ishistoryЭто встроенная переменная языка Pine. Если текущий BAR является историческим BAR,barstate.ishistoryЕсли это не исторический BAR, то это ложь. Таким образом, когда значение not barstate.ishistory равно true, то он находится на стадии K-линии реального времени.

Далее мы создали функцию

findTradeId(id) =>
    ret = "notFound"
    for i = 0 to strategy.opentrades - 1
        if strategy.opentrades.entry_id(i) == id 
            ret := strategy.opentrades.entry_id(i)
    ret 

Функция этой функции — выяснить, существует ли определенный ID во всех открытых в данный момент ордерах. Если он существует, функция findTradeId вернет ID существующего ордера при его вызове (обратите внимание, что этот ID не является ID ордера биржа, а идентификатор, присвоенный заказу стратегией). , или интерпретируемый как метка), если он не существует, возвращает строку «notFound».

Далее приступаем к изготовлению сетчатого листа:

// 实时K线阶段
if not barstate.ishistory
    // 检索网格
    for i = 1 to numbers
        // 做多
        direction = dir == "both" ? "long" : dir 
        plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
        if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.long,  qty=amount, limit=beginPrice-i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
        // 做空
        direction := dir == "both" ? "short" : dir 
        plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
        if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)

Цикл for используется для определения количества циклов на основе значения параметра numbers, то есть для упорядочивания соответствующего количества заказов. Задайте направление в соответствии с параметром dir. Используйте функцию findTradeId, чтобы узнать, открыт ли заказ метки в текущей позиции сетки. Размещайте запланированный заказ только в том случае, если он не был открыт (если он был открыт, вы не можете разместить дублирующий заказ). При размещении заказа используйте функцию strategy.order, чтобы указать параметр лимита для создания планового заказа. Разместите соответствующий закрывающий ордер одновременно с размещением запланированного ордера. Чтобы закрыть позицию, используйте функцию strategy.exit, укажите параметр прибыли и укажите пункты прибыли.

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я…

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я…

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я…

Если вы все еще не можете писать стратегии, используя простой в освоении и использовании язык Pine, то я…

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

Ну, если вы все еще не можете писать стратегии, используя простой в изучении и использовании язык Pine, то я…