概述
所有交易员都希望尽可能最大限度地提高投资回报率,但更高的回报率通常会带来更高的风险。这就是为什么风险调整后的回报是衡量投资行业业绩的主要指标的原因。风险调整收益有许多不同的衡量标准,每一种都有自己的优点和缺点。夏普比率是一种流行的风险收益衡量标准,以对所分析的收益分配强加不切实际的先决条件而闻名。这不可避免地导致了替代性能指标的发展,这些指标试图提供夏普比率的同样普遍性,而不存在其不足之处。在本文中,我们提供了替代风险回报指标的实现,并生成假设的权益曲线来分析其特征。
模拟权益曲线
为了确保可解释性,我们将使用标普500指数数据作为模拟交易策略的基础。我们不会使用任何特定的交易规则,而是使用随机数来生成权益曲线和相应的收益序列。初始资本将标准化为可配置的金额。随机数将由一个种子定义,这样任何想复制实验的人都可以这样做。
净利润 Burke 比率实现为netprofit_Burke()函数。该函数需要一组描述净值曲线的净值数值,以及一个表示计算中要考虑的最高回撤次数的整数值。
//+------------------------------------------------------------------+
//|Net profit based Burke ratio |
//+------------------------------------------------------------------+
double netprofit_burke(double &in_ec[],int n_highestdrawdowns=0)
{
double outdd[];
double sumdd=0;
int insize=ArraySize(in_ec);
if(n_highestdrawdowns<=0)
n_highestdrawdowns=int(insize/20);
if(MaxNDrawdowns(n_highestdrawdowns,in_ec,outdd))
{
for(int i=0; i<ArraySize(outdd); i++)
{
sumdd+=(outdd[i]*outdd[i]);
}
return (in_ec[insize-1]-in_ec[0])/(MathSqrt((1.0/double(insize)) * sumdd));
}
else
return 0;
}
当指定默认值为零时,函数使用公式N/20设置要考虑的回撤次数,其中N是权益数组的大小。
为了收集指定数量的回撤,将调用MaxNDradowns()函数。它输出一系列按升序排列的最高绝对回撤。
//+------------------------------------------------------------------+
//|Maximum drawdowns function given equity curve |
//+------------------------------------------------------------------+
bool MaxNDrawdowns(const int num_drawdowns,double &in_ec[],double &out_dd[])
{
ZeroMemory(out_dd);
ResetLastError();
if(num_drawdowns<=0)
{
Print("Invalid function parameter for num_drawdowns ");
return false;
}
double u[],v[];
int size = ArraySize(in_ec);
if((ArrayResize(v,(size*(size-1))/2)< int((size*(size-1))/2))||
(ArraySize(out_dd)!=num_drawdowns && ArrayResize(out_dd,num_drawdowns)<num_drawdowns))
{
Print(__FUNCTION__, " resize error ", GetLastError());
return false;
}
int k=0;
for(int i=0; i<size-1; i++)
{
for(int j=i+1; j<size; j++)
{
v[k]=in_ec[i]-in_ec[j];
k++;
}
}
ArraySort(v);
for(int i=0; i<k; i++)
{
if(v[i]>0)
{
if(i)
{
if(!ArrayRemove(v,0,i))
{
Print(__FUNCTION__, " error , ArrayRemove: ",GetLastError());
return false;
}
else
break;
}
else
break;
}
}
size=ArraySize(v);
if(size && size<=num_drawdowns)
{
if(ArrayCopy(out_dd,v)<size)
{
Print(__FUNCTION__, " error ", GetLastError());
return false;
}
else
return (true);
}
if(ArrayCopy(out_dd,v,0,size-num_drawdowns,num_drawdowns)<num_drawdowns)
{
Print(__FUNCTION__, " error ", GetLastError());
return false;
}
return(true);
}
使用平均收益作为分子的Burke比率计算被实现为 meanreturns_Burke 函数,并且具有类似的输入参数。
//+------------------------------------------------------------------+
//|Mean return based Burke ratio |
//+------------------------------------------------------------------+
double meanreturns_burke(double &in_ec[],int n_highestdrawdowns=0)
{
double outdd[];
double rets[];
double sumdd=0;
int insize=ArraySize(in_ec);
if(ArrayResize(rets,insize-1)<insize-1)
{
Print(__FUNCTION__," Memory allocation error ",GetLastError());
return 0;
}
for(int i=1; i<insize; i++)
rets[i-1] = (in_ec[i]/in_ec[i-1]) - 1.0;
if(n_highestdrawdowns<=0)
n_highestdrawdowns=int(insize/20);
if(MaxNDrawdowns(n_highestdrawdowns,in_ec,outdd))
{
for(int i=0; i<ArraySize(outdd); i++)
sumdd+=(outdd[i]*outdd[i]);
return MathMean(rets)/(MathSqrt((1.0/double(insize)) * sumdd));
}
else
return 0;
}