//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- создадим имя файла
string filename=AccountInfoString(ACCOUNT_SERVER) +"_"+IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN))+".sqlite";
//--- открываем/создаем базу данных в общей папке терминалов
int db=DatabaseOpen(filename, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
if(db==INVALID_HANDLE)
{
Print("DB: ", filename, " open failed with code ", GetLastError());
return;
}
//--- если таблица DEALS уже есть, удалим её
if(!DeleteTable(db, "DEALS"))
{
DatabaseClose(db);
return;
}
//--- создадим таблицу DEALS
if(!CreateTableDeals(db))
{
DatabaseClose(db);
return;
}
//--- запросим всю торговую историю
datetime from_date=0;
datetime to_date=TimeCurrent();
//--- запросим историю сделок в указанном интервале
HistorySelect(from_date, to_date);
int deals_total=HistoryDealsTotal();
PrintFormat("Торговая история насчитывает сделок: %d ", deals_total);
//--- замерим скорость выполнения транзакций с использованием DatabaseTransactionBegin/DatabaseTransactionCommit
ulong start=GetMicrosecondCount();
bool fast_transactions=true;
InsertDeals(db, fast_transactions);
double fast_transactions_time=double(GetMicrosecondCount()-start)/1000;
PrintFormat("Transations WITH DatabaseTransactionBegin/DatabaseTransactionCommit: time=%.1f milliseconds", fast_transactions_time);
//--- удалим таблицу DEALS - будем создавать её заново
if(!DeleteTable(db, "DEALS"))
{
DatabaseClose(db);
return;
}
//--- создадим заново таблицу DEALS
if(!CreateTableDeals(db))
{
DatabaseClose(db);
return;
}
//--- сделаем тест заново без использования DatabaseTransactionBegin/DatabaseTransactionCommit
fast_transactions=false;
start=GetMicrosecondCount();
InsertDeals(db, fast_transactions);
double slow_transactions_time=double(GetMicrosecondCount()-start)/1000;
PrintFormat("Transations WITHOUT DatabaseTransactionBegin/DatabaseTransactionCommit: time=%.1f milliseconds", slow_transactions_time);
//--- сообщим выигрыш по времени
PrintFormat("Использование DatabaseTransactionBegin/DatabaseTransactionCommit дало ускорение в %.1f раз", double(slow_transactions_time)/fast_transactions_time);
//--- закрываем базу данных
DatabaseClose(db);
}
/*
Результат:
Торговая история насчитывает сделок: 2737
Transations WITH DatabaseTransactionBegin/DatabaseTransactionCommit: time=48.5 milliseconds
Transations WITHOUT DatabaseTransactionBegin/DatabaseTransactionCommit: time=25818.9 milliseconds
Использование DatabaseTransactionBegin/DatabaseTransactionCommit дало ускорение в 532.8 раз
*/
//+------------------------------------------------------------------+
//| Удаляет из базы таблицу с указанным именем |
//+------------------------------------------------------------------+
bool DeleteTable(int database, string table_name)
{
if(!DatabaseExecute(database, "DROP TABLE IF EXISTS "+table_name))
{
Print("Failed to drop table with code ", GetLastError());
return(false);
}
//--- таблица успешно удалена
return(true);
}
//+------------------------------------------------------------------+
//| Создает таблицу DEALS |
//+------------------------------------------------------------------+
bool CreateTableDeals(int database)
{
//--- проверим наличие таблицы
if(!DatabaseTableExists(database, "DEALS"))
//--- создаем таблицу
if(!DatabaseExecute(database, "CREATE TABLE DEALS("
"ID INT KEY NOT NULL,"
"ORDER_ID INT NOT NULL,"
"POSITION_ID INT NOT NULL,"
"TIME INT NOT NULL,"
"TYPE INT NOT NULL,"
"ENTRY INT NOT NULL,"
"SYMBOL CHAR(10),"
"VOLUME REAL,"
"PRICE REAL,"
"PROFIT REAL,"
"SWAP REAL,"
"COMMISSION REAL,"
"MAGIC INT,"
"REASON INT );"))
{
Print("DB: create the table DEALS failed with code ", GetLastError());
return(false);
}
//--- таблица успешно создана
return(true);
}
//+------------------------------------------------------------------+
//| Вносит сделки в таблицу базы данных |
//+------------------------------------------------------------------+
bool InsertDeals(int database, bool begintransaction=true)
{
//--- вспомогательные переменные
ulong deal_ticket; // тикет сделки
long order_ticket; // тикет ордера,по которому была совершена сделка
long position_ticket; // ID позиция, к которой относится сделка
datetime time; // время совершения сделки
long type ; // тип сделки
long entry ; // направление сделки
string symbol; // по какому символу была сделка
double volume; // объем операции
double price; // цена
double profit; // финансовый результат
double swap; // своп
double commission; // комиссия
long magic; // Magic number
long reason; // причина или источник проведения сделки
//--- пройдем по всем сделкам и внесем в базу данных
bool failed=false;
int deals=HistoryDealsTotal();
//--- если используется быстрый способ проведения транзакций
if(begintransaction)
{
//--- заблокируем базу данных перед выполнением транзакций
DatabaseTransactionBegin(database);
}
for(int i=0; i<deals; i++)
{
deal_ticket= HistoryDealGetTicket(i);
order_ticket= HistoryDealGetInteger(deal_ticket, DEAL_ORDER);
position_ticket=HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);
time= (datetime)HistoryDealGetInteger(deal_ticket, DEAL_TIME);
type= HistoryDealGetInteger(deal_ticket, DEAL_TYPE);
entry= HistoryDealGetInteger(deal_ticket, DEAL_ENTRY);
symbol= HistoryDealGetString(deal_ticket, DEAL_SYMBOL);
volume= HistoryDealGetDouble(deal_ticket, DEAL_VOLUME);
price= HistoryDealGetDouble(deal_ticket, DEAL_PRICE);
profit= HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
swap= HistoryDealGetDouble(deal_ticket, DEAL_SWAP);
commission= HistoryDealGetDouble(deal_ticket, DEAL_COMMISSION);
magic= HistoryDealGetInteger(deal_ticket, DEAL_MAGIC);
reason= HistoryDealGetInteger(deal_ticket, DEAL_REASON);
//--- внесем каждую сделку через запрос
string request_text=StringFormat("INSERT INTO DEALS (ID,ORDER_ID,POSITION_ID,TIME,TYPE,ENTRY,SYMBOL,VOLUME,PRICE,PROFIT,SWAP,COMMISSION,MAGIC,REASON)"
"VALUES (%d, %d, %d, %d, %d, %d, '%s', %G, %G, %G, %G, %G, %d, %d)",
deal_ticket, order_ticket, position_ticket, time, type, entry, symbol, volume, price, profit, swap, commission, magic, reason);
if(!DatabaseExecute(database, request_text))
{
PrintFormat("%s: failed to insert deal #%dwith code %d", __FUNCTION__, deal_ticket, GetLastError());
PrintFormat("i=%d: deal #%d %s", i, deal_ticket, symbol);
failed=true;
break;
}
}
//--- проверим на наличие ошибок при выполнении транзакций
if(failed)
{
//--- если используется быстрый способ проведения транзакций
if(begintransaction)
{
//--- откатим все транзакции и разблокируем базу данных
DatabaseTransactionRollback(database);
}
Print("%s: DatabaseExecute() failed with code ", __FUNCTION__, GetLastError());
return(false);
}
//--- если используется быстрый способ проведения транзакций
if(begintransaction)
{
//--- все транзакции прошли успешно - зафиксируем изменения и разблокируем базу данных
DatabaseTransactionCommit(database);
}
//--- успешное завершение
return(true);
}
//+------------------------------------------------------------------+
|