Skip to content

WilliamsAccumulationDistribution

Summary

William's Accumulation Distribution is an oscillator that can identify if the market is driven by buyers (accumulation) or by sellers (distribution)

Remarks

The divergence between price and the William's Accumulation Distribution. When price is falling and WAD is rising, it is a buying opportunity

Signature

1
public abstract interface WilliamsAccumulationDistribution

Namespace

cAlgo.API.Indicators

Examples

1
2
3
4
5
6
7
8
9
 private WilliamsAccumulationDistribution _williamsAccumulationDistribution;
 protected override void Initialize()
 {
     _williamsAccumulationDistribution = Indicators.WilliamsAccumulationDistribution();
 }
 public override void Calculate(int index)
 {
     double result = _williamsAccumulationDistribution.Result[index];
 }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 using cAlgo.API;
 using cAlgo.API.Indicators;
 using System;
 using System.Linq;
 namespace cAlgo.Robots
 {
     // This sample cBot shows how to use the Williams Accumulation Distribution indicator
     [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
     public class WilliamsAccumulationDistributionSample : Robot
     {
         private double _volumeInUnits;
         private WilliamsAccumulationDistribution _williamsAccumulationDistribution;
         private SimpleMovingAverage _simpleMovingAverage;
         [Parameter("Volume (Lots)", DefaultValue = 0.01, Group = "Trade")]
         public double VolumeInLots { get; set; }
         [Parameter("Stop Loss (Pips)", DefaultValue = 10, Group = "Trade")]
         public double StopLossInPips { get; set; }
         [Parameter("Take Profit (Pips)", DefaultValue = 10, Group = "Trade")]
         public double TakeProfitInPips { get; set; }
         [Parameter("Label", DefaultValue = "Sample", Group = "Trade")]
         public string Label { get; set; }
         public Position[] BotPositions
         {
             get
             {
                 return Positions.FindAll(Label);
             }
         }
         protected override void OnStart()
         {
             _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
             _williamsAccumulationDistribution = Indicators.WilliamsAccumulationDistribution();
             _simpleMovingAverage = Indicators.SimpleMovingAverage(Bars.ClosePrices, 14);
         }
         protected override void OnBar()
         {
             var correlation = GetCorrelation(14);
             if (correlation > 0.85) return;
             if (Bars.ClosePrices.Last(1) > _simpleMovingAverage.Result.Last(1))
             {
                 ClosePositions(TradeType.Buy);
                 ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
             }
             else if (Bars.ClosePrices.Last(1) < _simpleMovingAverage.Result.Last(1))
             {
                 ClosePositions(TradeType.Sell);
                 ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
             }
         }
         private void ClosePositions(TradeType tradeType)
         {
             foreach (var position in BotPositions)
             {
                 if (position.TradeType != tradeType) continue;
                 ClosePosition(position);
             }
         }
         private double GetCorrelation(int period)
         {
             var x = _williamsAccumulationDistribution.Result.Skip(_williamsAccumulationDistribution.Result.Count - period).ToArray();
             var y = Bars.ClosePrices.Skip(Bars.ClosePrices.Count - period).ToArray();
             if (!x.Any() || !y.Any())
             {
                 return double.NaN;
             }
             var xSum = x.Sum();
             var ySum = y.Sum();
             var xSumSquared = Math.Pow(xSum, 2);
             var ySumSquared = Math.Pow(ySum, 2);
             var xSquaredSum = x.Select(value => Math.Pow(value, 2)).Sum();
             var ySquaredSum = y.Select(value => Math.Pow(value, 2)).Sum();
             var xAndyProductSum = x.Zip(y, (value1, value2) => value1 * value2).Sum();
             double n = x.Count();
             return (n * xAndyProductSum - xSum * ySum) / Math.Sqrt((n * xSquaredSum - xSumSquared) * (n * ySquaredSum - ySumSquared));
         }
     }
 }
1
2
3
4
5
6
7
8
 import clr
 clr.AddReference("cAlgo.API")
 from cAlgo.API import *
 class Test():    
     def initialize(self):
         self.williamsAccumulationDistribution = api.Indicators.WilliamsAccumulationDistribution()
     def calculate(self, index):
         result = self.williamsAccumulationDistribution.Result[index]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 import clr
 clr.AddReference("cAlgo.API")
 # Import cAlgo API types
 from cAlgo.API import *
 # Import trading wrapper functions
 from robot_wrapper import *
 import math
 class WilliamsAccumulationDistributionSample():
     def on_start(self):
         self.volumeInUnits = api.Symbol.QuantityToVolumeInUnits(api.VolumeInLots)
         self.williamsAccumulationDistribution = api.Indicators.WilliamsAccumulationDistribution()
         self.simpleMovingAverage = api.Indicators.SimpleMovingAverage(api.SourceMovingAverage, api.PeriodsMovingAverage)
     def on_bar_closed(self):
         correlation = self.get_correlation(14)
         if correlation > 0.85:
             return
         if api.Bars.ClosePrices.Last(0) > self.simpleMovingAverage.Result.Last(0):
             self.close_positions(TradeType.Sell)
             api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, self.volumeInUnits, api.Label, api.StopLossInPips, api.TakeProfitInPips)
         elif api.Bars.ClosePrices.Last(0) < self.simpleMovingAverage.Result.Last(0):
             self.close_positions(TradeType.Buy)
             api.ExecuteMarketOrder(TradeType.Sell, api.SymbolName, self.volumeInUnits, api.Label, api.StopLossInPips, api.TakeProfitInPips)
     def get_bot_positions(self):
         return api.Positions.FindAll(api.Label)
     def close_positions(self, tradeType):
         for position in self.get_bot_positions():
             if position.TradeType != tradeType:
                 continue
             api.ClosePosition(position)
     def get_correlation(self, periods):
         x = [self.williamsAccumulationDistribution.Result[self.williamsAccumulationDistribution.Result.Count - v] for v in reversed(range(periods))]
         y = [api.Bars.ClosePrices[api.Bars.ClosePrices.Count - v] for v in reversed(range(periods))]
         if len(x) == 0 or len(y) == 0:
             return None
         xSum = sum(x)
         ySum = sum(y)
         xSumSquared = pow(xSum, 2)
         ySumSquared = pow(ySum, 2)
         xSquaredSum = sum([pow(v, 2) for v in x])
         ySquaredSum = sum([pow(v, 2) for v in y])
         xAndyProductSum = sum([x[i] * y[i] for i in range(len(x))])
         n = len(x)
         return (n * xAndyProductSum - xSum * ySum) / math.sqrt((n * xSquaredSum - xSumSquared) * (n * ySquaredSum - ySumSquared))

Properties

Result

Summary

Gets the resulting time series of the Williams Accumulation Distribution indicator calculation.

Signature

1
public abstract IndicatorDataSeries Result {get;}

Return Value

IndicatorDataSeries

Examples

1
2
3
4
5
6
7
8
9
 private WilliamsAccumulationDistribution _result;
 protected override void Initialize()
 {
     _result = Indicators.WilliamsAccumulationDistribution();
 }
 public override void Calculate(int index)
 {
     double result = _result.Result[index];
 }
1
2
3
4
5
6
7
8
 import clr
 clr.AddReference("cAlgo.API")
 from cAlgo.API import *
 class Test():    
     def initialize(self):
         self.williamsAccumulationDistribution = api.Indicators.WilliamsAccumulationDistribution()
     def calculate(self, index):
         result = self.williamsAccumulationDistribution.Result[index]