.3, giới hạn=3)
Nếu không barstate.ishistory và đóng < mở
chiến lược. hủy bỏ ((
---------------------------
6. ```strategy.cancel_all```
The ```strategy.cancel_all``` function is similar to the ```strategy.cancel``` function. It can cancel/stop all pre-listed commands. The ```when``` parameter can be specified.
Parameters:
- ```when```: Execution conditions.
```pine
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
if not barstate.ishistory and close < open
strategy.cancel_all()
isStop := true
strategy.order
Các chức năng và cài đặt tham số củastrategy.order
chức năng gần như giống hệt vớistrategy.entry
Sự khác biệt làstrategy.order
không bị ảnh hưởng bởipyramiding
cài đặt tham số củastrategy
chức năng, và không có giới hạn số lượng lệnh.
Các thông số:
id
: Nó có thể được hiểu là cho một tên cho một vị trí giao dịch để tham chiếu.direction
: Nếu hướng lệnh dài (mua), truyền vào biến tích hợpstrategy.long
, và nếu bạn muốn đi ngắn (bán), đi trong biếnstrategy.short
.qty
: Xác định số lượng lệnh được đặt, nếu tham số này không được thông qua, số lượng lệnh mặc định sẽ được sử dụng.when
: Điều kiện thực thi, bạn có thể chỉ định tham số này để kiểm soát liệu hoạt động lệnh hiện tại này có được kích hoạt hay không.limit
: Xác định giá giới hạn lệnh.stop
Giá dừng lỗ.Chúng tôi sẽ sử dụng tính năngstrategy.order
không có giới hạn về số lượng đơn đặt hàng được đặt, kết hợp vớistrategy.exit
hàm thoát điều kiện để xây dựng một kịch bản tương tự như giao dịch lưới. ví dụ rất đơn giản và chỉ cho mục đích học tập:
/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/
varip beginPrice = -1
if not barstate.ishistory
if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0)
beginPrice := close
for i = 0 to 20
strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)
Các ví dụ về chiến lược trong hướng dẫn này chỉ dành cho mục đích hướng dẫn, để hướng dẫn các ý tưởng thiết kế chiến lược, và không phải là hướng dẫn hoặc lời khuyên giao dịch.
strategy("supertrend", overlay=true)
[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))
plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)
if direction < 0
if supertrend > supertrend[2]
strategy.entry("entry long", strategy.long)
else if strategy.position_size < 0
strategy.close_all()
else if direction > 0
if supertrend < supertrend[3]
strategy.entry("entry short", strategy.short)
else if strategy.position_size > 0
strategy.close_all()
Nó rất dễ dàng để viết một chiến lược xu hướng bằng cách sử dụng ngôn ngữ Pine, và ở đây chúng tôi sẽ thiết kế một xu hướng đơn giản sau chiến lược với một chỉ số siêu xu hướng.
Đầu tiên, mã chiến lược bắt đầu với một số cài đặt đơn giản bằng cách sử dụngstrategy
chức năng:strategy("supertrend", overlay=true)``, which just sets a strategy title "supertrend". The
lớp phủparameter is set to
đúng, so that the drawn indicator lines and other content are displayed on the main chart. The first thing we need to look at when designing a Pine strategy or learning a Pine strategy script is the strategy interface parameter design. Let's look at the source code of the ''supertrend indicator strategy'', which has the
input ` ` hàm chúng ta đã học trong khóa học trước
[supertrend, direction] = ta.supertrend(input(5,
factor input.int(10,), trPeriod ))
Cácinput
gọi chức năng được sử dụng như một tham số trực tiếp đểta.supertrend
chức năng chỉ số để tính toán chỉ số siêu xu hướng.
Theo mặc định, hàm đặt ra hai điều khiển tham số trên màn hình chiến lược ngôn ngữ Pine, như được hiển thị bên dưới:
Như chúng ta có thể thấy, giá trị mặc định trên điều khiển là tham số đầu tiên củainput
chức năng vàinput
chuỗi các chức năng (đây làinput.int
Với hai chức năng này, chúng ta có thể đặt các tham số củata.supertrend
chức năng trên màn hình chiến lược.supertrend
chức năng tính toán một dữ liệu giásupertrend
và một dữ liệu hướngdirection
Sau đó chúng ta sử dụngplot
chức năng để vẽ một biểu đồ, lưu ý rằng khi vẽ biểu đồ, nó dựa trên hướng của chỉ số siêu xu hướng, chỉ có hướng hiện tại được vẽ.direction
là -1, xu hướng thị trường hiện tại là tăng, khidirection
là 1, xu hướng thị trường hiện tại là giảm.plot
chức năng vẽ biểu đồ khi phán quyếtdirection
lớn hơn hoặc nhỏ hơn 0.
Tiếp theo.if... else if
logic là sự phán xét của tín hiệu giao dịch.direction < 0
là đúng, điều đó có nghĩa là thị trường hiện tại đang trong giai đoạn tăng.supertrend
trong chỉ số siêu xu hướng cao hơn giá của chỉ số siêu xu hướng trên hai BAR trước đó (tức làsupertrend[2], remember that the historical operator refers to the historical data of a variable
), nó sẽ được sử dụng như là một tín hiệu nhập để đi dài. nhớ rằng? nếu có một vị trí hiện tại, gọi chức năng lệnh ngược sẽ đóng vị trí trước đó đầu tiên, và sau đó mở vị trí theo hướng giao dịch hiện tại.supertrend > supertrend[2]
không được đáp ứng, miễn làstrategy.position_size < 0
giữ các vị trí ngắn, nó sẽ kích hoạtstrategy.close_all()
thực hiện chức năng để đóng tất cả các vị trí.
direction > 0
Nếu có các vị trí dài, tất cả các vị trí sẽ được đóng, và sau đó khi điều kiệnsupertrend < supertrend[3]
được đáp ứng, một tín hiệu ngắn sẽ được kích hoạt.[3]
để tham chiếu dữ liệu giá của chỉ số siêu xu hướng trên BAR thứ ba của số trước? đó có thể là ý định của tác giả chiến lược. sau tất cả, rủi ro ngắn trong một số thị trường, chẳng hạn như thị trường giao dịch hợp đồng, lớn hơn một chút so với rủi ro dài.
Đối vớita.supertrend
chỉ số, có ai quan tâm đến cách đánh giá liệu xu hướng hiện tại là lên hay xuống?
Trong thực tế, chỉ số này cũng có thể được thực hiện dưới dạng các hàm tùy chỉnh trong ngôn ngữ Pine:
pine_supertrend(factor, atrPeriod) =>
src = hl2
atr = ta.atr(atrPeriod)
upperBand = src + factor * atr
lowerBand = src - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]
if na(atr[1])
direction := 1
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Chức năng tùy chỉnh này là chính xác cùng một thuật toán như các chức năng tích hợp trongta.supertrend
, và tất nhiên dữ liệu chỉ số được tính toán cũng là chính xác như nhau.
Như chúng ta có thể thấy từ thuật toán chức năng tùy chỉnh này, Pinehl2
biến tích hợp (giá cao nhất và giá thấp nhất được cộng lại và sau đó chia cho 2, tức là mức trung bình của giá cao nhất và giá thấp nhất), sau đó chỉ số ATR (biến động) được tính toán cho một khoảng thời gian nhất định dựa trên tham số atrPeriod. Sau đó các đường dẫn trên và dưới được xây dựng bằng cách sử dụng hl2 và ATR.
Cập nhậtlowerBand
vàupperBand
theo các biểu thức ba trong mã.
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: lowerBand, được sử dụng để xác định xem xu hướng tăng có thay đổi hay không. upperBand: upperBand, được sử dụng để xác định xem xu hướng giảm có thay đổi hay không. lowerBand và upperBand luôn được tính toán, chỉ định hướng xu hướng hiện tại ở cuối hàm tùy chỉnh này.
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Ở đây nó được đánh giá rằng nếu giá trị giá của BAR cuối cùng trên siêu xu hướng làprevUpperBand
, tức là dải trên, nó có nghĩa là dòng là một xu hướng giảm.close
vượt quáupperBand
giá đột phá, xu hướng được coi là đã thay đổi tại thời điểm này và chuyển đổi thành xu hướng tăng.direction
là -1 (hành động tăng trưởng). nếu không nó vẫn được thiết lập là 1 (hành động giảm). đó là lý do tại sao bạn thấy trong chiến lược siêu xu hướngif direction < 0
khi các điều kiện tín hiệu được kích hoạt để đi dài.direction > 0
, điều kiện tín hiệu được kích hoạt để đi ngắn.
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Cuối cùng, dữ liệu giá và hướng của chỉ số Super Trend cụ thể được trả về dựa trên lựa chọn hướng.
/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/
varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")
maxDiffValue = input(1000, "maxDiffValue")
if balance - close * stocks > maxDiffValue and not barstate.ishistory
// more balance , open long
tradeAmount = (balance - close * stocks) / 2 / close
strategy.order("long", strategy.long, tradeAmount)
balance := balance - tradeAmount * close
stocks := stocks + tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
else if close * stocks - balance > maxDiffValue and not barstate.ishistory
// more stocks , open short
tradeAmount = (close * stocks - balance) / 2 / close
strategy.order("short", strategy.short, tradeAmount)
balance := balance + tradeAmount * close
stocks := stocks - tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)
Hãy tiếp tục với một số ví dụ về thiết kế chiến lược ngôn ngữ Pine, lần này chúng ta sẽ học một chiến lược cân bằng năng động.BaseCurrency
và số tiềnQuoteCurrency
. Bất kể giá tương đối của tài sản nào tăng, giá trị được giữ trong tài khoản sẽ tăng và tài sản sẽ được bán. Nếu giá tương đối của tài sản giảm, giá trị được giữ trong tài khoản sẽ giảm và tài sản sẽ được mua. Điều này được gọi là chiến lược cân bằng năng động. Trên thực tế, chiến lược cân bằng năng động là một loại chiến lược lưới hoạt động tốt trong thị trường dao động. Nhưng trong thị trường xu hướng, nó sẽ tiếp tục mất tiền, chúng ta cần đợi giá trở lại để giảm lỗ từ từ để kiếm lợi nhuận, nhưng lợi thế là chiến lược cân bằng năng động luôn có thể nắm bắt xu hướng dao động của thị trường.
Nhược điểm, như được hiển thị trên biểu đồ backtest của chiến lược này, là chiến lược có một lỗ nổi lớn trong giai đoạn xu hướng giá chung tăng (hoặc giảm).
Chúng ta hãy nhìn vào thiết kế mã chiến lược:
Chúng tôi sử dụng một thiết kế đơn giản hóa mô phỏng mộtbalance
(tức là, số lượng tài sản QuoteCurrency) vàstocks
Chúng tôi không đọc số lượng tài sản thực tế trong tài khoản, chúng tôi chỉ đơn giản là sử dụng số tiền mô phỏng để tính toán mua và bán thích hợp.maxDiffValue
, là tiêu chí đánh giá để thực hiện cân bằng.BaseCurrency
vàQuoteCurrency
vượt quámaxDiffValue
quá trình cân bằng diễn ra, bán tài sản với giá cao và mua tài sản với giá thấp để cân bằng lại tài sản.
Các chiến lược giao dịch tín hiệu kích hoạt phải là trong thời gian thực giai đoạn BAR, vì vậy nếu các phán đoán trong các điều kiện giao dịch chiến lược được thiết lập vớinot barstate.ishistory
. Mua khibalance
giá trị vượt quástocks
Một giao dịch bán hàng được thực hiện sau khi thực hiện báo cáo giao dịch.balance
vàstocks
Các biến được cập nhật và sau đó chờ đợi kích hoạt cân bằng tiếp theo.
Thông tin trên của backtest chiến lược chứa giá của loài tại thời điểm bắt đầu của backtest chiến lược, giá là 1458, vì vậy tôi đặt các thông sốbalance
để: 4374 (1458 * 3) cố tình, đặt tham sốstocks
Để tài sản bắt đầu cân bằng.
Trong khóa học trước, chúng ta đã học vềstrategy.exit
Trong ví dụ thiết kế chiến lược này, chúng ta sẽ sử dụng cácstrategy.exit
chức năng để tối ưu hóa một chiến lược siêu xu hướng.
Trước tiên hãy xem các thông số stop-loss và take-profit củastrategy.exit
chức năng:
trail_price
: Vị trí kích hoạt hành động hợp lý của việc đặt lệnh dừng lỗ theo dõi và lệnh đóng cửa dừng lỗ (ở vị trí được chỉ định bởi giá).trail_offset
: Khoảng cách từ giá cao nhất (khi mua) hoặc thấp nhất (khi mua) của một vị trí đóng được đặt sau khi thực hiện lệnh dừng lỗ theo dõi và lấy lợi nhuận.trail_points
Giống nhưtrail_price
tham số, ngoại trừ việc nó lấy điểm lợi nhuận như là vị trí được chỉ định.Không phải điều đó dễ hiểu sao? Không quan trọng! Hãy xem qua một kịch bản kiểm tra lại chiến lược để hiểu, thực sự khá đơn giản.
/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("test", overlay = true)
varip a = na
varip highPrice = na
varip isTrade = false
varip offset = 30
if not barstate.ishistory and not isTrade
strategy.entry("test 1", strategy.long, 1)
strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
a := close + offset
runtime.log("the price per point is:", syminfo.mintick, ", current close:", close)
isTrade := true
if close > a and not barstate.ishistory
highPrice := na(highPrice) ? close : highPrice
highPrice := close > highPrice ? close : highPrice
plot(a, "trail_price trigger line")
plot(strategy.position_size>0 ? highPrice : na, "current highest price")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "moving stop trigger line")
Ngay lập tức đầu vào dài khi chiến lược bắt đầu thực hiện, và sau đó ngay lập tức đặt mộtstrategy.exit
lệnh thoát (nó xác định các thông số theo dõi stop-loss và take-profit), khi giá của sự thay đổi thị trường tăng trên đường dẫn_price trigger, việc thực hiện logic stop-loss và take-profit, stop-loss và take-profit line (màu xanh) bắt đầu theo sự điều chỉnh động giá cao nhất, vị trí đường xanh là stop-loss và take-profit trigger để đóng vị trí, và cuối cùng khi giá thị trường giảm xuống dưới đường xanh kích hoạt việc đóng vị trí.
Sau đó chúng tôi sử dụng tính năng này để tối ưu hóa một chiến lược siêu xu hướng, chúng tôi chỉ đơn giản là chỉ định mộtstrategy.exit
lệnh exit plan vào lệnh entry chiến lược để thêm tính năng stop-loss và take-profit sau này.
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
Mã chiến lược đầy đủ:
/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0
findOrderIdx(idx) =>
ret = -1
if strategy.opentrades == 0
ret
else
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := i
break
ret
if strategy.position_size == 0
trail_price := na
state := 0
[superTrendPrice, dir] = ta.supertrend(input(2, "atr coefficient"), input(20, "atr period"))
if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.long, 1)
state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.short, 1)
state := 1
// Reverse signal, close all positions
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
strategy.cancel_all()
strategy.close_all()
runtime.log("trend reversal, long positions all closed")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
strategy.cancel_all()
strategy.close_all()
runtime.log("trend reversal, short positions all closed")
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ", trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)