MQL语言(用于MT4平台的C语言),K线形态的一部分:
//谷始形态: input bool Show6points = false;//是否显示低1高2低3这些谷形态点 input double param_1_1 = 11;//高2-低1 >= 任意数,确定高2 input double param_s_1_2_1 = 11;//绝对值(高2-低1) < ,较高者为低1; input double param_s_1_2_2 = -11;//高2-低1 <= ,高度差很大高2为低3,低1为高2 struct ShapePoint{ int k_index; datetime k_time; double k_price; }; struct SingalShape{ ShapePoint point1; ShapePoint point2; ShapePoint point3; ShapePoint point4; ShapePoint point5; ShapePoint point6; bool comfirmed_1; bool comfirmed_2; bool comfirmed_3; bool comfirmed_4; bool comfirmed_5; bool comfirmed_6; }; SingalShape temp_Valley_shapes;//谷的分身形态(在定型函数里用到) //标识一下高6是否生成过。 bool point6_enable = false;//point6是否存在 bool first_check = false;//第一次加载也是point1没有经过确定 // 2.谷始,谷的存储数组 ShapePoint valleys_start[];//谷始 ShapePoint valleys_bottom_ik[];//谷虚底 ShapePoint valley_M; bool point_M_enable = false;//M点是否存在 ShapePoint valley_M_group[]; ShapePoint valley_IM_points[]; //记录是否规则越界 bool IsOverRules = false; //1. 判断指定K线的状态 int K_ShapesCheck(const string t_symbol,const int k_index){ int ret_value=0; if(iOpen(t_symbol,0,k_index)<=iClose(t_symbol,0,k_index)){ ret_value=1; } else{ ret_value=-1; } return ret_value; } //4. 获取指定K线的底部数据 double Check_K_Bottom(const string t_symbol,const int k_index){ double ret_value = 0.0; if(K_ShapesCheck(t_symbol,k_index)==1){ ret_value = iOpen(t_symbol,0,k_index); } else{ ret_value = iClose(t_symbol,0,k_index); } return ret_value; } //5. 初始化形态类型变量 int ShapesInit(SingalShape &t_shapes){ t_shapes.comfirmed_1 = false; t_shapes.comfirmed_2 = false; t_shapes.comfirmed_3 = false; t_shapes.comfirmed_4 = false; t_shapes.comfirmed_5 = false; t_shapes.comfirmed_6 = false; SignalPointInit(t_shapes.point1); SignalPointInit(t_shapes.point2); SignalPointInit(t_shapes.point3); SignalPointInit(t_shapes.point4); SignalPointInit(t_shapes.point5); SignalPointInit(t_shapes.point6); return 0; } //5.1 初始化单点变量 int SignalPointInit(ShapePoint &t_point){ t_point.k_index = -1; t_point.k_price = 0.0; t_point.k_time = 0; return 0; } void CopyShapePoint(ShapePoint &t_src, ShapePoint &t_dest){ t_dest.k_index = t_src.k_index; t_dest.k_time = t_src.k_time; t_dest.k_price = t_src.k_price; } int CheckShapes_1(const int total_k_counts, const int end_k_index, SingalShape &t_V_shapes[]){ int ret_value = 0; int limit_total = 0; if(total_k_counts>2){ limit_total = total_k_counts-1; } else{ limit_total = total_k_counts; } for(int i=limit_total-1; i>=1; i--){ if(i<end_k_index){ break; } if(first_check==false){ SetPointValues(temp_Valley_shapes.point1,i); first_check==true; if(point6_enable==false){ continue; } } if((temp_Valley_shapes.comfirmed_1==false || temp_Valley_shapes.comfirmed_1==True) && temp_Valley_shapes.comfirmed_2==false && temp_Valley_shapes.comfirmed_6==false && point6_enable==false){ SetPointValues(temp_Valley_shapes.point2,i); if(NormalizeDouble(temp_Valley_shapes.point2.k.price-temp_Valley_shapes.point1.k.price,_Digits)>=NormalizeDouble(param_1_1*_Point,_Digits)){ temp_Valley_shapes.comfirmed_1 = true; temp_Valley_shapes.comfirmed_2 = true; continue; } else if(NormalizeDouble(MathAbs(temp_Valley_shapes.point2.k.price-temp_Valley_shapes.point1.k.price,_Digits))<NormalizeDouble(param_s_1_2_1*_Point,_Digits)){ if(temp_Valley_shapes.point1.k.price>temp_Valley_shapes.point2.k.price){ } else{ CopyShapePoint(temp_Valley_shapes.point2.k.price,temp_Valley_shapes.point1.k.price; } temp_Valley_shapes.comfirmed_1 = true; continue; } else if(NormalizeDouble(temp_Valley_shapes.point2.k.price-temp_Valley_shapes.point1.k.price,_Digits)<=NormalizeDouble(param_s_1_2_2*_Point,_Digits)){ CopyShapePoint(temp_Valley_shapes.point2.k.price,temp_Valley_shapes.point3.k.price); CopyShapePoint(temp_Valley_shapes.point1.k.price,temp_Valley_shapes.point2.k.price); temp_Valley_shapes.comfirmed_1 = true; temp_Valley_shapes.comfirmed_2 = true; temp_Valley_shapes.comfirmed_3 = true; if(temp_Valley_shapes.comfirmed_1==true && temp_Valley_shapes.comfirmed_2==true && temp_Valley_shapes.comfirmed_3==true){ PrintFormat("1:低5-高2-低3形态形成"); PrintFormat("低5 : k_index = %d ; k_time = %s ; k_price = %lf",temp_Valley_shapes.point5.k_index,TimeToString(temp_Valley_shapes.point5.k_time,TIME_DATE|TIME_SECONDS),temp_Valley_shapes.point5.k_price); PrintFormat("高2 : k_index = %d ; k_time = %s ; k_price = %lf",temp_Valley_shapes.point2.k_index,TimeToString(temp_Valley_shapes.point2.k_time,TIME_DATE|TIME_SECONDS),temp_Valley_shapes.point2.k_price); PrintFormat("低3 : k_index = %d ; k_time = %s ; k_price = %lf",temp_Valley_shapes.point3.k_index,TimeToString(temp_Valley_shapes.point3.k_time,TIME_DATE|TIME_SECONDS),temp_Valley_shapes.point3.k_price); } if(Show6points==true){ CreateText(temp_Valley_shapes.point5.k_time,text_pre,"低5",clrDeepPink,10,true,80); CreateText(temp_Valley_shapes.point2.k_time,text_pre,"高2",clrDeepPink,10,true,80); CreateText(temp_Valley_shapes.point3.k_time,text_pre,"低3",clrDeepPink,10,true,80); } int array_length = ArraySize(valleys_start); if(array_length==0){ ArrayResize(valleys_start,array_length+1); CopyShapePoint(temp_Valley_shapes.point2.k.price,valleys_start[array_length]); } else if(valleys_start[array_length-1].k_time!=temp_Valley_shapes.point2.k_time){ ArrayResize(valleys_start,array_length+1); CopyShapePoint(temp_Valley_shapes.point2.k.price,valleys_start[array_length]); } int array_length = ArraySize(valleys_bottom_ik); if(array_length>0){ int valley_start_length = ArraySize(valleys_start); if(valley_start_length>1){ int t_pre_index = iBarShift(_Symbol,0,valleys_start[valley_start_length-2].k_time); int t_curr_index = iBarShift(_Symbol,0,valleys_start[valley_start_length-1].k_time); Find_real_I(t_pre_index,t_curr_index,valley_IM_points); PrintFormat("time1=%s;time2=%s",TimeToString(valleys_start[valley_start_length-2].k_time,TIME_DATE|TIME_SECONDS), TimeToString(valleys_start[valley_start_length-2].k_time,TIME_DATE|TIME_SECONDS)); } if(ArraySize(valley_IM_points>0){ CopyShapePoint(valley_IM_points[0],valleys_bottom_ik[array_length-1]); } if(ArraySize(valley_IM_points>1) && valley_IM_points[0].k_time==valleys_start[valley_start_length-1].k_time){ CopyShapePoint(valley_IM_points[1],valley_M); point_M_enable = true; int array_M_group_counts = ArraySize(valley_M_group); ArrayResize(valley_M_group,array_M_group_counts+1); CopyShapePoint(valley_M_group,valley_M_group[array_M_group_counts]); } else{ point_M_enable = false; } } continue; } else{ IsOverRules = true; Alert("662: 程序测试数据已不在现有规则的控制范围","; time = ",iTime(_Symbol,0,i)); break } } //8. 设置点的值 void SetPointValues(ShapePoint &t_point, const int t_k_index){ t_point.k_index = t_k_index; t_point.k_price = Check_K_Bottom(_Symbol,t_k_index); t_point.k_time = iTime(_Symbol,0,t_k_index); } //找到最近的两个高2之间的真正I值 void Find_real_I(const int t_start_k, const int t_end_k, ShapePoint &virtual_points[]){ ShapePoint temp_point; int array_length = t_start_k-t_end_k+1; ArrayResize(virtual_points,array_length); for(int i=0; i<array_length; i++){ virtual_points[i].k_index = i+t_end_k; virtual_points[i].k_price = iLow(_Symbol,0,i+t_end_k); virtual_points[i].k_time = iTime(_Symbol,0,i+t_end_k); } for(int i=0; i<array_length-1; i++){ int k = i; for(int j=i+1; j<array_length; j++){ if(virtual_points[k].k_price>virtual_points[j].k_price){ k = j; } } if(k!=i){ CopyShapePoint(virtual_points[i],temp_point); CopyShapePoint(virtual_points[k],virtual_points[i]); CopyShapePoint(temp_point,virtual_points[k]); } } }