NexusFi: Find Your Edge


Home Menu

 





Van Tharp's Max Expectancy


Discussion in Psychology and Money Management

Updated
      Top Posters
    1. looks_one rickt with 7 posts (4 thanks)
    2. looks_two Big Mike with 4 posts (4 thanks)
    3. looks_3 caprica with 3 posts (16 thanks)
    4. looks_4 wuming79 with 3 posts (0 thanks)
      Best Posters
    1. looks_one gordo with 5.5 thanks per post
    2. looks_two caprica with 5.3 thanks per post
    3. looks_3 Anagoge with 4 thanks per post
    4. looks_4 rickt with 0.6 thanks per post
    1. trending_up 26,527 views
    2. thumb_up 47 thanks given
    3. group 24 followers
    1. forum 31 posts
    2. attach_file 1 attachments




 
Search this Thread

Van Tharp's Max Expectancy

  #31 (permalink)
 
aventeren's Avatar
 aventeren 
Bellingham, WA USA
 
Experience: Beginner
Platform: NT
Broker: Mirus (Broker), Continuum (Data), Dorman (Clearing)
Trading: Futures
Posts: 202 since Mar 2013
Thanks Given: 428
Thanks Received: 202


gordo View Post
I wrote two optimization types (that work in NT 7 quite nicely) based on the information from this thread and Van Tharp's book. Here are the links:

Expectancy Score (which includes expectancy X opportunity), and

Expectancy (which does not include opportunity).

I use the Expectancy optimization all the time and find it gives me great direction when I am optimizing my stategies.

Gordo

@gordo--

Thanks for coding the Expectancy Score optimizer.

I'm currently exploring the use of a few optimizers, and I have taken a look at the rationale behind the Expectancy Score, which appears pretty decent. So thanks for coding it up.

I did notice that the Expectancy Score does not appear to take commissions or slippage into account when calculating winsAmount or losesAmount.

Was the exclusion of commission and slippage on purpose?

It seems to me that we should be optimizing to a net expectancy score as opposed to a gross expectancy score.

What are your thoughts?

Thanks,

Aventeren

Here is the code for those that have not downloaded the .cs file.

 
Code
#region Using declarations
	using System;
	using System.ComponentModel;
	using System.Drawing;
	using NinjaTrader.Cbi;
	using NinjaTrader.Data;
	using NinjaTrader.Indicator;
	using NinjaTrader.Strategy;
#endregion

namespace NinjaTrader.Strategy
{
	// Expectany score calculations based on Van K. Tharp's book 'Trade Your Way to Financial Freedom'.
	// Portions of this code borrowed from fluxsmith at nexusfi.com (formerly BMT).  Thanks for the start!
	// 4/28/2011.  Gordon Brest.
	[Gui.Design.DisplayName("Expectancy Score")]
    public class ExpectancyScore : OptimizationType
	{
		#region variables
			private int normalizedNumberTradesPerYear;
			private int numberScratchTrades;
			private int numberOfTrades;
			
			private double studyDays;
			private double averageWinningTrade;
			private double probabilityOfWinning;
			private double averageLosingTrade;
			private double probabilityOfLosing;
			private double nonScratchTrades;
			private double valueScratchTrades;
			private double winsAmount;
			private double winsCount;
			private double losesAmount;
			private double losesCount;
			private double expectancy;
			private double opportunity;
			private double commission;
			
			private bool init = false;
			
			private double val;
			
			public double expectancyScore;
			
			private DateTime start = new DateTime();
			private DateTime stop = new DateTime();
			private TimeSpan span = new TimeSpan();
		#endregion
		
		public override double GetPerformanceValue(SystemPerformance systemPerformance)
		{
			#region Logic Description
			/*
			Reference:  http://www.unicorn.us.com/trading/expectancy.html
			
			EXPECTANCY is how much you expect to earn from each trade for every dollar you risk. Opportunity is how often your strategy trades. 
			You want to maximize the product of both.
			
			Expectancy = (AW × PW + AL × PL) ⁄ |AL| 
			(expected profit per dollar risked)
			
			Expectancy score = Expectancy × Opportunity
			
			where 
			AW = average winning trade (excluding maximum win) 
			AL = average losing trade (negative, excluding scratch losses) 
			|AL| = absolute value of AL 
			
			PW = probability of winning: PW = <wins> ⁄ NST (where <wins> is total wins excluding maximum win) 
			PL = probability of losing: PL = <non-scratch losses> ⁄ NST  
			Opportunity = NST × 365 ⁄ studydays   (opportunities to trade in a year) 
			
			where
			NST = <total trades> − <scratch trades> − 1
			In other words, NST = non-scratch trades during the period under test (a scratch trade loses commission+slippage or less) minus 1 (to exclude the maximum win). 
			studydays = calendar days of history being tested 
			
			NOTE:  The above verbage from the referenced website has been copied into the code below to explain the code's logic.
			*/
			#endregion
			
			/// Number of trades.
			numberOfTrades = systemPerformance.AllTrades.TradesPerformance.TradesCount;
			normalizedNumberTradesPerYear = (int)(systemPerformance.AllTrades.TradesPerformance.TradesPerDay * 365.0);
			commission = systemPerformance.AllTrades.TradesPerformance.Commission / numberOfTrades * -1;
			// studydays = calendar days of history being tested 
			foreach (Trade allTrades in systemPerformance.AllTrades)
			{
				if (!init)
				{
					init = true;
					start = allTrades.Entry.Time.Date;
				}
				stop = allTrades.Entry.Time.Date;
			}
			span = stop.Subtract(start);
			studyDays = span.TotalDays + 1;
			
			/// Calculate scratch trades.
			numberScratchTrades = 0;
			valueScratchTrades = 0;
			// NST = <total trades> − <scratch trades> − 1
			// In other words, NST = non-scratch trades during the period under test (a scratch trade loses commission+slippage or less) minus 1 (to exclude the maximum win). 			foreach (Trade myTrade in systemPerformance.AllTrades.LosingTrades)
			foreach (Trade losingTrades in systemPerformance.AllTrades.LosingTrades)
			{
				if (losingTrades.ProfitCurrency >= 1.25 * commission)
				{
					numberScratchTrades ++;
					valueScratchTrades += losingTrades.ProfitCurrency;
				}
			}	
			nonScratchTrades = numberOfTrades - numberScratchTrades - 1;
			winsCount = systemPerformance.AllTrades.WinningTrades.Count;
			losesCount = systemPerformance.AllTrades.LosingTrades.Count - numberScratchTrades;
			
			/// Reject optimizations that do not make any trades.
			if ( normalizedNumberTradesPerYear == 0 )
				return 777;
			
			/// Reject optimizations that trade less than once a week.
			if ( normalizedNumberTradesPerYear < 50 )
				return 888;
			
			/// Reject optimizations that do not have any losing trades as unrealistic.
			if ( systemPerformance.AllTrades.LosingTrades.Count == 0 )
				return 999;
			
			/// Calculate averages.
			// AW = average winning trade (excluding maximum win) 
			winsAmount = systemPerformance.AllTrades.TradesPerformance.GrossProfit - systemPerformance.AllTrades.TradesPerformance.Currency.LargestWinner;
			averageWinningTrade = winsAmount / (systemPerformance.AllTrades.WinningTrades.Count - 1);
			
			// AL = average losing trade (negative, excluding scratch losses) 
			losesAmount = systemPerformance.AllTrades.TradesPerformance.GrossLoss - valueScratchTrades;
			averageLosingTrade =  losesAmount / (systemPerformance.AllTrades.LosingTrades.Count - numberScratchTrades);
			
			/// Calculate probabilities.
			// PW = probability of winning: PW = <wins> ⁄ NST (where <wins> is total wins excluding maximum win) 
			probabilityOfWinning = winsCount / nonScratchTrades;
			// PL = probability of losing: PL = <non-scratch losses> ⁄ NST  
			probabilityOfLosing = losesCount / nonScratchTrades;
			
			/// Final calculations.
			// Expectancy = (AW × PW + AL × PL) ⁄ |AL| where |AL| = absolute value of AL.
			expectancy = (averageWinningTrade * probabilityOfWinning + averageLosingTrade * probabilityOfLosing) / Math.Abs(averageLosingTrade);
			
			//val = expectancy;
			// Opportunity = NST × 365 ⁄ studydays   (opportunities to trade in a year) 
			opportunity = nonScratchTrades * 365 / studyDays;
			
			// Expectancy score = Expectancy × Opportunity
			expectancyScore = expectancy * opportunity;
			
			/// Return the final value.
			return expectancyScore;
		}
	}
}

Reply With Quote
Thanked by:

Can you help answer these questions
from other members on NexusFi?
Are there any eval firms that allow you to sink to your …
Traders Hideout
Deepmoney LLM
Elite Quantitative GenAI/LLM
New Micros: Ultra 10-Year & Ultra T-Bond -- Live Now
Treasury Notes and Bonds
Exit Strategy
NinjaTrader
ZombieSqueeze
Platforms and Indicators
 
  #32 (permalink)
 VolTrading 
Toronto, Ontario, Canada
 
Experience: Advanced
Platform: Ninja, MultiCharts
Trading: ES
Posts: 14 since Feb 2014
Thanks Given: 36
Thanks Received: 17

@rickt - Replying to your post about dividing by AvgLoss vs. dividing by Std(TradeResults), I think that the latter gives a sense as to the likelihood that the TotalProfit occurred by chance or due to a true edge. This van Tharp approach strikes me as just a variation of the Sharpe Ratio (for good or ill).

In contrast the division by AvgLoss gives you what your results would look like over an extended period in terms of how much better your gains did over your losses, provided your system makes it over that extended period.

I like to analogize this to betting on the race car driver that wins the most races in a season as opposed to the one that is the wildest, fastest driver in the season's first three events but then crashes out in flames.

Reply With Quote




Last Updated on January 22, 2015


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts