приведите строки кода, как Вы преобразуете время
Конечно путанно получилось... Может есть более эффективные способы?
//Полностью одинаковые записи у меня получаются в результате перехлестов в запросах, от них можно избавиться, но пока они остаются.
//Вопрос, что делать с записями где одинаковые даты, но разные Vol !!!
Кусок программы
//В базе данных
//Поле open_time TIMESTAMP(4) типа
// пример 20040120020304 = '2004-01-20 02:03:04'
//Если сделать INTEGER, тогда в гридах и в эксплорере дата-время будет видна не как дата, а как целое, что нежелательно для моего приложения...
//
//установлен UNIQUE INDEX ... Simbol,Period,open_time
if(первое обращение){ //Взять время из базы
quQuotation->SQL->Text="SELECT MAX(open_time) AS mot FROM quotation WHERE Simbol="+s+" AND Period="+p;
quQuotation->Open();
//если запрос не пуст
TDateTime t1=(quQuotation->IsEmpty())? 0:quQuotation->Fields->Fields[0]->AsDateTime; //AsInteger не желает, выдает ошибку при компиляции
TDateTime t2=StrToDateTime("01/01/70 00:00:00");
long delta_time=(t1 - t2); //Сколько целых дней относительно 1970 г. Конечно это ГРУБЫЙ метод, дробная часть не совсем точная, поэтому я ее отбрасываю, что не совсем карашо...
delta_time*=86400; //Тоже в секундах 60*60*24
time_t last_time_from_1970=(t2>t1 || quQuotation->IsEmpty())? 0:delta_time; //Получается перехлест несколько записей. Это чтобы гарантированно не пропускать даты.
}
else //Берем из оперативки
last_time_from_1970=LastTime[si][pi]; //Перехлест ровно 1 запись
TestSleep(SLEEP_GetRates,&Last_GetRates);//Какие мы дисциплинированные...
LastTime[si][pi]=time(NULL); //Массив последних времен с учетом символов и периодов
Rates=m_api.GetRates(Simbols[si].c_str(),Period[pi],last_time_from_1970,&Count);
for(i=0;i<Count;i++){
v1=IntToStr(si); //в базе simbol TINY
v2=IntToStr(pi); // period TINY
time_t ctm=Rates[i].ctm; //Вот про ЭТО место вы спрашивали
struct tm *tmb;
tmb=localtime(&ctm); //Автоматически преобразует 1970 в 1900
//В структуре tmb год начинается с 1900
AnsiString ct=IntToStr(1900+tmb->tm_year)+"-"+IntToStr(tmb->tm_mon+1)+"-"+IntToStr(tmb->tm_mday)
+" "+IntToStr(tmb->tm_hour)+":"+IntToStr(tmb->tm_min)+":"+IntToStr(tmb->tm_sec);
v3="'"+ct+"'"; //MySQL преобразует эту строку в TIMESTAMP(4)
//Правильность преобразования я проверил
v4=FloatToStr(Rates[i].open);
v5=FloatToStr(Rates[i].high);
v6=FloatToStr(Rates[i].low);
v7=FloatToStr(Rates[i].close);
v8=IntToStr(Rates[i].vol);
quQuotation->SQL->Text="INSERT INTO quotation(simbol,Period,open_time,Open_price,High_price,Low_price,Close_price,vol) VALUES(" + v1 + "," + v2 + "," + v3 + "," + v4 + "," + v5 + "," + v6 + "," + v7 + "," + v8 +")";
try{
quQuotation->ExecSQL(); //С учетом уникального индекса
//Все. Оттуда потом и читаю
}
catch ( ... ){ //Если индексы одинаковы
//Сохранение ошибочной записи в другой таблице.
...
}
Конечно путанно получилось... Может есть более эффективные способы?
//Полностью одинаковые записи у меня получаются в результате перехлестов в запросах, от них можно избавиться, но пока они остаются.
//Вопрос, что делать с записями где одинаковые даты, но разные Vol !!!
Кусок программы
//В базе данных
//Поле open_time TIMESTAMP(4) типа
// пример 20040120020304 = '2004-01-20 02:03:04'
//Если сделать INTEGER, тогда в гридах и в эксплорере дата-время будет видна не как дата, а как целое, что нежелательно для моего приложения...
//
//установлен UNIQUE INDEX ... Simbol,Period,open_time
if(первое обращение){ //Взять время из базы
quQuotation->SQL->Text="SELECT MAX(open_time) AS mot FROM quotation WHERE Simbol="+s+" AND Period="+p;
quQuotation->Open();
//если запрос не пуст
TDateTime t1=(quQuotation->IsEmpty())? 0:quQuotation->Fields->Fields[0]->AsDateTime; //AsInteger не желает, выдает ошибку при компиляции
TDateTime t2=StrToDateTime("01/01/70 00:00:00");
long delta_time=(t1 - t2); //Сколько целых дней относительно 1970 г. Конечно это ГРУБЫЙ метод, дробная часть не совсем точная, поэтому я ее отбрасываю, что не совсем карашо...
delta_time*=86400; //Тоже в секундах 60*60*24
time_t last_time_from_1970=(t2>t1 || quQuotation->IsEmpty())? 0:delta_time; //Получается перехлест несколько записей. Это чтобы гарантированно не пропускать даты.
}
else //Берем из оперативки
last_time_from_1970=LastTime[si][pi]; //Перехлест ровно 1 запись
TestSleep(SLEEP_GetRates,&Last_GetRates);//Какие мы дисциплинированные...
LastTime[si][pi]=time(NULL); //Массив последних времен с учетом символов и периодов
Rates=m_api.GetRates(Simbols[si].c_str(),Period[pi],last_time_from_1970,&Count);
for(i=0;i<Count;i++){
v1=IntToStr(si); //в базе simbol TINY
v2=IntToStr(pi); // period TINY
time_t ctm=Rates[i].ctm; //Вот про ЭТО место вы спрашивали
struct tm *tmb;
tmb=localtime(&ctm); //Автоматически преобразует 1970 в 1900
//В структуре tmb год начинается с 1900
AnsiString ct=IntToStr(1900+tmb->tm_year)+"-"+IntToStr(tmb->tm_mon+1)+"-"+IntToStr(tmb->tm_mday)
+" "+IntToStr(tmb->tm_hour)+":"+IntToStr(tmb->tm_min)+":"+IntToStr(tmb->tm_sec);
v3="'"+ct+"'"; //MySQL преобразует эту строку в TIMESTAMP(4)
//Правильность преобразования я проверил
v4=FloatToStr(Rates[i].open);
v5=FloatToStr(Rates[i].high);
v6=FloatToStr(Rates[i].low);
v7=FloatToStr(Rates[i].close);
v8=IntToStr(Rates[i].vol);
quQuotation->SQL->Text="INSERT INTO quotation(simbol,Period,open_time,Open_price,High_price,Low_price,Close_price,vol) VALUES(" + v1 + "," + v2 + "," + v3 + "," + v4 + "," + v5 + "," + v6 + "," + v7 + "," + v8 +")";
try{
quQuotation->ExecSQL(); //С учетом уникального индекса
//Все. Оттуда потом и читаю
}
catch ( ... ){ //Если индексы одинаковы
//Сохранение ошибочной записи в другой таблице.
...
}
Конечно путанно получилось... Может есть более эффективные способы?
Вы должны получать ноль секунд
===
time_t ctm=Rates[i].ctm;struct tm *tmb;
tmb=localtime(&ctm);
AnsiString ct=IntToStr(1900+tmb->tm_year)+"-"+IntToStr(tmb->tm_mon+1)+"-"+IntToStr(tmb->tm_mday)
+" "+IntToStr(tmb->tm_hour)+":"+IntToStr(tmb->tm_min)+":"+IntToStr(tmb->tm_sec);
===
к преобразованиям вопросов нет, за исключением того, что вместо localtime надо использовать gmtime, но это влияет только на часовую разницу. секунды всё равно должны быть нулевые.
с какого сервера Вы получаете данные?
===
time_t ctm=Rates[i].ctm;struct tm *tmb;
tmb=localtime(&ctm);
AnsiString ct=IntToStr(1900+tmb->tm_year)+"-"+IntToStr(tmb->tm_mon+1)+"-"+IntToStr(tmb->tm_mday)
+" "+IntToStr(tmb->tm_hour)+":"+IntToStr(tmb->tm_min)+":"+IntToStr(tmb->tm_sec);
===
к преобразованиям вопросов нет, за исключением того, что вместо localtime надо использовать gmtime, но это влияет только на часовую разницу. секунды всё равно должны быть нулевые.
с какого сервера Вы получаете данные?
Да вы правы
Я разобрался с ошибкой преобразования и сейчас секунды и время в целом правильные.
Однако, остался вопрос по записям, где одинаковое время, но разные цены и объемы. Как их интерпретировать? Могут ли быть такие записи вообще?
И еще, рядом с ними часто обнаруживаются пропуски 1-минутных и более отсчетов( например 0,1,2, еще 2, пропуск, 6, 7 минут). Данные получены за один запрос. Цены меняются незначительно. Эти пропуски тоже могут иметь место? Может в эти периоды не было сделок?
Данные я получаю с 217.74.32.254
Я разобрался с ошибкой преобразования и сейчас секунды и время в целом правильные.
Однако, остался вопрос по записям, где одинаковое время, но разные цены и объемы. Как их интерпретировать? Могут ли быть такие записи вообще?
И еще, рядом с ними часто обнаруживаются пропуски 1-минутных и более отсчетов( например 0,1,2, еще 2, пропуск, 6, 7 минут). Данные получены за один запрос. Цены меняются незначительно. Эти пропуски тоже могут иметь место? Может в эти периоды не было сделок?
Данные я получаю с 217.74.32.254
приведите пример записей с одинаковым временем, но разными ценами и объёмами
такое возможно для текущего таймфрейма, если Вы неоднократно в течение этого таймфрейма запрашиваете данные. и то, только для последнего бара. в других случаях разницы не должно быть, если только на сервере не были изменены соответствующие записи.
по поводу пропусков. они могут быть. запустите клиентский терминал и посмотрите в архиве котировок.
такое возможно для текущего таймфрейма, если Вы неоднократно в течение этого таймфрейма запрашиваете данные. и то, только для последнего бара. в других случаях разницы не должно быть, если только на сервере не были изменены соответствующие записи.
по поводу пропусков. они могут быть. запустите клиентский терминал и посмотрите в архиве котировок.
Вот например такие записи ...
Взято с 217.74.32.254
"USDCHF",M1 / 20040120232000,1.2469,1.2471,1.2464,1.2466,4
"USDCHF",M1 / 20040120232000,1.2469,1.2471,1.2463,1.2466,7
..............................................................................^...........^
"GBPUSD",M1 / 20040120232000,1.8205,1.8208,1.8202,1.8205,4
"GBPUSD",M1 / 20040120232000,1.8205,1.8208,1.8202,1.8205,7
...........................................................................................^
"USDJPY",M1 / 20040120232100,1.2588,1.259,1.2585,1.2588,3
"USDJPY",M1 / 20040120232100,1.2588,1.259,1.2585,1.2588,9
..........................................................................................^
Взято с 217.74.32.254
"USDCHF",M1 / 20040120232000,1.2469,1.2471,1.2464,1.2466,4
"USDCHF",M1 / 20040120232000,1.2469,1.2471,1.2463,1.2466,7
..............................................................................^...........^
"GBPUSD",M1 / 20040120232000,1.8205,1.8208,1.8202,1.8205,4
"GBPUSD",M1 / 20040120232000,1.8205,1.8208,1.8202,1.8205,7
...........................................................................................^
"USDJPY",M1 / 20040120232100,1.2588,1.259,1.2585,1.2588,3
"USDJPY",M1 / 20040120232100,1.2588,1.259,1.2585,1.2588,9
..........................................................................................^
Ой опечатка! здесь правильный вариант...
Взято с 217.74.32.254
"USDCHF",M1 / '2004-01-20 23:20:00',1.2469,1.2471,1.2464,1.2466,4
"USDCHF",M1 / '2004-01-20 23:20:00',1.2469,1.2471,1.2463,1.2466,7
errors............................................................................^...........^
"GBPUSD",M1 / '2004-01-20 23:20:00',1.8205,1.8208,1.8202,1.8205,4
"GBPUSD",M1 / '2004-01-20 23:20:00',1.8205,1.8208,1.8202,1.8205,7
...................................................................................................^
"EURUSD",M1 / '2004-01-20 23:21:00',1.2588,1.259,1.2585,1.2588,3
"EURUSD",M1 / '2004-01-20 23:21:00',1.2588,1.259,1.2585,1.2588,9
.................................................................................................^
Взято с 217.74.32.254
"USDCHF",M1 / '2004-01-20 23:20:00',1.2469,1.2471,1.2464,1.2466,4
"USDCHF",M1 / '2004-01-20 23:20:00',1.2469,1.2471,1.2463,1.2466,7
errors............................................................................^...........^
"GBPUSD",M1 / '2004-01-20 23:20:00',1.8205,1.8208,1.8202,1.8205,4
"GBPUSD",M1 / '2004-01-20 23:20:00',1.8205,1.8208,1.8202,1.8205,7
...................................................................................................^
"EURUSD",M1 / '2004-01-20 23:21:00',1.2588,1.259,1.2585,1.2588,3
"EURUSD",M1 / '2004-01-20 23:21:00',1.2588,1.259,1.2585,1.2588,9
.................................................................................................^
Всеже спасибо за подсказку gmtime! Почти все неточности победил, кроме этих единичных случаев.
а не значения ли последних баров Вы привели?
тех, которые ещё не сформировались.
тех, которые ещё не сформировались.
Все может быть
Не знаю. Сейчас уже не узнать. Проверю еще разик на других данных.
Не знаю. Сейчас уже не узнать. Проверю еще разик на других данных.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
1)Функция GetRates возвращает данные среди которых часто попадаются записи с одинаковым временем открытия, но разными open, high, low, close и vol. Правда, цены бывают разные, реже чем vol. Это наблюдается для всех периодов.
Как интерпретировать такие записи?
2)Очень редко записи полностью 100% совпадают (дубликаты), тогда я их вообще удаляю, но возможно это тоже разные по смыслу записи?