พื้นฐาน Python สำหรับการเทรดด้วย Algo
นักเทรดใช้ Python เพื่อสร้างหุ่นยนต์เทรด อินดิเคเตอร์ทางเทคนิค ปลั๊กอิน และเครื่องมืออื่นๆ เพื่อช่วยในการเทรดด้วย Algo หรือการดำเนินการด้วยตนเอง และบทความนี้อธิบายพื้นฐานการเขียนโค้ดใน Python
Python เป็นภาษาโปรแกรมมิ่งระดับสูงที่ใช้งานทั่วไปและเป็นที่นิยม ใช้สำหรับการพัฒนาเว็บ วิทยาศาสตร์ข้อมูล การทำงานอัตโนมัติ และล่าสุดคือการเทรดด้วยอัลกอริทึมใน cTrader ไม่ว่าคุณจะกำลังสร้างหุ่นยนต์เทรดที่ใช้สัญญาณอย่างง่ายหรือกลยุทธ์ที่ใช้หลายอินดิเคเตอร์ที่ซับซ้อน Python ช่วยให้กระบวนการเร็วขึ้น มีประสิทธิภาพมากขึ้น และจัดการได้ง่ายขึ้น
อัลกอริทึม Python ในหนึ่งนาที!
- สัมผัสประสบการณ์การรองรับ Python ในตัวและการเข้าถึง cTrader Algo API อย่างไร้รอยต่อ โดย cTrader เป็นแพลตฟอร์มหลักเพียงรายเดียวที่นำเสนอการผสานรวมแบบเนทีฟออกจากกล่อง ไม่จำเป็นต้องใช้ปลั๊กอิน อะแดปเตอร์ หรือการตั้งค่าที่ซับซ้อน
- มุ่งเน้นไปที่สิ่งที่กลยุทธ์ของคุณควรบรรลุมากขึ้น เนื่องจากตรรกะกลายเป็นสิ่งที่ง่ายขึ้นในการประกอบ เพลิดเพลินกับการทำซ้ำอย่างรวดเร็ว ส่วนประกอบที่นำกลับมาใช้ใหม่ได้ และประสิทธิภาพที่ปรับขนาดได้
- พัฒนาอย่างรวดเร็ว แก้ไขข้อบกพร่องอย่างชาญฉลาด และทำงานร่วมกันโดยไม่มีอุปสรรค โค้ดของคุณจะสามารถปรับเปลี่ยนได้เสมอ เชื่อถือได้ และบำรุงรักษาได้
- เข้าถึงและได้รับประโยชน์จากไลบรารีฟรี/โอเพนซอร์สนับพัน บทช่วยสอนเชิงลึก ตัวอย่างโค้ด และการสนับสนุนจากชุมชนที่เข้มแข็งทั่วโลก
ตัวแปรและประเภทข้อมูล
ใน Python ตัวแปรมีการกำหนดประเภทแบบไดนามิก ซึ่งหมายความว่าคุณไม่จำเป็นต้องประกาศประเภทข้อมูลของพวกมันอย่างชัดเจน ตัวแปลจะกำหนดประเภทในขณะที่ทำงานตามค่าที่กำหนด
คุณสร้างตัวแปรโดยเพียงแค่กำหนดค่าให้กับหนึ่งตัวแปร:
1 2 3 4 | |
ประเภทข้อมูลทั่วไป
| ประเภท | คำอธิบาย | ตัวอย่าง |
|---|---|---|
int | จำนวนเต็ม | 5, 100, api.StepPips |
float | จำนวนทศนิยม | 1.1234, 100.5, api.Symbol.Ask |
bool | ค่าบูลีน | True, False |
str | สตริง | "EURUSD", api.Label |
list | คอลเลกชันของรายการ | [1, 2, 3], [p for p in api.Positions] |
ในอัลกอริทึม cTrader ตัวแปรจะเก็บข้อมูลสำคัญที่เกี่ยวข้องกับข้อมูลตลาด การตัดสินใจในการเทรด และการกำหนดค่า cBot ตัวแปรเหล่านี้มักแทนปริมาณการเทรดที่คำนวณแล้ว ค่าอินดิเคเตอร์ แฟล็กบูลีน ชื่อสัญลักษณ์ ป้ายกำกับ และอื่นๆ
นี่คือตัวอย่าง:
1 2 3 4 | |
ในกรณีนี้ self.volumeInUnits เป็น float ที่ใช้ในการวางคำสั่ง ในขณะที่ self.enoughMoney เป็น bool ที่ควบคุมว่าจะเปิดตำแหน่งต่อไปในกลยุทธ์แบบกริดหรือไม่
คลาสและออบเจ็กต์
ภาษา Python เป็นภาษาการเขียนโปรแกรมเชิงวัตถุ (OOP) ที่ให้เครื่องมือในการจัดระเบียบโค้ดผ่านคลาสและออบเจ็กต์ที่จำลองเอนทิตีและพฤติกรรมในโลกจริง คลาสกำหนดพิมพ์เขียวสำหรับการสร้างออบเจ็กต์ ซึ่งเป็นอินสแตนซ์ของคลาสนั้นที่มีข้อมูลและพฤติกรรมเฉพาะของตัวเอง แนวคิดหลักมีดังต่อไปนี้:
- คลาสถูกกำหนดโดยใช้คีย์เวิร์ด
class - เมธอด
__init__(คอนสตรักเตอร์) มักใช้เพื่อเริ่มต้นสถานะของออบเจ็กต์ - เมธอดของอินสแตนซ์กำหนดพฤติกรรม
- แอตทริบิวต์เก็บข้อมูลเฉพาะของแต่ละออบเจ็กต์
ตัวอย่างเช่น คุณสามารถสร้างคลาส Car ได้:
1 2 3 4 5 6 7 | |
จากนั้นคุณสามารถสร้างออบเจ็กต์ของคลาส Car และโต้ตอบกับมันได้:
1 2 3 | |
ในบริบทของ cTrader
ใน cTrader, cBot อินดิเคเตอร์ และปลั๊กอินถูกนำไปใช้เป็นคลาสที่รวมตรรกะทั้งหมดของพวกมันไว้ Algo โต้ตอบกับแพลตฟอร์ม cTrader โดยใช้ออบเจ็กต์พิเศษ api ที่ให้การเข้าถึงสัญลักษณ์ แผนภูมิ คำสั่ง อินดิเคเตอร์ และอื่นๆ
คุณสามารถสร้างคลาส SimplecBot ใน cTrader ได้ดังนี้:
1 2 3 | |
คลาส SimplecBot ประกอบด้วยเมธอดเดียว (on_start(self)) ที่ทำงานครั้งเดียวเมื่อบอทเทรดเริ่มต้น ฟังก์ชัน api.Print เขียนข้อความลงในบันทึก แสดงให้เห็นว่าเมธอดของออบเจ็กต์รวมพฤติกรรมการเทรดไว้อย่างไร
แต่ละอินสแตนซ์ของคลาสแสดงถึงอัลกอริทึมการเทรดที่มีการจัดการตัวเองซึ่งจัดการวงจรชีวิตและการตัดสินใจในการเทรดของตัวเองโดยใช้หลักการ OOP ใน cBot cTrader มาตรฐาน คลาสอาจเก็บข้อมูลสถานะภายใน เช่น ปริมาณ ผลลัพธ์ของอินดิเคเตอร์ ฯลฯ และใช้หลายเมธอดเพื่อจัดการตรรกะการเทรด
พิจารณาตัวอย่าง MACD crossover นี้ที่เริ่มต้นอินดิเคเตอร์ MACD เมื่อเริ่มต้นและวางคำสั่งซื้อเมื่อเกิดสัญญาณ MACD crossover:
1 2 3 4 5 6 7 | |
คีย์เวิร์ด self
ภายในคลาส self อ้างถึงอินสแตนซ์ของคลาสและให้การเข้าถึงตัวแปรและเมธอดของมัน self ใช้เพื่อ:
- เก็บข้อมูลเช่นผลลัพธ์ของอินดิเคเตอร์ ปริมาณของตำแหน่ง และค่าการกำหนดค่า
- ติดตามสถานะภายในระหว่างการเรียกเมธอดต่างๆ เช่น
on_start(),on_tick()หรือon_bar_closed()
ตัวอย่างนี้แสดงวิธีการใช้ self:
1 2 3 4 | |
ในกรณีนี้ self.volume เก็บปริมาณที่คำนวณแล้วเพื่อใช้ในการเทรด ในขณะที่ self.macd เก็บออบเจ็กต์อินดิเคเตอร์ MACD ซึ่งช่วยให้เข้าถึงค่าของมันได้ตลอดวงจรชีวิตของ cBot หากไม่มี self ตัวแปรเหล่านี้จะเป็นตัวแปรท้องถิ่นใน on_start() และไม่สามารถเข้าถึงได้ใน on_bar_closed() ซึ่งเป็นที่ที่อาจมีการตัดสินใจในการเทรด
เมธอดและฟังก์ชัน
ฟังก์ชันเป็นบล็อกของโค้ดที่นำกลับมาใช้ใหม่ได้ซึ่งใช้เพื่อทำงานเฉพาะ เมื่อฟังก์ชันถูกกำหนดภายในคลาส พวกมันถูกเรียกว่าเมธอด และพวกมันทำงานกับสถานะภายในของคลาสผ่านพารามิเตอร์ self ในบริบทของการเทรดด้วยอัลกอริทึมกับ cTrader เมธอดกำหนดว่าอัลกอริทึมการเทรดของคุณจะทำงานอย่างไรภายใต้เงื่อนไขต่างๆ เช่น การเปลี่ยนแปลงของตลาด การปิดแท่งเทียน หรือการเริ่มต้น
แพลตฟอร์มเรียกใช้เมธอดพิเศษ (ที่รู้จักกันในชื่อตัวจัดการเหตุการณ์) โดยอัตโนมัติในเวลาที่เหมาะสม เช่น:
on_start(self) – ถูกเรียกครั้งเดียวเมื่อบอทเริ่มต้น
1 2 | |
on_tick(self) – ถูกเรียกทุกครั้งที่มีการเปลี่ยนแปลงราคาในตลาด
1 2 | |
on_bar_closed(self) – ถูกเรียกเมื่อแท่งเทียน/แท่งใหม่ปิด (เหมาะสำหรับกลยุทธ์ที่ขึ้นอยู่กับเวลา)
1 2 3 4 | |
เมธอดที่กำหนดเองหรือเมธอดช่วยเหลือ
เพื่อหลีกเลี่ยงการเขียนซ้ำและการทำซ้ำโค้ด คุณสามารถกำหนดเมธอดของคุณเองได้ เมธอดที่กำหนดเองควรรวมตรรกะทั่วไปที่หุ่นยนต์เทรดของคุณอาจนำกลับมาใช้ใหม่
เมธอดด้านล่างส่งคืนตำแหน่งที่เปิดทั้งหมดที่เกี่ยวข้องกับป้ายกำกับของ cBot ปัจจุบัน ทำให้ง่ายต่อการติดตามหรือปิดตำแหน่งอย่างสม่ำเสมอ
1 2 | |
พิจารณาอีกเมธอดหนึ่งที่คำนวณระยะทางเป็น pip ระหว่างราคาปัจจุบันและราคาเข้าของตำแหน่ง ซึ่งสำคัญสำหรับการตัดสินใจในกลยุทธ์แบบตาราง
1 2 | |
เมื่อกำหนดเมธอดแล้ว คุณสามารถเรียกใช้มันจากภายในคลาสเดียวกันโดยใช้คีย์เวิร์ด self วิธีนี้ช่วยให้คุณนำตรรกะกลับมาใช้ใหม่ได้ทุกที่ในบอทของคุณโดยไม่ต้องทำซ้ำโค้ด
ตัวอย่างเช่น หลังจากกำหนด get_bot_positions() คุณอาจเรียกใช้มันภายในเมธอดอื่นเพื่อปิดตำแหน่งทั้งหมด:
1 2 3 4 | |
ที่นี่ self.get_bot_positions() เรียกใช้เมธอดช่วยเหลือ ส่งคืนเฉพาะตำแหน่งที่เกี่ยวข้องกับป้ายกำกับบอทปัจจุบัน
ในทำนองเดียวกัน เมธอด get_distance_in_pips() สามารถนำกลับมาใช้ใหม่เพื่อตัดสินใจในการเทรด ตัวอย่างเช่น ในกลยุทธ์แบบตาราง คุณอาจต้องการเปิดคำสั่งใหม่เฉพาะเมื่อตลาดเคลื่อนไหวไกลพอจากตำแหน่งล่าสุด:
1 2 3 4 5 6 7 | |
แนวคิดอื่นๆ
เนมสเปซและการนำเข้า
เนมสเปซใน Python ช่วยจัดระเบียบโค้ดและหลีกเลี่ยงการชนกันของชื่อโดยการจัดกลุ่มตัวระบุที่เกี่ยวข้อง (ตัวแปร ฟังก์ชัน คลาส) การนำเข้าช่วยให้คุณนำโมดูล ไลบรารี หรือแพ็คเกจภายนอก เข้ามาเพื่อขยายฟังก์ชันการทำงานนอกเหนือจากคุณสมบัติมาตรฐานของ Python
ใน Python คุณอาจนำเข้าโมดูลมาตรฐานหรือแพ็คเกจที่กำหนดเอง:
1 2 | |
คุณยังสามารถนำเข้าฟังก์ชันหรือคลาสเฉพาะได้:
1 2 | |
เมื่อเขียนอัลกอริทึมสำหรับ cTrader ใน Python การนำเข้าทำงานแตกต่างกันเล็กน้อยเนื่องจาก cTrader ผสานรวมกับ cTrader Algo API ที่อิงกับ .NET การตั้งค่านี้เกี่ยวข้องกับบริดจ์ที่อนุญาตให้โค้ด Python โต้ตอบกับแอสเซมบลี .NET และนี่อธิบายว่าทำไม cBot ทั่วไปจึงเริ่มต้นด้วย:
1 2 3 4 5 6 7 8 9 | |
ที่ซึ่ง:
import clrโหลด Common Language Runtime (CLR) ซึ่งช่วยให้ Python สามารถทำงานร่วมกับไลบรารี .NET ได้clr.AddReference("cAlgo.API")อ้างอิงถึงแอสเซมบลี cAlgo API ซึ่งมีคลาส เมธอด และออบเจ็กต์ที่เกี่ยวข้องกับการเทรดทั้งหมดfrom cAlgo.API import *นำเข้าประเภททั้งหมดจาก API (เช่นTradeType,Color,Position)from robot_wrapper import *โหลดฟังก์ชันช่วยเหลือและตัวห่อหุ้มที่ทำให้การดำเนินการเทรดทั่วไปง่ายขึ้น
ระบบเนมสเปซทำให้แน่ใจว่า:
- Python ใช้ชื่อที่มีอยู่ในตัว (เช่น
print) เพื่อหลีกเลี่ยงความขัดแย้งกับชื่อของ cTrader (เช่นapi.Print) - ออบเจ็กต์เฉพาะการเทรดทั้งหมด (
api.Symbol,api.Indicators,api.ExecuteMarketOrder) มาจากเนมสเปซ API ของ cTrader Algo ทำให้มีการจัดระเบียบและแยกแยะได้ชัดเจน - คุณสามารถขยายฟังก์ชันการทำงานได้โดยนำเข้าแพ็คเกจที่กำหนดเองของคุณเพื่อทำงานร่วมกับประเภทที่มีอยู่ในตัวของ cTrader
ลูป
ลูปช่วยให้คุณทำซ้ำการดำเนินการบนลำดับของค่าหรือจนกว่าจะเป็นไปตามเงื่อนไข ในการเทรดด้วยอัลกอริทึม ลูปมักใช้ในการประมวลผลโพซิชัน (เช่น ปิด กรอง หรืออัปเดต) ตรวจสอบเงื่อนไขในหลายสินทรัพย์หรืออินดิเคเตอร์ ใช้กลยุทธ์แบบกริดหรือมาร์ติงเกลที่ต้องมีการส่งคำสั่งซ้ำๆ และอื่นๆ
ใน Python การวนซ้ำทำได้ง่ายและรองรับทั้งลูป for (สำหรับการวนซ้ำผ่านคอลเลกชัน) และลูป while (สำหรับการทำซ้ำจนกว่าเงื่อนไขจะเปลี่ยน)
คุณสามารถเขียนลูปเพื่อปิดโพซิชันได้:
1 2 3 4 | |
ในกรณีนี้:
self.get_bot_positions()ส่งคืนโพซิชันทั้งหมดที่เป็นของ cBot ปัจจุบัน- ลูป
forจะวนผ่านแต่ละโพซิชัน - โพซิชันที่ตรงกันจะถูกปิดด้วย
api.ClosePosition
พิจารณาลูปอื่นที่วนซ้ำผ่านโพซิชันกริดที่เปิดทั้งหมด ปิดทีละตำแหน่ง และตรวจสอบซ้ำว่ามีโพซิชันที่เหลืออยู่หรือไม่ (ความปลอดภัยในกรณีที่มีการปิดบางส่วน)
1 2 3 4 5 6 | |
ประโยคเงื่อนไข
คำสั่งเงื่อนไขควบคุมการทำงานใน Python โดยอนุญาตให้อัลกอริทึมของคุณตัดสินใจตามนิพจน์ทางตรรกะ เงื่อนไขเป็นหัวใจสำคัญของตรรกะกลยุทธ์ ซึ่งกำหนดว่าเมื่อใดควรเข้า ออก หรือจัดการโพซิชัน
Python รองรับโครงสร้างเงื่อนไขหลัก 3 แบบ:
if– ดำเนินการโค้ดเมื่อเงื่อนไขเป็นจริงelif(else if) – ตรวจสอบเงื่อนไขอื่นหากเงื่อนไขแรกเป็นเท็จelse– ให้ทางเลือกสำรองเมื่อไม่มีเงื่อนไขใดเป็นจริง
พิจารณาเงื่อนไขการตัดกันของ MACD ที่แสดงในโค้ดนี้:
1 2 3 4 | |
โครงสร้างนี้:
- ส่งคำสั่งซื้อเมื่อเส้น MACD อยู่เหนือเส้นสัญญาณ
- ส่งคำสั่งขายเมื่อเส้น MACD อยู่ต่ำกว่าเส้นสัญญาณ
- ข้ามการเทรดหากไม่มีสัญญาณที่ชัดเจน
รายการ
Python มีเครื่องมือที่ทรงพลังและกระชับสำหรับการทำงานกับคอลเลกชันของข้อมูล เช่น การเทรด ราคา หรืออินดิเคเตอร์ สองอย่างที่พบบ่อยที่สุดคือ list comprehension และฟังก์ชันรวมที่มีอยู่ในตัว เช่น sum()
ตัวอย่างเช่น คุณสามารถเขียนโค้ดที่วนซ้ำผ่าน numbers และเก็บเฉพาะจำนวนคู่ได้ดังนี้:
1 2 | |
คุณสามารถใช้ list comprehension เพื่อเลือกเฉพาะโพซิชันสำหรับสัญลักษณ์ปัจจุบัน ซึ่งสร้างรายการที่กรองแล้วที่มีประโยชน์ในสภาพแวดล้อมที่มีหลายสัญลักษณ์
1 | |
การรวมกำไรหรือปริมาณโดยใช้ sum() เป็นวิธีมาตรฐานในกลยุทธ์การเทรดแบบกริดเพื่อกำหนดว่าเมื่อใดกำไรรวมถึงเป้าหมาย
1 | |
คุณสามารถรวมการกรองและการรวมได้ดังนี้:
1 2 | |
การดำเนินการแบบซิงโครนัสและอะซิงโครนัส
Python ใช้โมเดลการดำเนินการแบบซิงโครนัสโดยค่าเริ่มต้น วิธีวงจรชีวิตของอัลกอริทึมของคุณ เช่น on_start, on_tick และ on_bar_closed จะถูกเรียกใช้โดยลูปเหตุการณ์ของแพลตฟอร์มทีละรายการ
นี่คือการแสดงพื้นฐานของการไหลของการเทรดแบบซิงโครนัส:
graph TD
A(พบสัญญาณ) ==> B(ดำเนินการคำสั่ง)
B ==> C(โพซิชันถึง TP/SL)
C ==> D(ปิดโพซิชัน)
D ==> A ในการไหลแบบซิงโครนัส การดำเนินการที่ใช้เวลานานอาจบล็อกเธรด ซึ่งอาจทำให้เหตุการณ์ถัดไปล่าช้า อย่างไรก็ตาม ในกลยุทธ์จริง อัลกอริทึมมักเริ่มต้นการดำเนินการที่ไม่บล็อก เช่น การส่งคำสั่งหรือการตั้งค่า stop-loss และ take-profit จากนั้นรอเหตุการณ์ในอนาคต (เช่น tick หรือแท่งใหม่) เพื่อจัดการผลลัพธ์ การตั้งค่านี้ส่งผลให้เกิดการจัดการคล้ายกับแบบอะซิงโครนัส แม้ว่าจะไม่ได้ใช้โครงสร้าง async/await ของ Python
หมายเหตุ
สำหรับอัลกอริทึมการเทรดส่วนใหญ่ การเขียนโปรแกรมแบบอะซิงโครนัสอย่างชัดเจนไม่จำเป็น
cTrader จัดการการทำงานพร้อมกันโดยการจัดลำดับการเรียกกลับตามเหตุการณ์ของคุณ แต่ละวิธีจะถูกเรียกใช้อย่างอิสระและไม่เคยขนานกัน ซึ่งขจัดความจำเป็นในการป้องกันการทำงานหลายเธรด การออกแบบนี้ช่วยให้กลยุทธ์สามารถตอบสนองต่อเงื่อนไขการเทรดหลายอย่างพร้อมกันในเชิงตรรกะโดยไม่มีการบล็อก
ในตัวอย่างด้านล่าง กลยุทธ์จะประเมินสัญญาณซื้อและขายอย่างอิสระและตอบสนองตามนั้น โดยไม่มีการซ้อนทับในบริบทการดำเนินการ
graph TD
A([พบสัญญาณ]) ==> B([เปิดคำสั่งซื้อ]) & C([เปิดคำสั่งขาย<br>เพื่อป้องกันความเสี่ยง
]) ==> D([คำสั่งถึงระดับ<br>ทำกำไรหรือหยุดขาดทุน])
D ==> E([ปิดสถานะ])
E ==> A แม้ว่าการตัดสินใจอาจดูเหมือนเป็นแบบขนาน แต่จะถูกจัดการตามลำดับโดยระบบคิวภายในของ cTrader สถาปัตยกรรมของแพลตฟอร์มมีจุดมุ่งหมายเพื่อป้องกันปัญหาการทำงานพร้อมกัน ในขณะที่ทำให้หุ่นยนต์เทรดยังคงตอบสนองต่อการเปลี่ยนแปลงของตลาด
