forked from rosh/MQL5Book
88 lines
3.4 KiB
MQL5
88 lines
3.4 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| ChartCloseIdle.mq5 |
| |
//| Copyright 2021, MetaQuotes Ltd. |
| |
//| https://www.mql5.com |
| |
//+------------------------------------------------------------------+
| |
#include "..\..\Include\Periods.mqh"
| |
#include "..\..\Include\MapArray.mqh"
| |
| |
#define PUSH(A,V) (A[ArrayResize(A, ArraySize(A) + 1) - 1] = V)
| |
| |
//+------------------------------------------------------------------+
| |
//| Script program start function |
| |
//+------------------------------------------------------------------+
| |
void OnStart()
| |
{
| |
MapArray<string,int> chartCounts;
| |
ulong duplicateChartIDs[];
| |
// collect duplicated idle charts
| |
if(ChartIdleList(chartCounts, duplicateChartIDs))
| |
{
| |
for(int i = 0; i < ArraySize(duplicateChartIDs); ++i)
| |
{
| |
const ulong id = duplicateChartIDs[i];
| |
// request the next idle chart to bring to front
| |
ChartSetInteger(id, CHART_BRING_TO_TOP, true);
| |
// refresh the windows, so the chart is actually brought to front
| |
ChartRedraw(id);
| |
// ask user confirmation for deletion
| |
const int button = MessageBox(
| |
"Remove idle chart: "
| |
+ ChartSymbol(id) + "/" + PeriodToString(ChartPeriod(id)) + "?",
| |
__FILE__, MB_YESNOCANCEL);
| |
if(button == IDCANCEL) break;
| |
if(button == IDYES)
| |
{
| |
ChartClose(id);
| |
}
| |
}
| |
}
| |
else
| |
{
| |
Print("No idle charts.");
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Main worker function to collect idle charts |
| |
//+------------------------------------------------------------------+
| |
int ChartIdleList(MapArray<string,int> &map, ulong &duplicateChartIDs[])
| |
{
| |
// keep enumerating all charts until no more found
| |
for(long id = ChartFirst(); id != -1; id = ChartNext(id))
| |
{
| |
// skip objects with charts
| |
if(ChartGetInteger(id, CHART_IS_OBJECT)) continue;
| |
| |
// obtain main properties of the chart
| |
const int win = (int)ChartGetInteger(id, CHART_WINDOWS_TOTAL);
| |
const string expert = ChartGetString(id, CHART_EXPERT_NAME);
| |
const string script = ChartGetString(id, CHART_SCRIPT_NAME);
| |
const int objectCount = ObjectsTotal(id);
| |
| |
// calculate number of indicators (if any)
| |
int indicators = 0;
| |
for(int i = 0; i < win; ++i)
| |
{
| |
indicators += ChartIndicatorsTotal(id, i);
| |
}
| |
| |
const string key = ChartSymbol(id) + "/" + PeriodToString(ChartPeriod(id));
| |
| |
if(map[key] == 0 // always count first time occurence of symbol/timeframe
| |
// otherwise count only empty charts:
| |
|| (indicators == 0 // no indicators
| |
&& StringLen(expert) == 0 // no expert
| |
&& StringLen(script) == 0 // no script
| |
&& objectCount == 0)) // no objects
| |
{
| |
const int i = map.inc(key);
| |
if(map[i] > 1) // duplicate
| |
{
| |
PUSH(duplicateChartIDs, id);
| |
}
| |
}
| |
}
| |
return map.getSize();
| |
}
| |
//+------------------------------------------------------------------+
|