Author: Copyright � 2009, ������� �������
!Control

This script is designed to synchronize visual elements on your trading charts across different windows or platforms. Essentially, it allows for a "mirroring" effect where objects created on one chart can be automatically replicated and updated on another.

How the Logic Works

The script functions by designating one terminal window as a Writer and others as Listeners. It uses a shared data file to facilitate this communication.

1. The Communication System

The script identifies whether it should act as a sender or receiver based on specific internal variables.

  • The Writer: This is the "source" chart. When you add, move, or modify an object (like a trend line, rectangle, or text label), the Writer captures all the details of that object.
  • The Listener: These are the "destination" charts. They constantly check the data file to see if there are any updates from the Writer.

2. Data Capturing (Writing)

When the script identifies itself as a Writer, it scans your current chart for all visual objects. It gathers detailed information about each one, including:

  • The unique name of the object.
  • The type of object (e.g., an arrow vs. a line).
  • Detailed coordinates and visual properties (colors, styles, sizes, etc.). This information is then saved into a shared text file.

3. Synchronization (Listening)

When the script acts as a Listener, it performs a continuous "check and update" loop:

  • Object Creation: If the Listener sees an object in the data file that doesn't exist on its current chart, it automatically creates it.
  • Property Updating: If the object already exists, the script compares the properties of the local object with the data from the Writer. If anything is different (like a moved price point or a changed color), the Listener updates the local object to match the source perfectly.
  • Cleanup: The script also performs a cleanup routine. If an object exists on the chart but is no longer present in the Writer's data file, it removes the "extra" object to ensure the charts remain identical.

4. Performance and Execution

The script runs in the background, checking for updates every second. It includes a refresh mechanism that tells the platform to redraw the screen immediately whenever an update occurs, ensuring that the visual changes appear seamless and near-instantaneous to the user.

Miscellaneous
Uses files from the file systemIt writes information to fileIt reads information from a file
22 Views
1 Downloads
0 Favorites
!Control
//+------------------------------------------------------------------+
//|                                                        Dupel.mq4 |
//|                                Copyright © 2009, Ñåðãååâ Àëåêñåé |
//|                                      mailto: profy.mql@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Ñåðãååâ Àëåêñåé"
#property link      "mailto: profy.mql@gmail.com"

int i, j, type, w;
string name, st, var;
int obj, fo;
double d;
bool b, bNeedUpdate;
int gType, sType;
string gText, sText;
double gProp[232], sProp[232];
string names[1000];
//------------------------------------------------------------------
int start()
{
	while(!IsStopped())
	{
		Sleep(1000);
		bNeedUpdate=false;
		//ñîõðàíÿåì
		var="DupelSync_"+Symbol()+Period();
		if (!GlobalVariableCheck("DupelSync")) GlobalVariableSet("DupelSync", 0); // ñîçäà¸ì, åñëè íåò
		if (!GlobalVariableCheck("DupelSync_"+Symbol()+Period())) GlobalVariableSet("DupelSync_"+Symbol()+Period(), -1); // ñîçäà¸ì, åñëè íåò

		if (GlobalVariableGet(var)>0) // åñëè ýòà âàëþòà ïèñàòåëü
		{
			Comment("writter");
			if (GlobalVariableSetOnCondition("DupelSync", 1, 0))
			{
				obj=FileOpen("DupelSync.txt", FILE_CSV|FILE_WRITE); 
				if (obj<0) { Print("Íå ñìîãëè çàïèñàòü!"); GlobalVariableSet("DupelSync", 0); continue; }
				FileSeek(obj, 0, SEEK_SET);
				for (i=0; i<ObjectsTotal(); i++) 
				{
					name=ObjectName(i); 
					if (ObjectFind(name)!=0) continue; // áåð¸ì òîëüêî ãëàâíîå îêíî
					FileWrite(obj, name);  // ñîõðàíèëè èìÿ
					FileWrite(obj, ObjectType(name)); // ñîõðàíèëè òèï
					FileWrite(obj, ObjectDescription(name));  // ñîõðàíèëè îïèñàíèå
					for (j=0; j<=16; j++) FileWrite(obj, DoubleToStr(ObjectGet(name, j), Digits));
					for (j=100; j<=103; j++) FileWrite(obj, DoubleToStr(ObjectGet(name, j), Digits));
					for (j=200; j<=203; j++) FileWrite(obj, DoubleToStr(ObjectGet(name, j), Digits));
					for (j=210; j<=231; j++) FileWrite(obj, DoubleToStr(ObjectGet(name, j), Digits));
				}
				FileClose(obj);
				GlobalVariableSet("DupelSync", 0);
			}
		}
		if (GlobalVariableGet(var)<=0)  // åñëè ýòà âàëþòà ÷èòàòåëü
		{
			Comment("lister");
			if (GlobalVariableSetOnCondition("DupelSync", 1, 0))
			{
				obj=FileOpen("DupelSync.txt", FILE_CSV|FILE_READ); 
				if (obj<0) { Print("íå ñìîãëè îòêðûòü"); GlobalVariableSet("DupelSync", 0); continue; }
				
				// ñðàâíèâàåì íàëè÷èå îáúåêòîâ
				w=0;
				FileSeek(obj, 0, SEEK_SET);
				while (!FileIsEnding(obj))  // ÷èòàåì äàííûå îáúåêòîâ èç ôàéëà
				{
					names[w]=FileReadString(obj); if (names[w]=="") break;
					w++;
					st=FileReadString(obj); // òèï îáúåêòà
					st=FileReadString(obj); // òåêñò
					for (j=0; j<=16; j++) st=FileReadString(obj); for (j=100; j<=103; j++) st=FileReadString(obj);
					for (j=200; j<=203; j++) st=FileReadString(obj); for (j=210; j<=231; j++) st=FileReadString(obj);
				}
				// ïðîõîäèì ïî òåêóùèì è ñðàâíèâàåì íàëè÷èå îáúåêòîâ
				for (i=0; i<ObjectsTotal(); i++)
				{
					b=true;
					name=ObjectName(i);  // ïîëó÷èëè èìÿ 
					if (ObjectFind(name)>0) continue; // åñëè îáúåêò íå íà ãëàâíîì ãðàôèêå, òî ïðîïóñêàåì
					for(j=0; j<w; j++) if (name==names[j]) b=false; // åñëè íàøëè îáúåêò, òî ïðîïóñêàåì
					if (b) { ObjectsDeleteAll(0, -1); bNeedUpdate=true; break; } // óäàëÿåì âñå ëèøíèå îáúåêòû
				}
				
				// òåïåðü êîïèðóåì ñâîéñòâà
				FileSeek(obj, 0, SEEK_SET);
				while (!FileIsEnding(obj))  // ÷èòàåì äàííûå îáúåêòîâ èç ôàéëà
				{
					b=false;
					name=FileReadString(obj); if (name=="") break; // èìÿ îáúåêòà
					gType=StrToInteger(FileReadString(obj));  // òèï îáúåêòà
					gText=FileReadString(obj);  // òåêñò îáúåêòà
					for (j=0; j<=16; j++) gProp[j]=StrToDouble(FileReadString(obj)); for (j=100; j<=103; j++) gProp[j]=StrToDouble(FileReadString(obj));
					for (j=200; j<=203; j++) gProp[j]=StrToDouble(FileReadString(obj)); for (j=210; j<=231; j++) gProp[j]=StrToDouble(FileReadString(obj));
					
					if (ObjectFind(name)<0) { ObjectCreate(name, gType, 0, 0, 0); b=true; bNeedUpdate=true; }
					else 
					{
						// áåð¸ì äàííûå
						sType=ObjectType(name);  // òèï îáúåêòà
						sText=ObjectDescription(name); // òåêñò îáúåêòà
						for (j=0; j<=16; j++) sProp[j]=ObjectGet(name, j); for (j=100; j<=103; j++) sProp[j]=ObjectGet(name, j);
						for (j=200; j<=203; j++) sProp[j]=ObjectGet(name, j); for (j=210; j<=231; j++) sProp[j]=ObjectGet(name, j);
						if (IsDifObject()) { b=true; bNeedUpdate=true; }// åñëè îáúåêòû îòëè÷àþòñÿ, òî áóäåì îáíîâëÿòü
					}
					if (b)
					{
						ObjectSetText(name, gText); 
						for (j=0; j<=16; j++) ObjectSet(name, j, gProp[j]); for (j=100; j<=103; j++) ObjectSet(name, j, gProp[j]);
						for (j=200; j<=203; j++) ObjectSet(name, j, gProp[j]); for (j=210; j<=231; j++) ObjectSet(name, j, gProp[j]);
					}
				}

				FileClose(obj); // çàêðûëè ôàéë
				GlobalVariableSet("DupelSync", 0); // ðàçðåøèëè ðàáîòó ñ ôàéëîì
				if (bNeedUpdate) WindowRedraw(); // ïåðåðèñîâàëè
			}
		}
	}
	return(0);
}
//+------------------------------------------------------------------+
bool IsDifObject()
{
	int j;
	if (gType!=sType) return (true);
	if (gText!=sText) return (true);
	for (j=0; j<=16; j++) if (gProp[j]!=sProp[j]) return (true);
	for (j=100; j<=103; j++) if (gProp[j]!=sProp[j]) return (true);
	for (j=200; j<=203; j++) if (gProp[j]!=sProp[j]) return (true);
	for (j=210; j<=231; j++) if (gProp[j]!=sProp[j]) return (true);
}

Comments