[math] algorithm to establish value of parameter giving max value of equation

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[math] algorithm to establish value of parameter giving max value of equation

ahardy66

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.

Also apologies if this is the wrong list - I'm following the advice on
the commons-math proposal page which said to post here.

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?




Best regards
Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Luc Maisonobe
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];
          }
      }
      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.

Hope this helps,
Luc

>
>
>
>
> Best regards
> Adam
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Luc Maisonobe
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.
>
> Hope this helps,
> Luc
>
>>
>>
>>
>> Best regards
>> Adam
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Adam Hardy-7
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: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Luc Maisonobe
In reply to this post by ahardy66
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" <[hidden email]>
À: "Commons Users List" <[hidden email]>
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: [hidden email]
For additional commands, e-mail: [hidden email]


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Adam Hardy-7
[hidden email] on 29/05/08 10:24, wrote:

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

OK, great, I'll replace that. I'm just coding it now. The iteration count for
the solver is 7, which is great considering it would have been 22 by the brute
force algorithm, and potentially 100 with other data.



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Adam Hardy-7
Adam Hardy on 29/05/08 11:18, wrote:

> [hidden email] on 29/05/08 10:24, wrote:
>> 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;
>>   }
>>
>> }

By the way, why do you call the gradient result 'prime'?

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [math] algorithm to establish value of parameter giving max value of equation

Luc Maisonobe
Adam Hardy a écrit :

> Adam Hardy on 29/05/08 11:18, wrote:
>> [hidden email] on 29/05/08 10:24, wrote:
>>> 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;
>>>   }
>>>
>>> }
>
> By the way, why do you call the gradient result 'prime'?

It is a reference to the ' character. It is a classical notation in
math. See the corresponding article in Mathworld:
http://mathworld.wolfram.com/Prime.html

This has nothing to do with prime numbers.

Luc

>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]