В процессе загрузки ресурсов... загрузка...

Вводный учебник по языку PINE FMZ Quant

Автор:FMZ~Lydia, Создано: 2022-09-23 15:23:34, Обновлено: 2024-02-27 16:47:41

.3, предел=3)

Если нет, закройте и откройте Стратегия.Отменить. Стратегия.отменить ((long2) Стратегия.Отменить. isStop:= true


---------------------------

6. ```strategy.cancel_all```

The ```strategy.cancel_all``` function is similar to the ```strategy.cancel``` function. It can cancel/stop all pre-listed commands. The ```when``` parameter can be specified.

Parameters:

- ```when```: Execution conditions.

```pine
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

strategy("strategy.cancel Demo", pyramiding=3)

var isStop = false 
if isStop 
    runtime.error("stop")

strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)

if not barstate.ishistory and close < open 
    strategy.cancel_all()
    isStop := true 

  1. strategy.order

Функциональность и параметрыstrategy.orderФункции практически идентичны функциямstrategy.entryРазница в том, чтоstrategy.orderФункция не зависит отpyramidingпараметры настройкиstrategyФункция, и нет ограничения количества заказов.

Параметры:

  • idИдентификатор может быть использован для отмены, изменения ордеров и закрытия позиций.
  • direction: Если направление ордера длинное (купить), вставьте встроенную переменнуюstrategy.long, и если вы хотите пойти короткий (продать), пройти в переменнойstrategy.short.
  • qty: Укажите сумму заказов, которые должны быть размещены, если этот параметр не будет передан, будет использоваться сумма заказов по умолчанию.
  • when: Условие выполнения, вы можете указать этот параметр для контроля того, будет ли задействована текущая операция заказа или нет.
  • limit: Укажите предельную цену заказа.
  • stopСтоп-лосс.

Мы будем использовать функцию, котораяstrategy.orderне имеет ограничения на количество размещенных заказов, в сочетании сstrategy.exitУсловное выходная функция для построения сценария, аналогичного торговле сетью.

/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/

varip beginPrice = -1

if not barstate.ishistory
    if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0) 
        beginPrice := close
    
    for i = 0 to 20
        strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
        strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
        
        strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
        strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)

Примеры стратегии

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

Стратегия сверхпоказателя тренда

strategy("supertrend", overlay=true)

[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))

plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)

if direction < 0
    if supertrend > supertrend[2]
        strategy.entry("entry long", strategy.long)
    else if strategy.position_size < 0
        strategy.close_all()
else if direction > 0
    if supertrend < supertrend[3]
        strategy.entry("entry short", strategy.short)
    else if strategy.position_size > 0
        strategy.close_all()

Это очень просто написать трендовую стратегию с помощью языка Pine, и здесь мы разработаем простую стратегию тренда с супер-индикатором тренда.

Во-первых, код стратегии начинается с некоторых простых настроек с помощьюstrategyФункция:strategy("supertrend", overlay=true)``, which just sets a strategy title "supertrend". Theпокрытиеparameter is set toИстинно, so that the drawn indicator lines and other content are displayed on the main chart. The first thing we need to look at when designing a Pine strategy or learning a Pine strategy script is the strategy interface parameter design. Let's look at the source code of the ''supertrend indicator strategy'', which has theВходной функцию мы узнали в предыдущем курсе

[supertrend, direction] = ta.supertrend ((input ((5, factor),input.int(10, atrPeriod))

Вinputвызов функции используется в качестве параметра непосредственно кta.supertrendфункция индикатора для расчета индикатора супертенденции.

  • ввод ((5, фактор)
  • input.int(10, trPeriod)

По умолчанию функция устанавливает два элемента управления параметрами на экране стратегии языка Pine, как показано ниже:

img

Как мы можем видеть, значение по умолчанию на контроле является первым параметромinputФункция иinputсерии функций (здесьinput.intС помощью этих двух функций мы можем установить параметрыta.supertrendФункция на экране стратегии.supertrendФункция вычисляет данные ценыsupertrendи данные направленияdirectionТогда мы используемplotфункция, чтобы нарисовать график, обратите внимание, что при рисовании графика, он основан на направлении индикатора супертенденции, только текущее направление рисуется.direction-1, то текущая рыночная тенденция повышается, когдаdirectionТаким образом, мы можем видеть, чтоplotФункция рисует диаграмму, когда решениеdirectionбольше или меньше 0.

Следующий.if... else ifЛогика - это суждение торгового сигнала.direction < 0Это означает, что нынешний рынок находится на восходящей стадии.supertrendв индикаторе супертенденции выше, чем цена индикатора супертенденции на двух предыдущих BAR (т.е.supertrend[2], remember that the historical operator refers to the historical data of a variableЕсли существует текущая позиция, вызов функции обратного заказа сначала закрывает предыдущую позицию, а затем открывает позицию в соответствии с текущим направлением торговли.supertrend > supertrend[2]не были выполнены, до тех пор покаstrategy.position_size < 0Если вы держите короткие позиции, это вызоветstrategy.close_all()выполнение функции для закрытия всех позиций.

direction > 0Если есть длинные позиции, все позиции будут закрыты, а затем, когда состояниеsupertrend < supertrend[3]Почему он настроен на[3]Это может быть намерением автора стратегии. В конце концов, короткий риск на некоторых рынках, таких как рынок контрактной торговли, немного больше, чем длинный риск.

Дляta.supertrendИндикатор, кто-нибудь интересуется, как судить, является ли текущая тенденция вверх или вниз?

Фактически, этот показатель также может быть реализован в виде пользовательских функций на языке Pine:

pine_supertrend(factor, atrPeriod) =>
	src = hl2
	atr = ta.atr(atrPeriod)
	upperBand = src + factor * atr
	lowerBand = src - factor * atr
	prevLowerBand = nz(lowerBand[1])
	prevUpperBand = nz(upperBand[1])

	lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
	upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
	int direction = na
	float superTrend = na
	prevSuperTrend = superTrend[1]
	if na(atr[1])
		direction := 1
	else if prevSuperTrend == prevUpperBand
		direction := close > upperBand ? -1 : 1
	else
		direction := close < lowerBand ? 1 : -1
	superTrend := direction == -1 ? lowerBand : upperBand
	[superTrend, direction]

Эта пользовательская функция точно такой же алгоритм, как встроенная функцияta.supertrend, и, конечно, рассчитанные данные показателя также точно такие же. Как мы можем видеть из этого алгоритма пользовательской функции, Pine встроенный супер индикатор тренда рассчитывается с использованиемhl2Встроенная переменная (самые высокие и самые низкие цены суммируются вместе, а затем делятся на 2, то есть среднее значение самых высоких и самых низких цен), а затем индикатор ATR (волатильность) рассчитывается на определенный период на основе параметра atrPeriod.

ОбновлениеlowerBandиupperBandв соответствии с трехзначными выражениями в коде.

    lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
    upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand

lowerBand: lowerBand, используется для определения изменения тенденции к росту. upperBand: upperBand, используется для определения изменения тенденции к снижению. lowerBand и upperBand всегда рассчитываются, только текущее направление тенденции определяется в конце этой пользовательской функции.

    else if prevSuperTrend == prevUpperBand
        direction := close > upperBand ? -1 : 1
    else
        direction := close < lowerBand ? 1 : -1

Здесь считается, что если стоимость цены последнего BAR на супер трендеprevUpperBand, т.е. верхняя полоса, это означает, что ток имеет тенденцию к снижению.closeпревышаетupperBandВ этом случае тенденция считается перемещенной и преобразованной в восходящий тренд.directionВ противном случае он все равно будет установлен на 1 (низкий тренд). Вот почему вы видите в стратегии супер-тенденцииif direction < 0когда сигнал состояние запускается, чтобы пойти долго.direction > 0, сигнал становится коротким.

    superTrend := direction == -1 ? lowerBand : upperBand
    [superTrend, direction]

Наконец, на основе выбранного направления возвращаются конкретные данные о ценах и направлениях показателя Super Trend.

Динамическая стратегия балансирования

/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/

varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")

maxDiffValue = input(1000, "maxDiffValue")


if balance - close * stocks > maxDiffValue and not barstate.ishistory
    // more balance , open long 
    tradeAmount = (balance - close * stocks) / 2 / close
    strategy.order("long", strategy.long, tradeAmount)
    balance := balance - tradeAmount * close
    stocks := stocks + tradeAmount
    runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)

else if close * stocks - balance > maxDiffValue and not barstate.ishistory
    // more stocks , open short 
    tradeAmount = (close * stocks - balance) / 2 / close
    strategy.order("short", strategy.short, tradeAmount)
    balance := balance + tradeAmount * close
    stocks := stocks - tradeAmount
    runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)

plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)

img

img

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

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

Давайте посмотрим на дизайн кода стратегии:

Мы используем упрощенный дизайн, который имитируетbalance(т. е. количество активов в валюте котировки) иstocksМы не читаем реальное количество активов на счете, мы просто используем моделируемую сумму для расчета соответствующих покупок и продаж.maxDiffValueПри текущей цене только тогда, когда отклонение междуBaseCurrencyиQuoteCurrencyпревышаетmaxDiffValueпроисходит ли процесс балансирования, продавая актив по высокой цене и покупая актив по низкой цене для ребалансирования актива.

Стрелок сигналов стратегии торговли должен находиться на стадии BAR в режиме реального времени, поэтому если суждения в условиях стратегии торговли установлены сnot barstate.ishistoryПокупать, когдаbalanceзначение превышаетstocksПосле выполнения торгового заявления, операционная система получает информацию о стоимости, основанную на расчете текущей цены.balanceиstocksпеременные обновляются, а затем ждут следующего баланса.

Вышеуказанная информация стратегии backtest содержит цену вида на момент начала стратегии backtest, цена 1458, так что я установил параметрbalanceк: 4374 (1458*3) намеренно установить параметрstocksПусть актив начинается в балансе.

Стратегия супер-тенденции с отслеживанием стоп-потери и прибыли

В предыдущем курсе мы узнали оstrategy.exitВ этом примере дизайна стратегии мы будем использоватьstrategy.exitФункция оптимизации стратегии супер тренда.

Сначала давайте посмотрим на параметры отслеживания стоп-лосса и прибылиstrategy.exitФункция:

  1. Параметрtrail_price: Позиция, которая запускает логическое действие по размещению ордера с отслеживанием стоп-лосса и ордера с закрытием стоп-лосса (на позиции, указанной ценой).
  2. Параметрtrail_offset: Расстояние от самой высокой (при длинном ходе) или самой низкой (при коротком ходе) цены закрытой позиции, размещенной после выполнения операции с отслеживанием стоп-лосса и получением прибыли.
  3. Параметрtrail_pointsКак и...trail_priceпараметр, за исключением того, что он принимает точки прибыли в качестве указанной позиции.

Нелегко ли это понять? Это не имеет значения! Давайте пройдём через сценарий обратного тестирования стратегии, чтобы понять, что на самом деле довольно просто.

/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/

strategy("test", overlay = true)

varip a = na
varip highPrice = na
varip isTrade = false 
varip offset = 30

if not barstate.ishistory and not isTrade
    strategy.entry("test 1", strategy.long, 1)
    strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
    a := close + offset
    runtime.log("the price per point is:", syminfo.mintick, ", current close:", close)
    isTrade := true 

if close > a and not barstate.ishistory
    highPrice := na(highPrice) ? close : highPrice
    highPrice := close > highPrice ? close : highPrice

plot(a, "trail_price trigger line")    
plot(strategy.position_size>0 ? highPrice : na, "current highest price")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "moving stop trigger line")

img

img

img

Немедленный длинный вход, когда стратегия начинает выполнять, а затем немедленно разместилstrategy.exitпорядок выхода (он указывал параметры отслеживания стоп-лосса и прибыли), когда цена изменения рынка поднялась выше линии триггера trail_price, реализация логики отслеживания стоп-лосса и прибыли, линия стоп-лосса и прибыли (синяя) начала следовать за наивысшей динамической корректировкой цены, позиция синей линии является триггером стоп-лосса и прибыли для закрытия позиции, и, наконец, когда рыночная цена падает ниже синей линии, которая запускает закрытие позиции. В сочетании с линией, нарисованной на графике, это очень легко понять.

Затем мы используем эту функцию, чтобы оптимизировать стратегию супер трендов, мы просто назначаемstrategy.exitордер на выход из плана в ордер на вход в стратегию для добавления этой функции остановки потерь и получения прибыли.

if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
    trail_price := strategy.position_size > 0 ? close + offset : close - offset
    strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
    runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ",trail_price:", trail_price)
    state := 2 
    tradeBarIndex := bar_index

Полный код стратегии:

/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/

varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0  

findOrderIdx(idx) =>
    ret = -1 
    if strategy.opentrades == 0 
        ret
    else 
        for i = 0 to strategy.opentrades - 1 
            if strategy.opentrades.entry_id(i) == idx
                ret := i 
                break
        ret

if strategy.position_size == 0 
    trail_price := na 
    state := 0

[superTrendPrice, dir] = ta.supertrend(input(2, "atr coefficient"), input(20, "atr period"))

if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
    strategy.entry("open", strategy.long, 1)
    state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
    strategy.entry("open", strategy.short, 1)
    state := 1


// Reverse signal, close all positions
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
    strategy.cancel_all()
    strategy.close_all()
    runtime.log("trend reversal, long positions all closed")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
    strategy.cancel_all()
    strategy.close_all()
    runtime.log("trend reversal, short positions all closed")


if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
    trail_price := strategy.position_size > 0 ? close + offset : close - offset
    strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
    runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ", trail_price:", trail_price)
    state := 2 
    tradeBarIndex := bar_index


plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)

Больше