![[Pasted image 20230530204459.png]]
The slopes from any given point in a cycle to the same point in the next cycle are exactly the same. It doesn't matter whether the point you select is the peak, the valley, or anyplace in between; the slope between the same points in idealized cycles is zero.
If there is a different in amplitude between successive samples, either cycle period has changed or the market is in a trend.
This strategy measures the dominant cycle period and then uses that measured period to take a one cycle momentum (slope). Since momentum functions are noisy, it is smoothed with a 3-pole smoothing filter.
This is then used in a strategy where the trading rules are simply to buy when the filter crosses above zero, and sell when it crosses below zero.
```js
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © hunkOfTuna
//@version=5
strategy("Smooth Adaptive Momentum Strategy", initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 1, commission_type = strategy.commission.percent, commission_value = 0.25, pyramiding = 0)
date_from = input.time(defval = timestamp("01 Jan 2022 00:00 +0000"), title = "From")
date_thru = input.time(defval = timestamp("01 Jan 2024 00:00 +0000"), title = "To")
date_show = input (defval = true, title = "Show Date Range")
date() => time >= date_from and time <= date_thru
Price = (high+low)/2
alpha = 0.07
Cutoff = 8
Cycle = 0.0
Smooth = (Price + 2 * nz(Price[1]) + 2 * nz(Price[2]) + nz(Price[3]))/6
Cycle := (1 - 0.5 * alpha) * (1 - 0.5 * alpha) * (Smooth - 2 * nz(Smooth[1]) + nz(Smooth[2])) + 2 * (1 - alpha) * nz(Cycle[1]) - (1 - alpha) * (1 - alpha) * nz(Cycle[2])
if bar_index < 7
Cycle := (Price - 2 * nz(Price[1]) + nz(Price[2])) / 4
InstPeriod = 0.0
Q1 = (0.0962 * Cycle + 0.5769 * nz(Cycle[2]) - 0.5769 * nz(Cycle[4]) - 0.0962 * nz(Cycle[6])) * (0.5 + 0.8 * nz(InstPeriod[1]))
I1 = nz(Cycle[3])
DeltaPhase = 0.0
if Q1 != 0 and nz(Q1[1]) != 0
DeltaPhase := (I1/Q1 - nz(I1[1])/nz(Q1[1])) / (1 + I1*nz(I1[1])/(Q1*nz(Q1[1])))
if DeltaPhase < 0.1
DeltaPhase := 0.1
if DeltaPhase > 1.1
DeltaPhase := 1.1
MedianDelta = ta.median(DeltaPhase, 5)
DC = 0.0
if MedianDelta == 0
DC := 15
else
DC := 6.28318 / MedianDelta + 0.5
Period = 0.0
InstPeriod := 0.33 * DC + 0.67 * nz(InstPeriod[1])
Period := 0.15 * InstPeriod + 0.85 * nz(Period[1])
Value1 = Price - nz(Price[int(Period - 1)])
a1 = math.exp(-3.14159 / Cutoff)
b1 = 2 * a1 * math.cos(1.738 * 180 / Cutoff)
c1 = a1 * a1
coef2 = b1 + c1
coef3 = -(c1 + b1 * c1)
coef4 = c1 * c1
coef1 = 1 - coef2 - coef3 - coef4
Filt3 = 0.0
Filt3 := coef1 * Value1 + coef2*nz(Filt3[1]) + coef3*nz(Filt3[2]) + coef4*nz(Filt3[3])
if bar_index < 4
Filt3 := Value1
long_condition = ta.crossover(Filt3, 0)
short_condition = ta.crossunder(Filt3, 0)
plot(Filt3, "filter", color.blue)
hline(0, "zero", color.gray)
plot(long_condition ? Filt3 : na, 'Buy Signal', color.green, 2, plot.style_circles)
plot(short_condition ? Filt3 : na, 'Sell Signal', color.red, 2, plot.style_circles)
if long_condition
strategy.entry("long", strategy.long)
if short_condition
strategy.entry("short", strategy.short)
```
TODO: add money management stop