Skip to content

WilliamsAccumulationDistribution

interface cAlgo.API.Indicators

DesktopCLICloud

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

Definition

public interface WilliamsAccumulationDistribution

Namespace: cAlgo.API.Indicators · Group: Indicators · Implements: StandardIndicator

Remarks

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

Examples

Example 1

private WilliamsAccumulationDistribution _williamsAccumulationDistribution;
protected override void Initialize()
{
    _williamsAccumulationDistribution = Indicators.WilliamsAccumulationDistribution();
}
public override void Calculate(int index)
{
    double result = _williamsAccumulationDistribution.Result[index];
}
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]

Example 2

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
    public partial class WilliamsAccumulationDistributionSample : Robot
    {
        private double _volumeInUnits;

        private WilliamsAccumulationDistribution _williamsAccumulationDistribution;

        private SimpleMovingAverage _simpleMovingAverage;

        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));
        }
    }
}
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.Bars.ClosePrices, 14)

    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.Buy)
            api.ExecuteMarketOrder(TradeType.Sell, 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.Sell)
            api.ExecuteMarketOrder(TradeType.Buy, 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 - 1 - v] for v in reversed(range(periods))]
        y = [api.Bars.ClosePrices[api.Bars.ClosePrices.Count - 1 - v] for v in reversed(range(periods))]

        if len(x) == 0 or len(y) == 0:
            return float("nan")

        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))
{
  "AccessRights": "None",
  "TimeZone": "UTC",
  "Parameters": [
    {
      "Name": "VolumeInLots",
      "DisplayName": "Volume (Lots)",
      "Type": "Double",
      "DefaultValue": 0.01,
      "Group": "Trade"
    },
    {
      "Name": "StopLossInPips",
      "DisplayName": "Stop Loss (Pips)",
      "Type": "Double",
      "DefaultValue": 10,
      "Group": "Trade"
    },
    {
      "Name": "TakeProfitInPips",
      "DisplayName": "Take Profit (Pips)",
      "Type": "Double",
      "DefaultValue": 10,
      "Group": "Trade"
    },
    {
      "Name": "Label",
      "Type": "String",
      "DefaultValue": "Sample",
      "Group": "Trade"
    }
  ]
}

Properties

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

Inherited members

From StandardIndicator: AddToChart, Symbol, TimeFrame, Bars