Эта стратегия представляет собой количественную торговую стратегию, основанную на индикаторе P-сигнала, рассчитанном с помощью функции ошибки Гаусса для измерения изменений цен.
Основным показателем этой стратегии является P-сигнал.
fPSignal(ser, int) =>
nStDev = stdev(ser, int)
nSma = sma(ser, int)
fErf(nStDev > 0 ? nSma/nStDev/sqrt(2) : 1.0)
Здесь ser представляет серию цен, int представляет параметр nPoints, который является количеством строк, которые нужно посмотреть назад.
В целом формула состоит в том, чтобы взять скользящую среднюю цену, разделенную на стандартное отклонение цены, затем разделить на кврт (((2) для стандартизации, и, наконец, отобразить ее в диапазоне (-1, 1) функцией ошибки Гаусса. То есть, если колебание цены больше среднего, P-сигнал близок к 1; если колебание цены меньше среднего, P-сигнал близок к -1.
Стратегия использует значение P-сигнала и знак его изменения для определения входов и выходов:
strategy.entry("long", strategy.long, 1, when = nPSignal < 0 and ndPSignal > 0)
strategy.close("long", when = nPSignal > 0 and ndPSignal < 0)
Он длится, когда P-сигнал меньше 0 и меняется на положительный. Он закрывает позицию, когда P-сигнал больше 0 и меняется на отрицательный.
Преимущества этой стратегии включают:
Эта стратегия также сопряжена с некоторыми рисками:
Для уменьшения этих рисков могут быть приняты некоторые меры: добавление фильтров для уменьшения частоты торговли; оптимизация комбинации параметров и установка затрат на транзакции; живые испытания и выбор подходящих продуктов.
Есть возможности для дальнейшего совершенствования:
В заключение, основная идея этой стратегии заключается в инновационном, подходящем распределении цен с гауссианской функцией и автоматической корректировке параметров. Но как высокочастотная стратегия торговли, она требует дальнейшего тестирования и оптимизации контроля рисков и настройки параметров до стабильной прибыльности в живой торговле, особенно как высокочастотная стратегия торговли.
/*backtest start: 2023-01-12 00:00:00 end: 2024-01-18 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // ********************************************************************************************************** // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // P-Signal Strategy © Kharevsky // @version=4 // ********************************************************************************************************** strategy("P-Signal Strategy", precision = 3) // Parameters and const of P-Signal. nPoints = input(title = "Number of Bars", type = input.integer, defval = 9, minval = 4, maxval = 100, group = "Parameters of observation.") int nIntr = nPoints - 1 // Horner's method for the error (Gauss) & P-Signal functions. fErf(x) => nT = 1.0/(1.0 + 0.5*abs(x)) nAns = 1.0 - nT*exp(-x*x - 1.26551223 + nT*( 1.00002368 + nT*( 0.37409196 + nT*( 0.09678418 + nT*(-0.18628806 + nT*( 0.27886807 + nT*(-1.13520398 + nT*( 1.48851587 + nT*(-0.82215223 + nT*( 0.17087277 )))))))))) x >= 0 ? nAns : -nAns fPSignal(ser, int) => nStDev = stdev(ser, int) nSma = sma(ser, int) fErf(nStDev > 0 ? nSma/nStDev/sqrt(2) : 1.0) // Strat. float nPSignal = sma(fPSignal(change(ohlc4), nIntr), nIntr) float ndPSignal = sign(nPSignal[0] - nPSignal[1]) strategy.entry("long", strategy.long, 1, when = nPSignal < 0 and ndPSignal > 0) strategy.close("long", when = nPSignal > 0 and ndPSignal < 0) // Plotting. hline(+1.0, color = color.new(color.orange,70), linestyle = hline.style_dotted) hline(-1.0, color = color.new(color.orange,70), linestyle = hline.style_dotted) plot(nPSignal, color = color.blue, style = plot.style_line) plot(strategy.position_size, color = color.white, style = plot.style_cross) // Alerts. if(strategy.position_size[0] > strategy.position_size[1]) alert("P-Signal strategy opened the long position: " + syminfo.tickerid + " " + timeframe.period, alert.freq_once_per_bar) if(strategy.position_size[0] < strategy.position_size[1]) alert("P-Signal strategy closed the long position: " + syminfo.tickerid + " " + timeframe.period, alert.freq_once_per_bar) // The end.