Классический вариант решения:
1. Таблица, где хранятся котировки, имеет индекс по дате/времени.
2. Выгрузка идет отдельными транзакциями в цикле. Между транзакция не сохраняется никакого внутреннего состояния. По окончанию каждой транзакции программа (условно) возвращается в исходное состояние (этим обеспечивается восстановление после сбоев).
3. В самой транзакции сперва делается выборка записи с максимальным значением временной отметки (поиск по индексированному полю - мгновенно).
4. Это значение округляется в меньшую сторону до начала периода (минуты/часа/дня/года).
5. Производится запрос котировок за этот период.
6. Выбранные данные объединяются с содержимым таблицы таким образом, что пересекающиеся записи не дублируются (тут много вариантов решения на sql).
7. Транзакция закрывается.
Все.
Итого: полная гарантия отсутствия дублирующих записей в базе при любом раскладе. Этот скрипт/программу можно запускать вручную/автоматически/по_графику в любое время - ситуация с несколько одновременно работающими копиями не опасна (хоть и бессмысленна).