วันนี้ภาษาไพน์ได้รับการพัฒนาเป็น v5! เวอร์ชันใหม่ของภาษาโปรแกรมของอินดิเคเตอร์และกลยุทธ์ของเรานำเสนอคุณสมบัติและการปรับปรุงใหม่ที่น่าตื่นเต้นมากมาย ตอนนี้ไพน์มีประสิทธิภาพมากกว่าที่เคย และการเปลี่ยนแปลงใน v5 จะช่วยให้เราพัฒนาภาษาไปอีกระดับ โพสต์นี้แนะนำคุณสมบัติล่าสุดเพียงไม่กี่อย่าง อย่าลืมอ่าน บันทึกประจำรุ่น และ คู่มือการย้ายเวอร์ชั่น ของเรา
ตัวแปลง V4 เป็น V5
ไพน์สคริปต์ที่มีอยู่ซึ่งใช้ไพน์เวอร์ชันก่อนหน้าจะยังคงทำงานต่อไปโดยไม่มีการเปลี่ยนแปลง แต่เราได้จัดเตรียมเครื่องมือการแปลงใน Pine Editor เพื่อช่วยผู้เขียนโค้ดในการแปลงสคริปต์ v4 เป็น v5 การปรับปรุงไพน์ในอนาคตจะมีเฉพาะในเวอร์ชัน 5 เท่านั้น ดังนั้นเราขอแนะนำให้แปลงอินดิเคเตอร์และกลยุทธ์ของคุณหากคุณต้องการรับประโยชน์จากคุณสมบัติใหม่ เครื่องมือแปลง v4 เป็น v5 จะใช้งานได้เมื่อมีการโหลดสคริปต์ v4 ใน Pine Editor จากดรอปดาวน์เมนู เพิ่มเติม:
โปรดทราบว่าโค้ด v4 ทั้งหมดไม่สามารถแปลงโดยอัตโนมัติได้ หากคุณประสบปัญหาในการแปลงหรือต้องการแปลงสคริปต์ด้วยตนเอง คู่มือการย้ายเวอร์ชั่น ซึ่งบันทึกการเปลี่ยนแปลงทั้งหมดระหว่าง v4 และ v5 จะแนะนำคุณ
ไลบรารี
การเพิ่มเข้ามาที่สำคัญของไพน์ ที่มาพร้อมกับ v5 คือไลบรารี ไลบรารีเป็นสิ่งพิมพ์ประเภทใหม่ที่ช่วยให้คุณสามารถสร้างฟังก์ชันแบบกำหนดเองเพื่อนำกลับมาใช้ใหม่ในสคริปต์อื่นได้ เมื่อเผยแพร่ไลบรารีแล้ว สคริปต์อื่นๆ (ไม่ว่าจะเป็นอินดิเคเตอร์ กลยุทธ์ หรือแม้แต่ไลบรารีอื่นๆ) สามารถนำเข้าและใช้ฟังก์ชันของไลบรารีได้ คุณสามารถใช้ไลบรารีเพื่อรวมอัลกอริธึมที่ซับซ้อนหรือฟังก์ชันที่ใช้บ่อย เพื่อให้คุณหรือชุมชนไพน์ทั้งหมดสามารถนำกลับมาใช้ใหม่ได้อย่างง่ายดาย
ในการเริ่มทำงานกับไลบรารี ดูหน้า คู่มือผู้ใช้งานไลบรารีของเรา ที่ส่วนท้ายของโพสต์นี้ คุณจะพบตัวอย่างไลบรารีที่เผยแพร่โดยสมาชิกของทีม PineCoders ของเรา คุณสามารถดูไลบรารีที่เผยแพร่จากฟีดสคริปต์ได้ ที่นี่
ค่าเริ่มต้นสำหรับฟังก์ชันที่ผู้ใช้กำหนด
การปรับปรุงที่ควบคู่ไปกับไลบรารี: สามารถกำหนดค่าเริ่มต้นสำหรับพารามิเตอร์ในฟังก์ชันที่ผู้ใช้กำหนดเอง ซึ่งทำให้เป็นทางเลือกได้อย่างมีประสิทธิภาพ ในตัวอย่างด้านล่าง เราประกาศฟังก์ชันแบบกำหนดเอง customPow() ที่เพิ่ม base เป็นกำลังของ exp หากไม่ได้ระบุ exp เมื่อเรียกใช้ฟังก์ชัน 2 จะถูกใช้:
//@version=5 indicator("") customPow(base, exp = 2) => result = 1 for i = 1 to exp result *= base plot(customPow(11)) // 11^2 plot(customPow(11, 4)) // 11^4
Switch
คำสั่ง switch ใหม่เป็นการดัดแปลงคำสั่ง if ที่คุ้นเคย หากคุณเคยต้องสร้างโครงสร้างขนาดใหญ่ของคำสั่ง if-else คุณจะประทับใจกับความสะดวกมากขึ้นในการบรรลุผลลัพธ์ที่ต้องการด้วย switch คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในคู่มืออ้างอิง ของเรา ดูการใช้งานจริงในโค้ดด้านล่าง ซึ่งเป็นบิวท์อินอินดิเคเตอร์ Average True Range ของเรา ซึ่งตอนนี้ใช้คำสั่ง switch เพื่อจัดเตรียมอัลกอริธึมการปรับให้เรียบที่แตกต่างกันในการคำนวณ:
//@version=5 indicator(title="Average True Range", shorttitle="ATR", timeframe="") lengthInput = input.int(title="Length", defval=14, minval=1) smoothingInput = input.string(title="Smoothing", defval="RMA", options = ["RMA", "SMA", "EMA", "WMA"]) maFunction(source, length) => switch smoothingInput "RMA" => ta.rma(source, length) "SMA" => ta.sma(source, length) "EMA" => ta.ema(source, length) => ta.wma(source, length) plot(maFunction(ta.tr(true), lengthInput), title = "ATR", color=#B71C1C)
คอลเลกชันของภาพวาด
การปรับปรุงครั้งใหญ่สำหรับการทำงานกับภาพวาดไพน์: ตัวแปรอาร์เรย์ในตัว line.all, label.all, box.all และ table.all ใหม่จะมี ID ของภาพวาดทั้งหมดของประเภทที่วาดเสมอโดยสคริปต์ของคุณ
ตัวอย่างเช่น คุณสามารถใช้เพื่อตัดแต่งจำนวนภาพวาดที่แสดงบนแผนภูมิตามค่าที่ผู้ใช้กำหนด ในสคริปต์ด้านล่าง เราวาดเส้นในแต่ละการเปิดใหม่ในแต่ละวัน (ไม่เกิน ~50 ตามข้อจำกัดบรรทัดเริ่มต้นของสคริปต์) จากนั้นเราจะตรวจสอบว่าจำนวนบรรทัดที่อนุญาตแม้ว่าอินพุตของสคริปต์จะเกินหรือไม่ และลบบรรทัดที่เก่าที่สุดหากใช่:
//@version=5 indicator("Daily Open", overlay = true) qtyOfLinesInput = input.int(10, "Draw only last n lines", minval = 0, maxval = 50) if ta.change(time("1D")) line.new(bar_index, open, bar_index + 1, open, extend = extend.right) if array.size(line.all) > qtyOfLinesInput line.delete(array.get(line.all, 0))
While
คุณสมบัติของไพน์ที่รอคอยมานานที่มาพร้อมกับ v5 คือ while loop คำสั่ง while สร้างลูปที่จะหยุดเมื่อเงื่อนไขเป็นเท็จ หรือใช้คำสั่ง break ในลูป
ตัวอย่างเช่น นี่คืออินดิเคเตอร์ที่คำนวณความแตกต่างระหว่างระยะทางเฉลี่ยที่เราต้องมองย้อนกลับไปเพื่อหาปริมาณขึ้นและลงที่เท่ากับปริมาณรวมของ n แท่งสุดท้าย ยิ่งเราต้องมองย้อนกลับไปเพื่อหาปริมาณขึ้นหรือลง มูลค่าของตลาดหมีหรือตลาดกระทิงก็ยิ่งมากขึ้นเท่านั้น:
//@version=5 var int MAX_BARS_BACK = 500 indicator("Volume bias", max_bars_back = MAX_BARS_BACK) int lookBackInput = input.int(20, "Volume Look Back (bars)", minval = 2, maxval = int(MAX_BARS_BACK / 4)) // Stop the script if the chart does not contain volume data. bool noVol = na(volume) and nz(math.sum(nz(volume), 200) == 0, true) if noVol runtime.error("No volume data.") volumeBias(lookBack, maxLookBack) => bool barUp = ta.rising(close, 1) bool barDn = ta.falling(close, 1) float upVolume = 0. float dnVolume = 0. float avgVolume = math.sum(nz(volume), lookBack) int[] upBarNos = array.new_int(0) int[] dnBarNos = array.new_int(0) int bar = 1 bool volumeFound = false while (not volumeFound) and bar < maxLookBack if barUp[bar] and upVolume < avgVolume upVolume += nz(volume[bar]) array.push(upBarNos, bar) else if barDn[bar] and dnVolume < avgVolume dnVolume += nz(volume[bar]) array.push(dnBarNos, bar) bar += 1 volumeFound := upVolume >= avgVolume and dnVolume >= avgVolume float volumeBias = bar >= maxLookBack ? na : array.avg(dnBarNos) - array.avg(upBarNos) float bias = volumeBias(lookBackInput, MAX_BARS_BACK) plot(bias, "Volume Bias", bias > 0 ? color.lime : color.fuchsia) hline(0)
สคริปต์ while loop จะทำงานจนกว่าจะพบโวลุ่มที่ต้องการทั้งในวอลุ่มขึ้นและลง และเราไม่ได้มองย้อนกลับไปที่จำนวนแท่งสูงสุดที่อนุญาต สคริปต์ยังแสดงคุณลักษณะอื่นที่เพิ่มเข้ามาในไพน์ v5: runtime.error()
runtime.error()
ฟังก์ชัน runtime.error() ทำให้สามารถหยุดการทำงานของสคริปต์และแสดงข้อความแสดงข้อผิดพลาดในเงื่อนไขใดๆ ที่คุณสามารถกำหนดได้ในไพน์ สิ่งนี้จะมีประโยชน์สำหรับผู้สร้างสคริปต์ที่ต้องการป้องกันไม่ให้ผู้ใช้ใช้อินดิเคเตอร์อย่างไม่ถูกต้อง นอกจากนี้ยังสามารถใช้เป็นเครื่องมือดีบัก เพื่อหยุดการดำเนินการระหว่างลูปหรือจากภายในฟังก์ชัน เป็นต้น
หากต้องการใช้ฟังก์ชันใหม่ ให้เรียกใช้ฟังก์ชัน runtime.error() เมื่อตรงตามเงื่อนไขของคุณ เมื่อดำเนินการ สคริปต์จะหยุดทำงานและแสดงเครื่องหมายอัศเจรีย์ที่คุ้นเคยถัดจากชื่ออินดิเคเตอร์ เมื่อผู้ใช้คลิกที่ไอคอนเครื่องหมายอัศเจรีย์ ข้อความที่คุณใช้ในการเรียกฟังก์ชันจะปรากฏขึ้น
โค้ดด้านล่างเป็นอินดิเคเตอร์ VWAP แบบ barebones ที่มีข้อผิดพลาดที่กำหนดเองสองข้อ อันแรกปรากฏขึ้นเมื่อสัญลักษณ์ไม่มีข้อมูลโวลุ่ม: VWAP คำนวณตามปริมาณ ดังนั้นหากไม่มีโวลุ่ม สคริปต์จะไม่ทำงาน อันที่สองจะปรากฏขึ้นเมื่อกรอบเวลาบนแผนภูมิเป็น 1D หรือสูงกว่า การคำนวณพื้นฐานของ VWAP จะรวบรวมข้อมูลค่าเฉลี่ยเคลื่อนที่ที่ถ่วงน้ำหนักตามปริมาตรในแต่ละแถบใหม่ และรีเซ็ตเมื่อเริ่มต้นวันใหม่ ดังนั้นอินดิเคเตอร์จึงมีประโยชน์เฉพาะในกรอบเวลาระหว่างวัน
//@version=5 indicator("VWAP with custom errors") if na(volume) // Will be true on symbols with no volume data e.g. TVC:SPX runtime.error("There is no volume data for this symbol.") else if timeframe.isdwm // Will be true on 1D and higher timeframes runtime.error("Session-based VWAP does not show meaningful data on timeframes >= 1D. Please switch to a lower timeframe.") plot(ta.vwap)
พารามิเตอร์กลยุทธ์ใหม่
ข่าวดีสำหรับผู้เขียนโค้ดกลยุทธ์! เราได้เพิ่มตัวแปรและฟังก์ชันใหม่ๆ มากมายที่ช่วยให้คุณมองเห็นคุณสมบัติทางการเทรด สถิติ และอินดิเคเตอร์ ค่าของมันจะอัปเดตเมื่อโปรแกรมจำลองโบรกเกอร์ดำเนินการตามคำสั่งของคุณ ดังนั้นคุณจึงสามารถติดตามค่าต่างๆ ได้ในขณะที่กลยุทธ์ของคุณดำเนินไป
คลิกที่นี่เพื่อดูคู่มืออ้างอิงไพน์สำหรับรายละเอียดเกี่ยวกับแต่ละรายการ
strategy.closedtrades.entry_price() / strategy.opentrades.entry_price()
strategy.closedtrades.entry_bar_index() / strategy.opentrades.entry_bar_index()
strategy.closedtrades.entry_time() / strategy.opentrades.entry_time()
strategy.closedtrades.size() / strategy.opentrades.size()
strategy.closedtrades.profit() / strategy.opentrades.profit()
strategy.closedtrades.commission() / strategy.opentrades.commission()
strategy.closedtrades.max_runup() / strategy.opentrades.max_runup()
strategy.closedtrades.max_drawdown() / strategy.opentrades.max_drawdown()
strategy.closedtrades.exit_price()
strategy.closedtrades.exit_bar_index()
Namespaces ใหม่
ชุมชน Pine coders ของเราบอกเราว่าพวกเขาชื่นชมอัตราการเติบโตที่ไพน์อย่างที่ไม่เคยเกิดขึ้นมาก่อนในช่วงไม่กี่ปีที่ผ่านมา และเราตั้งใจที่จะรักษาระดับเดียวกันในอนาคต อย่างไรก็ตาม สิ่งนี้สร้างกระแสของฟังก์ชันไพน์ใหม่และตัวแปรในตัว เพื่อรองรับการเติบโตอย่างบ้าคลั่งนี้ เราจำเป็นต้องจัดระเบียบชื่อปัจจุบันประมาณ 600 ชื่อที่ใช้ในภาษานั้นให้ดียิ่งขึ้น เราทำสิ่งนี้โดยเพิ่มเนมสเปซใหม่เพื่อจัดกลุ่มฟังก์ชันในลักษณะที่สะท้อนถึงการใช้งานได้ดียิ่งขึ้น นอกจากนี้ ยังมีการเปลี่ยนชื่อพารามิเตอร์ของฟังก์ชันจำนวนมากเพื่อให้เข้าใจได้ง่ายขึ้น
ตัวอย่างของเนมสเปซใหม่คือ ta. ซึ่งตอนนี้รวมตัวแปรและฟังก์ชันทั้งหมดที่เกี่ยวข้องกับการวิเคราะห์ทางเทคนิค ซึ่งจะทำให้ง่ายต่อการเรียกดูคู่มืออ้างอิงและค้นหาตัวแปรและฟังก์ชันทั้งหมดที่คืนค่าของตัวบ่งชี้ทั่วไป ดังนั้น sma() จึงเป็น ta.sma() ไม่จำเป็นต้องจำเนมสเปซใหม่ หากคุณพิมพ์ชื่อเก่าของฟังก์ชันโดยไม่มีเนมสเปซในตัวแก้ไขและกดปุ่มลัด เติมข้อความอัตโนมัติ (Ctrl + Space หรือ Cmd + Space บน MacOS) ป๊อปอัปที่แสดงคำแนะนำที่ตรงกันจะปรากฏขึ้น:
เช่นเดียวกันเมื่อค้นหาคู่มืออ้างอิง การพิมพ์ชื่อฟังก์ชันที่คุ้นเคยโดยไม่มีเนมสเปซจะทำให้ชื่อใหม่ปรากฏขึ้น คุณสามารถดูรายการการเปลี่ยนแปลงทั้งหมดใน v5 ได้ใน คู่มือการย้ายเวอร์ชั่น ของเรา
ไลบรารีที่เผยแพร่
สิ่งตีพิมพ์ต่อไปนี้เป็นตัวอย่างของไลบรารีที่เผยแพร่บน TradingView โดย PineCoders ที่ช่วยเราทดสอบคุณสมบัติใหม่ของไพน์:
Matrix_Functions_Lib_JD โดย Duyck
Enchanced_ta โดย HeWhoMustNotBeNamed
เราหวังว่าคุณจะพบว่าคุณสมบัติใหม่มีประโยชน์ และโปรดให้ข้อเสนอแนะและข้อแนะนำแก่เราอยู่เสมอ เรากำลังสร้าง TradingView ให้กับคุณ และเราอยากรู้เสมอว่าคุณคิดอย่างไรเกี่ยวกับการอัปเดตแพลตฟอร์มของเรา