Search Framework:
VolumeProfile
Namespace: WealthLab.Core
Parent: Object

Generates a Volume Profile, which is a distribution of horizontal lines (represented by instances of the VolumeProfileItem class) distributed along the Y-axis of the chart. Each Volume Profile line has a horizontal length determined by the total volume that ocurred within its min/max range using a specified lookback period.
Volume Profile

Constructors
VolumeProfile
public VolumeProfile(BarHistory bars, int lookback, int barCount, double valueRange = 70.0, int? idx = null)

Creates a Volume Profile for the specified BarHistory instance (bars parameter), using the specified lookback period. The barCount parameter indicates the desired number of Volume Profile horizontal lines that should be generated. Depending on the range of data, the ultimate number of Volume Profile lines might be a little more or less than this. The optional valueRange parameter defaults to 70, and indicates the percentage of volume that should be considered the "High Value Range." The Volume Profile chart drawing object plots Volume Profile bars outside of this High Value Range using a dimmer color. The optional idx parameter can be used to generate the Volume Profile at some specific index within the BarHistory. If not supplied, it generates the Volume Profile at bars.Count - 1. The resulting Volume Profile bars are available via the Items property.



Members
Bars
public BarHistory Bars

Returns the BarHistory instance that was used to generate the Volume Profile.


GenerateVolumeProfile
public void GenerateVolumeProfile(int idx)

Generates the Volume Profile as of a specific index in the source BarHistory.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//display the Point of Control level of the 10 most recent Volume Profiles with a 20 bar lookback
			VolumeProfile vp = new VolumeProfile(bars, 20, 50);
			for (int n = 0; n < 10; n++)
			{
				vp.GenerateVolumeProfile(bars.Count - 1 - n);
				DrawDot(bars.Count - 1 - n, vp.PointOfControl, WLColor.NeonBlue, 5);
			}
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

Items
public List<VolumeProfileItem> Items

Returns a List of VolumeProfileInstances that represents the Volume Profile horizontal bars.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);
			vp.ValueRangePct = 50.0;
			vp.GenerateVolumeProfile(bars.Count - 1);

			//render a volume profile manually, render bars not in the High Value Area a dimmer color
			WLColor color = WLColor.FromArgb(128, WLColor.Teal);
			WLColor dim = WLColor.FromArgb(64, WLColor.LightBlue);
			foreach (VolumeProfileItem vpi in vp.Items)
			{
				int width = (int)(100.0 * vpi.WidthPct);
				int x1 = bars.Count - 1 - width;
				WLColor c = vpi.InValueArea ? color : dim;
				DrawLine(x1, vpi.RangeMax, bars.Count - 1, vpi.RangeMax, c, 4);
			}
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

Lookback
public int Lookback

Returns the lookback period that was used to generate the Volume Profile.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);

			//draw a horizontal line at the VP's "Point of Control"
			DrawHorzLine(vp.PointOfControl, WLColor.Red, 2);

			//for comparison, create a Volume Profile with a shorter lookback and fewer desired bars and display its POC in green
			vp.Lookback = 252 / 2;
			vp.ProfileBarsDesired = 25;
			vp.GenerateVolumeProfile(bars.Count - 1);
			DrawHorzLine(vp.PointOfControl, WLColor.Green, 2);
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

LowVolNodeLower
public double LowVolNodeLower

Returns the value of the Volume Profile bar whose volume is the lowest below the Point of Control bar, but within the High Value Area. The Volume Profile bar's RangeMax value is returned.

Remarks

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);
			vp.ValueRangePct = 50.0;
			vp.GenerateVolumeProfile(bars.Count - 1);

			//render a volume profile manually, render bars not in the High Value Area a dimmer color
			WLColor color = WLColor.FromArgb(128, WLColor.Teal);
			WLColor dim = WLColor.FromArgb(64, WLColor.LightBlue);
			foreach (VolumeProfileItem vpi in vp.Items)
			{
				int width = (int)(100.0 * vpi.WidthPct);
				int x1 = bars.Count - 1 - width;
				WLColor c = vpi.InValueArea ? color : dim;
				DrawLine(x1, vpi.RangeMax, bars.Count - 1, vpi.RangeMax, c, 4);
			}

			//render lines for the two low volume nodes
			DrawHorzLine(vp.LowVolNodeLower, WLColor.Green, 2);
			DrawHorzLine(vp.LowVolNodeUpper, WLColor.Green, 2);
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

LowVolNodeUpper
public double LowVolNodeUpper

Returns the value of the Volume Profile bar whose volume is the lowest above the Point of Control bar, but within the High Value Area. The Volume Profile bar's RangeMax value is returned.

Remarks

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);
			vp.ValueRangePct = 50.0;
			vp.GenerateVolumeProfile(bars.Count - 1);

			//render a volume profile manually, render bars not in the High Value Area a dimmer color
			WLColor color = WLColor.FromArgb(128, WLColor.Teal);
			WLColor dim = WLColor.FromArgb(64, WLColor.LightBlue);
			foreach (VolumeProfileItem vpi in vp.Items)
			{
				int width = (int)(100.0 * vpi.WidthPct);
				int x1 = bars.Count - 1 - width;
				WLColor c = vpi.InValueArea ? color : dim;
				DrawLine(x1, vpi.RangeMax, bars.Count - 1, vpi.RangeMax, c, 4);
			}

			//render lines for the two low volume nodes
			DrawHorzLine(vp.LowVolNodeLower, WLColor.Green, 2);
			DrawHorzLine(vp.LowVolNodeUpper, WLColor.Green, 2);
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

PointOfControl
public double PointOfControl

Returns the value that corresponds to the Volume Profile's "Point of Control", or the Volume Profile bar that had the most TotalVolume. That bar's RangeMax value is returned.

Remarks

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);
			vp.ValueRangePct = 50.0;
			vp.GenerateVolumeProfile(bars.Count - 1);

			//render a volume profile manually, render bars not in the High Value Area a dimmer color
			WLColor color = WLColor.FromArgb(128, WLColor.Teal);
			WLColor dim = WLColor.FromArgb(64, WLColor.LightBlue);
			foreach (VolumeProfileItem vpi in vp.Items)
			{
				int width = (int)(100.0 * vpi.WidthPct);
				int x1 = bars.Count - 1 - width;
				WLColor c = vpi.InValueArea ? color : dim;
				DrawLine(x1, vpi.RangeMax, bars.Count - 1, vpi.RangeMax, c, 4);
			}

			//render a red line showing the Point of Control
			DrawHorzLine(vp.PointOfControl, WLColor.Red, 2);
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

PointOfControlItem
public VolumeProfileItem PointOfControlItem

Returns the Volume Profile bar that is the Point of Control, having the largest TotalVolume of all the VolumeProfileItem instances in the Items collection.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);
			vp.ValueRangePct = 50.0;
			vp.GenerateVolumeProfile(bars.Count - 1);

			//render lines on the volume pane that demark up/down volume of the Point of Control item
			VolumeProfileItem vpi = vp.PointOfControlItem;
			DrawHorzLine(vpi.UpVolume, WLColor.Green, 2, LineStyle.Solid, "Volume");
			DrawHorzLine(vpi.DownVolume, WLColor.Red, 2, LineStyle.Solid, "Volume");

			//many times these values are too great for the pane scale
			if (vpi.UpVolume > Highest.Value(bars.Count - 1, bars.Volume, bars.Count))
			{
				DrawHeaderText($"Values too high for pane display range", WLColor.NeonGreen, 14, "Volume");
				DrawHeaderText($"vpi.UpVolume: {vpi.UpVolume:N0}", WLColor.Green, 14, "Volume");
				DrawHeaderText($"vpi.DownVolume: {vpi.DownVolume:N0}", WLColor.Red, 14, "Volume");
			}
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

ProfileBarsDesired
public int ProfileBarsDesired

Contains the desired number of Volume Profile bars that should be generated. Depending on the range of the source data, the ultimate number of Volume Profile bars might be a little more or less than the specified value.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);

			//draw a horizontal line at the VP's "Point of Control"
			DrawHorzLine(vp.PointOfControl, WLColor.Red, 2);

			//for comparison, create a Volume Profile with a shorter lookback and fewer desired bars and display its POC in green
			vp.Lookback = 252 / 2;
			vp.ProfileBarsDesired = 25;
			vp.GenerateVolumeProfile(bars.Count - 1);
			DrawHorzLine(vp.PointOfControl, WLColor.Green, 2);
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}

ValueRangePct
public double ValueRangePct

Contains the percentage of total volume that should be considered the "High Value Range." The Volume Profile uses this value to flag Volume Profile bars as within the High Value Range, setting their InValueRange property to true. The process begins at the Point of Control, and then expands outward, flagging the bars closest to the Point of Control until the percentage of volume is exhausted.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System.Drawing;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
			//generate a one year (if using daily data) Volume Profile
			VolumeProfile vp = new VolumeProfile(bars, 252, 50);
			vp.ValueRangePct = 50.0;
			vp.GenerateVolumeProfile(bars.Count - 1);

			//render a volume profile manually, render bars not in the High Value Area a dimmer color
			WLColor color = WLColor.FromArgb(128, WLColor.Teal);
			WLColor dim = WLColor.FromArgb(64, WLColor.LightBlue);
			foreach (VolumeProfileItem vpi in vp.Items)
			{
				int width = (int)(100.0 * vpi.WidthPct);
				int x1 = bars.Count - 1 - width;
				WLColor c = vpi.InValueArea ? color : dim;
				DrawLine(x1, vpi.RangeMax, bars.Count - 1, vpi.RangeMax, c, 4);
			}
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}
	}
}