"Sounds like a MACD with the Median Price as input. Or did I miss something?" Yes it's basically the same thing using 5 & 34 periods. Line changes from green to red on fall & vice versa. Maybe some chart packages do this on MACD too ? chart showing MACD & AO...
Here's the C code for his averages etc for Sierra Chart. Note the slight variations on standard displaced mas, macds etc (creating a certain proprietary nature) Code: /***********************************************************************/ extern "C" __declspec( dllexport ) void BWMA(struct s_sg &sg) { sg.GraphName="BWMA"; sg.Subgraph[0].Name="MA"; sg.Input[2].Name="3 MA Length"; sg.Input[3].Name="Offset"; sg.FreeDLL=0; if(sg.SetDefaults) {return;} if(sg.ArraySize<100) return; int i,pos,term=30; if(sg.Input[2].FloatValue==0) sg.Input[2].FloatValue=34; double sum1=0; double avg1=0; sg.DataStartIndex=50; for (pos=50; pos < sg.ArraySize; pos++) { sum1 = sum1 + sg.BaseDataIn[3][pos]; if(pos>=50+(int)sg.Input[2].FloatValue) {sum1 = sum1 - avg1;}; avg1 = sum1 / sg.Input[2].FloatValue; int pos2=pos+(int)sg.Input[3].FloatValue; if((pos2<sg.ArraySize) && (pos2>30)) sg.Subgraph[0].Data[pos2] = avg1; } }; /***********************************************************************/ extern "C" __declspec( dllexport ) void AC(struct s_sg &sg) { sg.GraphName="AC"; sg.Subgraph[0].Name="Up"; sg.Subgraph[1].Name="Dn"; sg.Subgraph[2].Name="Flat"; sg.Subgraph[3].Name="Do Not Draw"; sg.Input[2].Name="3 Long MA Length"; sg.Input[3].Name="4 Short MA Length"; sg.Input[4].Name="5 Signal MA Length"; sg.Input[5].Name="6 BWSmoothed (0), Exponential (1) or Simple (2) Moving Averages"; sg.FreeDLL=0; if(sg.SetDefaults) {return;} if(sg.ArraySize<100) return; int j,pos,term=30; if(sg.Input[2].FloatValue==0) sg.Input[2].FloatValue=34; if(sg.Input[3].FloatValue==0) sg.Input[3].FloatValue=5; if(sg.Input[4].FloatValue==0) sg.Input[4].FloatValue=5; double sum1=0; double sum2=0; double sum3=0; double sum4=0; double avg1=0; double avg2=0; double avg3=0; double avg4=0; double cfactor1=2/(sg.Input[2].FloatValue+1); double cinvfactor1=1-cfactor1; double cfactor2=2/(sg.Input[3].FloatValue+1); double cinvfactor2=1-cfactor2; double cfactor4=2/(sg.Input[4].FloatValue+1); double cinvfactor4=1-cfactor4; sg.DataStartIndex=50; for (pos=50; pos < sg.ArraySize; pos++) { if(sg.Input[5].FloatValue==0) { sum1 = sum1 + sg.BaseDataIn[3][pos]; if(pos>=50+sg.Input[2].FloatValue) {sum1 = sum1 - avg1;}; avg1 = sum1 / sg.Input[2].FloatValue; sum2 = sum2 + sg.BaseDataIn[3][pos]; if(pos>=50+sg.Input[3].FloatValue) {sum2 = sum2 - avg2;}; avg2 = sum2 / sg.Input[3].FloatValue; avg3 = avg2 - avg1; sg.Subgraph[5].Data[pos] = avg3; sum4 = sum4 + avg3; avg4 = sum4 / sg.Input[4].FloatValue; j=pos-(int)sg.Input[4].FloatValue+1; if(pos>50+sg.Input[4].FloatValue-2) {sum4 = sum4 - sg.Subgraph[5].Data[j];}; } else if(sg.Input[5].FloatValue==1) { avg1 = avg1*cinvfactor1+sg.BaseDataIn[3][pos]*cfactor1; avg2 = avg2*cinvfactor2+sg.BaseDataIn[3][pos]*cfactor2; avg3 = avg2 - avg1; sg.Subgraph[5].Data[pos] = avg3; avg4 = avg4*cinvfactor4+avg3*cfactor4; } else { sum1 = sum1 + sg.BaseDataIn[3][pos]; avg1 = sum1 / sg.Input[2].FloatValue; j=pos-(int)sg.Input[2].FloatValue+1; if(pos>50+sg.Input[2].FloatValue-2) {sum1 = sum1 - sg.BaseDataIn[3][j];}; sum2 = sum2 + sg.BaseDataIn[3][pos]; avg2 = sum2 / sg.Input[3].FloatValue; j=pos-(int)sg.Input[3].FloatValue+1; if(pos>50+sg.Input[3].FloatValue-2) {sum2 = sum2 - sg.BaseDataIn[3][j];}; avg3 = avg2 - avg1; sg.Subgraph[5].Data[pos] = avg3; sum4 = sum4 + avg3; avg4 = sum4 / sg.Input[4].FloatValue; j=pos-(int)sg.Input[4].FloatValue+1; if(pos>50+sg.Input[4].FloatValue-2) {sum4 = sum4 - sg.Subgraph[5].Data[j];}; } sg.Subgraph[3].Data[pos] = avg3-avg4; if(sg.Subgraph[3].Data[pos]>sg.Subgraph[3].Data[pos-1]) {sg.Subgraph[0].Data[pos] = sg.Subgraph[3].Data[pos]; sg.Subgraph[1].Data[pos] = 0; sg.Subgraph[2].Data[pos] = 0;} else if(sg.Subgraph[3].Data[pos] < sg.Subgraph[3].Data[pos-1]) {sg.Subgraph[0].Data[pos] = 0; sg.Subgraph[1].Data[pos] = sg.Subgraph[3].Data[pos]; sg.Subgraph[2].Data[pos] = 0;} else {sg.Subgraph[0].Data[pos] = 0; sg.Subgraph[1].Data[pos] = 0; sg.Subgraph[2].Data[pos] = sg.Subgraph[3].Data[pos];};; } }; /***********************************************************************/ extern "C" __declspec( dllexport ) void AO(struct s_sg &sg) { sg.GraphName="AO"; sg.Subgraph[0].Name="Up"; sg.Subgraph[1].Name="Dn"; sg.Subgraph[2].Name="Flat"; sg.Subgraph[3].Name="All"; sg.Input[2].Name="3 Long MA Length"; sg.Input[3].Name="4 Short MA Length"; sg.Input[4].Name="5 Signal MA Length"; sg.Input[5].Name="6 BWSmoothed (0), Exponential (1) or Simple (2) Moving Averages"; sg.FreeDLL=0; if(sg.SetDefaults) {return;} if(sg.ArraySize<100) return; // if(sg.DateIn[sg.ArraySize-1]>38350) return; int j,pos,term=30; if(sg.Input[2].FloatValue==0) sg.Input[2].FloatValue=34; if(sg.Input[3].FloatValue==0) sg.Input[3].FloatValue=5; if(sg.Input[4].FloatValue==0) sg.Input[4].FloatValue=5; double sum1=0; double sum2=0; double sum3=0; double sum4=0; double avg1=0; double avg2=0; double avg3=0; double avg4=0; double cfactor1=2/(sg.Input[2].FloatValue+1); double cinvfactor1=1-cfactor1; double cfactor2=2/(sg.Input[3].FloatValue+1); double cinvfactor2=1-cfactor2; double cfactor4=2/(sg.Input[4].FloatValue+1); double cinvfactor4=1-cfactor4; sg.DataStartIndex=50; for (pos=50; pos < sg.ArraySize; pos++) { if(sg.Input[5].FloatValue==0) { sum1 = sum1 + sg.BaseDataIn[3][pos]; if(pos>=50+sg.Input[2].FloatValue) {sum1 = sum1 - avg1;}; avg1 = sum1 / sg.Input[2].FloatValue; sum2 = sum2 + sg.BaseDataIn[3][pos]; if(pos>=50+sg.Input[3].FloatValue) {sum2 = sum2 - avg2;}; avg2 = sum2 / sg.Input[3].FloatValue; avg3 = avg2 - avg1; sg.Subgraph[5].Data[pos] = avg3; sum4 = sum4 + avg3; avg4 = sum4 / sg.Input[4].FloatValue; j=pos-(int)sg.Input[4].FloatValue+1; if(pos>50+sg.Input[4].FloatValue-2) {sum4 = sum4 - sg.Subgraph[5].Data[j];}; } else if(sg.Input[5].FloatValue==1) { avg1 = avg1*cinvfactor1+sg.BaseDataIn[3][pos]*cfactor1; avg2 = avg2*cinvfactor2+sg.BaseDataIn[3][pos]*cfactor2; avg3 = avg2 - avg1; sg.Subgraph[5].Data[pos] = avg3; avg4 = avg4*cinvfactor4+avg3*cfactor4; } else { sum1 = sum1 + sg.BaseDataIn[3][pos]; avg1 = sum1 / sg.Input[2].FloatValue; j=pos-(int)sg.Input[2].FloatValue+1; if(pos>50+sg.Input[2].FloatValue-2) {sum1 = sum1 - sg.BaseDataIn[3][j];}; sum2 = sum2 + sg.BaseDataIn[3][pos]; avg2 = sum2 / sg.Input[3].FloatValue; j=pos-(int)sg.Input[3].FloatValue+1; if(pos>50+sg.Input[3].FloatValue-2) {sum2 = sum2 - sg.BaseDataIn[3][j];}; avg3 = avg2 - avg1; sg.Subgraph[5].Data[pos] = avg3; sum4 = sum4 + avg3; avg4 = sum4 / sg.Input[4].FloatValue; j=pos-(int)sg.Input[4].FloatValue+1; if(pos>50+sg.Input[4].FloatValue-2) {sum4 = sum4 - sg.Subgraph[5].Data[j];}; } sg.Subgraph[4].Data[pos] = avg3-avg4; sg.Subgraph[3].Data[pos] = sg.Subgraph[5].Data[pos]; if(sg.Subgraph[5].Data[pos]>sg.Subgraph[5].Data[pos-1]) {sg.Subgraph[0].Data[pos] = sg.Subgraph[5].Data[pos]; sg.Subgraph[1].Data[pos] = 0; sg.Subgraph[2].Data[pos] = 0;} else if(sg.Subgraph[5].Data[pos] < sg.Subgraph[5].Data[pos-1]) {sg.Subgraph[0].Data[pos] = 0; sg.Subgraph[1].Data[pos] = sg.Subgraph[5].Data[pos]; sg.Subgraph[2].Data[pos] = 0;} else {sg.Subgraph[0].Data[pos]=0; sg.Subgraph[1].Data[pos] = 0; sg.Subgraph[2].Data[pos] = sg.Subgraph[5].Data[pos];};; } };
So I guess Williams next book will include his new Fantastic indicator which is nothing more than a slightly reshaped Stochastic Indicator with Median Price. As kiwi-trader already said: Just another marketing crap!