//+------------------------------------------------------------------+ //| LoCo_SnR.mq5 | //| LoCo_SnR (Local Convex Hull SnR) Copyright 2017, fxborg | //| http://fxborg-labo.hateblo.jp/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2017, fxborg" #property link "http://fxborg-labo.hateblo.jp/" #property version "1.0" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #import "loco_snr.dll" int Create(double,double); int Push(int,int,double,double,datetime,datetime);// void Destroy(int); // int GetShiftCount(int,int); bool GetLast(int,int,int,int &x1,double &y1,bool &is_ex,int &x2,double &y2); // int PushTrend(int,const double x,const double y,int dir);// void ClearTrend(int,int dir);// bool GetTrend(int instance,double &x,double &a,double &b,double &r,int dir);// #import //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 #property indicator_type1 DRAW_ARROW #property indicator_color1 clrRed #property indicator_width1 1 #property indicator_type2 DRAW_ARROW #property indicator_color2 clrDodgerBlue #property indicator_width2 1 #property indicator_type3 DRAW_SECTION #property indicator_color3 clrSilver #property indicator_width3 1 #property indicator_style3 STYLE_DOT #property indicator_type4 DRAW_SECTION #property indicator_color4 clrSilver #property indicator_width4 1 #property indicator_style4 STYLE_DOT //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ input double InpScale=0.1; // Scale x input int InpArmCount=7; // Arm Count input bool InpShowLoCo=true; // Show Local Convex input int InpThreshold=250; // Threshold(in points) input int InpLookBack=400; // LookBack input int InpLineWidth=1; // Line Width input color InpColor=clrLightYellow; // Line Color double Threshold=InpThreshold*_Point; double ArmSize=InpScale*InpArmCount; int WinNo=ChartWindowFind(); double UPPER[]; double UPPER_TOP[]; double LOWER[]; double LOWER_BTM[]; int instance; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct PointType { int x; double y; }; double upper[][2]; double lower[][2]; PointType NullPoint; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { ObjectDeleteByName("LoCoSnR"); if(InpShowLoCo) { PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ARROW); PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_ARROW); PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_SECTION); PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_SECTION); } else { PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_NONE); PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE); PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE); PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_NONE); } SetIndexBuffer(0,UPPER_TOP,INDICATOR_DATA); SetIndexBuffer(1,LOWER_BTM,INDICATOR_DATA); SetIndexBuffer(2,UPPER,INDICATOR_DATA); SetIndexBuffer(3,LOWER,INDICATOR_DATA); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE); instance=Create(InpScale,ArmSize); //インスタンスを生成 NullPoint.x=0; NullPoint.y=0; return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Destroy(instance); //インスタンスを破棄 ObjectDeleteByName("LoCoSnR"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { for(int i=(int)MathMax(prev_calculated-1,0); i0) ? time[i-1]: 0; int n=Push(instance,i,high[i],low[i],time[i],prev); if(n == 0 )continue; if(n<0) { ArrayResize(upper,0); ArrayResize(lower,0); Print(n," ------------- Reset --------------- ",time[i]); Destroy(instance); //インスタンスを破棄 instance=Create(InpScale,ArmSize); //インスタンスを生成 return 0; } //-------------------------------------------------- // UPPER //-------------------------------------------------- PointType h1,h2,l1,l2; bool h1_top; bool l1_btm; int h_push_sz=GetShiftCount(instance,1); int l_push_sz=GetShiftCount(instance,-1); PointType new_up=NullPoint; PointType new_dn=NullPoint; double temp_h[][2]; double temp_l[][2]; ArrayResize(temp_h,0); ArrayResize(temp_l,0); if(h_push_sz>0) { for(int k=h_push_sz-1;k>=0;k--) { if(GetLast(instance,1,k,h1.x,h1.y,h1_top,h2.x,h2.y)) { if(h1_top) { UPPER_TOP[h1.x]=h1.y; PushPoint(temp_h,h1.x,h1.y); } UPPER[h1.x]=h1.y; } } } if(l_push_sz>0) { for(int k=l_push_sz-1;k>=0;k--) { if(GetLast(instance,-1,k,l1.x,l1.y,l1_btm,l2.x,l2.y)) { if(l1_btm) { LOWER_BTM[l1.x]=l1.y; PushPoint(temp_l,l1.x,l1.y); } LOWER[l1.x]=l1.y; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ if(h_push_sz>0 || l_push_sz>0) { int h_sz=ArrayRange(temp_h,0); int l_sz=ArrayRange(temp_l,0); int h_idx=-1; int l_idx=-1; while(h_idx0 && l_idx>0) { if(upper[h_idx][1]>limit) { PushHist(hist_h,upper[h_idx][0]); --h_idx; } if(lower[l_idx][1]>limit) { PushHist(hist_l,lower[l_idx][0]); --l_idx; } if(upper[h_idx][1]<=limit && lower[l_idx][1]<=limit) break; } ArraySort(hist_h); ArraySort(hist_l); h_sz=ArrayRange(hist_h,0); l_sz=ArrayRange(hist_l,0); if(h_sz<5 || h_sz<5) { ObjectDeleteByName("LoCoSnR"); continue; } double hist_max=hist_h[h_sz-1]; double hist_min=hist_l[0]; double prev_h=hist_h[h_sz-1]; double resi=hist_h[h_sz-1]; double prev_l=hist_l[0]; double supp=hist_l[0]; int cnt=1; //Print("------------------ high -----------------"); //for(int j=h_sz-1;j>=0;j--) // { // Print(j,",",hist_h[j]); // } //Print("------------------ low -----------------"); //for(int j=l_sz-1;j>=0;j--) // { //Print(j,",",hist_l[j]); // } Print("Threshold:",Threshold); Print("------------------ high -----------------"); for(int j=h_sz-2;j>=0;j--) { Print(prev_h," - ",hist_h[j]," = ",prev_h-hist_h[j]); if((prev_h-hist_h[j])<=Threshold) { prev_h=hist_h[j]; cnt++; } else { PushGroup(group_h,hist_h[j+1],resi,cnt); cnt=1; resi=hist_h[j]; prev_h=hist_h[j]; } } Print("------------------ low -----------------"); cnt=1; for(int j=1;j2) { //ng ->skip continue; } } //ok ->push no++; ArrayResize(arr_snr,no); arr_snr[no-1]=resi; } Print("------------------ low -----------------"); h_idx=ArrayRange(group_h,0)-1; for(int j=0;j2) { //ng ->skip continue; } } //ok ->push no++; ArrayResize(arr_snr,no); arr_snr[no-1]=supp; } ObjectDeleteByName("LoCoSnR"); if(no>0) { for(int j=0;j=0;--i) { if(group[i][0]=0;--i) { if(group[i][1]>supp) return i; } return -1; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int last_max(const double &arr[][2],const int period) { int sz=ArrayRange(arr,0); if(sz < period)return -1; return ArrayMaximum(arr,sz-(period),period); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int last_min(const double &arr[][2],const int period) { int sz=ArrayRange(arr,0); if(sz < period)return -1; return ArrayMinimum(arr,sz-(period),period); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int PushPoint(double &arr[][2],const int x,const double y) { int sz=ArrayRange(arr,0)+1; ArrayResize(arr,sz); arr[sz-1][1]=x; arr[sz-1][0]=y; return sz; } //+------------------------------------------------------------------+ int PushHist(double &arr[],const double y) { int sz=ArrayRange(arr,0)+1; ArrayResize(arr,sz); arr[sz-1]=y; return sz; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int PushGroup(double &arr[][3],const double min,const double max,const int cnt) { int sz=ArrayRange(arr,0)+1; ArrayResize(arr,sz); arr[sz-1][0]=min; arr[sz-1][1]=max; arr[sz-1][2]=cnt; return sz; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ObjectDeleteByName(string prefix) { int total=ObjectsTotal(0), length=StringLen(prefix); for(int i=total-1; i>=0; i--) { string objName=ObjectName(0,i); if(StringSubstr(objName,0,length)==prefix) { ObjectDelete(0,objName); } } } //+------------------------------------------------------------------+