├── .github └── FUNDING.yml ├── AMA.lua ├── ATRNormalized.lua ├── AnchoredMomentum.lua ├── AutocorrelationPeriodogram.lua ├── BidAskVol.lua ├── CenterOfGravity.lua ├── CyberCycle.lua ├── DSMA.lua ├── EFSDO.lua ├── EIS.lua ├── FisherTransform.lua ├── HeikenAshi.lua ├── Hurst.lua ├── InstantaneousTrend.lua ├── JMA_Star_Light.lua ├── JRSX.lua ├── LICENSE ├── MA.lua ├── MA_ATR.lua ├── MESA.lua ├── MarginCalc.lua ├── MurreyLevels.lua ├── OnChartStochastic.lua ├── OpenCloseCrossR5.lua ├── README.md ├── RegRenkoATR.lua ├── RenkoATR.lua ├── SDSO.lua ├── StaticVar x64 lua5.3.zip ├── StepNRTR.lua ├── StepNRTRsimple ├── TEMABOL.lua ├── TMACD.lua ├── TTM_Squeeze.lua ├── WaveTrend.lua ├── _nrtr_my v41.lua ├── autoLevels.lua ├── barIndex.lua ├── barsSaver ├── barsSaver.lua ├── barsSaver_params.ini ├── readme.md └── sec_list.txt ├── bigPeriodLines.lua ├── corrCycle.lua ├── dinapoli.lua ├── dinapoliStoch.lua ├── emaRenkoATR.lua ├── extrLevels.lua ├── fibo_ema.lua ├── fibo_ema_atr.lua ├── hourOpen.lua ├── iReg.lua ├── invest_battle_pro ├── deals │ └── 2_291804.csv ├── images │ ├── buy.bmp │ ├── buy_dark.bmp │ ├── sell.bmp │ └── sell_dark.bmp ├── lchi_deals.lua └── readme.md ├── k-mean.lua ├── kReg.lua ├── lineFractals.lua ├── logging ├── log.lua └── readme.md ├── luaCOM ├── luacom.zip └── readme.md ├── lua_socket_ssl ├── lua_socket_ssl.zip ├── luasocket_lua54_x64.zip ├── readme.md └── socket_x64.zip ├── luasql ├── odbc.dll └── readme.md ├── luasqlite3 ├── lsqlite3.dll └── readme.md ├── maLib.lua ├── macdRenkoATR.lua ├── min_max_price.lua ├── nrtr_my.lua ├── pATR.lua ├── priceAvgProfile.lua ├── quantScript ├── StaticVar x64 lua5.3.zip ├── StaticVar.dll ├── priceProfile.lua ├── quantScript.csv ├── quantScript.lua ├── readme.md └── timeDelta.lua ├── rangeFlatHV.lua ├── rangeHV.lua ├── regRangeBar.lua ├── robot ├── ethlerAlgo.lua ├── nrtrAlgo.lua ├── readme.md ├── regAlgo.lua ├── renko.lua ├── robotAlgo.lua ├── robotOptimize.lua ├── robotTable.lua ├── shiftMaAlgo.lua ├── tableClass.lua └── thvAlgo.lua ├── scriptMonitor ├── Pictures │ ├── readme.md │ ├── МоиСделки_buy.bmp │ ├── МоиСделки_buy0.bmp │ ├── МоиСделки_buy1.bmp │ ├── МоиСделки_buy2.bmp │ ├── МоиСделки_buy3.bmp │ ├── МоиСделки_buy4.bmp │ ├── МоиСделки_buy5.bmp │ ├── МоиСделки_buy6.bmp │ ├── МоиСделки_buy7.bmp │ ├── МоиСделки_buy8.bmp │ ├── МоиСделки_buy9.bmp │ ├── МоиСделки_sell.bmp │ ├── МоиСделки_sell0.bmp │ ├── МоиСделки_sell1.bmp │ ├── МоиСделки_sell2.bmp │ ├── МоиСделки_sell3.bmp │ ├── МоиСделки_sell4.bmp │ ├── МоиСделки_sell5.bmp │ ├── МоиСделки_sell6.bmp │ ├── МоиСделки_sell7.bmp │ ├── МоиСделки_sell8.bmp │ └── МоиСделки_sell9.bmp ├── deals.lua ├── monitorEMA.lua ├── monitorRSI.lua ├── monitorRange.lua ├── monitorReg.lua ├── monitorStepNRTR.lua ├── monitorVSA.lua ├── monitorVolume.lua ├── nrtrMonitor.csv ├── pict │ ├── pict1.PNG │ └── pict2.PNG ├── rangeMonitor.csv ├── readme.md ├── scriptMonitor.csv ├── scriptMonitor.lua ├── scriptMonitorPar.lua └── w32.dll ├── secScanner ├── readme.md ├── secScanner.lua └── secScanner_params.ini ├── signalOrders ├── ReciveEmailProject │ ├── ReciveEmail.sln │ └── ReciveEmail │ │ ├── App.config │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── ReciveEmail.csproj │ │ ├── obj │ │ ├── Debug │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ ├── ReciveEmail.csproj.CopyComplete │ │ │ ├── ReciveEmail.csproj.CoreCompileInputs.cache │ │ │ ├── ReciveEmail.csproj.FileListAbsolute.txt │ │ │ ├── ReciveEmail.csprojAssemblyReference.cache │ │ │ ├── ReciveEmail.exe │ │ │ ├── ReciveEmail.pdb │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ └── Release │ │ │ ├── .NETFramework,Version=v4.6.1.AssemblyAttributes.cs │ │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ ├── ReciveEmail.csproj.CopyComplete │ │ │ ├── ReciveEmail.csproj.CoreCompileInputs.cache │ │ │ ├── ReciveEmail.csproj.FileListAbsolute.txt │ │ │ ├── ReciveEmail.csprojAssemblyReference.cache │ │ │ ├── ReciveEmail.exe │ │ │ ├── ReciveEmail.pdb │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ └── packages.config ├── email_bin.zip ├── libs │ ├── baseLib.lua │ └── tradeLib.lua ├── readme.md ├── signalOrders.async.lua └── tickers.csv ├── simpleSDSO.lua ├── smTMMS.lua ├── smartZZ2 ├── pict │ ├── pict1.PNG │ ├── pict2.PNG │ ├── pict3.PNG │ └── pict4.PNG ├── readme.md ├── smartZZ.lua ├── smartZZv2.lua ├── zzAnalisys.lua └── zz_algo.lua ├── telegramQuik ├── README.MD ├── SendTelegramServer v17.0.0 │ ├── App.config │ ├── MessagesQServer.csproj │ ├── MessagesQServer.csproj.user │ ├── MessagesQServer.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── SendTelegramServer v19.0.0 │ ├── App.config │ ├── MessagesQServer.csproj │ ├── MessagesQServer.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── SendTelegramServer v21 │ ├── App.config │ ├── MessagesQServer.csproj │ ├── MessagesQServer.csproj.user │ ├── MessagesQServer.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── nuget.config │ └── packages.config ├── SendTelegramServer v22.4.4 │ ├── App.config │ ├── MessagesQServer.csproj │ ├── MessagesQServer.csproj.user │ ├── MessagesQServer.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── SendTelegramServer │ ├── App.config │ ├── MessagesQServer.csproj │ ├── MessagesQServer.sln │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── ansi2utf8.lua ├── settings.ini ├── startTeleServer.bat └── test.lua ├── tema.lua ├── tester ├── Pictures │ ├── readme.md │ ├── МоиСделки_buy.bmp │ ├── МоиСделки_buy0.bmp │ ├── МоиСделки_buy1.bmp │ ├── МоиСделки_buy2.bmp │ ├── МоиСделки_buy3.bmp │ ├── МоиСделки_buy4.bmp │ ├── МоиСделки_buy5.bmp │ ├── МоиСделки_buy6.bmp │ ├── МоиСделки_buy7.bmp │ ├── МоиСделки_buy8.bmp │ ├── МоиСделки_buy9.bmp │ ├── МоиСделки_sell.bmp │ ├── МоиСделки_sell0.bmp │ ├── МоиСделки_sell1.bmp │ ├── МоиСделки_sell2.bmp │ ├── МоиСделки_sell3.bmp │ ├── МоиСделки_sell4.bmp │ ├── МоиСделки_sell5.bmp │ ├── МоиСделки_sell6.bmp │ ├── МоиСделки_sell7.bmp │ ├── МоиСделки_sell8.bmp │ └── МоиСделки_sell9.bmp ├── StaticVar.dll ├── algoResults.lua ├── barindex.lua ├── bolinger.lua ├── equityTester.lua ├── ishimoku.lua ├── oldRead.me ├── readme.md ├── renko.lua ├── testEthler.lua ├── testMonitor.csv ├── testNRTR.lua ├── testRangeHV.lua ├── testReg.lua ├── testSAR.lua ├── testShiftEMA.lua ├── testTHV_HA.lua ├── testZZ.lua └── tester.lua ├── thv_coral.lua ├── vsa.lua ├── vwap.lua ├── w32.dll.zip └── weekDayOpen.lua /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: quik_lua 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /AMA.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | nick-h@yandex.ru 3 | https://github.com/nick-nh/qlua 4 | 5 | Адаптивная скользящая средняя Перри Кауфмана. 6 | Adaptive Moving Average 7 | ]] 8 | 9 | _G.load = _G.loadfile or _G.load 10 | local maLib = load(_G.getWorkingFolder().."\\Luaindicators\\maLib.lua")() 11 | 12 | local logFile = nil 13 | --logFile = io.open(_G.getWorkingFolder().."\\LuaIndicators\\AMA.txt", "w") 14 | 15 | local message = _G['message'] 16 | local RGB = _G['RGB'] 17 | local TYPE_LINE = _G['TYPE_LINE'] 18 | local line_color = RGB(250, 0, 0) 19 | local os_time = os.time 20 | 21 | _G.Settings= { 22 | Name = "*Adaptive Moving Average", 23 | period = 10, 24 | fast_period = 2, 25 | slow_period = 30, 26 | data_type = 'Close', 27 | line = { 28 | { 29 | Name = 'Adaptive Moving Average', 30 | Color = line_color, 31 | Type = TYPE_LINE, 32 | Width = 2 33 | } 34 | } 35 | } 36 | 37 | local PlotLines = function() end 38 | local error_log = {} 39 | 40 | local function log_tostring(...) 41 | local n = select('#', ...) 42 | if n == 1 then 43 | return tostring(select(1, ...)) 44 | end 45 | local t = {} 46 | for i = 1, n do 47 | t[#t + 1] = tostring((select(i, ...))) 48 | end 49 | return table.concat(t, " ") 50 | end 51 | 52 | local function myLog(...) 53 | if logFile==nil then return end 54 | logFile:write(tostring(os.date("%c",os_time())).." "..log_tostring(...).."\n"); 55 | logFile:flush(); 56 | end 57 | 58 | local function Algo(Fsettings, ds) 59 | 60 | Fsettings = (Fsettings or {}) 61 | Fsettings.method = Fsettings.method or 'AMA' 62 | local period = Fsettings.period or 9 63 | 64 | error_log = {} 65 | 66 | local fMA 67 | local out 68 | local begin_index 69 | 70 | return function (index) 71 | 72 | out = nil 73 | 74 | local status, res = pcall(function() 75 | 76 | if not maLib then return end 77 | 78 | if fMA == nil or index == 1 then 79 | begin_index = index 80 | fMA = maLib.new(Fsettings, ds) 81 | fMA(index) 82 | return out 83 | end 84 | 85 | out = fMA(index)[(index - begin_index + 1) >= period and index or -1] 86 | 87 | end) 88 | if not status then 89 | if not error_log[tostring(res)] then 90 | error_log[tostring(res)] = true 91 | myLog(tostring(res)) 92 | message(tostring(res)) 93 | end 94 | return nil 95 | end 96 | return out 97 | end 98 | end 99 | 100 | function _G.Init() 101 | PlotLines = Algo(_G.Settings) 102 | return 1 103 | end 104 | 105 | function _G.OnChangeSettings() 106 | _G.Init() 107 | end 108 | 109 | function _G.OnCalculate(index) 110 | return PlotLines(index) 111 | end 112 | -------------------------------------------------------------------------------- /ATRNormalized.lua: -------------------------------------------------------------------------------- 1 | Settings = { 2 | Name = "*ATR Normalized + DayRange", 3 | round = "off", 4 | showATR = 1, 5 | Period = 64, 6 | NATR = 0, 7 | NATR_percent = 20, 8 | line = { 9 | { 10 | Name = "Day Range Pos", 11 | Type = TYPE_HISTOGRAM, 12 | Color = RGB(128, 255, 128), 13 | Width = 4 14 | }, 15 | { 16 | Name = "Day Range Neg", 17 | Type = TYPE_HISTOGRAM, 18 | Color = RGB(255, 128, 128), 19 | Width = 4 20 | }, 21 | { 22 | Name = "ATR", 23 | Type = TYPE_LINE, 24 | Color = RGB(0, 0, 0), 25 | Width = 2 26 | }, 27 | } 28 | } 29 | 30 | function Init() 31 | func = ATR() 32 | return #Settings.line 33 | end 34 | 35 | function OnCalculate(Index) 36 | return func(Index, Settings) 37 | end 38 | 39 | function ATR() --Average True Range ("ATR") 40 | local f_TR = TR() 41 | local ATR = {} 42 | 43 | return function (I, Fsettings, ds) 44 | 45 | local Out = nil 46 | local Fsettings=(Fsettings or {}) 47 | local P = (Fsettings.Period or 64) 48 | local showATR = (Fsettings.showATR or 1) 49 | local R = (Fsettings.round or "off") 50 | local NATR_percent = (Fsettings.NATR_percent or 0) 51 | local NATR = (Fsettings.NATR or 0) 52 | local delta = 0 53 | 54 | local previous = I-1 55 | 56 | if not CandleExist(previous) then 57 | previous = FindExistCandle(previous) 58 | end 59 | if CandleExist(I) and previous ~= 0 then 60 | delta=C(I)-C(previous) 61 | out_incrementum = math.abs(delta) 62 | else 63 | out_incrementum = 0 64 | end 65 | 66 | if showATR == 1 then 67 | if NATR == 0 then 68 | 69 | if I
P then
80 | ATR[I]=(ATR[I-1] * (P-1) + f_TR(I,{round="off"},ds)) / P
81 | end
82 |
83 | Out = ATR[I]
84 |
85 | else
86 |
87 | local myATR = {}
88 |
89 | for i = 0, P-1 do
90 | myATR[i] = f_TR(I-i,{round="off"},ds)
91 | end
92 |
93 | table.sort(myATR)
94 |
95 | local cut_num = math.ceil((P*NATR_percent)*0.01/2)
96 | local sred = 0
97 |
98 | for i = cut_num, P-cut_num-1 do
99 | sred = sred + myATR[i]
100 | end
101 |
102 | Out=sred/(P-cut_num*2)
103 |
104 | end
105 | end
106 |
107 | if I>=P then
108 | if delta>0 then
109 | return out_incrementum, nil, rounding(Out, R)
110 | else
111 | return nil, out_incrementum, rounding(Out, R)
112 | end
113 | else
114 | return 0,0,nil
115 | end
116 |
117 | end
118 | end
119 |
120 | ----------------------------
121 | function FindExistCandle(I)
122 |
123 | local out = I
124 |
125 | while not CandleExist(out) and out > 0 do
126 | out = out -1
127 | end
128 |
129 | return out
130 |
131 | end
132 |
133 | function TR() --True Range ("TR")
134 | return function (I, Fsettings, ds)
135 | local Fsettings=(Fsettings or {})
136 | local R = (Fsettings.round or "off")
137 | local Out = nil
138 | local previous = I-1
139 |
140 | if not CandleExist(I) then
141 | return 0
142 | end
143 | if not CandleExist(previous) then
144 | previous = FindExistCandle(previous)
145 | end
146 |
147 | if previous == 0 then
148 | return 0
149 | end
150 |
151 | if I==1 then
152 | Out = math.abs(Value(I,"Difference", ds))
153 | else
154 | Out = math.max(math.abs(Value(I,"Difference", ds)),
155 | math.abs(Value(I,"High",ds) - Value(previous,"Close",ds)),
156 | math.abs(Value(previous,"Close",ds)-Value(I,"Low",ds)))
157 | end
158 | return rounding(Out, R)
159 | end
160 | end
161 |
162 | function rounding(num, round)
163 | if round and string.upper(round)== "ON" then round=0 end
164 | if num and tonumber(round) then
165 | local mult = 10^round
166 | if num >= 0 then return math.floor(num * mult + 0.5) / mult
167 | else return math.ceil(num * mult - 0.5) / mult end
168 | else return num end
169 | end
170 |
171 | function Value(I,VType,ds)
172 | local Out = nil
173 | VType=(VType and string.upper(string.sub(VType,1,1))) or "A"
174 | if VType == "O" then --Open
175 | Out = (O and O(I)) or (ds and ds:O(I))
176 | elseif VType == "H" then --High
177 | Out = (H and H(I)) or (ds and ds:H(I))
178 | elseif VType == "L" then --Low
179 | Out = (L and L(I)) or (ds and ds:L(I))
180 | elseif VType == "C" then --Close
181 | Out = (C and C(I)) or (ds and ds:C(I))
182 | elseif VType == "V" then --Volume
183 | Out = (V and V(I)) or (ds and ds:V(I))
184 | elseif VType == "M" then --Median
185 | Out = ((Value(I,"H",ds) + Value(I,"L",ds)) / 2)
186 | elseif VType == "T" then --Typical
187 | Out = ((Value(I,"M",ds) * 2 + Value(I,"C",ds))/3)
188 | elseif VType == "W" then --Weighted
189 | Out = ((Value(I,"T",ds) * 3 + Value(I,"O",ds))/4)
190 | elseif VType == "D" then --Difference
191 | Out = (Value(I,"H",ds) - Value(I,"L",ds))
192 | elseif VType == "A" then --Any
193 | if ds then Out = ds[I] else Out = nil end
194 | end
195 | return Out
196 | end
197 |
--------------------------------------------------------------------------------
/AnchoredMomentum.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | nick-h@yandex.ru
3 | https://github.com/nick-nh/qlua
4 |
5 | Smoothed Anchored Momentum
6 | ]]
7 | _G.load = _G.loadfile or _G.load
8 | local maLib = load(_G.getWorkingFolder().."\\Luaindicators\\maLib.lua")()
9 |
10 | local logFile = nil
11 | --logFile = io.open(_G.getWorkingFolder().."\\LuaIndicators\\TEMA.txt", "w")
12 |
13 | local message = _G['message']
14 | local RGB = _G['RGB']
15 | local TYPE_LINE = _G['TYPE_LINE']
16 | local isDark = _G.isDarkTheme()
17 | local zero_color = isDark and RGB(123, 123, 123) or RGB(70, 70, 70)
18 | local line_color = RGB(250, 0, 0)
19 | local os_time = os.time
20 |
21 | _G.Settings= {
22 | Name = "*Smoothed Anchored Momentum",
23 | data_type = 'Close',
24 | period = 11, -- Период доп. усреднения SMA
25 | ema_period = 6, -- Период доп. усреднения EMA
26 | line = {
27 | {
28 | Name = 'zero',
29 | Color = zero_color,
30 | Type = TYPE_LINE,
31 | Width = 1
32 | },
33 | {
34 | Name = 'Smoothed Anchored Momentum',
35 | Color = line_color,
36 | Type = TYPE_LINE,
37 | Width = 2
38 | }
39 | }
40 | }
41 |
42 | local PlotLines = function() end
43 | local error_log = {}
44 |
45 | local function log_tostring(...)
46 | local n = select('#', ...)
47 | if n == 1 then
48 | return tostring(select(1, ...))
49 | end
50 | local t = {}
51 | for i = 1, n do
52 | t[#t + 1] = tostring((select(i, ...)))
53 | end
54 | return table.concat(t, " ")
55 | end
56 |
57 | local function myLog(...)
58 | if logFile==nil then return end
59 | logFile:write(tostring(os.date("%c",os_time())).." "..log_tostring(...).."\n");
60 | logFile:flush();
61 | end
62 | ------------------------------------------------------------------
63 | --Moving Average
64 | ------------------------------------------------------------------
65 |
66 | local function Algo(Fsettings, ds)
67 |
68 | Fsettings = (Fsettings or {})
69 | local data_type = (Fsettings.data_type or "Close")
70 | local period = (Fsettings.period or 11)
71 | local ema_period = (Fsettings.ema_period or 6)
72 | local round = (Fsettings.round or "off")
73 | local scale = (Fsettings.scale or 0)
74 |
75 | error_log = {}
76 |
77 | local fSMA
78 | local fEMA
79 | local out
80 | local begin_index
81 |
82 | return function (index)
83 |
84 | local status, res = pcall(function()
85 |
86 | out = nil
87 |
88 | if not maLib then return end
89 |
90 | if fSMA == nil or index == 1 then
91 | begin_index = index
92 | fSMA = maLib.new({period = 2*period + 1, method = 'SMA', data_type = data_type, round = round, scale = scale}, ds)
93 | fSMA(index)
94 | fEMA = maLib.new({period = ema_period, method = 'EMA', data_type = data_type, round = round, scale = scale}, ds)
95 | fEMA(index)
96 | return
97 | end
98 |
99 | local sma = fSMA(index)[index]
100 | local ema = fEMA(index)[index]
101 |
102 | out = (index - begin_index + 1) >= period and (sma == 0 and out or 100*((ema/sma) - 1)) or nil
103 | end)
104 | if not status then
105 | if not error_log[tostring(res)] then
106 | error_log[tostring(res)] = true
107 | myLog(tostring(res))
108 | message(tostring(res))
109 | end
110 | end
111 | return 0, out
112 | end
113 | end
114 |
115 | function _G.Init()
116 | PlotLines = Algo(_G.Settings)
117 | return 2
118 | end
119 |
120 | function _G.OnChangeSettings()
121 | _G.Init()
122 | end
123 |
124 | function _G.OnCalculate(index)
125 | return PlotLines(index)
126 | end
127 |
--------------------------------------------------------------------------------
/CenterOfGravity.lua:
--------------------------------------------------------------------------------
1 |
2 | Settings =
3 | {
4 | Name = "*CenterOfGravity",
5 | alpha = 0.07,
6 | cGLength = 10,
7 | cycletype = 1, -- 0 - simle, 1 - adaptive
8 | line=
9 | {
10 | {
11 | Name = "Cycle",
12 | Color = RGB(0, 128, 0),
13 | Type = TYPE_LINE,
14 | Width = 2
15 | }
16 | ,
17 | {
18 | Name = "Trigger Line",
19 | Color = RGB(255, 0, 0),
20 | Type = TYPE_LINE,
21 | Width = 2
22 | }
23 | }
24 | }
25 |
26 | ----------------------------------------------------------
27 | function CyberCycle()
28 |
29 | local Price={}
30 | local Smooth={}
31 | local Cycle={}
32 | local aCycle={}
33 | local Trigger={}
34 | local CyclePeriod={}
35 | local InstPeriod={}
36 | local Q1={}
37 | local I1={}
38 | local DeltaPhase={}
39 |
40 | --local SMA=fSMA()
41 |
42 | return function(ind, _a, _cg, _t)
43 |
44 | local index = ind
45 | local alpha = _a
46 | local cycletype = _t
47 | local cGLength = _cg
48 |
49 | local DC, MedianDelta, alpha1
50 |
51 | if index == 1 then
52 | Price = {}
53 | Smooth={}
54 | Cycle={}
55 | aCycle={}
56 | Trigger={}
57 | CyclePeriod={}
58 | InstPeriod={}
59 | Q1={}
60 | I1={}
61 | DeltaPhase={}
62 |
63 | Price[index] = (H(index) + L(index))/2
64 | Smooth[index]=0
65 | Cycle[index]=0
66 | aCycle[index]=0
67 | Trigger[index]=0
68 | CyclePeriod[index]=0
69 | InstPeriod[index]=0
70 | Q1[index]=0
71 | I1[index]=0
72 | DeltaPhase[index]=0
73 | return nil, nil
74 | end
75 |
76 | Price[index] = (H(index) + L(index))/2
77 |
78 | local Num = 0.0
79 | local Denom = 0.0
80 | local count = 0
81 |
82 | if cycletype == 1 then
83 |
84 | if index < 4 then
85 | Cycle[index]=0
86 | aCycle[index]=0
87 | CyclePeriod[index]=0
88 | InstPeriod[index]=0
89 | Q1[index]=0
90 | I1[index]=0
91 | DeltaPhase[index]=0
92 | return nil, nil
93 | end
94 |
95 | Smooth[index] = (Price[index]+2*Price[index - 1]+2*Price[index - 2]+Price[index - 3])/6.0
96 | Cycle[index]=(Price[index]-2.0*Price[index - 1]+Price[index - 2])/4.0
97 |
98 | if index < 7 then
99 | aCycle[index]=0
100 | CyclePeriod[index]=0
101 | InstPeriod[index]=0
102 | Q1[index]=0
103 | I1[index]=0
104 | DeltaPhase[index]=0
105 | return nil, nil
106 | end
107 |
108 | Cycle[index]=(1.0-0.5*alpha) *(1.0-0.5*alpha) *(Smooth[index]-2.0*Smooth[index - 1]+Smooth[index - 2])
109 | +2.0*(1.0-alpha)*Cycle[index - 1]-(1.0-alpha)*(1.0-alpha)*Cycle[index - 2]
110 |
111 | Trigger[index] = Cycle[index-1]
112 |
113 | Q1[index] = (0.0962*Cycle[index]+0.5769*Cycle[index-2]-0.5769*Cycle[index-4]-0.0962*Cycle[index-6])*(0.5+0.08*(InstPeriod[index-1] or 0))
114 | I1[index] = Cycle[index-3]
115 |
116 | if Q1[index]~=0.0 and Q1[index-1]~=0.0 then
117 | DeltaPhase[index] = (I1[index]/Q1[index]-I1[index-1]/Q1[index-1])/(1.0+I1[index]*I1[index-1]/(Q1[index]*Q1[index-1]))
118 | else DeltaPhase[index] = 0
119 | end
120 | if DeltaPhase[index] < 0.1 then
121 | DeltaPhase[index] = 0.1
122 | end
123 | if DeltaPhase[index] > 0.9 then
124 | DeltaPhase[index] = 0.9
125 | end
126 |
127 | MedianDelta = Median(DeltaPhase[index],DeltaPhase[index-1], Median(DeltaPhase[index-2], DeltaPhase[index-3], DeltaPhase[index-4]))
128 |
129 | if MedianDelta == 0.0 then
130 | DC = 15.0
131 | else
132 | DC = 6.28318/MedianDelta + 0.5
133 | end
134 |
135 | InstPeriod[index] = 0.33 * DC + 0.67 * (InstPeriod[index-1] or 0)
136 | CyclePeriod[index] = 0.15 * InstPeriod[index] + 0.85 * CyclePeriod[index-1]
137 |
138 | cGLength = math.floor(CyclePeriod[index]/2.0)
139 | end
140 |
141 | if index < cGLength then
142 | return nil, nil
143 | end
144 |
145 | while count < cGLength do
146 | Num = Num + (1.0+count)*Price[index - count]
147 | Denom = Denom + Price[index - count]
148 | count = count + 1
149 | end
150 |
151 | if Denom ~= 0.0 then
152 | aCycle[index] = -Num/Denom+(cGLength+1.0)/2.0
153 | else
154 | aCycle[index] = 0.0
155 | end
156 |
157 | Trigger[index] = aCycle[index-1]
158 |
159 | return aCycle[index], Trigger[index]
160 | end
161 | end
162 |
163 |
164 | function Init()
165 | myCyberCycle = CyberCycle()
166 | return #Settings.line
167 | end
168 |
169 | function OnCalculate(index)
170 |
171 | return myCyberCycle(index, Settings.alpha, Settings.cGLength, Settings.cycletype)
172 | end
173 |
174 | function Median(x, y, z)
175 | return (x+y+z) - math.min(x,math.min(y,z)) - math.max(x,math.max(y,z))
176 | end
177 |
178 | function fSMA()
179 |
180 | return function (Index, Period, bb)
181 |
182 | local Out = 0
183 |
184 | if Index >= Period then
185 | local sum = 0
186 | for i = Index-Period+1, Index do
187 | sum = sum + bb[i]
188 | end
189 | Out = sum/Period
190 | end
191 |
192 | return Out
193 | end
194 | end
--------------------------------------------------------------------------------
/DSMA.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | nick-h@yandex.ru
3 | https://github.com/nick-nh/qlua
4 |
5 | DSMA Deviation-Scaled Moving Average by John F. Ehlers
6 | ]]
7 |
8 | _G.load = _G.loadfile or _G.load
9 | local maLib = load(_G.getWorkingFolder().."\\Luaindicators\\maLib.lua")()
10 |
11 | local logFile = nil
12 | --logFile = io.open(_G.getWorkingFolder().."\\LuaIndicators\\DSMA.txt", "w")
13 |
14 | local message = _G['message']
15 | local RGB = _G['RGB']
16 | local TYPE_LINE = _G['TYPE_LINE']
17 | local isDark = _G.isDarkTheme()
18 | local os_time = os.time
19 |
20 | _G.Settings= {
21 | Name = "*DSMA",
22 | period = 40,
23 | poles = 2, --[2, 3]
24 | data_type = 'Close',
25 | line = {
26 | {
27 | Name = 'DSMA',
28 | Color = isDark and RGB(255, 193, 193) or RGB(113, 0, 0),
29 | Type = TYPE_LINE,
30 | Width = 2
31 | }
32 | }
33 | }
34 |
35 | local PlotLines = function() end
36 | local error_log = {}
37 |
38 | local function log_tostring(...)
39 | local n = select('#', ...)
40 | if n == 1 then
41 | return tostring(select(1, ...))
42 | end
43 | local t = {}
44 | for i = 1, n do
45 | t[#t + 1] = tostring((select(i, ...)))
46 | end
47 | return table.concat(t, " ")
48 | end
49 |
50 | local function myLog(...)
51 | if logFile==nil then return end
52 | logFile:write(tostring(os.date("%c",os_time())).." "..log_tostring(...).."\n");
53 | logFile:flush();
54 | end
55 |
56 | ------------------------------------------------------------------
57 | --Moving Average
58 | ------------------------------------------------------------------
59 |
60 | local function Algo(Fsettings, ds)
61 |
62 | Fsettings = (Fsettings or {})
63 | local data_type = (Fsettings.data_type or "Close")
64 | local period = Fsettings.period or 9
65 | local poles = Fsettings.poles or 2
66 |
67 | error_log = {}
68 |
69 | local fSSF
70 | local out
71 |
72 | local edsma
73 | local avgZeros
74 | local zeros
75 |
76 | return function (index)
77 |
78 | out = nil
79 |
80 | local status, res = pcall(function()
81 |
82 | if not maLib then return end
83 |
84 | local val = maLib.Value(index, data_type, ds)
85 |
86 | if fSSF == nil or index == 1 then
87 | edsma = {}
88 | edsma[index] = 0
89 | zeros = {}
90 | zeros[index] = 0
91 | avgZeros = {}
92 | avgZeros[index] = 0
93 | fSSF = poles == 2 and maLib.Get2PoleSSF({period = period, data_type = 'Any'}, avgZeros) or maLib.Get3PoleSSF({period = period, data_type = 'Any'}, avgZeros)
94 | fSSF(index)
95 | return
96 | end
97 |
98 | zeros[index] = zeros[index-1]
99 | avgZeros[index] = avgZeros[index-1]
100 | edsma[index] = edsma[index-1]
101 |
102 | --Ehlers Super Smoother Filter
103 | local ssf = fSSF(index)
104 |
105 | if not maLib.CheckIndex(index, ds) then
106 | return
107 | end
108 |
109 | zeros[index] = val - (maLib.Value(maLib.GetIndex(index, 2, ds, data_type), data_type, ds))
110 | avgZeros[index] = (zeros[index] + zeros[index-1])/2
111 |
112 | --Rescale filter in terms of Standard Deviations
113 | local stdev = maLib.Sigma(ssf, nil, index - period + 1, index)
114 | local scaledFilter = stdev ~= 0 and ssf[index]/stdev or 0
115 |
116 | local alpha = 5*math.abs(scaledFilter)/period
117 |
118 | edsma[index] = alpha*val + (1 - alpha)*(edsma[index - 1] or 0)
119 |
120 | out = edsma[index]
121 | end)
122 | if not status then
123 | if not error_log[tostring(res)] then
124 | error_log[tostring(res)] = true
125 | myLog(tostring(res))
126 | message(tostring(res))
127 | end
128 | return nil
129 | end
130 | return out
131 | end
132 | end
133 |
134 | function _G.Init()
135 | PlotLines = Algo(_G.Settings)
136 | return 1
137 | end
138 |
139 | function _G.OnChangeSettings()
140 | _G.Init()
141 | end
142 |
143 | function _G.OnCalculate(index)
144 | return PlotLines(index)
145 | end
146 |
--------------------------------------------------------------------------------
/EFSDO.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | nick-h@yandex.ru
3 | https://github.com/nick-nh/qlua
4 |
5 | EFDSO Ehlers Fisherized Deviation-Scaled Oscillator
6 | ]]
7 |
8 | _G.load = _G.loadfile or _G.load
9 | local maLib = load(_G.getWorkingFolder().."\\Luaindicators\\maLib.lua")()
10 |
11 | local logFile = nil
12 | --logFile = io.open(_G.getWorkingFolder().."\\LuaIndicators\\EFDSO.txt", "w")
13 |
14 | local message = _G['message']
15 | local RGB = _G['RGB']
16 | local TYPE_LINE = _G['TYPE_LINE']
17 | local isDark = _G.isDarkTheme()
18 | local os_time = os.time
19 | local zero_color = isDark and RGB(123, 123, 123) or RGB(70, 70, 70)
20 |
21 | _G.Settings= {
22 | Name = "*EFDSO",
23 | period = 20,
24 | poles = 2, --[2, 3]
25 | data_type = 'Close',
26 | obLevel = 2.0, -- уровень перекупленности
27 | osLevel = -2.0, -- уровень перпроданности
28 | line = {
29 | {
30 | Name = 'zero',
31 | Color = zero_color,
32 | Type = TYPE_LINE,
33 | Width = 1
34 | },
35 | {
36 | Name = 'OB',
37 | Color = isDark and RGB(123, 255, 123) or RGB(70, 193, 70),
38 | Type = TYPE_LINE,
39 | Width = 1
40 | },
41 | {
42 | Name = 'OS',
43 | Color = isDark and RGB(255, 150, 150) or RGB(193, 70, 70),
44 | Type = TYPE_LINE,
45 | Width = 1
46 | },
47 | {
48 | Name = 'EFDSO',
49 | Color = isDark and RGB(255, 193, 193) or RGB(23, 23, 23),
50 | Type = TYPE_LINE,
51 | Width = 2
52 | }
53 | }
54 | }
55 |
56 | local PlotLines = function() end
57 | local error_log = {}
58 |
59 | local function log_tostring(...)
60 | local n = select('#', ...)
61 | if n == 1 then
62 | return tostring(select(1, ...))
63 | end
64 | local t = {}
65 | for i = 1, n do
66 | t[#t + 1] = tostring((select(i, ...)))
67 | end
68 | return table.concat(t, " ")
69 | end
70 |
71 | local function myLog(...)
72 | if logFile==nil then return end
73 | logFile:write(tostring(os.date("%c",os_time())).." "..log_tostring(...).."\n");
74 | logFile:flush();
75 | end
76 |
77 | ------------------------------------------------------------------
78 | --Moving Average
79 | ------------------------------------------------------------------
80 |
81 | local function Algo(Fsettings, ds)
82 |
83 | Fsettings = (Fsettings or {})
84 | local data_type = (Fsettings.data_type or "Close")
85 | local period = Fsettings.period or 9
86 | local poles = Fsettings.poles or 2
87 | local obLevel = Fsettings.obLevel or 2
88 | local osLevel = Fsettings.osLevel or -2
89 |
90 | error_log = {}
91 |
92 | local fSSF
93 | local out
94 |
95 | local efsdo
96 | local avgZeros
97 | local zeros
98 | local scaledFilter
99 |
100 | return function (index)
101 |
102 | out = nil
103 |
104 | local status, res = pcall(function()
105 |
106 | if not maLib then return end
107 |
108 | local val = maLib.Value(index, data_type, ds)
109 |
110 | if fSSF == nil or index == 1 then
111 | efsdo = {}
112 | efsdo[index] = 0
113 | zeros = {}
114 | zeros[index] = 0
115 | avgZeros = {}
116 | avgZeros[index] = 0
117 | fSSF = poles == 2 and maLib.Get2PoleSSF({period = period, data_type = 'Any'}, avgZeros) or maLib.Get3PoleSSF({period = period, data_type = 'Any'}, avgZeros)
118 | fSSF(index)
119 | return
120 | end
121 |
122 | zeros[index] = zeros[index-1]
123 | avgZeros[index] = avgZeros[index-1]
124 | efsdo[index] = efsdo[index-1]
125 |
126 | --Ehlers Super Smoother Filter
127 | local ssf = fSSF(index)
128 |
129 | if not maLib.CheckIndex(index, ds) then
130 | return
131 | end
132 |
133 | zeros[index] = val - (maLib.Value(maLib.GetIndex(index, 2, ds, data_type), data_type, ds))
134 | avgZeros[index] = (zeros[index] + zeros[index-1])/2
135 |
136 | --Rescale filter in terms of Standard Deviations
137 | local stdev = maLib.Sigma(ssf, nil, index - period + 1, index)
138 | scaledFilter = stdev ~= 0 and ssf[index]/stdev or scaledFilter
139 |
140 | --Apply Fisher Transform to establish real Gaussian Probability Distribution
141 | efsdo[index] = math.abs(scaledFilter) < 2 and 0.5*math.log((1 + scaledFilter/2)/(1 - scaledFilter/2)) or efsdo[index]
142 |
143 | out = efsdo[index]
144 | end)
145 | if not status then
146 | if not error_log[tostring(res)] then
147 | error_log[tostring(res)] = true
148 | myLog(tostring(res))
149 | message(tostring(res))
150 | end
151 | return nil
152 | end
153 | return 0, obLevel, osLevel, out
154 | end
155 | end
156 |
157 | function _G.Init()
158 | PlotLines = Algo(_G.Settings)
159 | return 4
160 | end
161 |
162 | function _G.OnChangeSettings()
163 | _G.Init()
164 | end
165 |
166 | function _G.OnCalculate(index)
167 | return PlotLines(index)
168 | end
169 |
--------------------------------------------------------------------------------
/EIS.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/EIS.lua
--------------------------------------------------------------------------------
/HeikenAshi.lua:
--------------------------------------------------------------------------------
1 | Settings =
2 | {
3 | Name = "*HeikenAshi",
4 | line =
5 | {
6 | {
7 | Name = "HeikenAshiUP",
8 | Color = RGB(0,255,0),
9 | Type = TYPE_POINT,
10 | Width =3
11 | },
12 | {
13 | Name = "HeikenAshiDown",
14 | Color = RGB(255,0,0),
15 | Type = TYPE_POINT,
16 | Width =3
17 | }
18 | }
19 | }
20 |
21 | function dValue(i,param)
22 | local v = param or "C"
23 |
24 | if not CandleExist(i) then
25 | return nil
26 | end
27 |
28 | if v == "O" then
29 | return O(i)
30 | elseif v == "H" then
31 | return H(i)
32 | elseif v == "L" then
33 | return L(i)
34 | elseif v == "C" then
35 | return C(i)
36 | elseif v == "V" then
37 | return V(i)
38 | elseif v == "M" then
39 | return (H(i) + L(i))/2
40 | elseif v == "T" then
41 | return (H(i) + L(i)+C(i))/3
42 | elseif v == "W" then
43 | return (H(i) + L(i)+2*C(i))/4
44 | elseif v == "ATR" then
45 | local previous = math.max(i-1, 1)
46 |
47 | if not CandleExist(previous) then
48 | previous = FindExistCandle(previous)
49 | end
50 | if previous == 0 then
51 | return 0
52 | end
53 |
54 | return math.max(math.abs(H(i) - L(i)), math.abs(H(i) - C(previous)), math.abs(C(previous) - L(i)))
55 | else
56 | return C(i)
57 | end
58 | end
59 |
60 | function FindExistCandle(I)
61 |
62 | local out = I
63 |
64 | while not CandleExist(out) and out > 0 do
65 | out = out -1
66 | end
67 |
68 | return out
69 |
70 | end
71 |
72 | function Init()
73 | myHA = HA()
74 | return #Settings.line
75 | end
76 |
77 | function OnCalculate(index)
78 | return myHA(index, Settings)
79 | end
80 |
81 | function HA()
82 |
83 | local cache_O={}
84 | local cache_C={}
85 |
86 | return function(ind, Fsettings)
87 |
88 | local Fsettings=(Fsettings or {})
89 | local index = ind
90 |
91 | local openHA
92 | local closeHA
93 | local highHA
94 | local lowHA
95 |
96 | local outDown
97 | local outUP
98 |
99 | if index == 1 then
100 | cache_O = {}
101 | cache_C = {}
102 | cache_O[index]= 0
103 | cache_C[index]= 0
104 | return nil
105 | end
106 |
107 | cache_O[index] = cache_O[index-1]
108 | cache_C[index] = cache_C[index-1]
109 |
110 | if not CandleExist(index) then
111 | return nil
112 | end
113 |
114 | cache_O[index]=O(index)
115 | cache_C[index]=C(index)
116 |
117 | openHA = (cache_O[index-1] + cache_C[index-1])/2
118 | closeHA = (O(index) + H(index) + L(index) + C(index))/4
119 | highHA = math.max(H(index), math.max(openHA, closeHA))
120 | lowHA = math.min(L(index), math.min(openHA, closeHA))
121 |
122 | cache_O[index] = openHA
123 | cache_C[index] = closeHA
124 |
125 | if openHA < closeHA then
126 | outDown = nil
127 | outUP = (H(index) + L(index))/2
128 | elseif openHA > closeHA then
129 | outDown = (H(index) + L(index))/2
130 | outUP = nil
131 | end
132 |
133 | return outUP, outDown
134 |
135 | end
136 | end
137 |
138 | function round(num, idp)
139 | if idp and num then
140 | local mult = 10^(idp or 0)
141 | if num >= 0 then return math.floor(num * mult + 0.5) / mult
142 | else return math.ceil(num * mult - 0.5) / mult end
143 | else return num end
144 | end
145 |
--------------------------------------------------------------------------------
/InstantaneousTrend.lua:
--------------------------------------------------------------------------------
1 |
2 | Settings =
3 | {
4 | Name = "*Ehlers Instantaneous Trend",
5 | alpha = 0.03,
6 | shift = 5,
7 | cycletype = 1, -- 0 - simle, 1 - adaptive
8 | line=
9 | {
10 | {
11 | Name = "Trend",
12 | Color = RGB(0, 128, 0),
13 | Type = TYPE_LINE,
14 | Width = 2
15 | }
16 | ,
17 | {
18 | Name = "Trigger",
19 | Color = RGB(255, 0, 0),
20 | Type = TYPE_LINE,
21 | Width = 2
22 | }
23 | }
24 | }
25 |
26 | ----------------------------------------------------------
27 | function CyberCycle()
28 |
29 | local Price={}
30 | local Smooth={}
31 | local Cycle={}
32 | local it={}
33 | local Trigger={}
34 | local CyclePeriod={}
35 | local InstPeriod={}
36 | local Q1={}
37 | local I1={}
38 | local DeltaPhase={}
39 |
40 | --local SMA=fSMA()
41 |
42 | return function(ind, _a, _t, _s)
43 |
44 | local index = ind
45 | local alpha = _a
46 | local alpha1 = _a
47 | local cycletype = _t
48 | local shift = _s
49 |
50 | local DC, MedianDelta
51 |
52 | if index == 1 then
53 | Price = {}
54 | Smooth={}
55 | Cycle={}
56 | it={}
57 | Trigger={}
58 | CyclePeriod={}
59 | InstPeriod={}
60 | Q1={}
61 | I1={}
62 | DeltaPhase={}
63 |
64 | Price[index] = (H(index) + L(index))/2
65 | Smooth[index]=0
66 | Cycle[index]=0
67 | it[index]=0
68 | Trigger[index]=0
69 | CyclePeriod[index]=0
70 | InstPeriod[index]=0
71 | Q1[index]=0
72 | I1[index]=0
73 | DeltaPhase[index]=0
74 | return nil, nil
75 | end
76 |
77 | Price[index] = (H(index) + L(index))/2
78 |
79 | if index < 4 then
80 | Cycle[index]=0
81 | it[index]=0
82 | CyclePeriod[index]=0
83 | InstPeriod[index]=0
84 | Q1[index]=0
85 | I1[index]=0
86 | DeltaPhase[index]=0
87 | return nil, nil
88 | end
89 |
90 | Cycle[index]=(Price[index]-2.0*Price[index - 1]+Price[index - 2])/4.0
91 |
92 | if cycletype == 1 then
93 |
94 | Smooth[index] = (Price[index]+2*Price[index - 1]+2*Price[index - 2]+Price[index - 3])/6.0
95 |
96 | if index < 7 then
97 | it[index]=0
98 | CyclePeriod[index]=0
99 | InstPeriod[index]=0
100 | Q1[index]=0
101 | I1[index]=0
102 | DeltaPhase[index]=0
103 | return nil, nil
104 | end
105 |
106 | Cycle[index]=(1.0-0.5*alpha) *(1.0-0.5*alpha) *(Smooth[index]-2.0*Smooth[index - 1]+Smooth[index - 2])
107 | +2.0*(1.0-alpha)*Cycle[index - 1]-(1.0-alpha)*(1.0-alpha)*Cycle[index - 2]
108 |
109 | Q1[index] = (0.0962*Cycle[index]+0.5769*Cycle[index-2]-0.5769*Cycle[index-4]-0.0962*Cycle[index-6])*(0.5+0.08*(InstPeriod[index-1] or 0))
110 | I1[index] = Cycle[index-3]
111 |
112 | if Q1[index]~=0.0 and Q1[index-1]~=0.0 then
113 | DeltaPhase[index] = (I1[index]/Q1[index]-I1[index-1]/Q1[index-1])/(1.0+I1[index]*I1[index-1]/(Q1[index]*Q1[index-1]))
114 | else DeltaPhase[index] = 0
115 | end
116 | if DeltaPhase[index] < 0.1 then
117 | DeltaPhase[index] = 0.1
118 | end
119 | if DeltaPhase[index] > 0.9 then
120 | DeltaPhase[index] = 0.9
121 | end
122 |
123 | MedianDelta = Median(DeltaPhase[index],DeltaPhase[index-1], Median(DeltaPhase[index-2], DeltaPhase[index-3], DeltaPhase[index-4]))
124 |
125 | if MedianDelta == 0.0 then
126 | DC = 15.0
127 | else
128 | DC = 6.28318/MedianDelta + 0.5
129 | end
130 |
131 | InstPeriod[index] = 0.33 * DC + 0.67 * (InstPeriod[index-1] or 0)
132 | CyclePeriod[index] = 0.15 * InstPeriod[index] + 0.85 * CyclePeriod[index-1]
133 |
134 | alpha1 = 2.0/(CyclePeriod[index]+1.0)
135 | end
136 |
137 | it[index]=(alpha1-((alpha1*alpha1)/4.0))*Price[index]+0.5*alpha1*alpha1*Price[index-1]-(alpha1-0.75*alpha1*alpha1)*Price[index-2]+
138 | 2*(1-alpha1)*(it[index-1] or Cycle[index])-(1-alpha1)*(1-alpha1)*(it[index-2] or Cycle[index])
139 |
140 | lag = 2.0*it[index]-(it[index-shift] or 0)
141 |
142 |
143 | return it[index], lag
144 | end
145 | end
146 |
147 |
148 | function Init()
149 | myCyberCycle = CyberCycle()
150 | return #Settings.line
151 | end
152 |
153 | function OnCalculate(index)
154 |
155 | return myCyberCycle(index, Settings.alpha, Settings.cycletype, Settings.shift)
156 | end
157 |
158 | function Median(x, y, z)
159 | return (x+y+z) - math.min(x,math.min(y,z)) - math.max(x,math.max(y,z))
160 | end
161 |
162 | function fSMA()
163 |
164 | return function (Index, Period, bb)
165 |
166 | local Out = 0
167 |
168 | if Index >= Period then
169 | local sum = 0
170 | for i = Index-Period+1, Index do
171 | sum = sum + bb[i]
172 | end
173 | Out = sum/Period
174 | end
175 |
176 | return Out
177 | end
178 | end
179 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Nikolay Hartanovich P then
41 | ATR[I]=(ATR[I-1] * (P-1) + f_TR(I,{round="off"},ds)*(PR == 1 and (200/(Value(I,"High",ds) + Value(I,"Low",ds))) or 1)) / P
42 | end
43 | if I>=P then
44 | Out = ATR[I]
45 | return rounding(Out, R)
46 | else
47 | return nil
48 | end
49 | end
50 | end
51 |
52 | function TR() --True Range ("TR")
53 | return function (I, Fsettings, ds)
54 | local Fsettings=(Fsettings or {})
55 | local R = (Fsettings.round or "off")
56 | local Out = nil
57 | if I==1 then
58 | Out = math.abs(Value(I,"Difference", ds))
59 | else
60 | Out = math.max(math.abs(Value(I,"Difference", ds)),
61 | math.abs(Value(I,"High",ds) - Value(I-1,"Close",ds)),
62 | math.abs(Value(I-1,"Close",ds)-Value(I,"Low",ds)))
63 | end
64 | return rounding(Out, R)
65 | end
66 | end
67 |
68 | function rounding(num, round)
69 | if round and string.upper(round)== "ON" then round=0 end
70 | if num and tonumber(round) then
71 | local mult = 10^round
72 | if num >= 0 then return math.floor(num * mult + 0.5) / mult
73 | else return math.ceil(num * mult - 0.5) / mult end
74 | else return num end
75 | end
76 |
77 | function Value(I,VType,ds)
78 | local Out = nil
79 | VType=(VType and string.upper(string.sub(VType,1,1))) or "A"
80 | if VType == "O" then --Open
81 | Out = (O and O(I)) or (ds and ds:O(I))
82 | elseif VType == "H" then --High
83 | Out = (H and H(I)) or (ds and ds:H(I))
84 | elseif VType == "L" then --Low
85 | Out = (L and L(I)) or (ds and ds:L(I))
86 | elseif VType == "C" then --Close
87 | Out = (C and C(I)) or (ds and ds:C(I))
88 | elseif VType == "V" then --Volume
89 | Out = (V and V(I)) or (ds and ds:V(I))
90 | elseif VType == "M" then --Median
91 | Out = ((Value(I,"H",ds) + Value(I,"L",ds)) / 2)
92 | elseif VType == "T" then --Typical
93 | Out = ((Value(I,"M",ds) * 2 + Value(I,"C",ds))/3)
94 | elseif VType == "W" then --Weighted
95 | Out = ((Value(I,"T",ds) * 3 + Value(I,"O",ds))/4)
96 | elseif VType == "D" then --Difference
97 | Out = (Value(I,"H",ds) - Value(I,"L",ds))
98 | elseif VType == "A" then --Any
99 | if ds then Out = ds[I] else Out = nil end
100 | end
101 | return Out
102 | end
103 |
--------------------------------------------------------------------------------
/quantScript/StaticVar x64 lua5.3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/quantScript/StaticVar x64 lua5.3.zip
--------------------------------------------------------------------------------
/quantScript/StaticVar.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/quantScript/StaticVar.dll
--------------------------------------------------------------------------------
/quantScript/quantScript.csv:
--------------------------------------------------------------------------------
1 | Код класса;Имя;Идентификатор;ChartId;clasterSize;clasterTime;bigDealSize;collectStats;autoScan;showHourVWAP;showDayVWAP
2 | TQBR;Сбербанк;SBER;testGraphTQBR;5;2;20000;1;1;0;0
3 | TQBR;ВТБ;VTBR;;5;0;5000;0;0;0;0
4 | TQBR;Мосбиржа;MOEX;;5;0;5000;0;0;0;0
5 | TQBR;ФСК;FEES;;5;2;2000;0;0;0;0
6 | TQBR;Русгидро;HYDR;;5;0;5000;0;0;0;0
7 | TQBR;Новатек;NVTK;;5;0;5000;0;0;0;0
8 | TQBR;Газпром;GAZP;;5;0;5000;0;0;0;0
9 | TQBR;Лукойл;LKOH;;5;0;5000;0;0;0;0
10 | TQBR;Роснефть;ROSN;;5;0;5000;0;0;0;0
11 | TQBR;Алроса;ALRS;;5;0;5000;0;0;0;0
12 | TQBR;ГМК;GMKN;;5;0;5000;0;0;0;0
13 | TQBR;ММК;MAGN;;5;0;5000;0;0;0;0
14 | TQBR;НЛМК;NLMK;;5;0;5000;0;0;0;0
15 | TQBR;Северсталь;CHMF;;5;0;5000;0;0;0;0
16 | TQBR;Аэрофлот;AFLT;;5;0;5000;0;0;0;0
17 | TQBR;Магнит;MGNT;;5;0;5000;0;0;0;0
18 | SPBFUT;SiZ8;SiZ8;testGraphSi;5;2;3000;0;0;1;1
19 |
--------------------------------------------------------------------------------
/robot/ethlerAlgo.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/robot/ethlerAlgo.lua
--------------------------------------------------------------------------------
/robot/renko.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/robot/renko.lua
--------------------------------------------------------------------------------
/robot/robotOptimize.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/robot/robotOptimize.lua
--------------------------------------------------------------------------------
/robot/robotTable.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/robot/robotTable.lua
--------------------------------------------------------------------------------
/robot/tableClass.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/robot/tableClass.lua
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/readme.md:
--------------------------------------------------------------------------------
1 | Pictures
2 |
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy0.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy0.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy1.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy1.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy2.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy2.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy3.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy3.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy4.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy4.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy5.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy5.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy6.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy6.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy7.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy7.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy8.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy8.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_buy9.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_buy9.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell0.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell0.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell1.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell1.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell2.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell2.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell3.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell3.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell4.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell4.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell5.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell5.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell6.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell6.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell7.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell7.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell8.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell8.bmp
--------------------------------------------------------------------------------
/scriptMonitor/Pictures/МоиСделки_sell9.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/Pictures/МоиСделки_sell9.bmp
--------------------------------------------------------------------------------
/scriptMonitor/monitorRSI.lua:
--------------------------------------------------------------------------------
1 | RSISettings = {
2 | period = 29,
3 | Size = 1000
4 | }
5 |
6 | function initRSI()
7 | calcAlgoValue = nil
8 | RSI_H = nil
9 | RSI_L = nil
10 | end
11 |
12 | function RSI(iSec, ind, settings, DS)
13 |
14 | local period = settings.period or 29 -- period
15 | local Size = settings.Size or 1000
16 |
17 | local k = 2/(period+1)
18 | if ind == nil then ind = DS:Size() end
19 | Size = math.min(Size, DS:Size()) - 2
20 |
21 | calcAlgoValue = {}
22 | RSI_H={}
23 | RSI_L={}
24 | calcAlgoValue[ind-Size-1] = 0
25 | RSI_H[ind-Size-1] = 0
26 | RSI_L[ind-Size-1] = 0
27 |
28 | for index = ind-Size, DS:Size() do
29 | calcAlgoValue[index] = calcAlgoValue[index-1]
30 | RSI_H[index] = RSI_H[index-1]
31 | RSI_L[index] = RSI_L[index-1]
32 |
33 | if DS:C(index) ~= nil then
34 | if DS:C(index) > DS:C(index-1) then
35 | RSI_H[index]=RSI_H[index-1]*(1-2/(period*2+1)) + (math.abs(DS:C(index)-DS:C(index-1)))*2/(period*2+1)
36 | RSI_L[index]=RSI_L[index-1]*(1-2/(period*2+1))
37 | else
38 | RSI_H[index]=RSI_H[index-1]*(1-2/(period*2+1))
39 | RSI_L[index]=RSI_L[index-1]*(1-2/(period*2+1)) + (math.abs(DS:C(index)-DS:C(index-1)))*2/(period*2+1)
40 | end
41 |
42 | calcAlgoValue[index]=round(RSI_H[index]/(RSI_H[index]+RSI_L[index])*100, 2)
43 | end
44 | end
45 |
46 | return calcAlgoValue
47 |
48 | end
49 |
50 | function signalRSI(i, cell, settings, DS, signal)
51 |
52 | local testvalue = 50 -- сравниваемое значение
53 | local signaltestvalue1 = calcAlgoValue[DS:Size()-1] or 0
54 | local signaltestvalue2 = calcAlgoValue[DS:Size()-2] or 0
55 |
56 | if calcAlgoValue[DS:Size()] == nil or DS:Size() == 0 then return end
57 | local calcVal = calcAlgoValue[DS:Size()] or 0
58 |
59 | if INTERVALS["visible"][cell] then
60 | local colorGradation = math.floor((math.abs(calcVal- 50)/50)*(255-200))
61 | local Color = RGB(255, 255, 255)
62 | if calcVal<=50 then
63 | Color = RGB(math.max(255 - 0.5*colorGradation, 255), 255 - 3*colorGradation, 255 - 3*colorGradation) -- оттенки красного
64 | else
65 | Color = RGB(255 - 3*colorGradation, math.max(255 - 0.7*colorGradation, 255), 255 - 3.4*colorGradation) --оттенки зеленого
66 | end
67 |
68 | SetCell(t_id, i, tableIndex[cell], tostring(calcVal), calcVal)
69 | cellSetColor(i, tableIndex[cell], Color, RGB(0,0,0))
70 | end
71 |
72 | if signal then
73 | local isMessage = SEC_CODES['isMessage'][i]
74 | local isPlaySound = SEC_CODES['isPlaySound'][i]
75 | local mes0 = tostring(SEC_CODES['names'][i]).." timescale "..INTERVALS["names"][cell]
76 | local mes = ""
77 |
78 | if signaltestvalue1 < 50 and signaltestvalue2 > 50 then
79 | mes = mes0..": Сигнал Sell"
80 | myLog(mes)
81 | if isMessage == 1 then message(mes) end
82 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
83 | end
84 | if signaltestvalue1 > 50 and signaltestvalue2 < 50 then
85 | mes = mes0..": Сигнал Buy"
86 | myLog(mes)
87 | if isMessage == 1 then message(mes) end
88 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
89 | end
90 | --Теперь смотрим за текущей ситуацией
91 | signaltestvalue1 = calcAlgoValue[DS:Size()] or 0
92 | signaltestvalue2 = calcAlgoValue[DS:Size()-1] or 0
93 | if signaltestvalue1 > 70 and signaltestvalue2 < 70 then
94 | mes = mes0..": RSI превысил 70"
95 | myLog(mes)
96 | if isMessage == 1 then message(mes) end
97 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
98 | end
99 | if signaltestvalue1 > 53 and signaltestvalue2 < 53 then
100 | mes = mes0..": RSI оттолкнулся от 50 "
101 | myLog(mes)
102 | if isMessage == 1 then message(mes) end
103 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
104 | end
105 | if signaltestvalue1 < 47 and signaltestvalue2 > 47 then
106 | mes = mes0..": RSI отскочил от 50 "
107 | myLog(mes)
108 | if isMessage == 1 then message(mes) end
109 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
110 | end
111 | if signaltestvalue1 > 30 and signaltestvalue2 < 30 then
112 | mes = mes0..": RSI оттолкнулся от 30 "
113 | myLog(mes)
114 | if isMessage == 1 then message(mes) end
115 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
116 | end
117 | if signaltestvalue1 < 70 and signaltestvalue2 > 70 then
118 | mes = mes0..": RSI отскочил от 70 "
119 | myLog(mes)
120 | if isMessage == 1 then message(mes) end
121 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
122 | end
123 | end
124 |
125 | end
126 |
--------------------------------------------------------------------------------
/scriptMonitor/monitorVolume.lua:
--------------------------------------------------------------------------------
1 | function initVolume()
2 | lastVolume = {}
3 | lastPrice = {}
4 | volumeEMA = {}
5 | end
6 |
7 | function Volume(iSec)
8 |
9 | local seccode = SEC_CODES['sec_codes'][iSec]
10 | local classcode = SEC_CODES['class_codes'][iSec]
11 | local period = 5 -- период усреднения объема
12 | local volumeFactor = 3.5 -- превышение раз, чтоюы считать объем повышенным
13 | local k = 2/(period+1)
14 | local isMessage = SEC_CODES['isMessage'][iSec]
15 | local isPlaySound = SEC_CODES['isPlaySound'][iSec]
16 |
17 | if volumeEMA[seccode] == nil then
18 | volumeEMA[seccode] = {}
19 | end
20 |
21 | local lastSECVolume = tonumber(getParamEx(classcode,seccode,"valtoday").param_value)
22 | local lastSECPrice = tonumber(getParamEx(classcode,seccode,"last").param_value)
23 | --myLog(SEC_CODES['names'][iSec].." lastSECVolume: "..tostring(lastSECVolume))
24 |
25 | if lastVolume[seccode] == nil then
26 | lastVolume[seccode] = lastSECVolume
27 | lastPrice[seccode] = lastSECPrice
28 | end
29 |
30 | local intervalVolume = lastSECVolume - lastVolume[seccode]
31 | volumeEMA[seccode][#volumeEMA[seccode] + 1] = intervalVolume
32 | lastVolume[seccode] = lastSECVolume
33 |
34 | local mes0 = tostring(SEC_CODES['names'][iSec])
35 | if math.abs(lastPrice[seccode] - lastSECPrice)*100/lastPrice[seccode] >= 1 then
36 | local mes = mes0..": значительное изменение цены: ".."новая цена: "..tostring(lastSECPrice)..", прошлая цена: "..tostring(lastPrice[seccode])
37 | myLog(mes)
38 | if isMessage == 1 then message(mes) end
39 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
40 | end
41 | lastPrice[seccode] = lastSECPrice
42 |
43 | local ind = #volumeEMA[seccode]
44 | if ind==period then
45 | local sum = 0
46 | for n=2, ind do
47 | sum = sum + volumeEMA[seccode][n]
48 | end
49 | volumeEMA[seccode][ind] = sum/(ind-1)
50 | elseif ind>period then
51 | volumeEMA[seccode][ind]=round(k*volumeEMA[seccode][ind]+(1-k)*volumeEMA[seccode][ind-1], 5)
52 | --myLog(SEC_CODES['names'][iSec].." intervalVolume: "..tostring(intervalVolume))
53 | --myLog(SEC_CODES['names'][iSec].." volumeEMA: "..tostring(volumeEMA[seccode][ind]))
54 |
55 | if intervalVolume > volumeEMA[seccode][ind]*volumeFactor then
56 | local mes = mes0..": прошел повышенный тиковый объем"
57 | myLog(mes)
58 | myLog("interval vol: "..tostring(intervalVolume))
59 | myLog(SEC_CODES['names'][iSec].." volEMA: "..tostring(volumeEMA[seccode][ind]))
60 | if isMessage == 1 then message(mes) end
61 | if isPlaySound == 1 then PaySoundFile(soundFileName) end
62 | end
63 | end
64 | end
65 |
--------------------------------------------------------------------------------
/scriptMonitor/nrtrMonitor.csv:
--------------------------------------------------------------------------------
1 | SecCode;ChartId;Interval;isLong;isShort;Length;Kv
2 | FEES;testGraphFEES;1440;1;0;9;1.7
3 | ALRS;testGraphALRS;1440;1;0;16;1.8
4 | MOEX;testGraphMOEX;1440;1;0;9;1.7
5 | SBER;testGraphSBER;1440;1;0;47;1.9
6 | GAZP;testGraphGAZP;1440;1;0;101;1.4
7 | LKOH;testGraphLKOH;1440;1;0;9;1.7
8 | GMKN;testGraphGMKN;1440;1;0;9;1.7
9 | CHMF;testGraphCHMF;1440;1;0;9;1.7
10 | AFLT;testGraphAFLT;1440;1;0;9;1.7
11 | MAGN;testGraphMAGN;1440;1;0;22;2.5
12 |
--------------------------------------------------------------------------------
/scriptMonitor/pict/pict1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/pict/pict1.PNG
--------------------------------------------------------------------------------
/scriptMonitor/pict/pict2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/pict/pict2.PNG
--------------------------------------------------------------------------------
/scriptMonitor/rangeMonitor.csv:
--------------------------------------------------------------------------------
1 | SecCode;ChartId;Interval;isLong;isShort;bars;ratioFactor;kstd;ATR_factor
2 | FEES;testGraphFEES;1440;1;1;27;0.7;1.8;3
3 | ALRS;testGraphALRS;1440;1;1;27;0.7;1.8;3
4 | MOEX;testGraphMOEX;1440;1;1;27;0.7;1.8;3
5 | SBER;testGraphSBER;1440;1;1;27;0.7;1.8;3
6 | GMKN;testGraphGMKN;1440;1;1;27;0.7;1.8;3
7 | CHMF;testGraphCHMF;240;1;1;27;0.7;1.8;3
8 | CHMF;testGraphCHMF;1440;1;1;27;0.7;1.8;3
9 | AFLT;testGraphAFLT;15;1;1;27;0.7;1.8;3
10 | AFLT;testGraphAFLT;1440;1;1;27;0.7;1.8;3
11 | MAGN;testGraphMAGN;15;1;1;27;0.7;1.8;3
12 | MAGN;testGraphMAGN;60;1;1;27;0.7;1.8;3
13 | MAGN;testGraphMAGN;240;1;1;27;0.7;1.8;3
14 | MAGN;testGraphMAGN;1440;1;1;27;0.7;1.8;3
15 |
--------------------------------------------------------------------------------
/scriptMonitor/scriptMonitor.csv:
--------------------------------------------------------------------------------
1 | Код класса;Имя;Идентификатор;Выводить сообщения;Проигрывать звук;Рабочий объем;ATR период
2 | TQBR;Сбербанк;SBER;1;0;1;29
3 | TQBR;ВТБ;VTBR;1;0;1;29
4 | TQBR;Мосбиржа;MOEX;1;0;1;29
5 | TQBR;Система;AFKS;1;0;1;29
6 | TQBR;БСПБ;BSPB;1;0;1;29
7 | TQBR;QIWI;QIWI;0;0;1;29
8 | TQBR;ФСК;FEES;1;0;1;29
9 | TQBR;Русгидро;HYDR;1;0;1;29
10 | TQBR;Мосэнерго;MSNG;1;0;1;29
11 | TQBR;ОГК-2;OGKB;1;0;1;29
12 | TQBR;Россети;RSTI;1;0;1;29
13 | TQBR;ИнтерРао;IRAO;1;0;1;29
14 | TQBR;ТГК-1;TGKA;1;0;1;29
15 | TQBR;МРСК ЦП;MRKP;1;0;1;29
16 | TQBR;МРСК Вол.;MRKV;1;0;1;29
17 | TQBR;МОЭСК;MSRS;1;0;1;29
18 | TQBR;Газпром;GAZP;1;0;1;29
19 | TQBR;Лукойл;LKOH;1;0;1;29
20 | TQBR;Газпром нефть;SIBN;1;0;1;29
21 | TQBR;Сургут пр.;SNGSP;1;0;1;29
22 | TQBR;Новатек;NVTK;1;0;1;29
23 | TQBR;Роснефть;ROSN;1;0;1;29
24 | TQBR;НКНХ ап;NKNCP;1;0;1;29
25 | TQBR;Оргсинтез;KZOS;0;0;1;29
26 | TQBR;Алроса;ALRS;1;0;1;29
27 | TQBR;ММК;MAGN;1;0;1;29
28 | TQBR;ГМК;GMKN;1;0;1;29
29 | TQBR;НЛМК;NLMK;1;0;1;29
30 | TQBR;Северсталь;CHMF;1;0;1;29
31 | TQBR;Распадская;RASP;1;0;1;29
32 | TQBR;Мечел пр;MTLRP;1;0;1;29
33 | TQBR;Полюс;PLZL;1;0;1;29
34 | TQBR;Русал;RUAL;1;0;1;29
35 | TQBR;ТМК;TRMK;1;0;1;29
36 | TQBR;Полиметал;POLY;1;0;1;29
37 | TQBR;Русагро;AGRO;1;0;1;29
38 | TQBR;Фосагро;PHOR;1;0;1;29
39 | TQBR;ЛСР;LSRG;1;0;1;29
40 | TQBR;Мостотрест;MSTT;1;0;1;29
41 | TQBR;НКХП;NKHP;1;0;1;29
42 | TQBR;Протек;PRTK;0;0;1;29
43 | TQBR;Магнит;MGNT;1;0;1;29
44 | TQBR;Лента;LNTA;1;0;1;29
45 | TQBR;МТС;MTSS;1;0;1;29
46 | TQBR;Ростелеком пр;RTKMP;1;0;1;29
47 | TQBR;Яндекс;YNDX;1;0;1;29
48 | TQBR;Аэрофлот;AFLT;1;0;1;29
49 | TQBR;Камаз;KMAZ;0;0;1;29
50 |
--------------------------------------------------------------------------------
/scriptMonitor/w32.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/scriptMonitor/w32.dll
--------------------------------------------------------------------------------
/secScanner/readme.md:
--------------------------------------------------------------------------------
1 | Скрипт демонстратор.
2 |
3 | В данном скрипте показано как организовать постоянную работу скрипта с корректным переходом через сутки.
4 |
5 | Подключение и использование [библиотеки логирования](https://github.com/nick-nh/qlua/tree/master/logging)
6 |
7 | Чтение и переопределение параметров из внешнего файла.
8 |
9 | Как сканировать все инструменты класса, проверять параметры из "Таблицы текущих торгов".
10 |
11 | Подключение и использование [библиотеки оповещений](https://github.com/nick-nh/qlua/tree/master/telegramQuik). [Описание использования и настройки библиотеки оповещения](https://nick-nh.github.io/2021-03-14/teleMessage)
12 |
13 | Проигрывание звукового файла по событию. (Необходимо установить библиотеку w32.dll)
14 |
15 | Скрипт сканирует все инструменты указанных классов, проверяет на сильное изменение цены и объема. По событию отправляет оповещение.
16 | Для этого используются конструкторы CheckProcessor и CheckEMAProcessor. Это "замыкания", создаваемые для каждого инструмента.
17 | Для фильтрации также используется FilterProcessor. В примере отбираются инструменты с дневным оборотом от 7 000 000 руб.
18 |
19 |
20 | FilterProcessor принимает параметры
21 |
22 | - @param Sec table - таблица с описанием инструмента
23 | - @param info_string string - строка параметра "Таблицы текущих торгов"
24 | - @param filter_limit number - значение фильтра
25 | - @param sign number - знак. 1 - больше, -1 - меньше
26 | - @return function
27 |
28 |
29 | CheckProcessor и CheckEMAProcessor принимают параметры
30 |
31 | - @param Sec table - таблица с описанием инструмента
32 | - @param info_string string - строка параметра "Таблицы текущих торгов"
33 | - @param check_interval number - интервал проверки в сек.
34 | - @param msg_interval number - интервал отправки сообщений в сек.
35 | - @param change_limit number - предел изменения параметра для наступления события
36 | - @return function
37 |
38 | FilterProcessor - конструктор функции проверки параметра, указанного в параметре info_string. Если полученное значение выше(ниже) чем порог filter_limit, то возвращается true.
39 |
40 |
41 | CheckProcessor - конструктор функции контроля изменения параметра, указанного в параметре info_string на процент, указанный в параметре change_limit.
42 | Проверка осуществляется раз check_interval секунд. В примере показан контроль изменения параметра "Цена последней сделки". Интервал проверки 1 сек. Порог 2%.
43 | Если "Цена последней сделки" изменится выше порога за 1 сек., то происходит обработка события.
44 | Обработка события осуществляется раз msg_interval секунд. Это необходимо, чтобы сообщения не приходили очень часто.
45 |
46 |
47 | CheckEMAProcessor похож по смыслу и использованию на CheckProcessor. Основное отличие в том, что происходит не просто проверка параметра info_string, а рассчитанной EMA на его основе.
48 | Поэтому интервал проверки здесь выше чем в CheckProcessor. В примере продемонстрирована проверка изменения параметра "Оборот в деньгах". Интервал проверки 120 сек. Период расчета EMA - 5 значений. Порог 3,5.
49 | Т.о. раз в 120 секунд получаются данные о "Оборот в деньгах", рассчитывается прирост от прошлой проверки и записывается как значение для расчета EMA. Когда наберется достаточно значений для контроля, происходит анализ текущего изменения с прошлыми. Если текущий прирост выше чем 3.5*EMA, то происходит обработка события.
50 |
--------------------------------------------------------------------------------
/secScanner/secScanner_params.ini:
--------------------------------------------------------------------------------
1 | --Задержка основного цикла
2 | main_delay = 100
3 |
4 | --Временная зона (0, 1, -1, -2...)
5 | TIME_ZONE = 0
6 |
7 | --Классы инструментов для выбора
8 | TRACK_CLASS_CODES = 'TQBR|FQBR'
9 |
10 | USE_LOCAL_TIME_AS_SERVER = 0
11 |
12 | --Интервал обновления данных с текущим состоянием c сервера брокера (сек.)
13 | --Задается в настройках терминала в пункте меню «Система» / «Настройки» / «Основные настройки» / «Программа» на вкладке «Получение данных»
14 | --Если время сервера больше времени последнего сообщения чем период опроса, то связь с сервером брокера еще не установлена
15 | -- По умолчанию 1
16 | -- Для отключения проверки необходимо установить значение -1
17 | SERVER_DATA_CYCLE_TIME = -1
18 |
19 | --Допустимое расхождение (в сек.) времени сервера и локального времени рабочего места
20 | -- если -1, то не контролируется
21 | MAX_LOCAL_TO_SERVER_TIME_DIFF = -1
22 |
23 | -- Отправлять сообщения
24 | SEND_MESSAGES = 1
25 |
26 | -- Отправлять сообщение email
27 | -- 1 - да
28 | -- 0 - нет
29 | SEND_EMAIL = 1
30 |
31 | -- Отправлять сообщение в Телеграм
32 | -- 1 - да
33 | -- 0 - нет
34 | SEND_TELEGRAM = 0
35 |
36 | -- Имя канала отправки сообщений в телеграм, email.
37 | -- Такое же имя должно быть установлено в настройках сервера отправки.
38 | EMAIL_PIPE = 'email_pipe'
39 | TELEGRAM_PIPE = 'telegram_pipe'
40 |
41 | --Подключить библиотеку воспроизведения звукового файла.
42 | -- Значение: 1 - подключать
43 | -- Значение: 0 - не подключать
44 | PLAY_SOUND = 0
45 |
46 | --Путь к звуковом файлу
47 | SOUND_FILE = 'c:\\windows\\media\\Alarm03.wav'
48 |
49 | EMAIL_SEND_INTERVAL = 10
50 |
51 | LOGGING = 1 -- признак ведения лога. 1 - выводить, 0 - нет
52 | DEBUG_MODE = 1 -- признак вывода в лог отладочной информации. 1 - выводить, 0 - нет
53 |
54 | str_startNewDayTime = '06:00:00' -- Время начала нового дня
55 | str_startTradeTime = '09:50:00' -- Время начала сканирования
56 | str_endOfDay = '23:50:00' -- Окончание торгового дня
57 |
--------------------------------------------------------------------------------
/signalOrders/ReciveEmailProject/ReciveEmail.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.271
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReciveEmail", "ReciveEmail\ReciveEmail.csproj", "{19AEFD84-2E0C-4B25-8A65-FAE359D41DF4}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {19AEFD84-2E0C-4B25-8A65-FAE359D41DF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {19AEFD84-2E0C-4B25-8A65-FAE359D41DF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {19AEFD84-2E0C-4B25-8A65-FAE359D41DF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {19AEFD84-2E0C-4B25-8A65-FAE359D41DF4}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {90F8F3CB-3770-4F29-BBC0-B06EA02D4B44}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/signalOrders/ReciveEmailProject/ReciveEmail/App.config:
--------------------------------------------------------------------------------
1 |
2 |
28 |
29 | Значения статистических показателей рассчитаны как показано здесь:
30 | https://www.mql5.com/ru/articles/1492
31 |
32 | Чтобы выводить данные на график надо задать ChartId.
33 |
34 |
35 |
36 | Для вывода линий алгоритма и рассчитанной Эквити надо добавить на график два индикатора algoResults и equityTester.
37 | Они получают данные через библиотеку StaticVar {key,value}, поэтому ее надо не забыть положить в папку установки Квик.
38 |
39 | В этих индикаторах надо не забыть указать индентификатор графика, чтобы они получили данные своего инструмента.
40 |
41 |
42 |
43 | После запуска скрипта откроется окно со списоком инструментов. Можно задать размер и интервал прямо из этого окна.
44 | Для этого надо дважы щелкнуть по колонке с параметром. Для запуска теста надо дважды щелкнуть по колонкам "Инструмент" или "Алгоритм".
45 |
46 |
47 |
48 | После того как произойдет расчет откроется окно результатов, отсортированное по профиту. Лучшие данные будут выведены на график.
49 | Можно отсортировать данные по колонкам параметров, дважды щелкнув по данным в этой колонке.
50 |
51 |
52 |
53 | Чтобы вывести на график данные из конкретной строки надо дважды щелкнуть по "Инструмент" или "Алгоритм".
54 | Тем самым можно выводить на график данные одного алгоритма но с разными параметрами. Выводятся метки и данные линий, эквити (если добавлены индикаторы). Если окно результатов закрытили, то его можно повторно открыть дважды щелкнув по проценту выполнения из основного окна. Также можно открыть окно результатов еще в процессе расчета, для оценки данных.
55 |
56 |
57 |
58 |
59 | Установка тестера: проcто добавить скрипт testet в Квике. Не забыть добавить библиотеку обмена StaticVar в папку Квика. Индикаторы в папку Luaindicators.
60 |
61 | В функции simpleTrade заданы времена совершения сделок для срочного рынка. Я для себя определил начало торгов в 10:12, окончания в 18:42. Т.е. первая сделка будет совершана только после 10:12, а после 18:42 позиция будет закрыта. Данные параметры, конечно, можно менять.
62 |
63 | if time >= 1012 then
64 | dealTime = true
65 | end
66 | if time >= 1842 then
67 | dealTime = false
68 | end
69 |
--------------------------------------------------------------------------------
/tester/testSAR.lua:
--------------------------------------------------------------------------------
1 | -------------------------
2 | --SAR
3 | SARSettings = {
4 | SarPeriod = 0,
5 | SarPeriod2 = 0,
6 | SarDeviation = 0,
7 | Size = 0
8 | }
9 |
10 | function initSAR()
11 | cache_SAR=nil
12 | cache_ST=nil
13 | EMA=nil
14 | BB=nil
15 | end
16 |
17 | function iterateSAR(iSec, cell)
18 |
19 | param1Min = 4
20 | param1Max = 64
21 | param1Step = 2
22 |
23 | param2Min = 112
24 | param2Max = 312
25 | param2Step = 2
26 |
27 | param3Min = 0.4
28 | param3Max = 5
29 | param3Step = 0.1
30 |
31 |
32 | local allCount = 0
33 | local settingsTable = {}
34 |
35 | for _SarPeriod = param1Min, param1Max, param1Step do
36 | for _SarPeriod2 = param2Min, param2Max, param2Step do
37 | for _SarDeviation = param3Min, param3Max, param3Step do
38 |
39 | allCount = allCount + 1
40 |
41 | settingsTable[allCount] = {
42 | SarPeriod = _SarPeriod,
43 | SarPeriod2 = _SarPeriod2,
44 | SarDeviation = _SarDeviation,
45 | Size = Size
46 | }
47 |
48 |
49 | end
50 | end
51 | end
52 |
53 | iterateAlgorithm(iSec, cell, settingsTable)
54 |
55 | end
56 |
57 | function SAR(index, settings, DS)
58 |
59 | local SarPeriod = settings.SarPeriod or 32
60 | local SarPeriod2 = settings.SarPeriod2 or 256
61 | local SarDeviation = settings.SarDeviation or 3
62 | local sigma = 0
63 |
64 | local indexToCalc = 1000
65 | indexToCalc = settings.Size or indexToCalc
66 | local beginIndexToCalc = settings.beginIndexToCalc or math.max(1, settings.beginIndex - indexToCalc)
67 | local endIndexToCalc = settings.endIndex or DS:Size()
68 |
69 | if index == nil then index = 1 end
70 |
71 | if cache_SAR == nil then
72 | myLog("Показатель SarPeriod "..tostring(SarPeriod))
73 | myLog("Показатель SarPeriod2 "..tostring(SarPeriod2))
74 | myLog("Показатель SarDeviation "..tostring(SarDeviation))
75 | myLog("--------------------------------------------------")
76 | cache_SAR={}
77 | cache_ST={}
78 | EMA={}
79 | BB={}
80 | BB[index]=0
81 | cache_SAR[index]=0
82 | EMA[index]=0
83 | cache_ST[index]=1
84 | return cache_SAR
85 | end
86 |
87 | EMA[index]=EMA[index-1]
88 | BB[index]=BB[index-1]
89 | cache_SAR[index]=cache_SAR[index-1]
90 | cache_ST[index]=cache_ST[index-1]
91 |
92 | if index < beginIndexToCalc or index > endIndexToCalc then
93 | return cache_SAR, cache_ST, cache_SAR
94 | end
95 |
96 | if DS:C(index) ~= nil then
97 |
98 | EMA[index]=(2/(SarPeriod/2+1))*DS:C(index)+(1-2/(SarPeriod/2+1))*EMA[index-1]
99 | BB[index]=(2/(SarPeriod2/2+1))*(DS:C(index)-EMA[index])^2+(1-2/(SarPeriod2/2+1))*BB[index-1]
100 |
101 | sigma=BB[index]^(1/2)
102 |
103 | if index ==2 then
104 | return cache_SAR
105 | end
106 |
107 | if cache_ST[index] == 1 then
108 |
109 | cache_SAR[index]=math.max((EMA[index]-sigma*SarDeviation),cache_SAR[index-1])
110 |
111 | if (cache_SAR[index] > DS:C(index)) then
112 | cache_ST[index] = -1
113 | cache_SAR[index]=EMA[index]+sigma*SarDeviation
114 | end
115 | elseif cache_ST[index] == -1 then
116 |
117 | cache_SAR[index]=math.min((EMA[index]+sigma*SarDeviation),cache_SAR[index-1])
118 |
119 | if (cache_SAR[index] < DS:C(index)) then
120 | cache_ST[index] = 1
121 | cache_SAR[index]=EMA[index]-sigma*SarDeviation
122 | end
123 | end
124 | end
125 |
126 | return cache_SAR, cache_ST, cache_SAR
127 |
128 | end
129 |
130 | local newIndex = #ALGORITHMS['names']+1
131 |
132 | ALGORITHMS['names'][newIndex] = "Sar"
133 | ALGORITHMS['initParams'][newIndex] = initSAR
134 | ALGORITHMS['initAlgorithms'][newIndex] = initSAR
135 | ALGORITHMS['itetareAlgorithms'][newIndex] = iterateSAR
136 | ALGORITHMS['calcAlgorithms'][newIndex] = SAR
137 | ALGORITHMS['tradeAlgorithms'][newIndex] = simpleTrade
138 | ALGORITHMS['settings'][newIndex] = SARSettings
139 |
--------------------------------------------------------------------------------
/thv_coral.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | nick-h@yandex.ru
3 | https://github.com/nick-nh/qlua
4 |
5 | THV
6 | ]]
7 | _G.unpack = rawget(table, "unpack") or _G.unpack
8 | _G.load = _G.loadfile or _G.load
9 | local maLib = load(_G.getWorkingFolder().."\\Luaindicators\\maLib.lua")()
10 |
11 | local logFile = nil
12 | --logFile = io.open(_G.getWorkingFolder().."\\LuaIndicators\\THV.txt", "w")
13 |
14 | local message = _G['message']
15 | local RGB = _G['RGB']
16 | local TYPE_LINE = _G['TYPE_LINE']
17 | local TYPE_POINT = _G['TYPE_POINT']
18 | local line_color = RGB(250, 0, 0)
19 | local os_time = os.time
20 |
21 | _G.Settings= {
22 | Name = "*THV",
23 | period = 64,
24 | data_type = 'Close',
25 | koef = 1.0,
26 | trend_shift = 1,
27 | trend_sd = 1.0,
28 | color = 1,
29 | line = {
30 | {
31 | Name = 'THV',
32 | Color = line_color,
33 | Type = TYPE_LINE,
34 | Width = 2
35 | },
36 | {
37 | Name = "dir up",
38 | Type = TYPE_POINT,
39 | Width = 2,
40 | Color = RGB(89,213, 107)
41 | },
42 | {
43 | Name = "dir dw",
44 | Type = TYPE_POINT,
45 | Width = 2,
46 | Color = RGB(255, 58, 0)
47 | }
48 | }
49 | }
50 |
51 | local PlotLines = function(index) return index end
52 | local error_log = {}
53 | local lines = #_G.Settings.line
54 |
55 | local function log_tostring(...)
56 | local n = select('#', ...)
57 | if n == 1 then
58 | return tostring(select(1, ...))
59 | end
60 | local t = {}
61 | for i = 1, n do
62 | t[#t + 1] = tostring((select(i, ...)))
63 | end
64 | return table.concat(t, " ")
65 | end
66 |
67 | local function myLog(...)
68 | if logFile==nil then return end
69 | logFile:write(tostring(os.date("%c",os_time())).." "..log_tostring(...).."\n");
70 | logFile:flush();
71 | end
72 | ------------------------------------------------------------------
73 | --Moving Average
74 | ------------------------------------------------------------------
75 |
76 | local function Algo(Fsettings, ds)
77 |
78 | Fsettings = (Fsettings or {})
79 | error_log = {}
80 |
81 | local trend_shift = Fsettings.trend_shift or 1
82 | local trend_sd = Fsettings.trend_sd or 1
83 | local color = (Fsettings.color or 0) == 1
84 |
85 | local fMA, ma
86 | local out
87 | local begin_index
88 |
89 | local fDSD
90 | local delta
91 | local d_sd, trend
92 |
93 | return function (index)
94 |
95 | out = {}
96 |
97 | local status, res = pcall(function()
98 |
99 | if not maLib then return end
100 |
101 | if fMA == nil or index == begin_index then
102 | begin_index = index
103 | fMA = maLib.new({method = 'THV', period = Fsettings.period, koef = Fsettings.koef, data_type = Fsettings.data_type}, ds)
104 | ma = fMA(index)
105 | delta = {}
106 | delta[index] = 0
107 | fDSD = maLib.new({method = "SD", not_shifted = true, data_type = 'Any', period = Fsettings.period}, delta)
108 | fDSD(index)
109 | trend = {}
110 | return
111 | end
112 |
113 | out[1] = fMA(index)[index]
114 | trend[index] = trend[index-1] or 0
115 | local t_delta = ma[index] - (ma[index-trend_shift] or ma[index])
116 | delta[index] = math.abs(t_delta) or delta[index-1]
117 | d_sd = fDSD(index)[index-1] or 0
118 | if delta[index] > trend_sd*d_sd then
119 | if t_delta > 0 and trend[index] <= 0 then
120 | trend[index] = 1
121 | end
122 | if t_delta < 0 and trend[index] >= 0 then
123 | trend[index] = -1
124 | end
125 | end
126 | if color then
127 | out[2] = trend[index-1] == 1 and out[1] or nil
128 | out[3] = trend[index-1] == -1 and out[1] or nil
129 | out[1] = nil
130 | end
131 | if trend[index-1] ~= trend[index-2] and not color then
132 | out[2] = trend[index-1] == 1 and _G.O(index) or nil
133 | out[3] = trend[index-1] == -1 and _G.O(index) or nil
134 | end
135 | end)
136 | if not status then
137 | if not error_log[tostring(res)] then
138 | error_log[tostring(res)] = true
139 | myLog(tostring(res))
140 | message(tostring(res))
141 | end
142 | return nil
143 | end
144 | return unpack(out, 1, lines)
145 | end
146 | end
147 |
148 | function _G.Init()
149 | PlotLines = Algo(_G.Settings)
150 | return lines
151 | end
152 |
153 | function _G.OnChangeSettings()
154 | _G.Init()
155 | end
156 |
157 | function _G.OnCalculate(index)
158 | return PlotLines(index)
159 | end
--------------------------------------------------------------------------------
/vwap.lua:
--------------------------------------------------------------------------------
1 | Settings=
2 | {
3 | Name = "*VWAP",
4 | line =
5 | {
6 | {
7 | Name = "VWAP",
8 | Color = RGB(0, 0, 255),
9 | Type = TYPE_LINE, --TYPE_DASHDOT,
10 | Width = 2
11 | },
12 | {
13 | Name = "pVWAP",
14 | Color = RGB(255, 128, 0),
15 | Type = TYPE_LINE, --TYPE_DASHDOT,
16 | Width = 2
17 | }
18 | }
19 | }
20 |
21 |
22 | function Init()
23 | return #Settings.line
24 | end
25 |
26 | DSInfo = nil
27 |
28 | function OnCalculate(index)
29 |
30 | local vwap = nil
31 | local prevVwap = nil
32 |
33 | if index == 1 then
34 | DSInfo = getDataSourceInfo()
35 | end
36 | if index == Size() then
37 | SetValue(index-41, 1, nil)
38 | SetValue(index-1, 1, nil)
39 | SetValue(index-41, 2, nil)
40 | SetValue(index-1, 2, nil)
41 | vwap = tonumber(getParamEx(DSInfo.class_code, DSInfo.sec_code,"WAPRICE").param_value)
42 | prevVwap = tonumber(getParamEx(DSInfo.class_code, DSInfo.sec_code,"PREVWAPRICE").param_value)
43 | if vwap == 0 then vwap = nil end
44 | SetValue(index-40, 1,vwap)
45 | SetValue(index-40, 2,prevVwap)
46 | end
47 |
48 | return vwap, prevVwap
49 |
50 | end
--------------------------------------------------------------------------------
/w32.dll.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick-nh/qlua/132ff242abb2b39f7a49e8b9fa3ddfd6a8d629cd/w32.dll.zip
--------------------------------------------------------------------------------
/weekDayOpen.lua:
--------------------------------------------------------------------------------
1 | Settings =
2 | {
3 | Name = "*WeekDayOpen",
4 | showDay = 0,
5 | showWeek = 1,
6 | showMaxMin = 0,
7 | line =
8 | {
9 | {
10 | Name = "dayOpen",
11 | Color = RGB (0, 255, 0),
12 | Type = TYPET_BAR,
13 | Width = 2
14 | },
15 | {
16 | Name = "dayMax",
17 | Color = RGB (89, 213, 107),
18 | Type = TYPET_BAR,
19 | Width = 2
20 | },
21 | {
22 | Name = "dayMin",
23 | Color = RGB (251, 82, 0),
24 | Type = TYPET_BAR,
25 | Width = 2
26 | },
27 | {
28 | Name = "dayMiddle",
29 | Color = RGB (128, 128, 128),
30 | Type = TYPET_BAR,
31 | Width = 2
32 | },
33 | {
34 | Name = "weekOpen",
35 | Color = RGB (0, 128, 255),
36 | Type = TYPET_BAR,
37 | Width = 2
38 | },
39 | {
40 | Name = "weekMax",
41 | Color = RGB (89, 213, 107),
42 | Type = TYPET_BAR,
43 | Width = 2
44 | },
45 | {
46 | Name = "weekMin",
47 | Color = RGB (251, 82, 0),
48 | Type = TYPET_BAR,
49 | Width = 2
50 | },
51 | {
52 | Name = "weekMiddle",
53 | Color = RGB (128, 128, 128),
54 | Type = TYPET_BAR,
55 | Width = 2
56 | }
57 | }
58 | }
59 |
60 | dayOpen = nil
61 | dayMax = nil
62 | dayMin = nil
63 | dayMiddle = nil
64 | weekOpen = nil
65 | weekMax = nil
66 | weekMin = nil
67 | weekMiddle = nil
68 | dayOpenIndex = 0
69 | weekOpenIndex = 0
70 | Close = {}
71 | Open = {}
72 | High = {}
73 | Low = {}
74 |
75 |
76 | function Init ()
77 | return #Settings.line -- кол-во линий
78 | end
79 |
80 |
81 | function OnCalculate (index)
82 |
83 | if index == 1 then
84 | dayOpen = nil
85 | dayMax = nil
86 | dayMin = nil
87 | dayMiddle = nil
88 | weekOpen = nil
89 | weekMax = nil
90 | weekMin = nil
91 | weekMiddle = nil
92 | dayOpenIndex = 1
93 | weekOpenIndex = 1
94 | Close = {}
95 | Close[index] = C(index)
96 | Open = {}
97 | Open[index] = O(index)
98 | High = {}
99 | High[index] = H(index)
100 | Low = {}
101 | Low[index] = L(index)
102 | return nil
103 | end
104 |
105 | Close[index] = Close[index-1]
106 | Open[index] = Open[index-1]
107 | High[index] = High[index-1]
108 | Low[index] = Low[index-1]
109 |
110 | if not CandleExist(index) then return dayOpen, nil, nil, nil, weekOpen end
111 |
112 | Close[index] = C(index)
113 | Open[index] = O(index)
114 | High[index] = H(index)
115 | Low[index] = L(index)
116 |
117 | local t = T(index)
118 | local t1 = T(index-1)
119 |
120 | if (t.day > t1.day or t.month > t1.month or t.year > t1.year) and Settings.showDay == 1 then
121 | if Settings.showMaxMin==1 then
122 | --dayMax = math.max(Close[dayOpenIndex], Open[dayOpenIndex])
123 | --dayMin = math.min(Close[dayOpenIndex], Open[dayOpenIndex])
124 | dayMax = High[dayOpenIndex]
125 | dayMin = Low[dayOpenIndex]
126 | for i=dayOpenIndex+1,index-1 do
127 | --dayMax = math.max(Close[i], Open[i], dayMax)
128 | --dayMin = math.min(Close[i], Open[i], dayMin)
129 | dayMax = math.max(High[i], dayMax)
130 | dayMin = math.min(Low[i], dayMin)
131 | end
132 | dayMiddle = (dayMax+dayMin)/2
133 | for i=dayOpenIndex,index-1 do
134 | SetValue(i, 2, dayMax)
135 | SetValue(i, 3, dayMin)
136 | SetValue(i, 4, dayMiddle)
137 | end
138 | end
139 | dayOpenIndex = index
140 | dayOpen = O(index)
141 | end
142 | if (t.week_day < t1.week_day or t.month > t1.month or t.year > t1.year) and Settings.showWeek == 1 then
143 | if Settings.showMaxMin==1 then
144 | --weekMax = math.max(Close[weekOpenIndex], Open[weekOpenIndex])
145 | --weekMin = math.min(Close[weekOpenIndex], Open[weekOpenIndex])
146 | weekMax = High[weekOpenIndex]
147 | weekMin = Low[weekOpenIndex]
148 | for i=weekOpenIndex+1,index-1 do
149 | --weekMax = math.max(Close[i], Open[i], weekMax)
150 | --weekMin = math.min(Close[i], Open[i], weekMin)
151 | weekMax = math.max(High[i], weekMax)
152 | weekMin = math.min(Low[i], weekMin)
153 | end
154 | weekMiddle = (weekMax+weekMin)/2
155 | for i=weekOpenIndex,index-1 do
156 | SetValue(i, 6, weekMax)
157 | SetValue(i, 7, weekMin)
158 | SetValue(i, 8, weekMiddle)
159 | end
160 | end
161 | weekOpenIndex = index
162 | weekOpen = O(index)
163 | end
164 |
165 | return dayOpen, nil, nil, nil, weekOpen
166 | end
167 |
--------------------------------------------------------------------------------