#property copyright "Scriptong"
#property link "http://advancetools.net"
#property description "Ñîçäàíèå ôàéëà äëÿ òåñòåðà ñòðàòåãèé ÌÒ4 èç ôàéëà äàííûõ î ðåàëüíîì òèêîâîì ïîòîêå.\nÎïèñàíèå äîñòóïíî íà ñàéòå AdvanceTools.net â ñòàòüå \"Òåñòèðîâàíèå íà ðåàëüíîé èñòîðèè.\""
#property version "1.00"
#property strict
#property show_inputs
input datetime i_startDate = D'2014.07.28 00:00:00'; // Íà÷àëüíàÿ äàòà/âðåìÿ ïåðèîäà òåñòèðîâàíèÿ
input datetime i_endDate = D'2014.07.29 00:00:00'; // Êîíå÷íàÿ äàòà/âðåìÿ ïåðèîäà òåñòèðîâàíèÿ
input uint i_minPreviousBars = 1000; // Êîëè÷åñòâî áàðîâ äî íà÷àëà òåñòèðîâàíèÿ
input uint i_spread = 0; // Ñïðåä â ïóíêòàõ
string g_ticksFileName; // Èìÿ òèêîâîãî ôàéëà
ENUM_TIMEFRAMES g_tf; // Òàéìôðåéì ãðàôèêà â ìèíóòàõ
int g_periodSeconds, // Êîëè÷åñòâî ñåêóíä â îäíîé ñâå÷å òåêóùåãî òàéìôðåéìà
g_startPrevBar, // Èíäåêñ áàðà, ñ êîòîðîãî íà÷èíàåòñÿ çàïèñü èñòîðèè, ïðåäøåñòâóþùåé äàòå íà÷àëà òåñòèðîâàíèÿ
g_endPrevBar; // Èíäåêñ áàðà, íåïîñðåäñòâåííî ïðåäøåñòâóþùèé äàòå íà÷àëó òåñòèðîâàíèÿ
#import "kernel32.dll"
bool CopyFileW(string sourceFileName, string destinationFileName, bool bFailIfExists);
uint GetFileAttributesW(string fileName);
bool SetFileAttributesW(string fileName, int newAttributes);
#import
#define INVALID_FILE_ATTRIBUTES UINT_MAX // Îøèáêà ïðè ïîëó÷åíèè àòðèáóòîâ ôàéëà
#define FILE_ATTRIBUTE_READONLY 0x01 // Àòðèáóò "Read Only"
struct TestHistoryHeader
{
int version; // 405
char copyright[64]; // copyright
char description[128]; // server name
// 196
char symbol[12];
int period;
int model; // for what modeling type was the ticks sequence generated
int bars; // amount of bars in history
int fromdate;
int todate;
int totalTicks;
double modelquality; // modeling quality
// 240
//---- general parameters
char currency[12]; // currency base
int spread;
int digits;
int unknown1;
double point;
int lot_min; // minimum lot size
int lot_max; // maximum lot size
int lot_step;
int stops_level; // stops level value
int gtc_pendings; // instruction to close pending orders at the end of day
// 292
//---- profit calculation parameters
int unknown2;
double contract_size; // contract size
double tick_value; // value of one tick
double tick_size; // size of one tick
int profit_mode; // profit calculation mode { PROFIT_CALC_FOREX, PROFIT_CALC_CFD, PROFIT_CALC_FUTURES }
// 324
//---- swap calculation
int swap_enable; // enable swap
int swap_type; // type of swap { SWAP_BY_POINTS, SWAP_BY_DOLLARS, SWAP_BY_INTEREST }
int unknown3;
double swap_long;
double swap_short; // swap overnight value
int swap_rollover3days; // three-days swap rollover
// 356
//---- margin calculation
int leverage; // leverage
int free_margin_mode; // free margin calculation mode { MARGIN_DONT_USE, MARGIN_USE_ALL, MARGIN_USE_PROFIT, MARGIN_USE_LOSS }
int margin_mode; // margin calculation mode { MARGIN_CALC_FOREX,MARGIN_CALC_CFD,MARGIN_CALC_FUTURES,MARGIN_CALC_CFDINDEX };
int margin_stopout; // margin stopout level
int margin_stopout_mode;// stop out check mode { MARGIN_TYPE_PERCENT, MARGIN_TYPE_CURRENCY }
double margin_initial; // margin requirements
double margin_maintenance; // margin maintenance requirements
double margin_hedged; // margin requirements for hedged positions
double margin_divider; // margin divider
char margin_currency[12];// margin currency
// 420
//---- commission calculation
double comm_base; // basic commission
int comm_type; // basic commission type { COMM_TYPE_MONEY, COMM_TYPE_PIPS, COMM_TYPE_PERCENT }
int comm_lots; // commission per lot or per deal { COMMISSION_PER_LOT, COMMISSION_PER_DEAL }
// 436
//---- for internal use
int from_bar; // fromdate bar number
int to_bar; // todate bar number
int start_period[6]; // number of bar at which the smaller period modeling started
int set_from; // begin date from tester settings
int set_to; // end date from tester settings
// 476
//----
int end_of_test;
int freeze_level; // order's freeze level in points
int generating_errors;
// 488
//----
int reserved[60];
};
struct TestHistory
{
datetime otm; // âðåìÿ áàðà
double open; // çíà÷åíèÿ OHLCV
double high;
double low;
double close;
long volume;
int ctm; // òåêóùåå ðàáî÷åå âðåìÿ âíóòðè áàðà
int flag; // ôëàã çàïóñêà ýêñïåðòà (0-áàð ìîäèôèöèðóåì, à ýêñïåðòà íå çàïóñêàåì)
};
struct TickStruct
{
datetime time;
double bid;
double ask;
};
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Script program start function |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnStart()
{
g_tf = (ENUM_TIMEFRAMES)Period();
if (!IsParametersCorrect())
return;
if (!CreateFXTFile())
return;
if (!CopyFXTFileToTesterFolder())
return;
Alert("Ñêðèïò çàêîí÷èë ñâîå âûïîëíåíèå. Ôàéë FXT íàõîäèòñÿ â ïàïêå òåñòåðà ñòðàòåãèé.");
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà çíà÷åíèé íàñòðîå÷íûõ ïàðàìåòðîâ |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsParametersCorrect()
{
string name = WindowExpertName();
g_periodSeconds = PeriodSeconds();
if (g_periodSeconds <= 0)
{
Alert(name, ": ôàòàëüíàÿ îøèáêà òåðìèíàëà - ïåðèîä ãðàôèêà ðàâåí 0 ñåêóíä. Ñêðèïò îòêëþ÷åí.");
return false;
}
if (i_startDate >= i_endDate)
{
Alert(name, ": äàòà/âðåìÿ íà÷àëà òåñòèðîâàíèÿ äîëæíà áûòü ìåíüøå äàòû/âðåìåíè îêîí÷àíèÿ òåñòèðîâàíèÿ. Ñêðèïò îòêëþ÷åí.");
return false;
}
if (i_minPreviousBars < 1)
{
Alert(name, ": êîëè÷åñòâî áàðîâ äî íà÷àëà òåñòèðîâàíèÿ äîëæíî áûòü áîëüøå íóëÿ. Ñêðèïò îòêëþ÷åí.");
return false;
}
if (!IsPreviousHistoryEnough())
{
Alert(name, ": êîëè÷åñòâî áàðîâ â èñòîðèè, ïðåäøåñòâóþùåå íà÷àëó òåñòà, íåäîñòàòî÷íî. Ñêðèïò îòêëþ÷åí.");
return false;
}
if (!IsTicksDataEnough())
return false;
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Äîñòàòî÷íî ëè èñòîðèè, èìåþùåéñÿ äî äàòû äàòîé íà÷àëà òåñòà? |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsPreviousHistoryEnough()
{
g_endPrevBar = iBarShift(_Symbol, g_tf, i_startDate);
int total = iBars(_Symbol, g_tf);
while (iTime(_Symbol, g_tf, g_endPrevBar) >= i_startDate && g_endPrevBar < total)
g_endPrevBar++;
g_startPrevBar = g_endPrevBar + (int)i_minPreviousBars - 1;
return g_startPrevBar < total;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Èìååòñÿ ëè òèêîâàÿ èñòîðèÿ, ñîîòâåòñòâóþùàÿ çàäàííîìó èíòåðâàëó òåñòèðîâàíèÿ? |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTicksDataEnough()
{
int handle;
g_ticksFileName = _Symbol + ".tks";
if (!IsFileOpen(g_ticksFileName, handle))
return false;
TickStruct tickStart, tickEnd;
if (!IsFileRead(handle, tickStart))
return false;
if (!FileSeek(handle, -sizeof(TickStruct), SEEK_END))
{
Alert(WindowExpertName(), " îøèáêà ïåðåìåùåíèÿ ôàéëîâîãî óêàçàòåëÿ â ôàéëå òèêîâ. Ñêðèïò îòêëþ÷åí.");
FileClose(handle);
return false;
}
if (!IsFileRead(handle, tickEnd))
return false;
FileClose(handle);
if (tickStart.time <= i_startDate && tickEnd.time >= i_endDate)
return true;
Alert("÷òî íå ñîîòâåòñòâóåò çàäàííîìó èíòåðâàëó òåñòèðîâàíèÿ. Ñêðèïò îòêëþ÷åí.");
Alert(WindowExpertName(), ": òèêîâûé ôàéë ", g_ticksFileName, " ðàñïîëàãàåò äàííûìè ñ ", tickStart.time, " ïî ", tickEnd.time, ",");
return false;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Îòêðûòèå ôàéëà ñ óêàçàííûì èìåíåì è âîçâðàò äåñêðèïòîðà ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsFileOpen(string fileName, int &fileHandle)
{
fileHandle = FileOpen(fileName, FILE_READ | FILE_SHARE_READ | FILE_BIN);
if (fileHandle <= 0)
{
Alert(WindowExpertName(), ": îøèáêà (N", GetLastError(),") îòêðûòèÿ ôàéëà ", fileName, ". Ñêðèïò îòêëþ÷åí.");
return false;
}
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| ×òåíèå òèêîâîãî ôàéëà ñ îáðàáîòêîé îøèáîê |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsFileRead(int handle, TickStruct &tick)
{
if (FileReadStruct(handle, tick) == 0)
{
Alert(WindowExpertName(), ": îøèáêà ÷òåíèÿ ôàéëà òèêîâ. Ñêðèïò îòêëþ÷åí.");
FileClose(handle);
return false;
}
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ñîçäàíèå FXT-ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool CreateFXTFile()
{
int fxtFileHandle;
if (!IsEmptyHeaderWrite(fxtFileHandle))
return false;
if (!IsPreviousHistoryWrite(fxtFileHandle))
return false;
int savedBarsCnt = g_startPrevBar - g_endPrevBar + 1;
int savedTicksCnt = savedBarsCnt;
datetime startTickDateTime = 0, lastTickDateTime= 0;
if (!IsHistoryDataWrite(fxtFileHandle, savedBarsCnt, savedTicksCnt, startTickDateTime, lastTickDateTime))
return false;
if (!FileSeek(fxtFileHandle, 0, SEEK_SET))
{
Alert(WindowExpertName(), ": íå óäàëîñü âåðíóòüñÿ ê íà÷àëó ôàéëà FXT. Ñêðèïò îòêëþ÷åí.");
FileClose(fxtFileHandle);
return false;
}
bool result = IsHeaderWrite(fxtFileHandle, savedBarsCnt, savedTicksCnt, startTickDateTime, lastTickDateTime);
FileClose(fxtFileHandle);
return result;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ôîðìèðîâàíèå ïóñòîãî çàãîëîâêà FXT-ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsEmptyHeaderWrite(int &fxtFileHandle)
{
if (!IsFileCreate(GetFXTFileName(), fxtFileHandle))
return false;
TestHistoryHeader testerHeader;
return IsReadyHeaderWrite(fxtFileHandle, testerHeader);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ãåíåðàöèÿ èìåíè FXT-ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetFXTFileName()
{
return _Symbol + IntegerToString((int)g_tf) + "_0.fxt";
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïèñü çàãîëîâêà FXT-ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsReadyHeaderWrite(int fxtFileHandle, TestHistoryHeader &testerHeader)
{
if (FileWriteStruct(fxtFileHandle, testerHeader) == sizeof(TestHistoryHeader))
return true;
Alert(WindowExpertName(), ": íå óäàëîñü çàïèñàòü çàãîëîâîê FXT-ôàéëà. Ñêðèïò îòêëþ÷åí.");
FileClose(fxtFileHandle);
return false;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ôîðìèðîâàíèå è çàïèñü èñòîðèè, ïðåäøåñòâóþùåé óêàçàííîé äàòå íà÷àëà òåñòèðîâàíèÿ |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsPreviousHistoryWrite(int fxtFileHandle)
{
TestHistory testHistory = {0, 0, 0, 0, 0, 0, 0};
int size = sizeof(testHistory);
for (int i = g_startPrevBar; i >= g_endPrevBar; i--)
{
testHistory.otm = iTime(_Symbol, g_tf, i);
testHistory.open = iOpen(_Symbol, g_tf, i);
testHistory.high = iHigh(_Symbol, g_tf, i);
testHistory.low = iLow(_Symbol, g_tf, i);
testHistory.close = iClose(_Symbol, g_tf, i);
testHistory.volume = iVolume(_Symbol, g_tf, i);
testHistory.ctm = (int)testHistory.otm;
if (FileWriteStruct(fxtFileHandle, testHistory) != size)
{
Alert(WindowExpertName(), ": íå óäàëîñü çàïèñàòü äàííûå ïðåäøåñòâóþùåé èñòîðèè. Ñêðèïò îòêëþ÷åí.");
FileClose(fxtFileHandle);
return false;
}
}
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ñîçäàíèå ôàéëà ñ óêàçàííûì èìåíåì è âîçâðàò äåñêðèïòîðà ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsFileCreate(string fileName, int &fileHandle)
{
fileHandle = FileOpen(fileName, FILE_WRITE | FILE_SHARE_WRITE | FILE_BIN | FILE_ANSI);
if (fileHandle <= 0)
{
Alert(WindowExpertName(), ": îøèáêà (N", GetLastError(),") ñîçäàíèÿ ôàéëà. Ñêðèïò îòêëþ÷åí.");
return false;
}
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïèñü äàííûõ â FXT-ôàéë îò íà÷àëüíîé äî êîíå÷íîé äàòû èíòåðâàëà òåñòèðîâàíèÿ |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsHistoryDataWrite(int fxtFileHandle, int &savedBarsCnt, int &savedTicksCnt, datetime &startTickDateTime, datetime &lastTickDateTime)
{
int handle;
if (!IsFileOpen(g_ticksFileName, handle))
{
FileClose(fxtFileHandle);
return false;
}
// Ïîèñê ïåðâîãî òèêà, êîòîðûé áûäåò çàïèñàí â FXT-ôàéë
TickStruct tick = {0, 0, 0};
while (tick.time < i_startDate && !FileIsEnding(handle))
{
if (!IsFileRead(handle, tick))
{
FileClose(fxtFileHandle);
return false;
}
}
startTickDateTime = tick.time;
// Çàïèñü òèêîâ â FXT-ôàéë
TestHistory testerHistory = {0, 0, 0, 0, 0, 0, 0, 0};
while(tick.time <= i_endDate && !FileIsEnding(handle))
{
if (!IsSaveTickToFXT(fxtFileHandle, tick, testerHistory, savedBarsCnt, savedTicksCnt))
{
FileClose(handle);
return false;
}
lastTickDateTime = tick.time;
if (!IsFileRead(handle, tick))
{
FileClose(fxtFileHandle);
return false;
}
}
FileClose(handle);
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïèñü óêàçàííîãî òèêà â ôàéë FXT |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsSaveTickToFXT(int fxtFileHandle, TickStruct &tick, TestHistory &testerHistory, int &savedBarsCnt, int &savedTicksCnt)
{
testerHistory.close = tick.bid;
testerHistory.ctm = (int)tick.time;
// Ôîðìèðîâàíèå íîâîãî áàðà
if (tick.time >= testerHistory.otm + g_periodSeconds)
{
testerHistory.otm = (tick.time / g_periodSeconds) * g_periodSeconds;
testerHistory.open = tick.bid;
testerHistory.high = tick.bid;
testerHistory.low = tick.bid;
testerHistory.volume = 1;
testerHistory.flag = 1;
savedBarsCnt++;
}
else
// Ïðîäîëæåíèå ôîðìèðîâàíèÿ ïðåäûäóùåãî áàðà
{
testerHistory.high = MathMax(testerHistory.high, tick.bid);
testerHistory.low = MathMin(testerHistory.low, tick.bid);
testerHistory.volume++;
}
// Çàïèñü äàííûõ
if (FileWriteStruct(fxtFileHandle, testerHistory) == 0)
{
Alert(WindowExpertName(), ": íå óäàëîñü çàïèñàòü äàííûå èñòîðèè èíòåðâàëà òåñòèðîâàíèÿ. Ñêðèïò îòêëþ÷åí.");
FileClose(fxtFileHandle);
return false;
}
savedTicksCnt++;
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ôîðìèðîâàíèå çàãîëîâêà FXT-ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsHeaderWrite(int fxtFileHandle, int savedBarsCnt, int savedTicksCnt, datetime startTickDateTime, datetime lastTickDateTime)
{
TestHistoryHeader testerHeader;
CreateHeader(testerHeader, savedBarsCnt, savedTicksCnt, startTickDateTime, lastTickDateTime);
return IsReadyHeaderWrite(fxtFileHandle, testerHeader);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Çàïîëíåíèå ñòðóêòóðû çàãîëîâêà ôàéëà |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CreateHeader(TestHistoryHeader &testerHeader, int savedBarsCnt, int savedTicksCnt, datetime startTickDateTime, datetime lastTickDateTime)
{
testerHeader.version = 405;
string copyright = "Copyright 2001-2014, MetaQuotes Software Corp.";
ArrayInitialize(testerHeader.copyright, 0);
StringToCharArray(copyright, testerHeader.copyright);
string description = AccountInfoString(ACCOUNT_SERVER);
ArrayInitialize(testerHeader.description, 0);
StringToCharArray(description, testerHeader.description);
ArrayInitialize(testerHeader.symbol, 0);
StringToCharArray(_Symbol, testerHeader.symbol);
testerHeader.period = g_tf;
testerHeader.model = 0;
testerHeader.bars = savedBarsCnt;
testerHeader.fromdate = (int)startTickDateTime;
testerHeader.todate = (int)lastTickDateTime;
testerHeader.modelquality = 100.0;
testerHeader.totalTicks = 0;
ArrayInitialize(testerHeader.currency, 0);
StringToCharArray(SymbolInfoString(_Symbol, SYMBOL_CURRENCY_PROFIT), testerHeader.currency);
testerHeader.spread = (int)i_spread;
testerHeader.digits = _Digits;
testerHeader.unknown1 = 0;
testerHeader.point = _Point;
testerHeader.lot_min = (int)(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN) * 100);
testerHeader.lot_max = (int)(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX) * 100);
testerHeader.lot_step = (int)(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP) * 100);
testerHeader.stops_level = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
testerHeader.gtc_pendings = 1; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.  îáðàçöîâûõ FXT-ôàéëàõ óñòàíàâëèâàåòñÿ çíà÷åíèå 1
testerHeader.unknown2 = 0;
testerHeader.contract_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE);
testerHeader.tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
testerHeader.tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
testerHeader.profit_mode = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_CALC_MODE);
testerHeader.swap_enable = 1; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.  îáðàçöîâûõ FXT-ôàéëàõ óñòàíàâëèâàåòñÿ çíà÷åíèå 1
testerHeader.swap_type = (int)SymbolInfoInteger(_Symbol, SYMBOL_SWAP_MODE);
testerHeader.unknown3 = 0;
testerHeader.swap_long = SymbolInfoDouble(_Symbol, SYMBOL_SWAP_LONG);
testerHeader.swap_short = SymbolInfoDouble(_Symbol, SYMBOL_SWAP_SHORT);
testerHeader.swap_rollover3days = (int)SymbolInfoInteger(_Symbol, SYMBOL_SWAP_ROLLOVER3DAYS);
testerHeader.leverage = (int)AccountInfoInteger(ACCOUNT_LEVERAGE);
testerHeader.free_margin_mode = 1; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.  îáðàçöîâûõ FXT-ôàéëàõ óñòàíàâëèâàåòñÿ çíà÷åíèå 1
testerHeader.margin_mode = 0; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.  îáðàçöîâûõ FXT-ôàéëàõ óñòàíàâëèâàåòñÿ çíà÷åíèå 0
testerHeader.margin_stopout = (int)AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
testerHeader.margin_stopout_mode = (int)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
testerHeader.margin_initial = SymbolInfoDouble(_Symbol, SYMBOL_MARGIN_INITIAL);
testerHeader.margin_maintenance = SymbolInfoDouble(_Symbol, SYMBOL_MARGIN_MAINTENANCE);
testerHeader.margin_hedged = MarketInfo(_Symbol, MODE_MARGINHEDGED);
testerHeader.margin_divider = 1.0; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.  îáðàçöîâûõ FXT-ôàéëàõ óñòàíàâëèâàåòñÿ çíà÷åíèå 1.0 èëè 100.0
ArrayInitialize(testerHeader.margin_currency, 0);
StringToCharArray(SymbolInfoString(_Symbol, SYMBOL_CURRENCY_MARGIN), testerHeader.margin_currency);
testerHeader.comm_base = 0.0; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.
testerHeader.comm_type = 0; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.
testerHeader.comm_lots = 1; // Çàïðàøèâàåìîå ñâîéñòâî íå íàéäåíî.
testerHeader.from_bar = 0;
testerHeader.to_bar = (int)i_minPreviousBars + 1;
for (int i = 0; i < 6; i++)
testerHeader.start_period[i] = 0;
testerHeader.set_from = 0;
testerHeader.set_to = (int)i_startDate;
testerHeader.end_of_test = (int)i_endDate;
testerHeader.freeze_level = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
testerHeader.generating_errors = 0;
for (int i = 0; i < 60; i++)
testerHeader.reserved[i] = 0;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Êîïèðîâàíèå FXT-ôàéëà â ïàïêó òåñòåðà è óñòàíîâêà àòðèáóòà "Read Only" |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool CopyFXTFileToTesterFolder()
{
string dataFolder = TerminalInfoString(TERMINAL_DATA_PATH);
string fxtFileName = GetFXTFileName();
string sourceFullFileName = dataFolder + "\\MQL4\\Files\\" + fxtFileName;
string destinationFullFileName = dataFolder + "\\tester\\history\\" + fxtFileName;
if (!IsWriteNewFileAllowed(destinationFullFileName))
return false;
if (CopyFileW(sourceFullFileName, destinationFullFileName, false))
return IsSetReadOnly(destinationFullFileName);
Alert(WindowExpertName(), ": îøèáêà êîïèðîâàíèÿ ôàéëà â ïàïêó òåñòåðà ñòðàòåãèé. Ñêðèïò îòêëþ÷åí.");
return false;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Ïðîâåðêà ñóùåñòâîâàíèÿ ôàéëà ñ òàêèì æå èìåíåì â ïàïêå òåñòåðà è ñíÿòèå åìó àòðèáóòà "Read Only" â ñëó÷àå îáíàðóæåíèÿ |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsWriteNewFileAllowed(string fileName)
{
uint attributes = GetFileAttributesW(fileName);
if (attributes == INVALID_FILE_ATTRIBUTES) // Îøèáêà ïîëó÷åíèÿ àòðèáóòîâ ñâèäåòåëüñòâóåò î òîì, ÷òî ôàéë îòñóòñòâóåò. Çíà÷èò, ïóòü îòêðûò.
return true;
attributes &= 0xFFFE; // Óáèðàåì àòðèáóò "Read Only" â àòðèáóòàõ
if (SetFileAttributesW(fileName, attributes)) // Óñòàíîâêà íîâûõ àòðèáóòîâ
return true;
Alert(WindowExpertName(), ": íå óäàëîñü óáðàòü àòðèáóò \"òîëüêî äëÿ ÷òåíèÿ\" ñòàðîìó FXT-ôàéëó, íàõîäÿùåìóñÿ â ïàïêå òåñòåðà ñòðàòåãèé. Ñêðèïò îòêëþ÷åí.");
return false;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Óñòàíîâêà àòðèáóòà "Read Only" FXT-ôàéëó |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsSetReadOnly(string fileName)
{
uint attributes = GetFileAttributesW(fileName);
if (attributes == INVALID_FILE_ATTRIBUTES)
{
Alert(WindowExpertName(), ": íå óäàëîñü ïîëó÷èòü àòðèáóò ôàéëà. Ñêðèïò îòêëþ÷åí.");
return false;
}
if (SetFileAttributesW(fileName, attributes | FILE_ATTRIBUTE_READONLY))
return true;
Alert(WindowExpertName(), ": íå óäàëîñü óñòàíîâèòü àòðèáóò \"òîëüêî äëÿ ÷òåíèÿ\" FXT-ôàéëó. Ñêðèïò îòêëþ÷åí.");
return false;
}
Comments