//----------------------------------------------------------------------------------------------- void calc_volatility(int param_bars, int param_counted_bars) { // Output: vols[] array // Compute volatility using log price differences. // Adapted by E Farrell 2013 // from code supplied by J Blackledge 2012 for (int i = param_counted_bars; i >= 0; i--) { double sumHat1 = 0; double sumHat2 = 0; if( i >= param_bars - Lookback ){ Print("setting vols to zero!"); vols[i] = 0; continue; } for (int j = i + Lookback - 2; j >= i; j--){ sumHat1 += MathPow( MathAbs( MathLog( Close[j] / Close[j+1] ) ), 2); sumHat2 += MathLog(Close[j]/Close[j+1]); } // Calculate Volatility sumHat1 = MathSqrt(sumHat1); sumHat2 = sumHat2 / MathSqrt(Lookback-1); vols[i] = sumHat1- sumHat2; if (DEBUG == 1) { // Output array values to Expert Log //Print("\t vols[\t", DoubleToStr(i,0), "\t] \t", DoubleToStr(vols[i],6)); //Print("\t Close[\t", DoubleToStr(i,0), "\t] \t", DoubleToStr(Close[i],6)); // Write values to debug file file_result = FileWrite (file_handle, "close", i, Close[i], "vols", i, vols[i]); } } }
//----------------------------------------------------------------------------------------------- void calc_alpha_volatility (double Input_Array[], int param_counted_bars) { // Calculate alpha index of vols[] // using least squares algorithm. // Adapted by E Farrell 2013 // source supplied by J Blackledge 2012 // initialize R & T ArrayResize(T,Lookback); ArrayResize(R,Lookback); // set up the T array for(int t = 1; t <= Lookback; t++) T[t-1] = MathLog(t); for(int i = phase_lookback; i >= 0; i--) { // Create autocorrelation array for R, // based on "Input_Array" BuildRArray (Lookback, i, Input_Array); // Calculate alpha index // of volatility levy_vol[i] = -GetHurstExponent(Lookback, T, R); if (DEBUG == 1) { // Output array values to Expert Log //Print("\t levy_vol[\t", DoubleToStr(i,0), "\t] \t", DoubleToStr(levy_vol[i],6)); file_result = FileWrite (file_handle, "levy_vol", i, levy_vol[i]); } } }
//----------------------------------------------------------------------------------------------- void BuildRArray (int Lookback, int startIndex, double Base_Array[]) { for(int t = startIndex; t <= Lookback + startIndex; t++) R[t-startIndex] = (MathLog(Base_Array[t])); }
// LCOV_EXCL_STOP ex_expr::exp_return_type ExFunctionMath::eval(char *op_data[], CollHeap *heap, ComDiagsArea** diagsArea) { ex_expr::exp_return_type retcode = ex_expr::EXPR_OK; short err = 0; errno = 0; if ((getOperand()) && (getOperand(0)->getDatatype() != REC_FLOAT64)) { return evalUnsupportedOperations(op_data, heap, diagsArea); } switch (getOperType()) { case ITM_DEGREES: // radians to degrees *(double *)op_data[0] = (*(double *)op_data[1] * 180E0) / PIVALUE; break; case ITM_PI: *(double *)op_data[0] = PIVALUE; break; case ITM_RADIANS: // degrees to radians *(double *)op_data[0] = (*(double *)op_data[1] / 180E0) * PIVALUE; break; case ITM_ROUND: { double op, res; short err1 = 0, err2 = 0, err3 = 0; Int32 roundTo; roundTo = (getNumOperands() > 2) ? (Int32)(*((double*)op_data[2])) : 0; switch (getOperand(1)->getDatatype()) { case REC_IEEE_FLOAT32: op = *((float*)op_data[1]); break; case REC_IEEE_FLOAT64: op = *((double*)op_data[1]); break; default: // LCOV_EXCL_START ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("ROUND"); return ex_expr::EXPR_ERROR; // LCOV_EXCL_STOP } // // For commenting purposes, assume the following: // // op = -12.58 // roundTo = 0 // // double pow1 = MathPow(10.0, roundTo, err1); // = 1 double pow2 = MathPow(10.0, -roundTo, err2); // = 1 double pow3 = MathPow(10.0, roundTo+1, err3); // = 10 double abs1 = (op < 0.0) ? -op : op; // = 12.58 double sign = (op < 0.0) ? -1.0 : 1.0; // = -1.0 double floor1 = MathFloor(abs1*pow3, err); // = 125 double floor2 = 10.0 * MathFloor(floor1 / 10.0, err); // = 120 double floor3 = floor1 - floor2; // = 5 double floor4 = MathFloor(abs1*pow1, err); // = 12 double floor5 = pow2 * sign; // = -1.0 // Is digit at rounding position less than 5? if (floor3 < 5.0) { res = floor4 * floor5; // = -12.0 } // Is digit at rounding position greater than 5? else if (floor3 > 5.0) { res = (floor4 + 1.0) * floor5; // = -13.0 } else { // Are digits after rounding position greater than 0? if (((abs1*pow3) - floor1) > 0.0) res = (floor4 + 1.0) * floor5; // = -13.0 else { double floor6 = 2.0 * MathFloor(floor4 / 2.0, err); // = 12.0 // Now round to even if ((floor4 - floor6) == 1.0) res = (floor4 + 1.0) * floor5; // = -13.0 else res = floor4 * floor5; // = -12.0 } } *(double *)op_data[0] = res; break; } case ITM_SCALE_TRUNC: { // LCOV_EXCL_START ExRaiseSqlError(heap, diagsArea, EXE_MATH_FUNC_NOT_SUPPORTED); if (getOperType() == ITM_ROUND) **diagsArea << DgString0("ROUND"); else **diagsArea << DgString0("TRUNCATE"); retcode = ex_expr::EXPR_ERROR; } break; // LCOV_EXCL_STOP case ITM_ACOS: if ((*(double *)op_data[1] < -1) || (*(double *)op_data[1] > 1)) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("ACOS"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathAcos(*(double *)op_data[1], err); break; case ITM_ASIN: if ((*(double *)op_data[1] < -1) || (*(double *)op_data[1] > 1)) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("ASIN"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathAsin(*(double *)op_data[1], err); break; case ITM_ATAN: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathAtan(*(double *)op_data[1], err); break; case ITM_ATAN2: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathAtan2(*(double *)op_data[1], *(double *)op_data[2], err); break; case ITM_CEIL: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathCeil(*(double *)op_data[1], err); break; case ITM_COS: *(double *)op_data[0] = MathCos(*(double *)op_data[1], err); break; case ITM_COSH: *(double *)op_data[0] = MathCosh(*(double *)op_data[1], err); if (*(double *)op_data[0] == HUGE_VAL) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("COSH"); return ex_expr::EXPR_ERROR; } break; case ITM_EXP: *(double *)op_data[0] = MathExp(*(double *)op_data[1], err); // Check for overflow. if (err) // if (*(double *)op_data[0] == HUGE_VAL_REAL64) { // Overflow ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("EXP"); return ex_expr::EXPR_ERROR; } break; case ITM_FLOOR: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathFloor(*(double *)op_data[1], err); break; case ITM_LOG: if (*(double *)op_data[1] <= 0) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("LOG"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathLog(*(double *)op_data[1], err); break; case ITM_LOG10: if (*(double *)op_data[1] <= 0) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("LOG10"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathLog10(*(double *)op_data[1], err); break; case ITM_SIN: *(double *)op_data[0] = MathSin(*(double *)op_data[1], err); break; case ITM_SINH: *(double *)op_data[0] = MathSinh(*(double *)op_data[1], err); if (*(double *)op_data[0] == HUGE_VAL) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("SINH"); return ex_expr::EXPR_ERROR; } break; case ITM_SQRT: if (*(double *)op_data[1] < 0) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("SQRT"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathSqrt(*(double *)op_data[1], err); break; case ITM_TAN: *(double *)op_data[0] = MathTan(*(double *)op_data[1], err); break; case ITM_TANH: // No error checks, all numeric values allowed. *(double *)op_data[0] = MathTanh(*(double *)op_data[1], err); break; case ITM_EXPONENT: case ITM_POWER: if (((*(double *)op_data[1] == 0) && (*(double *)op_data[2] <= 0)) || ((*(double *)op_data[1] < 0) && (MathFloor(*(double *)op_data[2], err) != *(double *)op_data[2]))) { ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("POWER"); return ex_expr::EXPR_ERROR; } *(double *)op_data[0] = MathPow(*(double *)op_data[1], *(double *)op_data[2], err); if (errno == ERANGE) { // Overflow ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC); **diagsArea << DgString0("POWER"); return ex_expr::EXPR_ERROR; } break; default: { ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR); retcode = ex_expr::EXPR_ERROR; } break; } return retcode; }