dualea/Experts/Advisors/DualEA/Tests/Test_SQLiteCSVImport.mq5
2026-10-28 00:31:51 -04:00
63 lines
3 KiB
MQL5
#property strict
#include "../Include/CSQLiteKnowledgeBase.mqh"
int g_failures=0;
void Check(bool passed, string message)
{
Print(passed ? "[CSV-TEST PASS] " : "[CSV-TEST FAIL] ", message);
if(!passed) g_failures++;
}
int OnInit()
{
// Unique files prevent mutation of the user's KB/database.
string token = StringFormat("csv_regression_%I64u", GetMicrosecondCount());
string db_name = token + ".db";
string fixture = "DualEA\\" + token + ".csv";
FolderCreate("DualEA", DUALEA_FILE_COMMON);
if(FileIsExist(fixture, DUALEA_FILE_COMMON) || FileIsExist("DualEA\\Database\\"+db_name, DUALEA_FILE_COMMON))
return INIT_FAILED;
CSQLiteKnowledgeBase kb(db_name);
if(!kb.Initialize()) return INIT_FAILED;
int file = FileOpen(fixture, FILE_WRITE|FILE_TXT|DUALEA_FILE_COMMON|FILE_UNICODE);
if(file == INVALID_HANDLE) return INIT_FAILED;
FileWriteString(file, "timestamp,symbol,type,entry_price,stop_loss,take_profit,close_price,profit,strategy_id\r\n");
FileWriteString(file, "2026.10.01 10:00:00,USDCHF,0,0.8,0.79,0.82,0.81,20,Test'Strategy\r\n");
FileWriteString(file, "2026.10.01 11:00:00,USDCHF,0,0.8,0.79,0.82,0.79,-10,Test'Strategy\r\n");
FileClose(file);
Check(kb.ImportFromCSV(fixture)==2, "UTF-16 native KB schema imports both closed trades");
Check(kb.ImportFromCSV(fixture)==0, "Repeated preload does not double-count matching CSV records");
double wr=0, pf=0, pnl=0;
int total=0;
// Imported names must work in both insertion and downstream queries.
STradeRecord rows[];
int count=kb.GetRecentTrades("Test'Strategy", "USDCHF", rows, 10);
Check(count==2, "Quoted strategy names survive insertion");
if(count==2)
{
Check(rows[0].timestamp==D'2026.10.01 11:00:00', "Formatted timestamps retain their date and time");
Check(MathAbs(rows[0].pnl+10.0)<0.00001, "Imported close P&L is preserved");
}
// Switch to UTF-8 and canonical names, including a malformed timestamp.
file=FileOpen(fixture, FILE_WRITE|FILE_TXT|DUALEA_FILE_COMMON|FILE_ANSI, 0, CP_UTF8);
if(file == INVALID_HANDLE) return INIT_FAILED;
FileWriteString(file, "timestamp,symbol,strategy,order_type,entry_price,volume,sl,tp,pnl,close_price\r\n");
FileWriteString(file, "1790848800,USDCHF,Canonical,0,0.8,0.1,0.79,0.82,30,0.81\r\n");
FileWriteString(file, "bad,USDCHF,Canonical,0,0.8,0.1,0.79,0.82,30,0.81\r\n");
FileClose(file);
Check(kb.ImportFromCSV(fixture)==1, "UTF-8 canonical schema imports valid row and rejects invalid date");
Check(kb.GetStrategyStats("Canonical", "USDCHF", wr,pf,pnl,total), "Canonical statistics are queryable");
Check(total==1 && MathAbs(pnl-30.0)<0.00001 && MathAbs(wr-1.0)<0.00001, "Closed outcomes contribute to statistics");
kb.Close();
FileDelete(fixture, DUALEA_FILE_COMMON);
FileDelete("DualEA\\Database\\"+db_name, DUALEA_FILE_COMMON);
PrintFormat("[CSV-TEST RESULT] failures=%d", g_failures);
return g_failures==0 ? INIT_SUCCEEDED : INIT_FAILED;
}
void OnTick() {}
double OnTester() { return g_failures==0 ? 1.0 : -1.0; }