MQL4 中的皮尔逊相关系数是如何计算的?
How is the Pearson's Correlation calculated in MQL4?
为了轻松交易相关对 (hedge),我需要编写一个相关矩阵,例如 myfxbook 或 Oanda 上的那些。
要点是我希望能够遍历矩阵中的每个值并检查它是否大于 85.0 左右。
Q:
如何在 MQL4 中计算 Pearson 相关系数?
方法A:
使用MQL4
直接计算PearsonCorr_r
:
如果使用 double
的精度就足够了,MQL4
代码可以实现合理大小的值向量的过程 ( X[], Y[] )
#define RET_OK 0
#define RET_ERROR EMPTY
#define VAL_ERROR EMPTY_VALUE
int PearsonCorr_r( double const &vectorX[], // |-> INPUT X[] = { 1, 3, 5, 5, 6 }
double const &vectorY[], // |-> INPUT Y[] = { 5, 6, 10, 12, 13 }
double &pearson_r // <=| returns RESULT = 0.968
){
double sumX = 0,
meanX = 0,
meanY = 0,
sumY = 0,
sumXY = 0,
sumX2 = 0,
sumY2 = 0;
// deviation_score_x[], // may be re-used for _x^2
// deviation_score_y[], // may be re-used for _y^2
// deviation_score_xy[];
/* =====================================================================
DEVIATION SCORES >>> http://onlinestatbook.com/2/describing_bivariate_data/calculation.html
X[] Y[] x y xy x^2 y^2
1 4 -3 -5 15 9 25
3 6 -1 -3 3 1 9
5 10 1 1 1 1 1
5 12 1 3 3 1 9
6 13 2 4 8 4 16
_______________________________________
SUM 20 45 0 0 30 16 60
MEAN 4 9 0 0 6
r = SUM(xy) / SQRT( SUM( x^2 ) * SUM( y^2 ) )
r = 30 / SQRT( 960 )
r = 0.968
=====================================================================
*/
int vector_maxLEN = MathMin( ArrayRange( vectorX, 0 ),
ArrayRange( vectorY, 0 )
);
if ( vector_maxLEN == 0 ){
pearson_r = VAL_ERROR; // STOR VAL ERROR IN RESULT
return( RET_ERROR ); // FLAG RET_ERROR in JIT/RET
}
for ( int jj = 0; jj < vector_maxLEN; jj++ ){
sumX += vectorX[jj];
sumY += vectorY[jj];
}
meanX = sumX / vector_maxLEN; // DIV!0 FUSED
meanY = sumY / vector_maxLEN; // DIV!0 FUSED
for ( int jj = 0; jj < vector_maxLEN; jj++ ){
// deviation_score_x[ jj] = meanX - vectorX[jj]; //
// deviation_score_y[ jj] = meanY - vectorY[jj];
// deviation_score_xy[jj] = deviation_score_x[jj]
// * deviation_score_y[jj];
// sumXY += deviation_score_x[jj]
// * deviation_score_y[jj];
sumXY += ( meanX - vectorX[jj] ) // PSPACE MOTIVATED MINIMALISTIC WITH CACHE-BENEFITS IN PROCESSING
* ( meanY - vectorY[jj] );
// deviation_score_x[jj] *= deviation_score_x[jj]; // PSPACE MOTIVATED RE-USE, ROW-WISE DESTRUCTIVE, BUT VALUE WAS NEVER USED AGAIN
// sumX2 += deviation_score_x[jj]
// * deviation_score_x[jj];
sumX2 += ( meanX - vectorX[jj] ) // PSPACE MOTIVATED MINIMALISTIC WITH CACHE-BENEFITS IN PROCESSING
* ( meanX - vectorX[jj] );
// deviation_score_y[jj] *= deviation_score_y[jj]; // PSPACE MOTIVATED RE-USE, ROW-WISE DESTRUCTIVE, BUT VALUE WAS NEVER USED AGAIN
// sumY2 += deviation_score_y[jj]
// * deviation_score_y[jj];
sumY2 += ( meanY - vectorY[jj] ) // PSPACE MOTIVATED MINIMALISTIC WITH CACHE-BENEFITS IN PROCESSING
* ( meanY - vectorY[jj] );
}
pearson_r = sumXY
/ MathSqrt( sumX2
* sumY2
); // STOR RET VALUE IN RESULT
return( RET_OK ); // FLAG RET_OK in JIT/RET
方法 B:
在 R、MATLAB 等中重新使用具有 Pearson 相关性的外部库:
可以使用分布式处理,例如使用 ZeroMQ 消息传递基础设施来请求在 MQL4 之外/独立于本地主机处理执行微积分。
如果有兴趣,请阅读我的other posts on distributed processes in MQL4
( a code-example -- just to have some feeling of how the MQL4
side gets setup -- could be found here)
和 MATLAB
( ZeroMQ 基础设施设置的代码示例可以是 found here
从而允许使用 MATLAB 内置的 Pearson 相关性实现(请记住将数据正确地预先格式化为列,最好还添加一个 DIV!0
-融合 ), 计算:
[ RHO, PVAL ] = corr( vectorX, vectorY, 'type', 'Pearson' );
% note: double-r in corr()
% # 'Pearson' is default method
类似地,R
-语言有一个内置工具:
corr_r <- cor( vecORmatX, vecORmatY, use = "everything", method = "pearson" )
# "Pearson" is default method
最后但并非最不重要的是 python scipy.stats.stats pearsonr
-作为工具的实施,同时具有 float32
和float64
精度:
>>> from scipy.stats.stats import pearsonr as pearson_r
>>>
>>> X = np.zeros( (5,), dtype = np.float32 )
>>> Y = np.zeros( (5,), dtype = np.float32 )
>>>
>>> X[0] = 1; X[1] = 3; X[2] = 5; X[3] = 5; X[4] = 6
>>> Y[0] = 5; Y[1] = 6; Y[2] = 10; Y[3] = 12; Y[4] = 13
>>>
>>> pearson_r( X, Y)
(0.94704783, 0.01451040731338055)
>>>
>>> X = np.zeros( (5,), dtype = np.float64 )
>>> Y = np.zeros( (5,), dtype = np.float64 )
>>>
>>> X[0] = 1; X[1] = 3; X[2] = 5; X[3] = 5; X[4] = 6
>>> Y[0] = 5; Y[1] = 6; Y[2] = 10; Y[3] = 12; Y[4] = 13
>>>
>>> pearson_r( X, Y)
(0.94704783738690446, 0.014510403904375592)
>>>
结语:
方法 A 产生结果 == python.scipy.stats.stats.pearsonr(X,Y)
(即引用的 onlinestatbook.com 结果不准确 )
2016.10.13 11:31:55.421 ___Whosebug_Pearson_r_DEMO XAUUSD,H1:
PearsonCorr_r( testX, testY, Pearson_r ):= 0.968
The actual call returned aReturnCODE == 0,
whereas the Pearson_r == 0.9470
为了轻松交易相关对 (hedge),我需要编写一个相关矩阵,例如 myfxbook 或 Oanda 上的那些。
要点是我希望能够遍历矩阵中的每个值并检查它是否大于 85.0 左右。
Q:
如何在 MQL4 中计算 Pearson 相关系数?
方法A:
使用MQL4
直接计算PearsonCorr_r
:
如果使用 double
的精度就足够了,MQL4
代码可以实现合理大小的值向量的过程 ( X[], Y[] )
#define RET_OK 0
#define RET_ERROR EMPTY
#define VAL_ERROR EMPTY_VALUE
int PearsonCorr_r( double const &vectorX[], // |-> INPUT X[] = { 1, 3, 5, 5, 6 }
double const &vectorY[], // |-> INPUT Y[] = { 5, 6, 10, 12, 13 }
double &pearson_r // <=| returns RESULT = 0.968
){
double sumX = 0,
meanX = 0,
meanY = 0,
sumY = 0,
sumXY = 0,
sumX2 = 0,
sumY2 = 0;
// deviation_score_x[], // may be re-used for _x^2
// deviation_score_y[], // may be re-used for _y^2
// deviation_score_xy[];
/* =====================================================================
DEVIATION SCORES >>> http://onlinestatbook.com/2/describing_bivariate_data/calculation.html
X[] Y[] x y xy x^2 y^2
1 4 -3 -5 15 9 25
3 6 -1 -3 3 1 9
5 10 1 1 1 1 1
5 12 1 3 3 1 9
6 13 2 4 8 4 16
_______________________________________
SUM 20 45 0 0 30 16 60
MEAN 4 9 0 0 6
r = SUM(xy) / SQRT( SUM( x^2 ) * SUM( y^2 ) )
r = 30 / SQRT( 960 )
r = 0.968
=====================================================================
*/
int vector_maxLEN = MathMin( ArrayRange( vectorX, 0 ),
ArrayRange( vectorY, 0 )
);
if ( vector_maxLEN == 0 ){
pearson_r = VAL_ERROR; // STOR VAL ERROR IN RESULT
return( RET_ERROR ); // FLAG RET_ERROR in JIT/RET
}
for ( int jj = 0; jj < vector_maxLEN; jj++ ){
sumX += vectorX[jj];
sumY += vectorY[jj];
}
meanX = sumX / vector_maxLEN; // DIV!0 FUSED
meanY = sumY / vector_maxLEN; // DIV!0 FUSED
for ( int jj = 0; jj < vector_maxLEN; jj++ ){
// deviation_score_x[ jj] = meanX - vectorX[jj]; //
// deviation_score_y[ jj] = meanY - vectorY[jj];
// deviation_score_xy[jj] = deviation_score_x[jj]
// * deviation_score_y[jj];
// sumXY += deviation_score_x[jj]
// * deviation_score_y[jj];
sumXY += ( meanX - vectorX[jj] ) // PSPACE MOTIVATED MINIMALISTIC WITH CACHE-BENEFITS IN PROCESSING
* ( meanY - vectorY[jj] );
// deviation_score_x[jj] *= deviation_score_x[jj]; // PSPACE MOTIVATED RE-USE, ROW-WISE DESTRUCTIVE, BUT VALUE WAS NEVER USED AGAIN
// sumX2 += deviation_score_x[jj]
// * deviation_score_x[jj];
sumX2 += ( meanX - vectorX[jj] ) // PSPACE MOTIVATED MINIMALISTIC WITH CACHE-BENEFITS IN PROCESSING
* ( meanX - vectorX[jj] );
// deviation_score_y[jj] *= deviation_score_y[jj]; // PSPACE MOTIVATED RE-USE, ROW-WISE DESTRUCTIVE, BUT VALUE WAS NEVER USED AGAIN
// sumY2 += deviation_score_y[jj]
// * deviation_score_y[jj];
sumY2 += ( meanY - vectorY[jj] ) // PSPACE MOTIVATED MINIMALISTIC WITH CACHE-BENEFITS IN PROCESSING
* ( meanY - vectorY[jj] );
}
pearson_r = sumXY
/ MathSqrt( sumX2
* sumY2
); // STOR RET VALUE IN RESULT
return( RET_OK ); // FLAG RET_OK in JIT/RET
方法 B:
在 R、MATLAB 等中重新使用具有 Pearson 相关性的外部库:
可以使用分布式处理,例如使用 ZeroMQ 消息传递基础设施来请求在 MQL4 之外/独立于本地主机处理执行微积分。
如果有兴趣,请阅读我的other posts on distributed processes in MQL4
( a code-example -- just to have some feeling of how the MQL4
side gets setup -- could be found here)
和 MATLAB
( ZeroMQ 基础设施设置的代码示例可以是 found here
从而允许使用 MATLAB 内置的 Pearson 相关性实现(请记住将数据正确地预先格式化为列,最好还添加一个 DIV!0
-融合 ), 计算:
[ RHO, PVAL ] = corr( vectorX, vectorY, 'type', 'Pearson' );
% note: double-r in corr()
% # 'Pearson' is default method
类似地,R
-语言有一个内置工具:
corr_r <- cor( vecORmatX, vecORmatY, use = "everything", method = "pearson" )
# "Pearson" is default method
最后但并非最不重要的是 python scipy.stats.stats pearsonr
-作为工具的实施,同时具有 float32
和float64
精度:
>>> from scipy.stats.stats import pearsonr as pearson_r
>>>
>>> X = np.zeros( (5,), dtype = np.float32 )
>>> Y = np.zeros( (5,), dtype = np.float32 )
>>>
>>> X[0] = 1; X[1] = 3; X[2] = 5; X[3] = 5; X[4] = 6
>>> Y[0] = 5; Y[1] = 6; Y[2] = 10; Y[3] = 12; Y[4] = 13
>>>
>>> pearson_r( X, Y)
(0.94704783, 0.01451040731338055)
>>>
>>> X = np.zeros( (5,), dtype = np.float64 )
>>> Y = np.zeros( (5,), dtype = np.float64 )
>>>
>>> X[0] = 1; X[1] = 3; X[2] = 5; X[3] = 5; X[4] = 6
>>> Y[0] = 5; Y[1] = 6; Y[2] = 10; Y[3] = 12; Y[4] = 13
>>>
>>> pearson_r( X, Y)
(0.94704783738690446, 0.014510403904375592)
>>>
结语:
方法 A 产生结果 == python.scipy.stats.stats.pearsonr(X,Y)
(即引用的 onlinestatbook.com 结果不准确 )
2016.10.13 11:31:55.421 ___Whosebug_Pearson_r_DEMO XAUUSD,H1:
PearsonCorr_r( testX, testY, Pearson_r ):= 0.968
The actual call returned aReturnCODE == 0,
whereas the Pearson_r == 0.9470