Stocks News
Thread Swarm with leader and global variables, for 1 terminal – Analysis and Forecast – December 13, 2023
And that’s pretty much it
Attached is the test code for the indicator.
Please let me know if you find any issues.
#property indicator_chart_window #define SWARM_INDY_SHORTNAME "SwarmTest" #define SWARM_EA_NAME "SwarmTest" #define GVSS_NAME "SWARMGV" #define GVSS_LOCK GVSS_NAME+"_LOCK" #define GVSS_LEADER GVSS_NAME+"_LEADER" #define GVSS_LAST_CHECK_FOR_DATA_TIME GVSS_NAME+"_LAST_CHECK" #define GVSS_LAST_DATA_TIME GVSS_NAME+"_LAST_TIME" input long SecsForNewAnalysisCheck=60; int OnInit() SWU.reset(true,SWARM_INDY_SHORTNAME); SWU.setup(ChartID()); EventSetMillisecondTimer(1000); return(INIT_SUCCEEDED); 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()) return(rates_total); void OnTimer() SWU.swarm_maintain(); SWU.display_swarm(); class swarm_unit{ public: long chart_id; long leader_id; long others(); datetime last_check_for_data; datetime last_data_time; datetime last_update_time; swarm_unit(void)reset(); ~swarm_unit(void)reset(); void reset(bool is_indicator=false,string indyshortname=NULL) last_check_for_data=0; chart_id=-1; leader_id=-1; ArrayFree(others); if(is_indicator) IndicatorSetString(INDICATOR_SHORTNAME,indyshortname); void setup(long _id) chart_id=_id; void swarm_maintain(){ get_others_from_charts(); bool reLock=false; if(canOccupyGSVS(this,reLock)) if(reLock) LongToGV(GVSS_LOCK,chart_id); long new_leader=GvToLong(GVSS_LEADER); if(new_leader==0) leader_id=chart_id; LongToGV(GVSS_LEADER,chart_id); else bool is_on=false; for(int i=0;i<ArraySize(others);i++)if(others(i)==new_leader)is_on=true;break; if(is_on) leader_id=new_leader; else leader_id=chart_id; LongToGV(GVSS_LEADER,chart_id); if(chart_id==leader_id) last_check_for_data=(datetime)GvToLong(GVSS_LAST_CHECK_FOR_DATA_TIME); long elapsed=TimeGMT()-last_check_for_data; if(elapsed>=SecsForNewAnalysisCheck) bool gotnew=false; if(gotnew) last_data_time=last_check_for_data; LongToGV(GVSS_LAST_DATA_TIME,((long)last_data_time)); last_data_time=(datetime)GvToLong(GVSS_LAST_DATA_TIME); if(last_data_time>last_update_time) last_update_time=last_data_time; UnlockGVSS(); } void get_others_from_charts(){ ArrayFree(others); long read_chart=ChartFirst(); while(read_chart>=0){ bool has_swarm_unit=false; if(read_chart!=ChartID()&&read_chart!=0){ if(ChartGetString(read_chart,CHART_EXPERT_NAME)==SWARM_EA_NAME) has_swarm_unit=true; else int windows=(int)ChartGetInteger(read_chart,CHART_WINDOWS_TOTAL); for(int w=0;w<windows;w++) int indicators=ChartIndicatorsTotal(read_chart,w); for(int i=0;i<indicators;i++) string indicator_name=ChartIndicatorName(read_chart,w,i); if(indicator_name==SWARM_INDY_SHORTNAME) has_swarm_unit=true; break; if(has_swarm_unit)break; if(has_swarm_unit) add_to_others(read_chart); } if(read_chart!=0) read_chart=ChartNext(read_chart); else read_chart=ChartNext(ChartID()); } } void display_swarm() string swarmids="(SELF) "+IntegerToString(chart_id); if(leader_id==chart_id)swarmids+=" <LEADER>"; swarmids+="\n"; for(int i=0;i<ArraySize(others);i++) swarmids+="("+IntegerToString(i)+") "+IntegerToString(others(i)); if(others(i)==leader_id) swarmids+=" <LEADER>"; swarmids+="\n"; Comment(swarmids); string bool_to_string(bool _bool)if(_bool)return("True");return("False"); private: void add_to_others(long id) ArrayResize(others,ArraySize(others)+1,0); others(ArraySize(others)-1)=id; }; swarm_unit SWU; bool canOccupyGSVS(swarm_unit &self,bool &reLock){ reLock=true; long gv=GvToLong(GVSS_LOCK); if(gv>0) if(gv==ChartID())reLock=false;return(true); else reLock=false; for(int i=0;i<ArraySize(self.others);i++) if(self.others(i)==gv) return(false); reLock=true; return(true); return(true); } void UnlockGVSS() LongToGV(GVSS_LOCK,0); long GvToLong(string name) if(GlobalVariableCheck(name+"_A")&&GlobalVariableCheck(name+"_B")&&GlobalVariableCheck(name+"_AFrontDigits")&&GlobalVariableCheck(name+"_BFrontDigits")&&GlobalVariableCheck(name+"_ABackDigits")&&GlobalVariableCheck(name+"_BBackDigits")) int digits_front_a=(int)MathFloor(GlobalVariableGet(name+"_AFrontDigits")); int digits_back_a=(int)MathFloor(GlobalVariableGet(name+"_ABackDigits")); int digits_front_b=(int)MathFloor(GlobalVariableGet(name+"_BFrontDigits")); int digits_back_b=(int)MathFloor(GlobalVariableGet(name+"_BBackDigits")); long p1=(long)MathFloor(GlobalVariableGet(name+"_A")); long p2=(long)MathFloor(GlobalVariableGet(name+"_B")); return(assembleParts(p1,p2,digits_front_a,digits_back_a,digits_front_b,digits_back_b)); return(0); void LongToGV(string name,long value) long part_a=0,part_b=0; int part_a_front_digits=0,part_a_back_digits=0,part_b_front_digits=0,part_b_back_digits=0; long_to_parts(value,part_a,part_a_front_digits,part_a_back_digits,part_b,part_b_front_digits,part_b_back_digits); GlobalVariableSet(name+"_A",part_a); GlobalVariableSet(name+"_B",part_b); GlobalVariableSet(name+"_AFrontDigits",part_a_front_digits); GlobalVariableSet(name+"_ABackDigits",part_a_back_digits); GlobalVariableSet(name+"_BFrontDigits",part_b_front_digits); GlobalVariableSet(name+"_BBackDigits",part_b_back_digits); long assembleParts(long part_a, long part_b, int part_a_front_digits, int part_a_back_digits, int part_b_front_digits, int part_b_back_digits) string partA=longToStringWithDigits(part_a,part_a_front_digits,part_a_back_digits); string partB=longToStringWithDigits(part_b,part_b_front_digits,part_b_back_digits); string full=partA+partB; long result=(long)StringToInteger(full); return(result); string longToStringWithDigits(long l,int front_digits,int back_digits) string front=""; for(int i=0;i<front_digits;i++) front+="0"; string back=""; for(int i=0;i<back_digits;i++) back+="0"; string middle=IntegerToString(l); return(front+middle+back); void long_to_parts(long original, long &part_a, int &part_a_front_digits, int &part_a_back_digits, long &part_b, int &part_b_front_digits, int &part_b_back_digits) string full=IntegerToString(original); part_a=0; part_a_front_digits=0; part_a_back_digits=0; part_b=0; part_b_front_digits=0; part_b_back_digits=0; int alldigits=StringLen(full); int alength=(int)MathFloor(((double)alldigits)/((double)2.0)); int blength=alldigits-alength; string partA=StringSubstr(full,0,alength); string partB=StringSubstr(full,alength,blength); for(int i=0;i<alength;i++) string ch=StringSubstr(partA,i,1); if(ch=="0")part_a_front_digits++; elsebreak; for(int i=alength-1;i>=0;i--) string ch=StringSubstr(partA,i,1); if(ch=="0")part_a_back_digits++; elsebreak; for(int i=0;i<blength;i++) string ch=StringSubstr(partB,i,1); if(ch=="0")part_b_front_digits++; elsebreak; for(int i=blength-1;i>=0;i--) string ch=StringSubstr(partB,i,1); if(ch=="0")part_b_back_digits++; elsebreak; part_a=(long)StringToInteger(partA); part_b=(long)StringToInteger(partB); void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam) void OnDeinit(const int reason)