# EasyLanguage Code for Optimal F (Multi-Charts and VBA too!)

## Optimal F in EasyLanguage for TradeStation and MultiCharts

Here is the code for the Optimal F calculation.  For a really good explanation of Optimal f, I refer you to Ralph Vince’s Book Portfolio Management FORMULAS.  We had programmed this years ago for our Excalibur software and I was surprised the EasyLanguage code was not really all that accessible on the internet.  Finding the Optimal f is found through an iterative process or in programmers terms a loop.  The code is really quite simple and I put it into a Function.  I decided to create this function because I wanted to demonstrate the ideas from my last post on how a function can store variable and array data.  Plus this code should be readily available somewhere out there.

``//OptimalFGeo by George Pruitt//My interpretation Sept. 2018//www.georgepruitt.com//georgeppruitt@gmail.cominput: minNumTrades(numericSimple);vars: totalTradesCount(0),tradeCnt(0);array: tradesArray(0);vars: iCnt(00),jCnt(00),grandTot(0),highI(0);vars: optF(0.0),gMean(0.0),fVal(0.0),HPR(0.0),TWR(0.0),hiTWR(0.0);vars: biggestLoser(0.0),gat(0.0);totalTradesCount = totalTrades;If totalTradesCount > totalTradesCount thenbegin	tradeCnt = tradeCnt + 1; 	tradesArray[tradeCnt] = positionProfit(1);end;// Taken from my Fortran library - GPP and Vince Book PMFoptF = 0.0;gMean = 1.00;gat   = 0.00;//Only calculate if new tradeIF(tradeCnt>minNumTrades and totalTradesCount > totalTradesCount) then Begin	biggestLoser = 0;	grandTot = 0;	For iCnt = 1 to tradeCnt //get the biggest loser	begin   		grandTot = grandTot + tradesArray[iCnt];   		IF(tradesArray[iCnt]<biggestLoser) then biggestLoser = tradesArray[iCnt];	end;//	print(grandTot," ",biggestLoser);	IF({grandTot > 0 and} biggestLoser <0) then 	begin//		print("Inside TWR Calculations");		highI = 0;		hiTWR = 0.0;		for iCnt = 1 to 100		begin			fVal = .01 * iCnt;			TWR = 1.0;			for jCnt = 1 to tradeCnt // calculate the Terminal Wealth Relative			begin    			HPR = 1. + (fVal * (-1*tradesArray[jCnt]) / biggestLoser);    			TWR = TWR * HPR; //   			print(fVal," ",iCnt," " ,jCnt," Trades ",tradesArray[jCnt]," HPR ",HPR:6:4," TWR : ",TWR:6:4," hiTWR",hiTWR:6:4," bl ",biggestLoser);			end;//			print(iCnt," ",TWR," ",hiTWR);			IF(TWR>hiTWR) THEN			begin    			hiTWR = TWR;    			optF = fVal;    	// assign optF to fVal in case its the correct one					end			else    			break;                     //highest f found - stop looping		end;				If (TWR <= hiTWR or optF >= 0.999999) then		begin			TWR  = hiTWR;			OptimalFGeo = optF;  //assign optF to the name of the function		end;			gmean = power(TWR,(1.0 / tradeCnt));				if(optF<>0) then GAT   = (gMean - 1.0) * (biggestLoser / -(optF));				print(d," gmean ",gmean:6:4," ",GAT:6:4);  // I calculate the GMEAN and GeoAvgTrade	end;end;``
Optimal F Calculation by Ralph Vince code by George Pruitt

#### VBA version of Optimal F

For those of you who have a list of trades and want to see how this works in Excel here is the VBA code:

``Sub OptimalF()    Dim tradesArray(1000) As Double    i = 0    biggestLoser = 0#    Do While (Cells(3 + i, 1) <> "")        tradesArray(i) = Cells(3 + i, 1)        If tradesArray(i) < bigLoser Then biggestLoser = tradesArray(i)        i = i + 1    Loop    tradeCnt = i - 1    highI = 0    hiTWR = 0#    rc = 3    For fVal = 0.01 To 1 Step 0.01        TWR = 1#        For jCnt = 0 To tradeCnt            HPR = 1# + (fVal * (-1 * tradesArray(jCnt)) / biggestLoser)            TWR = TWR * HPR            Cells(rc, 5) = jCnt            Cells(rc, 6) = tradesArray(jCnt)            Cells(rc, 7) = HPR            Cells(rc, 8) = TWR            rc = rc + 1        Next jCnt        Cells(rc, 9) = fVal        Cells(rc, 10) = TWR        rc = rc + 1        If (TWR > hiTWR) Then            hiTWR = TWR            optF = fVal        Else            Exit For        End If    Next fVal    If (TWR <= hiTWR Or optF >= 0.999999) Then        TWR = hiTWR        OptimalFGeo = optF    End If    Cells(rc, 8) = "Opt f"    Cells(rc, 9) = optF    rc = rc + 1    gMean = TWR ^ (1# / (tradeCnt + 1))    If (optF <> 0) Then GAT = (gMean - 1#) * (biggestLoser / -(optF))    Cells(rc, 8) = "Geo Mean"    Cells(rc, 9) = gMean    rc = rc + 1    Cells(rc, 8) = "Geo Avg Trade"    Cells(rc, 9) = GATEnd Sub``
VBA code for Optimal F

I will attach the eld and .xlsm file a little later.

# Function Variable Data Survives Between Calls

### Function Variable Data Survives from One Call to the Next – A Pretty Nifty Tool in EasyLanguage!

Creating a function that can store data and then have that data survive on successive function calls without having to pass information back and forth is really a cool and powerful tool in EasyLanguage.  In most programming languages, the variables defined in a function are local to that particular bit of code and once program execution exits the function, then the data is destroyed.  There are two exceptions (in other languages) that come to mind – if the variable is passed back and forth via their addresses, then the data can be maintained or if the variable is global in scope to the function and the calling program.  EasyLanguage prevents you from having to do this and this can definitely save on headaches.  I wrote a function that defines an array that will hold a list of trades.  Once the number of trades reaches a certain level, I then calculate a moving average of the last 10 trades.  The average is then passed back to the calling strategy.  Here is the simple code to the function.

``{Function Name:   StoreTradesFunc by George Pruitt}{Function to Calculate the average trade for past N trades. ---------------------------------------------------------- Function remembers the current trade count in tradeCnt. It also remembers the values in the array tradesArray. It does this between function calls.  Values - simple and array - undoubtedly are global to the function} input: avgTradeCalcLen(numericSimple);vars: totalTradesCount(0),tradeCnt(0);array: tradesArray(0);totalTradesCount = totalTrades;If totalTradesCount > totalTradesCount thenbegin	tradeCnt = tradeCnt + 1;	tradesArray[tradeCnt] = positionProfit(1);//	print("Storing data ",tradesArray[tradeCnt]," ",tradeCnt);end;If totalTrades > avgTradeCalcLen thenbegin	Value2 = 0;	For value1 = totalTrades downTo totalTrades - avgTradeCalcLen	begin		Value2 = value2 + tradesArray[value1];	end;	print("Sum of last 10 Trades: ",value2);	StoreTradesFunc = value2/avgTradeCalcLen;end;``
Store A List of Trades in a Function