-
Notifications
You must be signed in to change notification settings - Fork 64
/
TTM_Squeeze.lua
245 lines (214 loc) · 8.41 KB
/
TTM_Squeeze.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
--[[
https://github.com/nick-nh/qlua
TTM Squeeze от John Carter
]]
_G.unpack = rawget(table, "unpack") or _G.unpack
_G.load = _G.loadfile or _G.load
local maLib = load(_G.getWorkingFolder().."\\Luaindicators\\maLib.lua")()
local logFile = nil
-- logFile = io.open(_G.getWorkingFolder().."\\LuaIndicators\\Squeeze.txt", "w")
local message = _G['message']
local RGB = _G['RGB']
local isDark = _G.isDarkTheme()
local zero_color = isDark and RGB(123, 123, 123) or RGB(70, 70, 70)
local line_color = isDark and RGB(240, 240, 240) or RGB(0, 0, 0)
local up_line_color = isDark and RGB(0, 230, 0) or RGB(0, 210, 0)
local dw_line_color = isDark and RGB(230, 0, 0) or RGB(210, 0, 0)
local sq_no_color = isDark and RGB(0, 63, 103) or RGB(176, 215, 255)
_G.Settings= {
Name = "*TTM Squeeze",
data_type = 'Close',
useATR = 0, -- использовать ATR; 0 - не использовать; 1 - использовать
periodBB = 29, -- Период расчета полос Болинджера
multBB = 2.0, -- коэффициент при расчете полос Болинджера
periodKC = 29, -- Период расчета канала Кельтнера
multKC = 1.5, -- коэффициент при расчете канала Кельтнера
line = {
{
Name = 'zero',
Color = zero_color,
Type = _G['TYPE_LINE'],
Width = 1
},
{
Name = 'Momentum Up',
Color = up_line_color,
Type = _G['TYPE_HISTOGRAM'],
Width = 2
},
{
Name = 'Momentum Down',
Color = dw_line_color,
Type = _G['TYPE_HISTOGRAM'],
Width = 2
},
{
Name = 'NO Squeeze',
Color = sq_no_color,
Type = _G['TYPE_POINT'],
Width = 2
},
{
Name = 'Squeeze',
Color = line_color,
Type = _G['TYPE_POINT'],
Width = 2
}
}
}
local PlotLines = function(index) return index end
local error_log = {}
local math_max = math.max
local math_min = math.min
local os_time = os.time
local table_remove = table.remove
local function log_tostring(...)
local n = select('#', ...)
if n == 1 then
return tostring(select(1, ...))
end
local t = {}
for i = 1, n do
t[#t + 1] = tostring((select(i, ...)))
end
return table.concat(t, " ")
end
local function myLog(...)
if logFile==nil then return end
logFile:write(tostring(os.date("%c",os_time())).." "..log_tostring(...).."\n");
logFile:flush();
end
--TTM Squeeze от John Carter
local function Algo(Fsettings, ds)
Fsettings = (Fsettings or {})
local data_type = (Fsettings.data_type or "Close")
local periodBB = (Fsettings.periodBB or 10)
local periodKC = (Fsettings.periodKC or 10)
local round = (Fsettings.round or "off")
local scale = (Fsettings.scale or 0)
local multBB = (Fsettings.multBB or 2)
local multKC = (Fsettings.multKC or 2)
local useATR = (Fsettings.useATR or 0)
local m_period = math_max(periodBB, periodKC)
error_log = {}
local fSMA_BB
local fSMA_KC
local fATR
local sourceH
local sourceL
local range
local fSMA_Range
local Average
local Raw
local fReg
local out_up
local out_dw
local squeeze
local no_squeeze
local l_index
local reg
local begin_index
return function (index)
local status, res = pcall(function()
out_up = nil
out_dw = nil
squeeze = nil
if fSMA_BB == nil or index == 1 then
begin_index = index
sourceH = {}
sourceH[1] = maLib.Value(index, 'High', ds)
sourceL = {}
sourceL[1] = maLib.Value(index, 'Low', ds)
fSMA_BB = maLib.new({period = periodBB, method = 'BOL', avg_method = 'SMA', data_type = 'Close', k_std = multBB,round = round, scale = scale}, ds)
fSMA_BB(index)
fSMA_KC = maLib.new({period = periodKC, method = 'SMA', data_type = 'Close', round = round, scale = scale}, ds)
fSMA_KC(index)
range = {}
range[index] = sourceH[index] - sourceL[index]
if useATR == 1 then
fATR = maLib.new({period = periodKC, method = 'ATR'}, ds)
range[index] = fATR(index)[index]
end
fSMA_Range = maLib.new({period = periodKC, method = 'SMA', data_type = 'Any', round = round, scale = scale}, range)
fSMA_Range(index)
Average = {}
Average[1] = maLib.Value(index, data_type, ds)
Raw = {}
Raw[1] = 0
fReg = maLib.new({period = periodKC, method = 'REG', data_type = 'Any', round = round, scale = scale}, Raw)
fReg(1)
reg = {}
reg[index] = 0
return
end
local upperBB, lowerBB = fSMA_BB(index)
local sma_kc = fSMA_KC(index)
range[index] = range[index - 1]
reg[index] = reg[index - 1]
if not maLib.CheckIndex(index, ds) then
if useATR == 1 then
range[index] = fATR(index)[index]
end
fSMA_Range(index)
return
end
if index ~= l_index then
sourceH[#sourceH + 1] = sourceH[#sourceH]
if #sourceH > periodKC then table_remove(sourceH, 1) end
sourceL[#sourceL + 1] = sourceL[#sourceL]
if #sourceL > periodKC then table_remove(sourceL, 1) end
Average[#Average + 1] = Average[#Average]
if #Average > periodKC then table_remove(Average, 1) end
Raw[#Raw + 1] = Raw[#Raw]
if #Raw > periodKC then table_remove(Raw, 1) end
end
local data = maLib.Value(index, data_type, ds)
sourceH[#sourceH] = maLib.Value(index, 'High', ds)
sourceL[#sourceL] = maLib.Value(index, 'Low', ds)
if useATR == 1 then
range[index] = fATR(index)[index]
else
range[index] = sourceH[#sourceH] - sourceL[#sourceL]
end
local sma_range = fSMA_Range(index)[index]
Average[#Average] = ((math_max(unpack(sourceH)) + math_min(unpack(sourceL)))/2 + sma_kc[index])/2
Raw[#Raw] = data - Average[#Average]
if (index - begin_index + 1) >= m_period then
reg[index] = fReg(#Raw, true)[#Raw]
if reg[index] >= (reg[index-1] or reg[index]) then
out_up = reg[index]
else
out_dw = reg[index]
end
local upperKC = sma_kc[index] + sma_range*multKC
local lowerKC = sma_kc[index] - sma_range*multKC
local sqzOn = (lowerBB[index] > lowerKC) and (upperBB[index] < upperKC)
-- local sqzOff = (lowerBB[index] < lowerKC) and (upperBB[index] > upperKC)
local noSqz = (lowerBB[index] < lowerKC) or (upperBB[index] > upperKC)
no_squeeze = noSqz and 0 or nil
squeeze = sqzOn and 0 or nil
-- myLog(tostring(index)..' '..os.date('%Y.%m.%d %H:%M', os.time(T(index)))..' reg'..' '..tostring(reg[index])..' sqzOn'..' '..tostring(sqzOn)..' sqzOff'..' '..tostring(sqzOff)..' noSqz'..' '..tostring(noSqz))
end
l_index = index
end)
if not status then
if not error_log[tostring(res)] then
error_log[tostring(res)] = true
myLog(tostring(res))
message(tostring(res))
end
end
return 0, out_up, out_dw, no_squeeze, squeeze
end
end
function _G.Init()
PlotLines = Algo(_G.Settings)
return 5
end
function _G.OnChangeSettings()
_G.Init()
end
function _G.OnCalculate(index)
return PlotLines(index)
end