Search Framework:
Position
Namespace: WealthLab.Backtest
Parent: Object

The Position class represents a long (result of a buy order) or short (result of a sell short order) position that was generated by the backtester.

Members
Bars
public BarHistory Bars

Returns the BarHistory instance that this Position was based on. Certain Strategies (such as pairs trading or symbol rotation) can trade on multiple symbols. The Bars property allows you to determine which symbol a particular Position was established on, for example.

Remarks

  • See the BarHistory class reference for more information about its properties and events.

BarsHeld
public int BarsHeld

Returns the number of bars that the position was held. If the Position is still active, BarsHeld returns the total number of bars held as of the last bar of the chart.

Remarks

  • The BarsHeld property is primarily intended for use by Performance Visualizers, not Strategies.
  • See example to get the current number of bars held for an active position.
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class BarsHeldExample : UserStrategyBase
	{
		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			StartIndex = bars.Count - 20;
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				int currentBarsHeld = idx - p.EntryBar + 1;
				DrawBarAnnotation(currentBarsHeld.ToString(), idx, true, WLColor.Black, 10);

				// p.BarsHeld is a constant
				DrawBarAnnotation(p.BarsHeld.ToString(), idx, false, WLColor.Red, 10);
			}
		}
	}
}

BasisPrice
public double BasisPrice

A Position's "basis price" is the price that was used to establish how many shares the Position should be sized to. For OrderType Market and MarketClose, the basis price is typically the closing price of the previous bar, but this may be changed in the Strategy Settings to be the opening price of the trade bar. For limit/stop orders, the basis price is always the limit/stop price specified.

The actual entry price can of course differ because the market may open above or below the previous close or limit/stop price specified. In certain situations this difference can cause a trade to not be filled by the backtester due to Not Sufficient Funds, and are marked as NSF positions. For more information see Help > Strategy > Strategy Settings > Basis Price.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class BasisPriceExample : UserStrategyBase
	{
		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			StartIndex = bars.Count - 20;
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;

				if (idx == bars.Count - 1)
				{
					DrawHeaderText("Basis Price for the trade was: " + p.BasisPrice.ToString("N2"), WLColor.Red, 12);
					DrawHeaderText("Entry Price for the trade was: " + p.EntryPrice.ToString("N2"), WLColor.Red, 12);
				}


			}
		}
	}
}

BrokerTag
public object BrokerTag

Allows Broker Adapters to store broker-specific information along with a Position, for the purposes of mapping the Position back to a broker-specific identifier.


Commission
public double Commission

Returns the total commission (entry plus exit) for the Position. In a Multi-Currency backtest, Commission is given in the base currency. See also: CommissionNonBase

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class CommissionExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);

		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				if (idx - LastPosition.EntryBar + 1 > 5)        // wait at least 5 bars
					if (bars.Close[idx] < _ma[idx])
						PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			base.BacktestComplete();

			foreach (Position p in GetPositions())
			{
				WriteToDebugLog("Position Entry Date: " + p.EntryDate.ToShortDateString());
				WriteToDebugLog("Commission (total): $" + p.Commission.ToString("N2"));
				WriteToDebugLog("EntryCommission: $" + p.EntryCommission.ToString("N2"));

				if (p.ExitDate != DateTime.MaxValue)
				{
					WriteToDebugLog("Position Exit Date: " + p.ExitDate.ToShortDateString());
					WriteToDebugLog("ExitCommission: $" + p.ExitCommission.ToString("N2"));
				}
				else
					WriteToDebugLog("Position Exit Date: Active");

				WriteToDebugLog("");
			}
		}
	}
}

CommissionNonBase
public double CommissionNonBase

Returns the total commission (entry plus exit) for the Position. In a Multi-Currency backtest, CommissionNonBase is given in the trade's currency. See also: Commission


CostBasis
public double CostBasis

Returns the cost basis for the Position in the base currency for a Multi-Currency backtest. This is the Position's EntryPrice multipled by its Quantity and converted to the base currency. In Futures Mode, it is the symbol's Margin multipled by Quantity.


CostBasisNonBase
public double CostBasisNonBase

Returns the cost basis for the Position in the trade (non-base) currency. This is the Position's EntryPrice multipled by its Quantity. In Futures Mode, it is the symbol's Margin multipled by Quantity.


DaysInPosition
public int DaysInPosition(int idx, bool countByLastBarOfDay)

Returns how many trading days have passed since establishing a Position when using intraday data.

Remarks

  • Returns -1 for Daily and all non-Intraday scales.
  • Pass false to countByLastBarOfDay for DaysInPosition to return 1 on the trading day after which the position was entered.
  • Pass true to countByLastBarOfDay for DaysInPosition to return 1 on the last bar of the trading day on which the position was entered - even if the Position is entered on the last bar of the day.
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript3
{
	public class MyStrategy : UserStrategyBase
	{
		public override void Initialize(BarHistory bars)
		{
		}

		public override void Execute(BarHistory bars, int idx)
		{
			if (bars.IsIntraday)
			{
				if (!HasOpenPosition(bars, PositionType.Long))
				{
					//enter on the 4th bar of the day
					if (bars.IntradayBarNumber(idx) == 3)
						PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
				}
				else
				{
					if (LastPosition.DaysInPosition(idx, false) > 3)
						ClosePosition(LastPosition, OrderType.Market, 0, "Exited after 3 days");
				}
			}
		}
	}
}

EntryBar
public int EntryBar

Returns the bar number into the source BarHistory (Bars property) where the Position entry occurred.

Remarks In development of Position Sizers and Performance Visualizers, checking for EntryBar or ExitBar may produce unexpected results because the historical DataSets aren't synchronized when backtesting.

Solution: check for the date with EntryDate/ExitDate rather than the bar number.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class EntryBarExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);
			PlotIndicatorLine(_ma);

		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				if (idx - LastPosition.EntryBar + 1 > 5)        // wait at least 5 bars
					if (bars.Close[idx] < _ma[idx])
						PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}
	}
}

EntryCommission
public double EntryCommission

Returns the entry commission for the Position. In a Multi-Currency backtest, EntryCommission is given in the base currency. See also: EntryCommissionNonBase

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class CommissionExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);

		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				if (idx - LastPosition.EntryBar + 1 > 5)        // wait at least 5 bars
					if (bars.Close[idx] < _ma[idx])
						PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			base.BacktestComplete();

			foreach (Position p in GetPositions())
			{
				WriteToDebugLog("Position Entry Date: " + p.EntryDate.ToShortDateString());
				WriteToDebugLog("Commission (total): $" + p.Commission.ToString("N2"));
				WriteToDebugLog("EntryCommission: $" + p.EntryCommission.ToString("N2"));

				if (p.ExitDate != DateTime.MaxValue)
				{
					WriteToDebugLog("Position Exit Date: " + p.ExitDate.ToShortDateString());
					WriteToDebugLog("ExitCommission: $" + p.ExitCommission.ToString("N2"));
				}
				else
					WriteToDebugLog("Position Exit Date: Active");

				WriteToDebugLog("");
			}
		}
	}
}

EntryCommissionNonBase
public double EntryCommissionNonBase

Returns the entry commission for the Position in the trade's currency for a Multi-Currency backtest. See also: EntryCommission


EntryDate
public DateTime EntryDate

Returns the DateTime the Position was entered.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class EntryBarExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);
			PlotIndicatorLine(_ma);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				if (bars.Close.CrossesUnder(_ma, idx))
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			//Write a list of Entry and Exit dates to the debug window
			foreach (Position p in GetPositionsAllSymbols())
			{
				string s = string.Format("{0}\t{1}\t{2:d}\t{3}\t{4:d}",
					p.Symbol, p.EntryBar, p.EntryDate, p.ExitBar, p.ExitDate);
				WriteToDebugLog(s);

			}
		}
	}
}

EntryOrderType
public OrderType EntryOrderType

Returns the type of order that was used to establish the Position. Possible values are:

  • OrderType.Market
  • OrderType.Limit
  • OrderType.Stop
  • OrderType.MarketClose
  • OrderType.LimitMove
  • OrderType.FixedPrice

EntryPrice
public double EntryPrice

Returns the price at which the Position was entered.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class EntryBarExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);
			PlotIndicatorLine(_ma);
			PlotStopsAndLimits(4);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				if (idx - p.EntryBar + 1 > 5)
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market, 0, "Time-based");
				else
				{
					double limit = p.EntryPrice * 1.05;     // 5% profit target
					PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, limit, "5%");
				}
			}
		}
	}
}

EntrySignalName
public string EntrySignalName

Contains the SignalName string that was used by the Transaction object that opened this position .The value that you specify is visible in the Positions list and is also accessible via this EntrySignalName property.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript1
{
	public class EntryExitSignalsExample : UserStrategyBase
	{
		IndicatorBase _sma;
		IndicatorBase _smaSlow;
		IndicatorBase _rsi;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			StartIndex = 100;
			PlotStopsAndLimits(4);
			_sma = SMA.Series(bars.Close, 50);
			_smaSlow = SMA.Series(bars.Close, 100);
			_rsi = RSI.Series(bars.Close, 10);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				//buy the crossover
				if (_sma.CrossesOver(_smaSlow, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, "SMA Xing");

				//buy a selloff
				if (_rsi.CrossesUnder(30, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, "RSI<30");
			}
			else
			{
				Position p = LastPosition;
				double tgt = p.EntryPrice * 1.20;   //20% gain
				double stop = p.EntryPrice * 0.75;  //-25% stop
				string exitSignal = "Stop";

				// change target to break even if the MAEPercent reaches -10%
				if (p.MAEPctAsOf(idx) < -10)
				{
					tgt = p.EntryPrice;
					exitSignal = "break even";
				}
				PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, stop, "stop loss");
				PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, tgt, exitSignal);

			}
		}
	}
}

ExitBar
public int ExitBar

Returns the bar number into the source BarHistory (Bars property) where the Position exit occurred. If the Position is still open, returns -1.

Remarks In development of Position Sizers and Performance Visualizers, checking for EntryBar or ExitBar may produce unexpected results because the historical DataSets aren't synchronized when backtesting.

Solution: check for the date with EntryDate/ExitDate rather than the bar number.


ExitCommission
public double ExitCommission

Returns the exit commission for the Position. In a Multi-Currency backtest, ExitCommission is given in the base currency. See also: ExitCommissionNonBase

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class CommissionExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);

		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				if (idx - LastPosition.EntryBar + 1 > 5)        // wait at least 5 bars
					if (bars.Close[idx] < _ma[idx])
						PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			base.BacktestComplete();

			foreach (Position p in GetPositions())
			{
				WriteToDebugLog("Position Entry Date: " + p.EntryDate.ToShortDateString());
				WriteToDebugLog("Commission (total): $" + p.Commission.ToString("N2"));
				WriteToDebugLog("EntryCommission: $" + p.EntryCommission.ToString("N2"));

				if (p.ExitDate != DateTime.MaxValue)
				{
					WriteToDebugLog("Position Exit Date: " + p.ExitDate.ToShortDateString());
					WriteToDebugLog("ExitCommission: $" + p.ExitCommission.ToString("N2"));
				}
				else
					WriteToDebugLog("Position Exit Date: Active");

				WriteToDebugLog("");
			}
		}
	}
}

ExitCommissionNonBase
public double ExitCommissionNonBase

Returns the exit commission for the Position in the trade's currency for a Multi-Currency backtest. See also: ExitCommission


ExitDate
public DateTime ExitDate

Returns the DateTime the Position was exited. If the Position is still open, returns DateTime.MaxValue.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class EntryBarExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);
			PlotIndicatorLine(_ma);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				if (bars.Close.CrossesUnder(_ma, idx))
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			//Write a list of Entry and Exit dates to the debug window
			foreach (Position p in GetPositionsAllSymbols())
			{
				string s = string.Format("{0}\t{1}\t{2:d}\t{3}\t{4:d}",
					p.Symbol, p.EntryBar, p.EntryDate, p.ExitBar, p.ExitDate);
				WriteToDebugLog(s);

			}
		}
	}
}

ExitOrderType
public OrderType ExitOrderType

Returns the type of order that was used to close the Position. Possible values are:

  • OrderType.Market
  • OrderType.Limit
  • OrderType.Stop
  • OrderType.MarketClose
  • OrderType.FixedPrice

ExitPrice
public double ExitPrice

Returns the price at which the Position was exited. If the Position is still open, returns zero.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class EntryBarExample : UserStrategyBase
	{
		IndicatorBase _ma;

		public override void Initialize(BarHistory bars)
		{
			StartIndex = 20;
			_ma = SMA.Series(bars.Close, 20);
			PlotIndicatorLine(_ma);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_ma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				if (bars.Close.CrossesUnder(_ma, idx))
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			//Write a list of Entry and Exit dates to the debug window
			foreach (Position p in GetPositionsAllSymbols())
			{
				string s = string.Format("{0}\t{1:d}\t{2:d}\t{3:N4}",
					p.Symbol, p.EntryDate, p.ExitDate, p.ExitPrice);
				WriteToDebugLog(s);

			}
		}
	}
}

ExitSignalName
public string ExitSignalName

Contains the SignalName string that was used by the Transaction object that closed this position. The value that you specify is visible in the Positions list for Exit Signal and is also accessible via this ExitSignalName property. If the Position is still active, ExitSignalName returns a blank string.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript1
{
	public class EntryExitSignalsExample : UserStrategyBase
	{
		IndicatorBase _sma;
		IndicatorBase _smaSlow;
		IndicatorBase _rsi;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			StartIndex = 100;
			PlotStopsAndLimits(4);
			_sma = SMA.Series(bars.Close, 50);
			_smaSlow = SMA.Series(bars.Close, 100);
			_rsi = RSI.Series(bars.Close, 10);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				//buy the crossover
				if (_sma.CrossesOver(_smaSlow, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, "SMA Xing");

				//buy a selloff
				if (_rsi.CrossesUnder(30, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, "RSI<30");
			}
			else
			{
				Position p = LastPosition;
				double tgt = p.EntryPrice * 1.20;   //20% gain
				double stop = p.EntryPrice * 0.75;  //-25% stop
				string exitSignal = "Stop";

				// change target to break even if the MAEPercent reaches -10%
				if (p.MAEPctAsOf(idx) < -10)
				{
					tgt = p.EntryPrice;
					exitSignal = "break even";
				}
				PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, stop, "stop loss");
				PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, tgt, exitSignal);

			}
		}
	}
}

FuturesMode
public bool FuturesMode

Returns true if the Position was operating under Futures Mode. This will be true if Futures Mode was turned on in Backtest Settings, and the Position's symbol (Bars.Symbol) has a Point Value and Margin defined.


GetMetric
public double GetMetric(string metricName)

Returns the value of a Position Metric that is either a built-in metric (such as Profit or BarsHeld), or a metric created by calling SetMetric. Typically used within Performance Visualizers such as Position Metrics in the Power Pack Extension. The roster of all available Position Metrics can be obtained via the Backtester.PositionMetricNames property.


Index
public int Index

Returns the index into the Backtester Positions list that this Position occupies. Used in certain Performance Visualizers, for example Position Metrics (Trade Stability preset) in the Power Pack Extension.


IsOpen
public bool IsOpen

Returns true if the Position is currently open (not yet exited).


MAE
public double MAE

Returns the Maximum Adverse Excursion (MAE) that was generated by the Position with commissions applied. MAE is in the base currency for a Multi-Currency backtest and represents the largest intraday loss that the trade experienced during its lifetime. This property is intended for use by Performance Visualizers and not in Strategies.

Remarks

  • MAE will be a negative number (or zero).

MAEAsOf
public double MAEAsOf(int idx)

Returns the Maximum Adverse Excursion (MAE) generated by the Position, as of the specified bar number with commissions applied. MAEAsOf is in the base currency for a Multi-Currency backtest and represents the largest intraday loss that the trade experienced up to and including the specified bar.

Remarks

  • MAEAsOf will be a negative number (or zero).

MAENonBase
public double MAENonBase

Returns the Maximum Adverse Excursion (MAE) that was generated by the Position with commissions applied. MAENonBase is always in the trade (non-base) currency for a Multi-Currency backtest (see MAE) and represents the largest intraday loss that the trade experienced during its lifetime. This property is intended for use by Performance Visualizers and not in Strategies.

Remarks

  • During Strategy execution use MAENonBaseAsOf.
  • MAENonBase will be a negative number (or zero).

MAENonBaseAsOf
public double MAENonBaseAsOf(int idx)

Returns the Maximum Adverse Excursion (MAE) generated by the Position, with commissions applied, as of the specified bar number. MAENonBaseAsOf represents the largest intraday loss that the trade experienced up to and including the specified bar, always expressed in the trade currency.

Remarks

  • MAENonBaseAsOf will be a negative number (or zero).

MAEPctAsOf
public double MAEPctAsOf(int idx)

Returns the Maximum Adverse Excursion (MAE) that was generated by the Position, with commissions applied, as a percentage, as of the specified bar number. MAEPctAsOf represents the largest intraday percentage loss in the base currency for a Multi-Currency backtest that the trade experienced up to and including the specified bar.

Remarks

  • MAEPctAsOf will be a negative number (or zero).
  • For Futures Mode, MAEPct considers MAE dollar loss and futures margin.

Example (Futures Mode)
2 ES contracts ($50 point value) shorted at 4000.00 advanced to an intraday high of 4050.00, a -1.25% loss "non futures mode". The MAE dollar loss is (2 * $50 * -50) = -$5,000 and for a futures margin of $18,000 per contract, the MAEPct is -5000/36000 * 100 = -13.89%.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript1
{
	public class MAEExample : UserStrategyBase
	{
		IndicatorBase _sma;
		IndicatorBase _smaSlow;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			StartIndex = 100;
			PlotStopsAndLimits(4);
			_sma = SMA.Series(bars.Close, 50);
			_smaSlow = SMA.Series(bars.Close, 100);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (_sma.CrossesOver(_smaSlow, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;
				double tgt = p.EntryPrice * 1.20;   //20% gain
				double stop = p.EntryPrice * 0.75;  //-25% stop
				string exitSignal = "Stop";

				// change target to break even if the MAEPercent reaches -10%
				if (p.MAEPctAsOf(idx) < -10)
				{
					tgt = p.EntryPrice;
					exitSignal = "break even";
				}
				PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, stop);
				PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, tgt, exitSignal);

			}
		}
	}
}

MAEPctNonBaseAsOf
public double MAEPctNonBaseAsOf(int idx)

Returns the Maximum Adverse Excursion (MAE) that was generated by the Position, with commissions applied, as a percentage as of the specified bar number. MAEPctNonBaseAsOf represents the largest intraday percentage loss, always with respect to the trade currency, that the trade experienced up to and including the specified bar.

Remarks

  • MAEPctNonBaseAsOf will be a negative number (or zero).
  • For Futures Mode, MAEPct considers MAE dollar loss and futures margin.

WealthLab 8 Build 36 - Multi-Currency Backtests


MAEPercent
public double MAEPercent

Returns the Maximum Adverse Excursion (MAE) that was generated by the Position as a percentage. MAEPercent represents the largest intraday percentage loss that the trade experienced during its lifetime. In a Multi-Currency backtest, MAEPercent is with respect to the base currency.

This property is intended for use by Performance Visualizers, and not in Strategies.

Remarks

  • Includes commissions.
  • During Strategy execution use MAEPctAsOf.
  • MAEPercent will be a negative number (or zero).
  • For Futures Mode, MAEPercent considers MAE dollar loss and futures margin.

MAEPercentNonBase
public double MAEPercentNonBase

Same as MAEPercent, but always with respect to the trade's currency.


MFE
public double MFE

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position with commissions applied. MFE is in the base currency for a Multi-Currency backtest and represents the highest intraday profit that the trade experienced during its lifetime. This property is intended for use by Performance Visualizers and not in Strategies.

Remarks

  • During Strategy execution use MFEAsOf.

MFEAsOf
public double MFEAsOf(int idx)

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position, with commissions applied, as of the specified bar number. MFEAsOf is in the base currency for a Multi-Currency backtest and represents the highest intraday profit that the trade experienced up to and including the specified bar.

WealthLab 8 Build 36 - Multi-Currency Backtests


MFENonBase
public double MFENonBase

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position with commissions applied. MFENonBase is always in the trade (non-base) currency and represents the highest intraday profit that the trade experienced during its lifetime. This property is intended for use by Performance Visualizers and not in Strategies.


MFENonBaseAsOf
public double MFENonBaseAsOf(int idx)

Returns the Maximum Favoralble Excursion (MFE) generated by the Position, with commissions applied, as of the specified bar number. MAENonBaseAsOf represents the largest intraday profit that the trade experienced up to and including the specified bar, always expressed in the trade currency.

WealthLab 8 Build 36 - Multi-Currency Backtests


MFEPctAsOf
public double MFEPctAsOf(int idx)

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position, with commissions applied, as a percentage and as of the specified bar number. MFEPctAsOf represents the highest intraday percentage profit with respect to the base currency for a Multi-Currency backtest that the trade experienced up to and including the specified bar.

Remarks

  • For Futures Mode, MFEPct considers MFE dollar profit and futures margin.

Example (Futures Mode)
2 long ES contracts ($50 point value) purchased at 4000.00 advanced to an intraday high of 4050.00, a 1.25% rise for "non futures mode". The MFE dollar profit is (2 * $50 * 50) = $5,000 and for a futures margin of $18,000 per contract, the MFEPct is 5000/36000 * 100 = 13.89%.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript1
{
	public class MFEExample : UserStrategyBase
	{
		IndicatorBase _sma;
		IndicatorBase _smaSlow;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			StartIndex = 100;
			PlotStopsAndLimits(4);
			_sma = SMA.Series(bars.Close, 50);
			_smaSlow = SMA.Series(bars.Close, 100);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (_sma.CrossesOver(_smaSlow, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				Position p = LastPosition;

				// change to a trailing stop when MFE Percent reaches 15%
				if (p.MFEPctAsOf(idx) > 15)
				{
					PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, _sma.GetHighest(idx, idx - p.EntryBar));
				}
				else
				{
					double tgt = p.EntryPrice * 1.20;   //20% gain
					double stop = p.EntryPrice * 0.85;  //-15% stop

					PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, stop);
					PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, tgt);
				}
			}
		}
	}
}

MFEPctNonBaseAsOf
public double MFEPctNonBaseAsOf(int idx)

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position, with commissions applied, as a percentage as of the specified bar number. MFEPctNonBaseAsOf represents the largest intraday percentage profit, always with respect to the trade currency, that the trade experienced up to and including the specified bar.

WealthLab 8 Build 36 - Multi-Currency Backtests


MFEPercent
public double MFEPercent

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position as a percentage. MFEPercent represents the highest intraday percentage profit that the trade experienced during its lifetime. This property is intended for use by Performance Visualizers, and not in Strategies.

This property is intended for use by Performance Visualizers, and not in Strategies.

Remarks

  • In a Multi-Currency backtest, MFEPercent is with respect to the base currency.
  • Includes commissions.
  • During Strategy execution use MFEPctAsOf.
  • MAEPercent will be a negative number (or zero).
  • For Futures Mode, MFEPercent considers MFE dollar profit and futures margin.

MFEPercentNonBase
public double MFEPercentNonBase

Same as MFEPercent, but always with respect to the trade's currency.


PositionTag
public int PositionTag

Contains an int tag value that you can establish at the time the Position is entered. The PlaceTrade method has a positionTag parameter where you can tag Positions for identification. These Positions can be located at a later point by calling FindPosition.


PositionType
public PositionType PositionType

Returns the position type, possible values are PositionType.Long and PositionType.Short.


Profit
public double Profit

Returns the profit of the Position, with commissions deducted. This property is mainly meant for use in Performance Visualizers, not during backtesting. If you need to obtain a Position's profit during a backtest, use ProfitAsOf instead.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class MyStrategy : UserStrategyBase
	{
		TimeSeries _sma;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			_sma = SMA.Series(bars.Close, 10);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_sma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			//header
			string s = String.Format("{0, 12}\t{1}\t{2, 12}  vs. {3, 12}{4, 12}  vs. {5, 6}",
					"Symbol", "ExitDate", "WL8 Profit", "My Profit", "WL8 Profit%", "My Profit%");
			WriteToDebugLog(s);

			//let's check Wealth-Lab's Profit calculations!
			foreach (Position p in GetPositionsAllSymbols())
			{
				int sign = p.PositionType == PositionType.Long ? 1 : -1;
				double profit = p.Quantity * sign * (p.ExitPrice - p.EntryPrice);
				double profitPct = 100 * sign * (p.ExitPrice / p.EntryPrice - 1);



				s = String.Format("{0, 12}\t{1:d}\t{2, 12:C2}  vs. {3, 12:C2}{4, 12:N2}%  vs. {5, 6:N2}%",
					p.Symbol, p.ExitDate, p.Profit, profit, p.ProfitPercent, profitPct);
				WriteToDebugLog(s );
			}
		}

	}
}

ProfitAsOf
public double ProfitAsOf(int idx)

Returns the profit of the Position (in the trade currency) as of the specified bar number. Commissions are included in the calculation.

Remarks

  • See also MAEAsOf, MFEAsOf
Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;

namespace WealthScript123
{
    public class MyStrategy : UserStrategyBase
    {
        //create indicators and other objects here, this is executed prior to the main trading loop
        public override void Initialize(BarHistory bars)
        {
			_sma = SMA.Series(bars.Close, 20);
			PlotIndicator(_sma); 
        }

        //execute the strategy rules here, this is executed once for each bar in the backtest history
        public override void Execute(BarHistory bars, int idx)
        {
            if (!HasOpenPosition(bars, PositionType.Long))
            {
				if (bars.Close.CrossesOver(_sma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
            }
            else
            {
				Position pos = LastPosition; 
				// exit after 10 bars or a $500 profit
				if (idx - pos.EntryBar + 1 >= 10)
					ClosePosition(pos, OrderType.Market, exitSignalName: "Time out"); 
	            else if (pos.ProfitAsOf(idx) >= 500)
					ClosePosition(pos, OrderType.Market, exitSignalName: "$500"); 	            
            }	
        }

		//declare private variables below
		SMA _sma; 
    }
}

ProfitPct
public double ProfitPercent

Returns the percentage profit of the Position in the base currency for a Multi-Currency backtest, with commissions deducted.

Remarks
This property is mainly meant for use in Performance Visualizers, not during backtesting. Strategies should use ProfitPctAsOf to obtain a Position's profit % at a specified bar during a backtest.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript2
{
	public class MyStrategy : UserStrategyBase
	{
		TimeSeries _sma;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			_sma = SMA.Series(bars.Close, 10);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_sma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				PlaceTrade(bars, TransactionType.Sell, OrderType.Market);
			}
		}

		public override void BacktestComplete()
		{
			//header
			string s = String.Format("{0, 12}\t{1}\t{2, 12}  vs. {3, 12}{4, 12}  vs. {5, 6}",
					"Symbol", "ExitDate", "WL8 Profit", "My Profit", "WL8 Profit%", "My Profit%");
			WriteToDebugLog(s);

			//let's check Wealth-Lab's Profit calculations!
			foreach (Position p in GetPositionsAllSymbols())
			{
				int sign = p.PositionType == PositionType.Long ? 1 : -1;
				double profit = p.Quantity * sign * (p.ExitPrice - p.EntryPrice);
				double profitPct = 100 * sign * (p.ExitPrice / p.EntryPrice - 1);



				s = String.Format("{0, 12}\t{1:d}\t{2, 12:C2}  vs. {3, 12:C2}{4, 12:N2}%  vs. {5, 6:N2}%",
					p.Symbol, p.ExitDate, p.Profit, profit, p.ProfitPercent, profitPct);
				WriteToDebugLog(s );
			}
		}

	}
}

ProfitPctAsOf
public double ProfitPctAsOf(int idx)

Returns the percentage profit of the Position as of the specified bar number. Commissions are included in the calculation.

Remarks

  • For Futures Mode, ProfitPctAsOf returns the current trade percentage profit with respect to futures margin.

Example (Futures Mode)
2 long ES contracts ($50 point value) purchased at 4000.00 last closed at 4050.00, a 1.25% profit % for "non futures mode". The dollar profit is (2 * $50 * 50) = $5,000, and for a futures margin of $18,000 per contract, the Profit percentage is 5000/36000 * 100 = 13.89%.

Example Code
using WealthLab.Backtest;
using System;
using WealthLab.Core;
using WealthLab.Indicators;
using System.Drawing;
using System.Collections.Generic;

namespace WealthScript123
{
	public class MyStrategy : UserStrategyBase
	{
		TimeSeries _sma;

		//create indicators and other objects here, this is executed prior to the main trading loop
		public override void Initialize(BarHistory bars)
		{
			_sma = SMA.Series(bars.Close, 10);
		}

		//execute the strategy rules here, this is executed once for each bar in the backtest history
		public override void Execute(BarHistory bars, int idx)
		{
			if (!HasOpenPosition(bars, PositionType.Long))
			{
				if (bars.Close.CrossesOver(_sma, idx))
					PlaceTrade(bars, TransactionType.Buy, OrderType.Market);
			}
			else
			{
				//Exit at market (tomorrow) when the closed Position Profit % exceeds 6% or after 20 bars
				Position p = LastPosition;
				if (p.ProfitPctAsOf(idx) >= 6)
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market, 0, "Profit %");
				else if (idx + 1 - p.EntryBar > 20)
					PlaceTrade(bars, TransactionType.Sell, OrderType.Market, 0, "Time Based");
			}
		}
	}
}

ProfitPctNonBase
public double ProfitPercentNonBase

Returns the percentage profit of the Position in the trade (non-base) currency with commissions deducted.

WealthLab 8 Build 36 - Multi-Currency Backtests


Quantity
public double Quantity

Returns the number of shares or contracts that comprise the Position.


RiskStopLevel
public double RiskStopLevel

Contains the established stop loss level of the trade that was used for Max Risk Percent position sizing. You can use this value to issue stop loss orders for open positions so the maximum loss of the trade does not exceed the desired maximum risk.


SetMetric
public void SetMetric(string metric, double value)

Adds a Position Metric with the specified metricName and value. Position Metrics are typically added at the Transaction level, using the Transaction SetPositionMetric method, but they can also be assigned directly to Positions. For example, during the BacktestComplete method. Certain Performance Visualizers, for example the Position Metrics in the Power Pack Extension, access Position Metrics.


Tag
public object Tag

Lets you store Strategy-specific information with a Position. If you assigned a value to the Tag property of the Transaction instance that opened this Position, that Tag value will be passed along to the Position.


TrailingStopPrice
public double TrailingStopPrice

Provides access to the most recent trailing stop value for the Position. Trailing stop levels come from calling the CloseAtTrailingStop WealthScript method. The trailing stop is adjusted upward if the most recently passed value is higher than the current stop level.


ValueAsOf
public double ValueAsOf(int idx, bool useOpenPrice)

Returns the dollar size of the Position as of the specified bar index. In a Multi-Currency Backtest, this value is in the base currency. For equities and mutual funds this is the shares multiplied by the entry price (CostBasis property). For futures, this is the contracts multiplied by the margin of the contract.