commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From luc.maison...@free.fr
Subject Re: [math] algorithm to establish value of parameter giving max value of equation
Date Thu, 29 May 2008 09:24:48 GMT
Hi,

In the previous message, I called twr what was really twrPrime, and I used a too slow method
to compute it with a double loop. Here is a much simpler and faster way to compute this derivative:

public class TwrDerivative implements UnivariateRealFunction {

  private final double[] a;

  public TwrDerivative(double[] pl, double[] b) {
    a = new double[pl.length];
    for (int i = 0; i < a.length; ++i) {
      a[i] = pl[i] / b[i];
    }
  }

  public double value(double f) {
    double twr      = 1;
    double twrPrime = 0;
    for (int i = 0; i < a.length; ++i) {
      double factor = 1 + a[i] * f;
      twrPrime = twrPrime * factor + twr * a[i];
      twr     *= factor;
    }
    return twrPrime;
  }

}

Luc

----- Mail Original -----
De: "Adam Hardy" <adam.ts@cyberspaceroad.com>
À: "Commons Users List" <user@commons.apache.org>
Envoyé: Jeudi 29 Mai 2008 01:05:05 GMT +01:00 Amsterdam / Berlin / Berne / Rome / Stockholm
/ Vienne
Objet: Re: [math] algorithm to establish value of parameter giving max value of equation

Luc Maisonobe on 28/05/08 20:21, wrote:
> Luc Maisonobe a écrit :
>> Adam Hardy wrote:
>>> Please excuse my ignorance to begin with, it's been years since my last
>>> mathematics or statistics class in school. I looked through the user
>>> guide on commons.apache.org but I was struggling with the terminology,
>>> and had a hard time figuring out whether I could find what I'm looking for.
>> No problem.
>>
>>> Also apologies if this is the wrong list - I'm following the advice on
>>> the commons-math proposal page which said to post here.
>> This is the right list.
>>
>>> I have two equations:
>>>
>>> HPR = (( profit_loss / biggest_loss ) * f ) + 1
>>>
>>> where HPR = 'holding period return' (percent gain)
>>> profit_loss = dollar win (or loss if negative)
>>> biggest_loss = worst loss (given beforehand)
>>> and f = 'fixed fraction' (to optimize)
>>>
>>> TWR = product of all HPRs for a series of profits and losses from a
>>> financial trading or gambling system for value of f
>>>
>>> Solving this by "brute force", I would find the value of 'f' by
>>> incrementing up from 0.01 in steps of perhaps 0.01 and solving TWR for
>>> each value until TWR peaks.
>>>
>>> Fortunately it will always peak before f reaches 1.0.
>>>
>>> Would it be possible to use part of commons-math to do this rather than
>>> writing loops within loops to iterate the profits and losses and then
>>> the f-values?
>> In mathematical terms, your TWR computation is univariate function, i.e.
>> a function of one parameter: the f value. You want to find the value of
>> the parameter for which the function reaches an extremum.
>>
>> In this case (only one parameter), the simplest way to solve it is to
>> find for which value of f the slope of the function changes from
>> increasing to decreasing. The slope is the "derivative" of the function,
>> it is positive when the function is increasing, negative when the
>> function is decreasing and zero when the function is at an extremum. The
>> derivative of a function is often noted by adding a ' character after
>> the name of the function.
>>
>> In other words, you need to solve the equation TWR'(f) = 0
>>
>> The part of [math] that can help you is the analysis package, and the
>> solvers it provides.
>>
>> You start by implementing the function you want to solve (here the
>> derivative of TWR) as a class implementing the UnivariateRealFunction
>> interface. Here are the equations you need in your case:
>>
>> compute each HPR and put them in an array:
>>   hpr[i] = 1 + f * pl[i] / b[i];
>> compute the derivative of each HPR and put them in another array:
>>   hprPrime[i] = pl[i] / b[i];
>> compute the derivative of TWR as follows:
>>   double twr = 0;
>>   for (int i = 0; i < hprPrime.length; ++i) {
>>       double d = hprPrime[i];
>>       for (int j = 0; j < hpr.length; ++j) {
>>           if (j != i) {
>>               d *= hpr[i];
> 
> there is an error here, it should be:
>    d *= hpr[j];
> 
> 
> sorry
> 
> 
>>           }
>>       }
>>       twr += d;
>>   }
>>   return twr;
>>
>> Then you provide an instance of the class implementing this equation to
>> the constructor of a solver (say the BrentSolver for instance, it is a
>> good one). Call the solve method of the solver with the parameters 0.0
>> and 1.0 to search the solution of the equation in the [0.0, 1.0]
>> interval. This method will call your class several times, searching for
>> the solution until it converges to a small interval around the solution.
>> You can tune the solver by calling some tuning methods before you call
>> solve. You can for example change the convergence threshold (see the
>> methods in the UnivariateRealSolver interface this solver implements).
>>
>> Beware that if the derivative increases (or decreases) at both ends of
>> the interval you provide to the solve method, the solver will complain
>> that this interval does not bracket a zero. In your case, this will for
>> example happen if the pl and b arrays contain only one element.
>>
>> Beware also that what this method will find is an extremum ... which may
>> be a minumum and not a maximum if the function decreases first and
>> increases afterwards. This may not be what you want.
>>
>> I advise you to check this does work and that this leads to the right
>> solution (you can plot a few points around the solution found, to check
>> it). I have just written this mail in a hurry and may well be wrong on
>> the algorithm to compute the derivative for your function.


Hi Luc,

thanks v. much for the advice. That should enable me to get a long way with 
this. I will of course test as thoroughly as I can.

Best regards
Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Mime
View raw message