.3, предел=3)
Если нет, закройте и откройте
Стратегия.Отменить.
Стратегия.отменить ((
---------------------------
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
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
функция индикатора для расчета индикатора супертенденции.
По умолчанию функция устанавливает два элемента управления параметрами на экране стратегии языка Pine, как показано ниже:
Как мы можем видеть, значение по умолчанию на контроле является первым параметром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
, и, конечно, рассчитанные данные показателя также точно такие же.
Как мы можем видеть из этого алгоритма пользовательской функции, Pinehl2
Встроенная переменная (самые высокие и самые низкие цены суммируются вместе, а затем делятся на 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)
Давайте продолжим с некоторыми примерами дизайна стратегии на языке Пайна, на этот раз мы узнаем динамическую стратегию балансирования.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
Функция:
trail_price
: Позиция, которая запускает логическое действие по размещению ордера с отслеживанием стоп-лосса и ордера с закрытием стоп-лосса (на позиции, указанной ценой).trail_offset
: Расстояние от самой высокой (при длинном ходе) или самой низкой (при коротком ходе) цены закрытой позиции, размещенной после выполнения операции с отслеживанием стоп-лосса и получением прибыли.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")
Немедленный длинный вход, когда стратегия начинает выполнять, а затем немедленно разместил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)