-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy path(IK) Grid Script.pine
More file actions
203 lines (200 loc) · 10.3 KB
/
(IK) Grid Script.pine
File metadata and controls
203 lines (200 loc) · 10.3 KB
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
Script Name: (IK) Grid Script
Author: tapRoot_coding
Description: This is my take on a grid trading strategy. From Investopedia:
"Grid trading is most commonly associated with the foreign exchange market. Overall the technique seeks to capitalize on normal price volatility in an asset by placing buy and sell orders at certain regular intervals above and below a predefined base price."
This strategy is best used on sideways...
PineScript code:
Pine Script™ strategy
(IK) Grid Script
Copy code
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
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tapRoot_coding - Ian Kuzmik
//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
// == INPUT ==
i_autoBounds = input(group="Grid Bounds", title="Use Auto Bounds?", defval=false, type=input.bool) // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"]) // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1) // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float) // for manual grid bounds only. The upperbound price of your grid
i_lowerBound = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float) // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty = input(group="Grid Lines", title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer) // how many grid lines are in your grid
// == FUNCTIONS ==
// for auto grid only. return the upperbound if _up == true, or the lowerbound if _up == false
f_getGridBounds(_bs, _bl, _bd, _up) =>
if _bs == "Hi & Low"
_up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl) * (1 - _bd)
else
avg = sma(close, _bl)
_up ? avg * (1 + _bd) : avg * (1 - _bd)
// using the lowerbound, grid width, and grid line quantity, build an array of prices (grid lines) from the bottom up
f_buildGrid(_lb, _gw, _gq) =>
gridArr = array.new_float(0)
for i=0 to _gq-1
array.push(gridArr, _lb+(_gw*i))
gridArr
// return an array that contains the closest grid lines above and below current price (not counting the line price is currently on). This is solely for plotting purposes
f_getNearGridLines(_gridArr, _price) =>
arr = array.new_int(3)
for i = 0 to array.size(_gridArr)-1
if array.get(_gridArr, i) > _price
array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
array.set(arr, 1, i == 0 ? i : i-1)
break
arr
// == VARIABLES ==
var upperBound = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound // upperbound of our grid
var lowerBound = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth = (upperBound - lowerBound)/(i_gridQty-1) // space between lines in our grid
var gridLineArr = f_buildGrid(lowerBound, gridWidth, i_gridQty) // an array of prices that correspond to our grid lines
var orderArr = array.new_bool(i_gridQty, false) // a boolean array that indicates if there is an open order corresponding to each grid line
var closeLineArr = f_getNearGridLines(gridLineArr, close) // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0) // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1) // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
// == LOGIC ==
// ENTRY & EXIT
for i = 0 to (array.size(gridLineArr) - 1)
if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
buyId = i
array.set(orderArr, buyId, true)
strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
if close > array.get(gridLineArr, i) and i != 0
if array.get(orderArr, i-1)
sellId = i-1
array.set(orderArr, sellId, false)
strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))
// MAINTAIN GRID
// update auto grid (if active)
if i_autoBounds
upperBound := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
lowerBound := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
gridWidth := (upperBound - lowerBound)/(i_gridQty-1)
gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)
// update near grid lines (for plotting purposes)
closeLineArr := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)
// plot grid lines
plot(array.size(gridLineArr) > 0 ? array.get(gridLineArr,0) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 1 ? array.get(gridLineArr,1) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 2 ? array.get(gridLineArr,2) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 3 ? array.get(gridLineArr,3) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 4 ? array.get(gridLineArr,4) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 5 ? array.get(gridLineArr,5) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 6 ? array.get(gridLineArr,6) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 7 ? array.get(gridLineArr,7) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 8 ? array.get(gridLineArr,8) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 9 ? array.get(gridLineArr,9) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 10 ? array.get(gridLineArr,10) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 11 ? array.get(gridLineArr,11) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 12 ? array.get(gridLineArr,12) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 13 ? array.get(gridLineArr,13) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
plot(array.size(gridLineArr) > 14 ? array.get(gridLineArr,14) : na, color=bar_index % 2 == 1 ? color.rgb(255,255,0,50) : #00000000)
// plot near grid lines
plot(array.get(gridLineArr, nearTopGridLine), color=color.rgb(255,0,255,20), style=plot.style_stepline, linewidth=2)
plot(array.get(gridLineArr, nearBotGridLine), color=color.rgb(0,0,255,20), style=plot.style_stepline, linewidth=2)
Expand (102 lines)