
Основная идея этой стратегии заключается в том, чтобы автоматически рассчитывать верхнюю и нижнюю границы сетки на основе последних высоких и низких цен или простой движущейся средней, а затем разделить эту область на несколько линий сетки. Когда цена касается определенной линии сетки, открывается позиция на этом месте. Таким образом, стратегия может постоянно открывать и ликвидировать позиции в условиях потрясений и получать прибыль от разницы в цене.
Вычислить верхнюю и нижнюю границы сетки. В зависимости от выбора пользователя, верхняя и нижняя границы могут быть основаны на наивысших и самых низких точках ближайшей N-корневой K-линии и могут быть настроены на увеличение или уменьшение процентов; также можно настроить простую подвижную среднюю на основе ближайшей N-корневой K-линии и установить отклонение вверх-вниз.
Вырабатывает матричный массив. В зависимости от количества установленных матричных линий, распределяя матричный диапазон, получается матричный массив, соответствующий цене.
Вход/прибавка к позиции. Пересечение линии сетки вверх и вниз. Если текущая цена закрытия меньше цены линии сетки, а линия сетки еще не имеет позиции, то открывается дополнительная позиция в этой позиции. Таким образом, прибавка к позиции будет продолжаться, когда цена коснется линии сетки выше.
Выход/уменьшение позиций. Прохождение по линии сетки вверх-вниз. Если цена закрытия превышает цену линии сетки, а у линии сетки ниже имеется позиция, выровняется множество линий линии сетки ниже. Таким образом, снижение позиций будет продолжаться, когда цена вернется.
Динамическая коррекция. Если вы выберете функцию динамической сетки, то каждая K-линия будет пересчитывать верхнюю и нижнюю границы сетки и массив сетки, что позволит сетке постоянно адаптироваться к изменениям.
Сильная адаптивность. Торговая стратегия сетки способна адаптироваться к шокирующим и трендовым ситуациям. В шокирующих ситуациях стратегия сетки может постоянно открывать позиции, чтобы заработать разницу в цене; в трендовых ситуациях, благодаря тому, что сетка следует за ценовым движением, она также может поддерживать определенные позиции, получая трендовую прибыль.
Контролируемый риск. Размер позиции при каждом открытии позиции определяется количеством установленных сеток. Одноразовый рисковый пробел небольшой и контролируемый.
Высокая степень автоматизации. Стратегия может работать практически полностью автоматически, без какого-либо вмешательства человека, и подходит для инвесторов, которым необходима стабильная и долгосрочная прибыль.
Гибкость параметров. Пользователь может гибко настраивать количество решеток в зависимости от рыночных характеристик, динамических параметров решеток и т. Д., Чтобы оптимизировать эффективность стратегии.
Риск чёрного белка. В случае экстремального падения, когда цена поднимается прямо до нижней сетчатки, эта стратегия может быть полностью заполнена и столкнуться с большим отходом.
Параметры сетки неправильно настроены. Если сетка слишком плотная, разница в цене при открытии позиции будет небольшой, а комиссионные могут поглотить большую часть прибыли. Если сетка слишком широка, процент разовых открытий будет выше, а рыночная выгода будет больше.
Основной риск. Эта стратегия основана на условиях открытия позиции на текущей цене. На рынках, таких как фьючерсы, фактическая цена открытия позиции может отклоняться от ожиданий, если контрактная цена отличается от цены, указанной в стандарте.
Включение фильтра на тренд. Стратегия сетки плохо работает в одностороннем тренде. Можно включить индикатор тренда в качестве фильтра, например, включить сетку только тогда, когда ADX ниже определенного порога, а закрыть сетку, когда тренд очевиден, и иметь только односторонние позиции.
Сигнальная оптимизация. Можно настраивать другие сигналы на основе сетки, такие как сетка + средняя линия, то есть основное решение о открытии позиции принимается сеткой, но при пересечении цены через определенную среднюю линию она открывается, в противном случае она не открывается. Таким образом, можно снизить затраты на частое открытие позиции.
Управление позициями. Каждая позиция в настоящей стратегии является фиксированной, и ее можно установить, чтобы снизить позиции в каждой позиции, когда цена находится дальше от средней рыночной цены, и увеличить позиции, когда она приближается к средней рыночной цене, чтобы повысить эффективность использования капитала.
Приспосабливаясь к динамике ценовых колебаний, можно увеличивать количество сетей, а при низкой колебательности уменьшать их. Таким образом, можно оптимизировать ширину сетки и повысить эффективность использования средств.
Эта стратегия является более адаптивной среднесрочной линейной количественной стратегией для получения трендовых доходов путем адаптации к динамической сетке, часто открывающей позиции для получения ценовых разрывов в условиях шок, а также поддерживающей определенную направленность отверстия в условиях тренда. Благодаря разумной установке логики и управления позицией, которая вызывает сетку, можно получить стабильную прибыль.
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jcloyd
//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool) // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"]) // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1) // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float) // for manual grid bounds only. The upperbound price of your grid
i_lowerBound = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float) // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty = input(group="Grid Lines", title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer) // how many grid lines are in your grid
f_getGridBounds(_bs, _bl, _bd, _up) =>
if _bs == "Hi & Low"
_up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl) * (1 - _bd)
else
avg = sma(close, _bl)
_up ? avg * (1 + _bd) : avg * (1 - _bd)
f_buildGrid(_lb, _gw, _gq) =>
gridArr = array.new_float(0)
for i=0 to _gq-1
array.push(gridArr, _lb+(_gw*i))
gridArr
f_getNearGridLines(_gridArr, _price) =>
arr = array.new_int(3)
for i = 0 to array.size(_gridArr)-1
if array.get(_gridArr, i) > _price
array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
array.set(arr, 1, i == 0 ? i : i-1)
break
arr
var upperBound = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound // upperbound of our grid
var lowerBound = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth = (upperBound - lowerBound)/(i_gridQty-1) // space between lines in our grid
var gridLineArr = f_buildGrid(lowerBound, gridWidth, i_gridQty) // an array of prices that correspond to our grid lines
var orderArr = array.new_bool(i_gridQty, false) // a boolean array that indicates if there is an open order corresponding to each grid line
var closeLineArr = f_getNearGridLines(gridLineArr, close) // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0) // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1) // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
strategy.initial_capital = 50000
for i = 0 to (array.size(gridLineArr) - 1)
if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
buyId = i
array.set(orderArr, buyId, true)
strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
if close > array.get(gridLineArr, i) and i != 0
if array.get(orderArr, i-1)
sellId = i-1
array.set(orderArr, sellId, false)
strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))
if i_autoBounds
upperBound := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
lowerBound := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
gridWidth := (upperBound - lowerBound)/(i_gridQty-1)
gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)
closeLineArr := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)