Андрей Кольцов
Андрей Кольцов личный блог
18 декабря 2017, 15:23

Как узнать какие акции самые волатильные…

Для реализации одной задумки в один прекрасный момент мне необходимо было узнать какие акции, торгуемые на ММВБ, являются самыми волатильными за определенный период…

Скачивать историю по всем акциям и прогонять ее через Excel слишком долго и нудно…

Захотелось написать робота, чтобы он сам за меня все посчитал… Но так как я знаком только с языком программирования Qpile, то мне пришлось столкнуться с проблемой – для получения данных по свечкам используется функция «GET_CANDLE», а она работает только при открытом графике… Открывать в Квике три сотни графиков мне тоже не хотелось…

На помощь пришла «Текущая таблица параметров» в QUIK… Но у нее один недостаток – информация в ней содержится только за текущий день. Что-же делать? Можно и подождать…

Пришлось быстренько написать робота и запустить его для накапливания информации. Каждый торговый день после 18:50 робот сохраняет информацию в файлы и одновременно отображает ее. Формула для расчета простая: (Max-Min)/среднедневная цена. То есть, волатильность в процентном выражении от среднедневной цены.

Выглядит таблица вот так:

Как узнать какие акции самые волатильные…

Далее копируем таблицу в буфер и сортируем в Excel как нам надо...
-----
Кому надо копируйте. Мне не жалко.

В коде надо обязательно указать путь к папке, в которой будет сохраняться рабочая информация и указать за какой период накапливать и рассчитывать волатильность.

Код:

PORTFOLIO_EX Koltsov-ATR-1.0;
DESCRIPTION Koltsov-ATR-1.0;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST FIRMID;
USE_CASE_SENSITIVE_CONSTANTS;

PROGRAM
'________________________________________________________________________________________

DELETE_ALL_ITEMS()

'---------- НАСТРОЙКИ ПОЛЬЗОВАТЕЛЯ ----------

Classcode = "TQBR"         'Код Класса
period    = 14             'За какой период рассчитываем ATR

papka     = "C:/Quik_Open/Info/raschet/ATR/"     'Папка для сохранения информации (НЕОБХОДИМО СОЗДАТЬ САМОСТОЯТЕЛЬНО!!!)

'________________________________________________________________________________________

line = 0    'Идентификатор для подсветки строк
'------------------
'Задаем время онлайн

Vrema           = GET_INFO_PARAM ("SERVERTIME")               'определяем время 

Hour0="" & (0 + substr(Vrema,0,2))
Min0 =floor (substr(Vrema,3,2))
Sec0 =floor (substr(Vrema,6,2))

if len(Sec0) == 1
Sec0= "0" & Sec0
end if
if len(Min0) == 1
Min0= "0" & Min0
end if
if len(Hour0) == 1
Hour0= "0" & Hour0
end if

Time0=Hour0 & Min0 & Sec0         'Время on-line
Time0=Time0+0
Time=Hour0 & Min0 & 0 & 0         'Время с округлением до минуты

'------------------
'Задаем дату

dats = GET_INFO_PARAM ("TRADEDATE")

Year="" & (0 + substr(dats,6,4))

Month="" & (0 + substr(dats,3,2))
if len(Month) == 1
Month= "0" & Month
end if

Day="" & (0 + substr(dats,0,2))
if len(Day) == 1
Day= "0" & Day
end if

Date = Year & Month & Day   'переводим в нужный формат
Date = Date+0

'===============================================================================================================================
'===============================================================================================================================

pozicii_a =0
pozicii_a =GET_CLASS_SECURITIES(Classcode)        'Получение списка кодов бумаг (в одной строке через запятую)
razdelitel=find(pozicii_a,0,",")+0
pozicii_b =0
pozicii_b =len(pozicii_a)/(razdelitel+1)          'Сколько всего бумаг в списке (примерно)
pozicii_c =0
razdelitel=0
'===============================================================================================================================
'===============================================================================================================================

'Начало основного цикла

for cikl from 1 to pozicii_b

'==============================================================================
'Получаем Код бумаги из Текущей таблицы параметров

razdelitel_new = find(pozicii_a,(razdelitel+1),",")+0

if razdelitel_new>razdelitel

   razdelitel = razdelitel_new
   Seccode    = substr(pozicii_a,pozicii_c,(razdelitel-pozicii_c))
   pozicii_c  = razdelitel+1

'----------

today_f                    = papka & "today_" & Seccode & ".log"
ATR_f                      = papka & "ATR_" & Seccode & ".log"    

'----------
'Получение Краткого названия бумаги из Таблицы текущих значений параметров

Seccode_name = ""
Seccode_name = GET_PARAM_EX (Classcode, Seccode, "SHORTNAME")
Seccode_name = GET_VALUE(Seccode_name,"PARAM_IMAGE")

'----------
'Максимальная цена сделки из Таблицы текущих значений параметров

HIGH_now = 0
HIGH_now = GET_PARAM_EX (Classcode, Seccode, "HIGH")
HIGH_now = GET_VALUE(HIGH_now,"PARAM_VALUE")+0

'----------
'Минимальная цена сделки из Таблицы текущих значений параметров

LOW_now = 0
LOW_now = GET_PARAM_EX (Classcode, Seccode, "LOW")
LOW_now = GET_VALUE(LOW_now,"PARAM_VALUE")+0

'----------
'Дата торгов из Таблицы текущих значений параметров

TRADE_DATE = 0
TRADE_DATE = GET_PARAM_EX (Classcode, Seccode, "TRADE_DATE_CODE")
TRADE_DATE = GET_VALUE(TRADE_DATE,"PARAM_VALUE")+0

'----------
'Расчет волатильности за текущий день

ATR   = 0
today = 0
if HIGH_now>0 and LOW_now>0 
   ATR = (HIGH_now-LOW_now)/((HIGH_now+LOW_now)/2)*100    'Волатильность в % от среднедневной цены
   today = READ_LINE(today_f,1,"error")+0
   if Date<>today and Date=TRADE_DATE and Time0>185000 and Date>0 and ATR>0
      CLEAR_FILE(today_f)
      WRITELN (today_f,Date)
      WRITELN (ATR_f,ATR)
   end if   'Date<>today
end if      'HIGH_now>0 and LOW_now>0

'----------
'Расчет общей волатильности

ATR_all = 0
str     = 0
str     = GET_FILE_LEN(ATR_f)+0   'Сколько строк в файле
for n from 1 to str
   ATR0 = READ_LINE(ATR_f,n,"error")+0
   ATR_all = ATR_all + ATR0
end for

if ATR_all>0 and str>0
   ATR_all = ATR_all/str
end if

'----------
'Расчет волатильности за период

ATR_per = 0
str     = 0
p       = 0
str     = GET_FILE_LEN(ATR_f)+0   'Сколько строк в файле
period_on = str-period+1
if period_on<1
   period_on=1
end if
for n from period_on to str
   ATR0 = READ_LINE(ATR_f,n,"error")+0
   ATR_per = ATR_per + ATR0
   p = p+1
end for

if ATR_per>0 and p>0
   ATR_per = ATR_per/p
end if

'==============================================================================

output=CREATE_MAP()
output=SET_VALUE(output,"1",Seccode_name)
output=SET_VALUE(output,"2",HIGH_now)
output=SET_VALUE(output,"3",LOW_now)
output=SET_VALUE(output,"4",ATR)
output=SET_VALUE(output,"5",ATR_per)
output=SET_VALUE(output,"6",ATR_all)
ADD_ITEM(cikl,Output)

'----------
'Подсветка четных линий

if line=1
   SET_ROW_COLOR_EX (cikl, "RGB(235,235,235)", "DEFAULT_COLOR", "DEFAULT_COLOR", "DEFAULT_COLOR")            'легкая серая заливка слабая
   line=0
  else
   line=line+1
end if

'==============================================================================
'Конец основного цикла

 end if    'razdelitel_new>razdelitel
end for

'==============================================================================

END_PROGRAM

PARAMETER 1;
PARAMETER_TITLE Бумага;
PARAMETER_DESCRIPTION Бумага;
PARAMETER_TYPE STRING(32);
END

PARAMETER 2;
PARAMETER_TITLE MAX;
PARAMETER_DESCRIPTION MAX;
PARAMETER_TYPE STRING(32);  
END

PARAMETER 3;
PARAMETER_TITLE MIN;
PARAMETER_DESCRIPTION MIN;
PARAMETER_TYPE STRING(32);  
END

PARAMETER 4;
PARAMETER_TITLE ATR-now (%);
PARAMETER_DESCRIPTION ATR (%);
PARAMETER_TYPE NUMERIC(10,2);
END

PARAMETER 5;
PARAMETER_TITLE ATR-per (%);
PARAMETER_DESCRIPTION ATR (%);
PARAMETER_TYPE NUMERIC(10,2);
END

PARAMETER 6;
PARAMETER_TITLE ATR-all (%);
PARAMETER_DESCRIPTION ATR (%);
PARAMETER_TYPE NUMERIC(10,2);
END

END_PORTFOLIO_EX




8 Комментариев
  • KarL$oH
    18 декабря 2017, 15:26
    Спасибо! Нужно попробовать.
  • _Beginner_
    18 декабря 2017, 15:47
    Задумка норм.  
    Для акций, предлагаю, допилить и сделать расчет для нового индекса ММВБ (который включает 50 бумаг)
    Кстати, скрипт отлично зашел бы для фьючей.
    Жаль «плюсануть» не могу, новичЁк на форуме.

  • Владимир
    18 декабря 2017, 16:30
    Как среднедневную цену считаете? Хайло пополам?
  • Prophetic
    18 декабря 2017, 18:04
    Вы здорово усложнили себе задачу. Решать конечно только Вам, но если не C#, то хотя бы на QLua переходите. Рано или поздно Вы к этому все равно придете (если все еще будете заниматься разработкой торговых роботов), и лучше рано, чем поздно.
    Попробуйте поверить на слово, т.к. и QPile и QLua мне пришлось изучать с нуля. Начинал, как и Вы, с QPile. Сейчас полностью перешел на C#.

    Например, для получения ВСЕЙ истории свечек, которую может хранить Квик, по одному инструменту, в Lua достаточно использовать всего одну команду «CreateDataSource». И никаких таблиц в квике открывать при этом не надо.
  • noname
    18 декабря 2017, 23:15
    На фьючи такая же табличка была бы удобна, как ее реализовать

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн