Избранное трейдера ezomm
YNDX POLY |
Yandex clA Polymetal |
NL0009805522 JE00B6T5S470 |
AGRO | AGRO-гдр | US7496552057 |
CIAN | CIAN-адр | US83418T1088 |
EM44 | EM44-гдр | US91085A1043 |
ETLN | ETLN-гдр | US29760G1031 |
FIVE | FIVE-гдр | US98387E2054 |
FIXP | FIXP-гдр | US33835G2057 |
GEMC | GEMC-гдр | US91085A2033 |
GLTR | GLTR-гдр | US37949E2046 |
HHRU | iHHRU-адр | US42207L1061 |
HMSG | HMSG-гдр | US40425X4079 |
LNTA | Лента др | US52634T2006 |
MDMG | MDMG-гдр | US55279C2008 |
OKEY | OKEY-гдр | US6708662019 |
OZON | OZON-адр | US69269L1044 |
QIWI | iQIWI | US74735M1080 |
SFTL | iSFTL-гдр | US83407L2079 |
TCSG | TCS-гдр | US87238U2033 |
VKCO | VK-гдр | US5603172082 |
Написал скрипт, который переделывает тиковые данные в range заданной размерности.
Но есть нюанс, когда идет быстрый рынок, некоторые бары могут иметь одинаковое время открытия, что приводит к некоторому несоответствию range баров.
<code>"""
Скрипт из файлов с тиковыми данными делает файл с рандже барами
"""
import re
from datetime import datetime
from pathlib import *
import pandas as pd
def zero_hour(cell):
""" Функция преобразует время (с финама приходят часы без нулей (с марта 2021), которые pandas не воспринимает)"""
cell = f'{int(cell)}'
tmp_time = datetime.strptime(cell, "%H%M%S")
return tmp_time.strftime("%H%M%S")
def run(tick_files: list[Path], razmer: int, target_dir: Path):
for ind_file, tick_file in enumerate(tick_files, start=1): # Итерация по тиковым файлам
list_split = re.split('_', tick_file.name, maxsplit=0) # Разделение имени файла по '_'
tiker = list_split[0] # Получение тикера из имени файла
date_quote_file = re.findall(r'\d+', str(tick_file)) # Получение цифр из пути к файлу
target_name = f'{tiker}_range{razmer}_{date_quote_file[0]}.txt' # Создание имени новому файлу
target_file_range: Path = Path(target_dir / target_name) # Составление пути к новому файлу
if Path.is_file(target_file_range):
print(f'Файл уже существует {target_file_range}')
continue
else:
df_ticks_file: pd = pd.read_csv(tick_file, delimiter=',') # Считываем тиковые данные в DF
# Создание DF под рандже бары одного тикового файла
df: pd = pd.DataFrame(columns='<DATE> <TIME> <OPEN> <HIGH> <LOW> <CLOSE> <VOL>'.split(' '))
for tick in df_ticks_file.itertuples(): # Итерация по строкам тикового DF
print('\rCompleted file: {:.2f}%. Completed files: {:.2f}%'.format(
tick[0] * 100 / len(df_ticks_file.index),
ind_file * 100 / len(tick_files)
),
end=''
)
if tick[0] == 0:
# Добавление строки в DF с рандже барами
df.loc[len(df.index)] = [int(tick[1]), int(tick[2]), tick[3], tick[3], tick[3], tick[3], tick[4]]
continue
# Если бар сформирован по размеру возрастающий бар
if df.loc[len(df.index) - 1, '<LOW>'] + razmer < tick[3]:
df.loc[len(df.index) - 1, '<CLOSE>'] = df.loc[len(df.index) - 1, '<LOW>'] + razmer
df.loc[len(df.index) - 1, '<HIGH>'] = df.loc[len(df.index) - 1, '<CLOSE>']
# Добавление строки в DF с дельта барами
df.loc[len(df.index)] = [int(tick[1]), int(tick[2]), tick[3], tick[3], tick[3], tick[3], tick[4]]
continue
# break
# Если бар сформирован по размеру падающий бар
if df.loc[len(df) - 1, '<HIGH>'] - razmer > tick[3]:
df.loc[len(df) - 1, '<CLOSE>'] = df.loc[len(df) - 1, '<HIGH>'] - razmer
df.loc[len(df) - 1, '<LOW>'] = df.loc[len(df) - 1, '<CLOSE>']
# Добавление строки в DF с дельта барами
df.loc[len(df.index)] = [int(tick[1]), int(tick[2]), tick[3], tick[3], tick[3], tick[3], tick[4]]
continue
# break
# Заполняем(изменяем) последнюю строку DF с рандже баром --------------------------------------
# Записываем <CLOSE> --------------------------------------------------------------------------
df.loc[len(df.index) - 1, '<CLOSE>'] = tick[3] # Записываем последнюю цену как цену close бара
# Записываем <HIGH> ---------------------------------------------------------------------------
if float(tick[3]) > df.loc[len(df) - 1, '<HIGH>']: # Если цена последнего тика больше чем high
df.loc[len(df.index) - 1, '<HIGH>'] = tick[3] # Записываем цену последнего тика как high
# Записываем <LOW> ----------------------------------------------------------------------------
if float(tick[3]) < df.loc[len(df.index) - 1, '<LOW>']:
df.loc[len(df.index) - 1, '<LOW>'] = tick[3] # Записываем цену последней сделки как low
# Записываем <VOL> ----------------------------------------------------------------------------
df.loc[len(df.index) - 1, '<VOL>'] += tick[4] # Увеличиваем объем
# Изменение типа колонок
df[['<DATE>', '<TIME>', '<VOL>']] = df[['<DATE>', '<TIME>', '<VOL>']].astype(int)
# Преобразуем столбец <TIME>, где нужно добавив 0 перед часом
df['<TIME>'] = df.apply(lambda x: zero_hour(x['<TIME>']), axis=1)
df.to_csv(target_file_range, index=False) # Запись в файл для одного тикового файла
# break
if __name__ == "__main__":
razmer: int = 250
ticker: str = 'RTS'
year_tick: str = '2022'
source_dir_tick: Path = Path(f'c:/data_quote/data_finam_{ticker}_tick') # Путь к ресурсному каталогу
target_dir: Path = Path(f'c:/data_quote/data_prepare_{ticker}_range') # Путь к целевому каталогу
# Создание списка путей к файлам с тиками
tick_files: list[Path] = list(source_dir_tick.glob(f'*{year_tick}*.csv'))
run(tick_files, razmer, target_dir)
</code>
Привет, Всем!
Хотел бы рассчитать размерность range баров, чтобы их количество в одном дне было бы как и количество 5 мин баров.
Написал скрипт но значения так разнятся. Может кто-то уже занимался таким вопросом?
Рассчитанное значение величины range в поле <RAZMER>
<code>"""
Для расчета рендж баров эквивалентных 5 мин
"""
from pathlib import *
import pandas as pd
import talib
def body(open: float, close: float) -> float:
return abs(close - open)
if __name__ == "__main__":
# 198 баров 5м в дне (с 7:00)
period: int = 198
source_file: Path = Path('c:\data_quote\data_finam_RTS_5m\SPFB.RTS_210301_220131.csv')
df: pd = pd.read_csv(source_file, delimiter=',') # Считываем тиковые данные в DF
# Преобразуем столбец <TIME>, где нужно добавив 0 перед часом
df['<BODY>'] = df.apply(lambda x: body(x['<OPEN>'], x['<CLOSE>']), axis=1)
df['<RAZMER>'] = talib.MA(df['<BODY>'], timeperiod=period, matype=0)
df_15: pd = df.loc[df['<TIME>'] == 150000] # Бары в 15:00
print(df_15.tail(20))
"""
Получается, что рендж бар для фьючерса RTS должен быть размером 250, чтобы количество баров в дне,
примерно совпадало с с количеством 5 мин баров.
"""</code>