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, Color.Black, 10);

				// p.BarsHeld is a constant
				DrawBarAnnotation(p.BarsHeld.ToString(), idx, false, Color.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"), Color.Red, 12);
					DrawHeaderText("Entry Price for the trade was: " + p.EntryPrice.ToString("N2"), Color.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.

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("");
			}
		}
	}
}

CostBasis
public double CostBasis

Returns the cost basis for the Position. 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.

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("");
			}
		}
	}
}

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.

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("");
			}
		}
	}
}

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.


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 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 MAEAsOf.

MAEAsOf
public double MAEAsOf(int idx)

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


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 that the trade experienced up to and including the specified bar.

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);

			}
		}
	}
}

MAEPercent
public double MAEPercent

Returns the Maximum Adverse Excursion (MAE) that was generated by the Position, with commissions applied, as a percentage. MAEPercent represents the largest intraday percentage 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 MAEPctAsOf.


MFE
public double MFE

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position with commissions applied. MFE 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 represents the highest intraday profit that the trade experienced up to and including the specified bar.


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 that the trade experienced up to and including the specified bar.

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);
				}
			}
		}
	}
}

MFEPercent
public double MFEPercent

Returns the Maximum Favorable Excursion (MFE) that was generated by the Position, with commissions applied, 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.

Remarks During Strategy execution use MFEPctAsOf.


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.

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", "WL7 Profit", "My Profit", "WL7 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 that was generated by the Position, including commissions, as of the specified bar number.


ProfitPct
public double ProfitPercent

Returns the percentage profit of the Position, with commissions deducted.

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", "WL7 Profit", "My Profit", "WL7 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 that was generated by the Position, including commissions, as of the specified bar number.

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");
			}
		}
	}
}

Quantity
public double Quantity

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


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. 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.