Fixing a Rolling Minimum in a Donchian Channel Function
Summary
The document presents a Python function intended to calculate Donchian channel bounds from high and low price arrays over a rolling window. It identifies a specific bug in the lower-bound loop: the function appends the entire low-price input array to the output on every iteration, instead of appending the minimum value calculated for that window. This produces a nested list rather than a series of rolling minima.
The proposed correction is to append the computed minimum, paralleling the upper-bound loop’s use of its computed maximum. The example shows why the output shape matters when plotting the channel. The discussion is limited to this implementation error; it does not assess other edge cases, such as initializing extrema with values that may not suit all price ranges or how to handle incomplete windows at the beginning of the series.
Key ideas
- A Donchian channel uses rolling highs and lows over a specified window.
- The lower-bound loop must append its computed minimum, not the full input array.
- Appending the input array on each iteration creates a nested output with repeated copies.
- The example fixes the return value but does not address initialization or partial-window conventions.
Tags
Full text
# need help with Donchian-channels function!
# need help with Donchian-channels function!
I want to be able to plot Donchian-channels. It's probably easier to use numpy but, am not that fluent with numpy yet so i thought i could make a function that takes two arrays as input(Highs and lows), make a little size-limited-dynamical-array over x days and then within that array find out the max and min value. And at the end output two arrays to plot the data with.
The code that i came up with is
zl=[2,3,4,5,5,4,3,2,3,4,3,4,5,6,7,8,7,6,5,4,5,6]
zh=[3,4,5,6,6,5,4,3,4,5,4,5,6,7,8,9,8,7,6,5,6,7]
def donchianChannels(highValue, lowValue, window):
```
highOutput = []
lowOutput = []
lsth = [None]*window
lstl = [None]*window
for i in range(0, len(highValue)):
maxValue=0
lsth.append(highValue[i])
lsth = lsth[-window:]
for j in range(0, len(lsth)):
if lsth[j] > maxValue:
maxValue = lsth[j]
highOutput.append(maxValue)
for i in range(0, len(lowValue)):
minValue=100000
lstl.append(lowValue[i])
lstl = lstl[-window:]
for j in range(0, len(lstl)):
if lstl[j] < minValue:
minValue = lstl[j]
lowOutput.append(lowValue)
return highOutput, lowOutput
```
maxvalue, minvalue = donchianChannels(zh, zl, 3) print maxvalue, minvalue
and the output i get is
[3, 4, 5, 6, 6, 6, 6, 5, 4, 5, 5, 5, 6, 7, 8, 9, 9, 9, 8, 7, 6, 7] [[2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6], [2, 3, 4, 5, 5, 4, 3, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 5, 6]]
the algorithm for the maximum array works fine, but the minimum one does not work at all. First of all it makes 22 arrays(the lenght of the input array) within one array. Second none of the minimum arrays plots the minimum values. They should be
```
[2,2,2,3,4,4,3,2,2,2,3,3,3,4,5,6,7,6,5,4,4,4,5]
```
Due to my calculations i can not see the problem it would be great if i could get some help please :)
## Answer by meh (score 1)
https://quant.stackexchange.com/a/19413
```
highOutput = []
lowOutput = []
lsth = [None]*window
lstl = [None]*window
for i in range(0, len(highValue)):
maxValue=0
lsth.append(highValue[i])
lsth = lsth[-window:]
for j in range(0, len(lsth)):
if lsth[j] > maxValue:
maxValue = lsth[j]
highOutput.append(maxValue)
for i in range(0, len(lowValue)):
minValue=100000
lstl.append(lowValue[i])
lstl = lstl[-window:]
for j in range(0, len(lstl)):
if lstl[j] < minValue:
minValue = lstl[j]
lowOutput.append(minValue) #Change this
return highOutput, lowOutput
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.