Settings={ Name="STATDIV3", period=50, line= { { Name="curve", Color=RGB(0,0,255), Type=TYPE_LINE, Width=1 }, { Name="line", Color=RGB(255,0,0), Type=TYPE_LINE, Width=1 }, { Name="MA", Color=RGB(0,0,255), Type=TYPE_LINE, Width=1 }, { Name="MA2", Color=RGB(0,128,128), Type=TYPE_LINE, Width=1 }, { Name="line2", Color=RGB(0,0,255), Type=TYPE_LINE, Width=1 }, { Name="line3", Color=RGB(0,128,128), Type=TYPE_LINE, Width=1 } } } function Init() cache_ind={} cache_ind2={} cache_ind3={} return 2 end function OnCalculate(index) if index < Settings.period then return nil else local sum1=0 local sum2=0 local sum0=0 local sum02=0 local sum03=0 for i=index-Settings.period+1, index do do if C(i) > O(i) then sum1 = sum1 + C(i) - O(i) sum2 = sum2 + C(i) - O(i) else sum2 = sum2 + O(i) - C(i) end end cache_ind[index] = sum1/sum2 if index > Settings.period+12 then --[[ sum0 = 1*cache_ind[index]+ (1)*cache_ind[index-1]+ (1)*cache_ind[index-2]+ (1)*cache_ind[index-3]+ (1)*cache_ind[index-4]+ (1)*cache_ind[index-5]+ (1)*cache_ind[index-6]+ (1)*cache_ind[index-7]+ (1)*cache_ind[index-8]+ (1/2)*cache_ind[index-9]+ (1/3)*cache_ind[index-10]+ (1/4)*cache_ind[index-11]+ (1/5)*cache_ind[index-12] --]] sum0 = 1*cache_ind[index]+ (1/2)*cache_ind[index-1]+ (1/3)*cache_ind[index-2]+ (1/4)*cache_ind[index-3]+ (1/5)*cache_ind[index-4]+ (1/6)*cache_ind[index-5]+ (1/7)*cache_ind[index-6]+ (1/8)*cache_ind[index-7]+ (1/9)*cache_ind[index-8]+ (1/10)*cache_ind[index-9]+ (1/11)*cache_ind[index-10]+ (1/12)*cache_ind[index-11]+ (1/13)*cache_ind[index-12] end --[[ sum0 = sum0/(1+1+1+1+1+1+1+1+1+1/2+1/3+1/4+1/5) --]] sum0 = sum0/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13) cache_ind2[index] = sum0 if index > Settings.period+50 then sum02 = 1*cache_ind2[index]+ (1)*cache_ind2[index-1]+ (1)*cache_ind2[index-2]+ (1)*cache_ind2[index-3]+ (1)*cache_ind2[index-4]+ (1)*cache_ind2[index-5]+ (1)*cache_ind2[index-6]+ (1)*cache_ind2[index-7]+ (1/2)*cache_ind2[index-8]+ (1/3)*cache_ind2[index-9]+ (1/4)*cache_ind2[index-10]+ (1/5)*cache_ind2[index-11]+ (1/6)*cache_ind2[index-12] --[[ sum02 = 1*cache_ind2[index]+ (1/2)*cache_ind2[index-1]+ (1/3)*cache_ind2[index-2]+ (1/4)*cache_ind2[index-3]+ (1/5)*cache_ind2[index-4]+ (1/6)*cache_ind2[index-5]+ (1/7)*cache_ind2[index-6]+ (1/8)*cache_ind2[index-7]+ (1/9)*cache_ind2[index-8]+ (1/10)*cache_ind2[index-9]+ (1/11)*cache_ind2[index-10]+ (1/12)*cache_ind2[index-11]+ (1/13)*cache_ind2[index-12] --]] end sum02 = sum02/(1+1+1+1+1+1+1+1+1/2+1/3+1/4+1/5+1/6) --[[ sum02 = sum02/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13) --]] cache_ind3[index] = sum0 - sum02 if index > Settings.period+50 then sum03 = 1*cache_ind3[index]+ (1/2)*cache_ind3[index-1]+ (1/3)*cache_ind3[index-2]+ (1/4)*cache_ind3[index-3]+ (1/5)*cache_ind3[index-4]+ (1/6)*cache_ind3[index-5]+ (1/7)*cache_ind3[index-6]+ (1/8)*cache_ind3[index-7]+ (1/9)*cache_ind3[index-8]+ (1/10)*cache_ind3[index-9]+ (1/11)*cache_ind3[index-10]+ (1/12)*cache_ind3[index-11]+ (1/13)*cache_ind3[index-12] end sum03 = sum03/(1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9+1/10+1/11+1/12+1/13) end if sum1/sum2 > 0.5 and sum03 > 0 then sum1 = sum03 else if sum1/sum2 < 0.5 and sum03 < 0 then sum1 = sum03 else sum1 = 0 end end return sum1, 0 end end
--Массив с Тикерами, добавьте нужные тикеры aTickerList = {"MSNG", "GAZP", "LKOH", "SIBN", "GMKN","ROSN", "SBER", "TATN", "NVTK", "IRAO", "RSTI", "SBERP", "PHOR", "SNGS", "TRNFP", "VTBR", "FEES", "MVID", "RASP", "MFON", "AFLT", "MAGN", "ALRS", "MTSS", "MOEX", "RTKM", "MGNT", "NLMK", "SNGSP", "CHMF", "MTLR", "HYDR", "MFON", "RSTI", "PLZL", "BANEP", "POLY" }; --Функция поиска цены function fGetPrice(sTickerName, sNum) --Подключаемся к источнику данных local ds=CreateDataSource("TQBR", sTickerName, INTERVAL_D1); while (Error=="" or Error == nil) and ds:Size() ==0 do sleep(10) end; if Error ~="" and Error ~=nil then message("Error: "..Error, 1) end; local sSize=ds:Size(); local sCurrentPrice=ds:O(sSize); local sLastWeekPrice7=0; local sLastWeekPrice14=0; --Берем цену закрытия свечи неделю назад sLastWeekPrice7=ds:C(sSize-4); --Берем цену закрытия свечи 2 недели назад sLastWeekPrice14=ds:C(sSize-8); --Вычисляем проценты local sPrc7=math.floor((100-((sLastWeekPrice7*100)/sCurrentPrice))*100)/100; local sPrc14=math.floor((100-((sLastWeekPrice14*100)/sCurrentPrice))*100)/100; --Заполняем таблицу значениями SetCell(t_id, sNum, 0, tostring(sTickerName)); SetCell(t_id, sNum, 1, tostring(sCurrentPrice),sCurrentPrice); SetCell(t_id, sNum, 2, tostring(sLastWeekPrice7),sLastWeekPrice7); SetCell(t_id, sNum, 3, tostring(sLastWeekPrice14),sLastWeekPrice14); SetCell(t_id, sNum, 4, tostring(sPrc7),sPrc7); SetCell(t_id, sNum, 5, tostring(sPrc14),sPrc14); --Текущая цена больше цены прошлой недели - раскрашиваем зеленым if sCurrentPrice>sLastWeekPrice7 then fGreen(sNum); end; --Текущая цена меньше цены прошлой недели - раскрашиваем красным if sCurrentPrice<sLastWeekPrice7 then fRed(sNum); end; --Текущая цена больше цены прошлой недели и цена прошлой недели больше цены позапрошлой недели --раскрашиваем желтым if sCurrentPrice>sLastWeekPrice7 and sLastWeekPrice7>sLastWeekPrice14 then fYellow(sNum); end; end; --- Функция создает таблицу function CreateTable() -- Получает доступный id для создания t_id = AllocTable(); -- Добавляет 6 колонок AddColumn(t_id, 0, "Тикер", true, QTABLE_INT_TYPE, 15); AddColumn(t_id, 1, "Сегодня", true, QTABLE_INT_TYPE, 15); AddColumn(t_id, 2, "Неделя", true, QTABLE_INT_TYPE, 15); AddColumn(t_id, 3, "2 Недели", true, QTABLE_INT_TYPE, 15); AddColumn(t_id, 4, "Неделя (%)", true, QTABLE_INT_TYPE, 15); AddColumn(t_id, 5, "2 Недели (%)", true, QTABLE_INT_TYPE, 15); -- Создаем t = CreateWindow(t_id); -- Даем заголовок SetWindowCaption(t_id, "7 Days"); -- Добавляем строки for k,v in pairs(aTickerList) do InsertRow(t_id, k); end; end; --- Функции раскрашивают ячейки таблицы function fRed(col) SetColor(t_id, col, -1, RGB(255,168,164), RGB(0,0,0), RGB(255,168,164), RGB(0,0,0)); end; function fGreen(col) SetColor(t_id, col, -1, RGB(157,241,163), RGB(0,0,0), RGB(157,241,163), RGB(0,0,0)); end; function fYellow(col) SetColor(t_id, col, -1, RGB(249,247,172), RGB(0,0,0), RGB(249,247,172), RGB(0,0,0)); end; --Основная функция function main() -- Создаем таблицу CreateTable(); --Пробегаемся по массиву тикеров for k,v in pairs(aTickerList) do fGetPrice(v, k); end; end;как выглядит в квике:
Коллеги, всем добрый день!
В силу жизненных обстоятельств был вынужден вывести остатки денежных средств с торговой площадки. Но сила лудомании и тяга к исследованию рынка выше данных обстоятельств. Поэтому решил написать небольшое дополнение, которое позволяет протестировать стратегию без непосредственного выставления заявок в торговую систему. Вы скажете зачем это нужно, когда можно довольствоваться результатами бэк-теста. Но на мой взгляд данные результаты не в полной мере эмулируют реальную ситуацию на рынке, кроме того, форвардное тестирование тоже никто не отменял. Но, а в моём случае отсутствие дс на торговом счёте является ключевым фактором в пользу данного решения.
Если конкретизировать в программе появилась дополнительная кнопка «Equity» при нажатии на которую отображается график доходности тестируемой системы в декартовой системе координат: левая шкала-доходность в пунктах, ось X-номер сделки (см. рисунок нужен).