понедельник, 3 декабря 2012 г.

Оптимизированный VolumeProfile с лейблом точки контроля.

Нажми на изображение для увеличения
Сегодня сделал модификацию стандартного VolumeProfile программы thinkorswim. Отключил по умолчанию все ненужные мне функции, вписал по умолчанию свои опции и добавил лейбл со значением точки контроля. (при желании в опциях индикатора все можно включить снова).

Для чего это? В основном для тех кто меня порой спрашивает, где взять VolumeProfile в thinkorswim и как его настроить, что бы выглядело как у меня.

Лейбл изменяет цвет в зависимости от того, где находится цена относительно точки контроля. Красный лейбл - цена ниже точки контроля, зеленый лейбл - цена выше точки контроля. Если цена находится в диапазоне +/- 3 цента от точки контроля, то лейбл станет голубым. Со временем я сделаю ко всем своим скриптам такие лейблы, что позволит оценивать качество сигнала на вход взглянув всего на одну строку.


#mod Egor Masalskiy
#last modify 03.12.2012

input pricePerRowHeightMode = {AUTOMATIC, default TICKSIZE, CUSTOM};
input customRowHeight = 1.0;
input timePerProfile = {CHART, MINUTE, HOUR, default DAY, WEEK, MONTH, "OPT EXP", BAR};
input multiplier = 1;
input onExpansion = no;
input profiles = 1000;
input showPointOfControl = yes;
input showValueArea = yes;
input valueAreaPercent = 70;
input opacity = 50;

def period;
def yyyymmdd = GetYYYYMMDD();
def seconds = SecondsFromTime(0);
def month = GetYear() * 12 + GetMonth();
def day_number = DaysFromDate(First(yyyymmdd)) + GetDayOfWeek(First(yyyymmdd));
def dom = GetDayOfMonth(yyyymmdd);
def dow = GetDayOfWeek(yyyymmdd - dom + 1);
def expthismonth = (if dow > 5 then 27 else 20) - dow;
def exp_opt = month + (dom > expthismonth);
switch (timePerProfile) {
case CHART:
    period = 0;
case MINUTE:
    period = Floor(seconds / 60 + day_number * 24 * 60);
case HOUR:
    period = Floor(seconds / 3600 + day_number * 24);
case DAY:
    period = CountTradingDays(Min(First(yyyymmdd), yyyymmdd), yyyymmdd) - 1;
case WEEK:
    period = Floor(day_number / 7);
case MONTH:
    period = Floor(month - First(month));
case "OPT EXP":
    period = exp_opt - First(exp_opt);
case BAR:
    period = BarNumber() - 1;
}

rec count = CompoundValue(1, if period != period[1] then (count[1] + period - period[1]) % multiplier else count[1], 0);
def cond = count < count[1] + period - period[1];
def height;
switch (pricePerRowHeightMode) {
case AUTOMATIC:
    height = PricePerRow.AUTOMATIC;
case TICKSIZE:
    height = PricePerRow.TICKSIZE;
case CUSTOM:
    height = customRowHeight;
}

profile vol = VolumeProfile("startNewProfile" = cond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);
rec pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
rec hVA = if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else vol.GetHighestValueArea();
rec lVA = if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else vol.GetLowestValueArea();

rec hProfile = if IsNaN(vol.GetHighest()) and con then hProfile[1] else vol.GetHighest();
rec lProfile = if IsNaN(vol.GetLowest()) and con then lProfile[1] else vol.GetLowest();
def plotsDomain = IsNaN(close) == onExpansion;

plot POC = if plotsDomain then pc else Double.NaN;
plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;

DefineGlobalColor("Profile", GetColor(6));
DefineGlobalColor("Point Of Control", GetColor(5));
DefineGlobalColor("Value Area", GetColor(3));

vol.Show(GlobalColor("Profile"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT, opacity);
POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VALow.SetDefaultColor(GlobalColor("Value Area"));
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(GetColor(3));
ProfileLow.SetDefaultColor(GetColor(3));
ProfileHigh.Hide();
ProfileLow.Hide();

#-----------------------------Label---------------------------------------------------
def Price = close;
AddLabel(yes, Concat("PoC ", Round(pc, 2)), (if (Price < pc + 0.03 and Price > pc - 0.03) then color.CYAN else if pc > price then Color.RED else Color.GREEN));



P.S. О том как и куда вставлять эти скрипты в терминале ThinkOrSwim написано здесь.

9 комментариев:

  1. Спасибо. Интересная штукенция.

    ОтветитьУдалить
  2. только по дефолту стоит жутко зеленый цвет обьемов ))

    ОтветитьУдалить
    Ответы
    1. Да, но это любой сможет поменять. Главное что опции все сразу нужные. Не все знают как правильно их выставлять.

      Удалить
  3. Привет,Егор! А как просто установить один лейбл без всего остального? Подскажи,пожалуйста,формулу.
    Спасибо. Сергей Быстров

    ОтветитьУдалить
  4. Егор, в шапке скрипта в таком случае нужно обязательно указывать что это мод стандартного скрипта. У вас стоит первой строчкой ##by Egor Masalskiy как заявка на авторство но по сути вашего кода здесь с гулькин нос... Это не наезд, просто на будущее учтите и такую вещь.

    ОтветитьУдалить
  5. Приет,Егор! А как применить данную формулу для работы на 5 мин. графике? Что-то поменять? Спасибо.
    Сергей Быстров

    ОтветитьУдалить
    Ответы
    1. Нет. На сколько помню ничего менять не нужно. Это стандартный ТоСовский профиль, я просто лейбл допилил и настройки по-умолчанию изменил. Если вы умеете настраивать стандартный профиль и вам не нужен лейбл то сможете получить аналогичный вариант.

      Удалить