avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi...

Được tạo ra trong: 2022-06-01 17:37:55, cập nhật trên: 2023-09-18 20:19:45
comments   6
hits   2992

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…

Có rất nhiều chiến lược nguồn mở trên TradingView. Thật đáng tiếc khi rất nhiều chiến lược, ý tưởng và chỉ báo tuyệt vời không thể đưa vào thực tế. Nhìn thấy điều này, FMZ, đơn vị cam kết phổ biến công nghệ giao dịch định lượng cho nhiều nhà giao dịch, tự nhiên không thể kìm nén được sự thôi thúc giải quyết nhu cầu này!

Yêu cầu này thực sự không thể chịu đựng được!

Vì vậy, trong thế giới lập trình mã, tôi đã đi qua những ngọn núi và dòng sông, và trải nghiệm 9*9=81 pit, sau khi chịu đựng vô số đêm mất ngủ, một núi lon Red Bull rỗng chất đống ở góc. Cuối cùng, FMZ hỗ trợ và tương thích với ngôn ngữ Pine và có thể sử dụng nhiều tập lệnh Pine của TradingView.

Nói về ngôn ngữ Pine, tôi chỉ mới tự học nó gần đây thôi. Nhưng thành thật mà nói, ngôn ngữ Pine dành cho giao dịch định lượng thực sự đơn giản, dễ sử dụng và dễ học. Cái gì? Bạn không tin ư? Hãy xem tôi đang viết chiến lược lưới cho bạn nhé~

/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="间距价格")
var dir = input.string("long", title="方向", options = ["long", "short", "both"])
var amount = input.float(-1, title="下单量")
var numbers = input.int(-1, title="网格数量")
var profit = input.int(-1, title="盈利价差") / syminfo.mintick

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("参数错误")

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

findTradeId(id) =>
    ret = "notFound"
    for i = 0 to strategy.opentrades - 1
        if strategy.opentrades.entry_id(i) == id 
            ret := strategy.opentrades.entry_id(i)
    ret 

// 实时K线阶段
if not barstate.ishistory
    // 检索网格
    for i = 1 to numbers
        // 做多
        direction = dir == "both" ? "long" : dir 
        plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
        if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.long,  qty=amount, limit=beginPrice-i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
        // 做空
        direction := dir == "both" ? "short" : dir 
        plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
        if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)

Công cụ giao dịch theo thời gian thực, công cụ kiểm tra ngược, nhiều chức năng và ngôn ngữ Pine dễ sử dụng của FMZ giống như thêm cánh cho hổ vậy! Bao gồm cả cài đặt tham số và mã cấu hình kiểm tra ngược, tổng số mã không vượt quá 50 dòng. Người mới bắt đầu không còn phải lo lắng về việc viết lưới nữa…

Tất nhiên, chiến lược này là chiến lược lưới. Chiến lược lưới cũng có những nhược điểm và không phải là cỗ máy in tiền được đảm bảo. Chìa khóa nằm ở cách sử dụng và các thông số của nó. Tôi sẽ không nói thêm về điểm này. Hãy tập trung nhiều hơn vào cách viết chiến lược dễ dàng, triển khai logic giao dịch của riêng bạn và kiếm tiền bằng cách viết chiến lược của riêng bạn. Cảm giác thật tuyệt mà không cần nhờ ai giúp đỡ! !

Giải thích mã

Để tôi giải thích cho bạn, mã lệnh rất đơn giản và dễ hiểu. Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi sẽ…….. ……… …………………………..Để tôi kể cho bạn nghe chi tiết nhé!

Vào lúc bắt đầu/*backtest*/Nội dung được gói là mã cấu hình kiểm tra ngược FMZ, đây là chức năng của FMZ, không phải là nội dung của ngôn ngữ Pine. Tất nhiên, bạn có thể chọn không viết phần này. Khi kiểm tra ngược, bạn sẽ cần phải nhấp thủ công vào các điều khiển tham số để thiết lập cấu hình và tham số kiểm tra ngược.

/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/

Mã sau đây:

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="间距价格")
var dir = input.string("long", title="方向", options = ["long", "short", "both"])
var amount = input.float(-1, title="下单量")
var numbers = input.int(-1, title="网格数量")
var profit = input.int(-1, title="盈利点数") / syminfo.mintick
  • strategy(overlay=true): Được sử dụng để thiết lập một số tùy chọn của tập lệnh, overlay=true, tức là cung cấp tham sốoverlayGán giá trị true để vẽ hình ảnh trên hình ảnh chính của biểu đồ (biểu đồ K-line là hình ảnh chính, có thể hiểu đơn giản như thế này).
  • varip beginPrice = 0: Biến beginPrice được khai báo bằng từ khóa varip và ban đầu được gán giá trị 0, được dùng làm giá ban đầu của lưới.
  • var spacing = input.float(-1, title="间距价格"): Đặt tham số chiến lược. Tên tham số là “giá khoảng”, là khoảng giữa mỗi điểm lưới. Nếu đặt thành 100, nghĩa là giao dịch sẽ được thực hiện mỗi khi giá vượt quá 100.
  • var dir = input.string("long", title="方向", options = ["long", "short", "both"]): Một tham số chiến lược được thiết lập, có tên là “hướng”. Tham số này là một tùy chọn có hộp thả xuống và bạn có thể chọn dài, ngắn hoặc cả hai. Chúng lần lượt chỉ ra rằng lưới chỉ giao dịch dài hạn, chỉ giao dịch ngắn hạn hoặc giao dịch cả dài hạn và ngắn hạn.
  • var amount = input.float(-1, title="下单量"): Đặt tham số để kiểm soát khối lượng giao dịch tại mỗi giao dịch điểm lưới.
  • var numbers = input.int(-1, title="网格数量"): Số điểm lưới. Đặt thành 20 nghĩa là có 20 điểm lưới theo một hướng.
  • var profit = input.int(-1, title="盈利价差") / syminfo.mintick: Thiết lập tham số để kiểm soát chênh lệch giá tại đó vị thế tại mỗi điểm lưới sẽ được đóng lại.

Tiếp theo, hãy xem mã:

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("参数错误")

Điều này có nghĩa là nếu bất kỳ tham số nào như khoảng cách, số lượng, số và lợi nhuận không được thiết lập, giá trị mặc định là -1, nghĩa là chiến lược sẽ dừng lại (bạn không thể chạy mà không thiết lập tham số ~ haha!)

Go on !

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

Điều này có nghĩa là khi chiến lược đang ở giai đoạn K-line thời gian thực và beginPrice == 0, hãy sửa đổi giá trị của beginPrice thành giá mới nhất hiện tại. Có thể hiểu rằng khi chiến lược chính thức chạy thì giá hiện tại ban đầu chính là giá ban đầu của lưới. Bởi vì kịch bản có giai đoạn BAR K-line lịch sử, chiến lược sẽ thực hiện logic trong giai đoạn BAR lịch sử. Việc sắp xếp lưới trên BAR lịch sử chắc chắn là vô nghĩa.

Giai đoạn BAR lịch sử là gì?

Để đưa ra một ví dụ đơn giản, tại thời điểm hiện tại A, chiến lược bắt đầu chạy và chiến lược thu thập dữ liệu với 100 thanh K-line BAR. Theo thời gian, 100 thanh chắc chắn sẽ trở thành 101, 102… N. Khi chạy từ thời điểm A, BAR thứ 101 là giai đoạn K-line thời gian thực, tức là dữ liệu thời gian thực mới nhất. Vì vậy, từ BAR thứ 1 đến BAR thứ 100, đây đều là những điều kiện thị trường lịch sử đã qua, nhưng chiến lược cũng sẽ được thực hiện dựa trên những điều kiện thị trường lịch sử này, vì vậy giai đoạn này là giai đoạn K-line lịch sử.

barstate.ishistoryĐây là một biến tích hợp của ngôn ngữ Pine. Nếu BAR hiện tại là BAR lịch sử,barstate.ishistoryNếu không phải là BAR lịch sử thì nó là sai. Do đó, khi barstate.ishistory không đúng thì nó đang ở giai đoạn K-line thời gian thực.

Tiếp theo, chúng tôi đã tạo một hàm

findTradeId(id) =>
    ret = "notFound"
    for i = 0 to strategy.opentrades - 1
        if strategy.opentrades.entry_id(i) == id 
            ret := strategy.opentrades.entry_id(i)
    ret 

Chức năng của hàm này là tìm xem một ID nào đó có tồn tại trong tất cả các lệnh hiện đang mở hay không. Nếu có, hàm findTradeId sẽ trả về ID của lệnh hiện tại khi nó được gọi (lưu ý rằng ID này không phải là ID lệnh của trao đổi, nhưng ID được gán cho lệnh theo chiến lược). , hoặc được hiểu là nhãn), nếu không tồn tại, trả về chuỗi “notFound”.

Tiếp theo, chúng ta bắt đầu tạo lưới:

// 实时K线阶段
if not barstate.ishistory
    // 检索网格
    for i = 1 to numbers
        // 做多
        direction = dir == "both" ? "long" : dir 
        plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
        if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.long,  qty=amount, limit=beginPrice-i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
        // 做空
        direction := dir == "both" ? "short" : dir 
        plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
        if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)

Vòng lặp for được sử dụng để xác định số vòng lặp dựa trên giá trị của tham số number, nghĩa là sắp xếp số thứ tự tương ứng. Đặt hướng theo tham số dir. Sử dụng hàm findTradeId để tìm hiểu xem lệnh của nhãn tại vị trí lưới hiện tại đã được mở hay chưa. Chỉ đặt lệnh đã lên kế hoạch nếu lệnh đó chưa được mở (nếu lệnh đó đã được mở, bạn không thể đặt lệnh trùng lặp). Khi đặt lệnh, hãy sử dụng hàm strategy.order để chỉ định tham số giới hạn để tạo lệnh theo kế hoạch. Đặt lệnh đóng tương ứng cùng lúc với lệnh kế hoạch. Để đóng một vị thế, hãy sử dụng hàm strategy.exit, chỉ định tham số lợi nhuận và chỉ định điểm lợi nhuận.

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…

Nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…

Chỉ cần nhìn vào đường cong lợi suất, bạn có thể thấy rằng lưới điện cũng có rủi ro và không phải là chiến thắng được đảm bảo. Chỉ là rủi ro tương đối nhỏ hơn khi lưới điện được mở rộng trên quy mô lớn.

Vâng, nếu bạn vẫn không thể viết chiến lược bằng ngôn ngữ Pine dễ học và dễ sử dụng, thì tôi…