ThaiQuantsUtilities (สั้นๆว่า TQU) เป็น AmiBroker Plugin ที่ถูกสร้างขึ้นมาเพื่อช่วยนักลงทุนด้วยระบบเทรดหุ้นสามารถพัฒนากลยุทธ์การเทรดใน AmiBroker ได้อย่างรวดเร็วและถูกต้อง ทั้งทางด้านการเขียนโค้ดและการทดสอบระบบ
DEPRECATED
TQU Application ได้หยุดให้บริการและปิด server สำหรับคนทั่วไป เพราะ คนใช้น้อย (ทั้งๆที่ทำให้ใช้กันฟรีๆ) ไม่คุ้มค่าเสียเวลาในการอัฟเดทและค่าใช้จ่าย ThaiQuants จึงขอสงวนสิทธิ์การใช้ app ให้เฉพาะ นศ ที่สามารถเข้าระบบคอร์สและ server ของทางโรงเรียนเท่านั้น โดยหวังว่าจะมีโปรแกรมเมอร์คนอื่นพัฒนาแอพคล้ายๆกันให้คนไทยได้ใช้
Objectives:
- Rapid Prototyping with Accuracy พัฒนาต้นแบบระบบอย่างรวดเร็วและถูกต้อง
- Rapid คือ พัฒนาได้อย่างรวดเร็ว ไม่ต้องจุกจิกเขียนโค้ดซ้ำ ในส่วนของโค้ดที่จริงๆแล้วมีมาตราฐานหรือเหมือนๆกันกับกลยุทธ์ทั่วๆไป แต่ให้ไปเน้นด้านการปรับปรุง Fine Tuning กลยุทธ์การเทรดนั้นๆแทน
- Prototyping สร้างต้นแบบด้วยการโฟกัสไปที่โค้ดหลักๆ ได้แก่ Signals และ PositionScore เท่านั้น โดยส่วนที่เหลือให้ TQU เป็นตัวช่วยเขียนโค้ดให้เกือบทั้งหมด
- Accuracy เน้นย้ำความถูกต้องทั้งในด้านการโค้ด (Coding) และการทดสอบ (Backtesting) ด้วย Default Parameters จาก TQU และ ด้วย Simulation มาตราฐานที่ถูกจัดเตรียมไว้ให้ พร้อมใช้งาน ไม่ต้องโค้ด ดังนี้: Slippage, Missing Trades, และ PositionScoreNoise อีกทั้งยังรวมไปถึงการช่วยตรวจสอบ หุ้นแตกพาร์ (Avoid Split) และ ช่องราคาหุ้น (Tick Size)
- Proper Scope and Direction in Trading System Development กำหนดขอบเขตและทิศทางในการพัฒนาระบบอย่างเหมาะสม ซึ่งช่วยหลีกเลี่ยง Overfitting, Over Optimizing, และ Over Optimism (โลกสวย กำไรร้อยล้าน) จากค่า Defaults และ Simulation ที่เตรียมให้ใช้ใน TQU functions ต่างๆ
- Educational Purpose in Mind ทาง ThaiQuants ได้สร้าง TQU ด้วยมีเจตนาที่จะสอนให้นักลงทุนเรียนรู้การพัฒนาระบบอย่างถูกต้อง ไม่ใช่แค่เพียงนำ Plugin ไปใช้ โดยได้มีการจัดวางโครงสร้างโค้ด พร้อมทั้งคำอธิบาย Tooltip เด้งขึ้นมาให้อ่านตอนเขียนชื่อฟังก์ชั่นนั้นๆของ TQU และเพจนี้จะทำการชี้แจงโค้ดเปรียบเทียบระหว่าง โค้ด AFL ปรกติ กับ โค้ด TQU ฟังก์ชั่น
- Ease of Use hiding standard code layers ใช้งานง่ายและทำการซ่อนโค้ดมาตราฐานที่ต้องเขียนซ้ำๆออกไป
- Transparency in Code and Ethics โปร่งใสทั้งในด้านโค้ดและจรรยาบรรณ โดยที่ TQU จะชี้แจงทุกๆค่าตัวแปรที่ใช้ (Default Parameters) ซึ่งทำให้ผู้ใช้สามารถลองเขียนโค้ด AFL ด้วยตนเองเพื่อทดสอบเปรียบเทียบผลลัพธ์จาก TQU ได้ และ ทาง ThaiQuants จะชี้แจงว่าอะไรดี อะไรไม่ดี อะไรที่ควรใช้… ไม่ใช่ว่าทุกอย่างใน TQU จะดีไปทั้งหมด. This is not about fame or money. It is about directing the ship to the shining direction.
ขั้นตอนการใช้งาน ThaiQuantsUtilities.dll
- ปิดโปรแกรม AmiBroker
- กดปุ่นดาวน์โหลด ThaiQuantsUtilities.dll ข้างล่าง แล้วเลือก AmiBroker เวอร์ชั่นที่ใช้งานอยู่
- ก๊อปปี้ไฟล์ ThaiQuantsUtilities.dll ไปไว้ยังโฟรเดอร์ AmiBroker -> โฟรเดอร์ Plugins
- เปิด AmiBroker AFL Editor แล้วลองพิมพ์ ThaiQuantsSetOptions(); ควรจะเห็นว่าฟังก์ชั่นพร้อมใช้งาน
เลือกดาวน์โหลด ThaiQuantsUtilities??.dll
- เลือกดาวน์โหลดให้เหมาะสมกับ AmiBroker เวอร์ชั่นที่ใช้อยู่ แค่เพียงไฟล์เดียว! (ถ้าก๊อปปี้ไปวางทั้งสองตัว AmiBroker จะสับสนเลือกไม่ถูก!)
- นำ ThaiQuantsUtilities??.dll ไปวางไว้ในโฟลเดอร์ AmiBroker/Plugins (อย่าลืมปิดโปรแกรม AmiBroker ก่อนก๊อปปี้ไฟล์ .dll ไปวาง)
- มีผู้ใช้บางคนแจ้งมาว่า ต้องปิดเปิดคอมพิวเตอร์ใหม่ถึงจะใช้ได้ (พิมพ์ ThaiQ… แล้วมีฟังก์ชั่น TQU ขึ้นมาให้เลือก)
ดาวน์โหลด ThaiQuantsUtilities64.dll สำหรับ AmiBroker 64 bits
ดาวน์โหลด ThaiQuantsUtilities32.dll สำหรับ AmiBroker 32 bits
เปรียบเทียบโค้ดระหว่างกรณีไม่ใช้ TQU และ กรณีที่ใช้ TQU
ลองพิจารณาโค้ดทั้ง 2 กรณีซื่งทำงานเหมือนกัน ภายใต้มาตราฐานเงื่อนไขที่ครบถ้วน ทั้งการตรวจสอบช่วงราคาหุ้นและการแตกพาร์ รวมถึงการเพิ่มความไม่แน่นอนเข้าไปในการทดสอบระบบ แต่ทั้งกระนั้นจะเห็นว่าการเขียนโค้ดทั้งสองต่างกันมาก เพราะ TQU เข้ามาช่วยในการแบ่งเบาภาระและลดความผิดพลาดในการเขียนโค้ด ผนวกทั้ง TQU ช่วยทดสอบระบบอย่างถูกต้องด้วย Simulation ภายใต้ข้อจำกัดที่ป้องกันไม่ให้นักพัฒนาทำการ over optimization ด้วยค่า Default Parameters ต่างๆที่สร้างด้วย TQU
ตัวอย่างการใช้ TQU และคำอธิบายอย่างละเอียด
Example 0 TQU AFL Template
แสดงโครงสร้างการเขียนโค้ด AmiBroker AFL ที่เหมาะสม พร้อมกับตัวอย่างโค้ดของ TQU ซึ่งถูกออกแบบมาให้สอดคล้องกับโครงสร้าง ซึ่งมีทั้งหมด 6 Sections ได้แก่ OPTION, MARKET, SIGNAL, POSITION, STOP, และ SIMULATION ซึ่งจะเห็นว่าตัวโค้ดจริงๆสั้นมาก เพราะโค้ดหลายส่วนที่มีมาตราฐานได้ถูกซ่อนไว้ในฟังก์ชั่นต่างๆของ ThaiQuants…() เพื่อที่นักพัฒนาจะได้เน้นโฟกัสที่ยังส่วนที่สำคัญจริงในเบื้องต้นของการพัฒนาระบบเทรด ซึ่งก็คือ Signals (BUY & SELL conditions) และ PositionScore เป็นหลัก
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 |
{/* ThaiQuants Utilities (TQU), plugin for AmiBroker To rapidly and accurately PROTOTYPING your strategy, you require only 3 things: Buy Sell PositionScore Many parameters are provided by TQU according to standard and trading in Thailand's stock market. MARKET Section is included here only for the completion of TQU. ThaiQuantsSetMarketIndicators function generates various indicators causing slower performance espicially in Simulation/Optimization. Thus, it is preferable and faster to use AmiBroker's SetForeign & RestorePriceArrays. No Copyright or Any Rights Reserved. One for All ThaiQuants.com */} {/*OPTION*/ ThaiQuantsSetOptions(); } {//MARKET ThaiQuantsSetMarketIndicators("SET"); buyConMK = ... ; } {//SIGNAL Buy = ... AND buyConMK; Sell = ... ; ThaiQuantsAvoidSplits(); } {/*POSITION*/ ThaiQuantsSetPositions( ... ); } {/*STOP*/ ThaiQuantsApplyStops(); } {//SIMULATION ThaiQuantsSetRandoms(); ThaiQuantsVerifyPrices(); Optimize("_simRuns", 1, 1, 30, 1); } |
หมายเหตุ: ผู้สนใจศีกษาโครงสร้างโค้ด 6 Sections สามารถอ่านเพิ่มเติมได้ที่ TQ AFL Code Template (จริงๆพยายามทำความเข้าใน ThaiQuantsUtilities บนเพจนี้ก่อนก็พอครับ ไว้ว่างๆ ถ้าอยากลงลึก ค่อยไปอ่านก็ได้)
Example 1 Minimum AFL Template
โครงสร้างขั้นต่ำที่สุดที่เริ่มสามารถทำการทดสอบระบบได้ (โค้ดตัวอย่างนี้ยัง Backtest ไม่ได้ เพราะมีแต่โครงสร้าง) ซึ่งจะเห็นได้ว่า ถ้าใช้ TQU แล้ว นักพัฒนาจะสามารถเริ่มทดสอบระบบได้ โดยทำการโค้ดเริ่มต้นจริงๆแค่ในส่วนของ OPTION, SIGNAL, และ POSITION เท่านั้น แล้วโฟกัสที่…
- เงื่อนไขซื้อหุ้น บรรทัดที่ 4: Buy = … ;
- เงื่อนไขขายหุ้น บรรทัดที่ 5: Sell = … ;
- คะแนนการเข้าซื้อหุ้น PositionScore บรรทัดที่ 8: ThaiQuantsSetPositions( … );
1 2 3 4 5 6 7 8 |
{/*OPTION*/ ThaiQuantsSetOptions(); } {//SIGNAL Buy = ... ; Sell = ... ; } {/*POSITION*/ ThaiQuantsSetPositions( ... ); } |
คำถาม: นักพัฒนาอาจสงสัยว่าค่าตัวแปรอื่นๆที่จำเป็นในการทดสอบ Backtesting อยู่ตรงไหน?
คำตอบ: TQU ทำการสร้างโค้ดและตัวแปรที่จำเป็น พร้อมกับให้ค่า Default Parameters ที่จำเป็นโดยอัตโนมัติ ซึ่งสามารถดูได้ว่าค่าต่างๆเป็นเท่าไหร่ ตอนที่พิมพ์ชื่อ TQU ฟังก์ชั่นนั้นๆ ถึงเครื่องหมายวงเล็บเปิด ( ครับ เช่น MaxOpenPositions มีค่า default คือ 25 และ InitialEquity คือ 1,000,000 บาท และ PositionSize คือ 4% of Equity ซึ่งจะมีการอธิบายรายละเอียดต่อๆไปใน Example ด้านล่าง
Example 2 Minimum Code for Backtesting
แสดงตัวอย่างโค้ดที่เริ่มสามารถทดสอบได้จริง ด้วยการเพิ่ม BUY บรรทัดที่ 12, SELL ที่ 13, และ PostionScore ที่ 15 โดยโค้ดที่ถูกคอมเม้นออกไปคือโค้ด AFL ที่ถูกทำงานแทนด้วยโค้ดที่อยู่ด้านบนก่อนคอมเม้นชุดนั้นๆ
- โค้ดบรรทัดที่ 1 ทำงานแทนโค้ดบรรทัดที่ 2 ถึง 10
- โค้ดบรรทัดที่ 15 ทำงานแทนโค้ดบรรทัดที่ 16 ถึง 17
ยิ่งโค้ดน้อย ยิ่งมีโอกาสผิดพลาดน้อย เพื่อเร่งพัฒนาระบบต้นแบบ แล้วพอทดสอบสมมุติฐานเบื้องต้นได้ตามความต้องการ จึงค่อยๆมาปรับเพิ่มโค้ดด้วยตนเอง
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
ThaiQuantsSetOptions(); //SetOption("InitialEquity", 10^6); //TQMOP = 25 //SetOption("MaxOpenPositions", TQMOP); //SetOption("MinShares", 100); //RoundLotSize = 100; //SetOption("CommissionMode", 1); //SetOption("CommissionAmount", 0.16); //SetTradeDelays(1, 1, 0, 0); //BuyPrice = SellPrice = Open; Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsSetPositions( C*V/MA(C*V, 20)); //PositionScore = C*V/MA(C*V, 20); //SetPositionSize(100/TQMOP, spsPercentOfEquity); |
โค้ดในส่วนของ BUY เป็นเบรคไฮเดิม 200 วัน ทำงานร่วมกับ MACD เพื่อเพิ่มความมั่นใจและลดความส่วน และในส่วนของ SELL เป็นการสร้างเงื่อนไขป้องกันไม่ให้ มีเงื่อนไขซื้อและเงื่อนไขขายในวันเดียวกัน One Exact Opposite Condition
หมายเหตุ ThaiQuantsSetOptions มีการสร้างตัวแปรชื่อ TQMOP (TQ จาก ThaiQuants และ MOP จาก MaxOpenPositions) เพื่อนำไปใช้ใน ThaiQuantsSetPositions ในส่วนของ PositionSize โดย TQMOP มีค่า default คือ 25 ส่งผลให้ PositionSize มีค่าเท่ากับ 100/TQMOP = 4% of Equity
Example 3 Cut loss and protect profit with ApplyStops
ตัวอย่างนี้เริ่มมีการใช้ ApplyStop ในส่วนของ Stop Loss เพื่อทำการคัดลอส และใช้ Stop Trailing ในการปกป้องผลกำไร จากในส่วนของ AFL
- โค้ดบรรทัดที่ 8 ทำงานแทนบรรทัดที่ 9 ถึง 11
จะเห็นว่า ซึ่งใช้ค่า defaults จากทาง ThaiQuants สำหรับ stopTypeLoss, stopTypeTrailing, และ stopTypeProfit คือ 15, 25, และ 100 ตามลำดับ
1 2 3 4 5 6 7 8 9 10 11 |
ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops();//New Code //ApplyStop(stopTypeLoss, stopModePercent, 15, 0); //ApplyStop(stopTypeTrailing, stopModePercent, 25, 0); //ApplyStop(stopTypeProfit, stopModePercent, 100, 0); |
เหตุผลที่ stopTypeProfit ถูกนำเข้ามาใช้ด้วย ก็เพื่อป้องกันโชคช่วย ดวงดี แค่หนเดียว แต่ทำให้ผลลัพธ์ที่ได้ดูดีเกินจริง (โดยที่นักพัฒนาระบบเทรดอาจจะเปลี่ยนเป็น 50 ก็ได้ แทน 100) ซึ่งในตอนถัดๆไปเมื่อใช้ Simulation ปัญหาประเภทนี้ก็จะถูกบรรเทาลงเช่นกัน
หมายเหตุ นักพัฒนาระบบไม่ควรคิดว่า ถ้าใส่ค่าเปอร์เซนต์เป็น 0 (ศูนย์) แล้ว AmiBroker จะไม่พิจารณา Stop ประเภทนั้นๆ ซึ่งไม่ใช่ ดังนั้นถ้าไม่ต้องการพิจารณา Stop ประเภทนั้น ให้ตั้งค่าเปอร์เซนต์สำหรับ stopTypeLoss และ stopTypeTrailing เป็น 100 แล้วให้ตั้งค่า stopTypeProfit เป็น 10000 เผื่อๆเข้าไว้ ตามโค้ดข้างล่างนี้
ข้อเสริมว่า จริงแล้ว ThaiQuants สามารถสร้าง TQU ให้รับค่าเป็นศูนย์% แล้วไม่ต้องพิจารณา Stop ประเภทนั้นๆก็ได้ แต่ที่ตัดสินใจไม่ทำเพราะ เชื่อว่า TQU ควรทำงานตามพฤติกรรมจริงๆของ AmiBroker ดังนั้นถ้าใส่ 0% แล้ว AmiBroker ยังพิจารณา stopModeProfit อยู่ ทาง TQU ก็ควรพิจารณา stopModeProfit ที่ 0% เช่นกัน
1 2 3 4 5 6 7 8 9 10 11 |
ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops(100, 100, 10000);//New Code //ApplyStop(stopTypeLoss, stopModePercent, 100, 0); //ApplyStop(stopTypeTrailing, stopModePercent, 100, 0); //ApplyStop(stopTypeProfit, stopModePercent, 10000, 0); |
ณ จุดนี้ ThaiQuantsApplyStops มีข้อจำกัดคือ ใช้ได้เฉพราะ แบบที่เป็น stopModePercent และเป็นตัวเลขเท่านั้น ไม่สามารถใช้แบบ stopMode… อื่นๆได้ และไม่สามารถใช้แบบเป็นสูตร AFL ได้ ศึกษาเพิ่มเติมที่ AmiBroker ApplyStop อย่างที่แจ้งไว้ในข้างต้นว่า TQU โฟกัสที่หัวใจหลักในการพัฒนาต้นแบบ แล้วเมื่อได้ผลลัพธ์ที่ต้องการ นักพัฒนาก็ค่อยๆปรับแก้ไขโค้ดต่อไปด้วยตนเอง
Example 4 Improve accuracy by Avoiding Split
แสดงฟังก์ชั่น ThaiQuantsAvoidSplits ที่ใช้หลีกเลี่ยงการเข้าซื้อหรือถือหุ้นที่กำลังจะแตกพาร์ ซึ่งจะทำให้ผลลัพธ์จากการทดสอบผิดพลาด เช่นหุ้น 300 บาท เหลือ 30 บาท กลายเป็นว่าขาดทุนไป 90% ตัวฟังก์ชั่น ThaiQuantsAvoidSplits ทำพิจารณาทั้ง Normal Split และ Reverse Split ล่วงหน้า 2 วัน จากตรวจสอบส่วนต่างราคาปิดและเปิดที่ 35% (บ้านเรามี ceiling และ floor อยู่ที่ 30%) ผู้สนใจสามารถอ่านเพิ่มเติม และดูโค้ดได้ที่ แก้ไขหุ้นแตกพาร์ด้วย AFL Code
1 2 3 4 5 6 7 8 9 |
ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsAvoidSplits();//New Code ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops(); |
ไม่ต้องตกใจครับ โค้ดสั้นจริงๆ ลองรัน Backtest ดูครับ (หล่อเลย)
Example 5 Improve analysis with Simulation
ตัวอย่างนี้มีการเพิ่มโค้ด 2 บรรทัด ในส่วนของการ Random ค่า Slippage, Missing Trades, และ PositionScoreNoise ในบรรทัดที่ 11 และใช้ AmiBroker ฟังก์ชั่น Optimize ในการหลอกให้ AmiBroker ทำงานเหมือน Simulation Software ในบรรทัดที่ 12
1 2 3 4 5 6 7 8 9 10 11 12 |
ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops(); ThaiQuantsSetRandoms();//New Code Optimize("_simRuns", 1, 1, 30, 1); //New Code (For 30 simulation runs) |
Randomization ใน ThaiQuantsSetRandoms ใช้ Uniform Distribution ตาม AmiBroker ในการสุ่มทำ 3 ประเภท
- Slippage โดยเพิ่ม BuyPrice (ซื้อแพง) ระหว่าง +0% ถึง +5% แล้วปรับขึ้นอีกด้วยค่า Tick Size และลด SellPrice (ขายถูก) ระหว่าง -0% ถึง -5% แล้วปรับลงอีกด้วยค่า Tick Size จาก ThaiQuantsVerifyPrices ในตัวอย่างต่อไป
- Missing Trades พลาดเข้าซื้อ Buy = true กลายเป็น false พลาดขาย Sell = true กลายเป็น false ที่ความน่าจะเป็น 10%
- PositionScoreNoise สุ่มค่าปรับเปลี่ยน PositionScore ด้วย PositionScore = PositionScore – (PositionScore*PositionScoreNoise)/200 + random() * PositionScoreNoise/100
ผู้สนใจรายละเอียดจริงๆเรื่อง Simulation in AmiBroker สามารถศึกษาเพิ่มเติมที่ Monte Carlo Simulation in AmiBroker
Example 6 Double check prices after randomizing
ฟังก์ชั่น ThaiQuantsVerifyPrices เข้ามาช่วย:
- ในการตรวจสอบราคาซื้อขายว่ายังคงถูกต้องมั้ย ไม่ซื้อแพงกว่า High และไม่ขายถูกกว่า Low เนื่องจากการทำงานของ Simulation ซึ่งจริงๆแล้ว AmiBroker ก็มีการตรวจสอบในส่วนนี้
- ปรับช่วงราคาหุ้นนั้นๆให้ถูกต้องตามระดับราคาให้ถูกต้องซึ่งถูกกำหนดไว้โดย Stock Exchange of Thailand ผู้สนใจโค้ดสามารถดูโค้ดได้ที่ ตั้งช่วงราคาหุ้นด้วย-afl-code
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops(); ThaiQuantsSetRandoms(); ThaiQuantsVerifyPrices();//New Code Optimize("_simRuns", 1, 1, 30, 1); |
Example 7 Reduce drawdown with Market Index
แสดงการใช้ Market Index เช่น “SET” ในการช่วยวิเคราะห์สัญญาณซื้อ เพื่อเลือกช่วงตลาดที่เอื้ออำนวยและส่งผลให้ความเสี่ยงลดลง ด้วยฟังก์ชั่น ThaiQuantsSetMarketIndicators โดยที่ตัวฟังก์ชั่นเองมีหน้าที่สร้าง Indicators เบื้องต้นของตลาดที่คนส่วนมากใช้กัน ให้นักพัฒนาพร้อมใช้งาน ดังนี้ TQMKclose, TQMKrsi, TQMKmacd, TQMKsignal, TQMKadx, TQMKpdi, และ TQMKatr (MK มาจาก Market)
ในโค้ดจะเห็นว่า ไม่มีการประกาศตัวแปรชื่อ TQMKadx, TQMKpdi, และ TQMKmdi แต่ที่ยังรัน Backtest ได้ก็เพราะ ThaiQuantsSetMarketIndicators ได้สร้างอัตโนมัติไว้ให้ในบรรทัดที่ 9 ไว้แล้ว
หลังจากที่ AmiBroker ทำตามคำสั่ง ThaiQuantsSetMarketIndicators ซึ่งจะได้ตัวแปรทั้งหมด TQMK… นักพัฒนาสามารถสร้าง buyConMK ดังในบรรทัดที่ 15 แล้วนำไปใช่ร่วมกับ Buy ได้เลย ดังในบรรทัดที่ 17
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 |
{/* MARKET Section is included here only for the completion of TQU. ThaiQuantsSetMarketIndicators function generates various indicators causing slower performance espicially in Simulation/Optimization. Thus, it is preferable and faster to use AmiBroker's SetForeign & RestorePriceArrays. */} ThaiQuantsSetOptions(); ThaiQuantsSetMarketIndicators("SET");//New Code //SetForeign("SET"); // TQMKadx = ADX(); // TQMKpdi = PDI(); // TQMKmdi = MDI(); //RestorePriceArrays(); buyConMK = TQMKadx > 20 AND TQMKpdi > TQMKmdi;//New Code Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) AND buyConMK;//Modified with New Code Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops(); ThaiQuantsSetRandoms(); ThaiQuantsVerifyPrices(); Optimize("_simRuns", 1, 1, 30, 1); |
หมายเหตุสำคัญ
- ตามที่คอมเม้นไว้ในโค้ดเลยครับ ว่าจริงๆแล้ว ThaiQuants ลังเลที่จะเขียนฟังก์ชั่นนี้ขึ้นมา เพราะมันสร้าง Indicators ด้วย SetForeign ที่ไม่จำเป็นและส่งผลต่อความเร็วในการทำ Simulation แต่ทั้งนี้ทั้งนั้น เพื่อความสมบูรณ์ของ ThaiQuantsUtilities Plugin ทาง ThaiQuants จึงสร้างขึ้นมา แต่ยังแนะนำให้ใช้ SetForeign จะดีกว่าครับ
- ThaiQuants ได้ลองใช้เวลากว่า 100 ชั่วโมง เฉพาะกับ ThaiQuantsSetMarketIndicators ในการ optimize ความเร็ว แต่ทั้งกระนั้น ผลที่ได้ออกมาขึ้นกับหลายปัจจัยมาก เช่น คุณภาพของข้อมูล หุ้นตัวแรก และ Setting ของผู้ใช้งาน จึงทำให้ตัดสินใจว่าไม่ควรทำการ optimize ความเร็ว (ยากกว่าที่คิดไว้เยอะมาก)
- เผื่อมีคนสงสัยว่าแค่ใช้ Status(“stocknum”) == 0 ก็ได้แล้วไม่ใช่เหรอ? คำตอบคือไม่ใช่ครับ เพราะเรากำลังจะพึ่งการสร้าง Market Indicators ให้หุ้นในตลาด ด้วยคุณภาพของหุ้นตัวแรกที่กำลังจะถูก AmiBroker สแกน Phrase 1 อีกทั้ง Setting Pad & Align ก็ให้ค่าไม่แตกต่างกันทางด้านความเร็ว The Devil is in the Details.
- หนึ่งในทางออก คือ สร้าง Artificial Ticker ด้วย Market Index นั้นๆ หรือ Market Breadth แล้วตั้งชื่อนำหน้าด้วย 0 (ศูนย์) ซึ่งคงอยู่นอกเหนือหน้าที่ของ ThaiQuantsUtilities plugin.
Example 8 Final Recommended Code
แสดงโค้ดที่ทาง ThaiQuants แนะนำให้ใช้ และทำการนำคอมเม้นหลักที่ต้นไฟล์กลับเข้ามา แล้วแบ่งโค้ดออกเป็นสัดส่วนตามโครงสร้าง พร้อมกับใช้งาน SetForeign & RestorePriceArrays แทน ThaiQuantsSetMarketIndicators
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 |
{/* ThaiQuants Utilities (TQU), plugin for AmiBroker To rapidly and accurately PROTOTYPING your strategy, you require only 3 things: Buy Sell PositionScore Many parameters are provided by TQU according to standard and trading in Thailand's stock market. MARKET Section is included here only for the completion of TQU. ThaiQuantsSetMarketIndicators function generates various indicators causing slower performance espicially in Simulation/Optimization. Thus, it is preferable and faster to use AmiBroker's SetForeign & RestorePriceArrays. No Copyright or Any Rights Reserved. One for All ThaiQuants.com */} {/*OPTION*/ ThaiQuantsSetOptions(); } {//MARKET //ThaiQuantsSetMarketIndicators("SET"); SetForeign("SET"); TQMKadx = ADX(); TQMKpdi = PDI(); TQMKmdi = MDI(); RestorePriceArrays(); buyConMK = TQMKadx > 20 AND TQMKpdi > TQMKmdi; } {//SIGNAL Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) AND buyConMK;//Modified with New Code Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); } {/*POSITION*/ ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); } {/*STOP*/ ThaiQuantsApplyStops(); } {//SIMULATION ThaiQuantsSetRandoms(); ThaiQuantsVerifyPrices(); Optimize("_simRuns", 1, 1, 30, 1); } |
แถมครับ Example 9 Best Performance and Accuracy for Educated Developers
ตัวอย่างนี้แสดงการใช้ TQU ร่วมกับ AFL Code เพื่อให้ได้ทั้งประสิทธิภาพและความถูกต้อง สำหรับนักพัฒนาระบบที่มีความรู้ AmiBroker ตั้งแต่ระดับกลางขึ้นไป ด้วยการ…
- ใช้ AmiBroker’s SetOption แทน ThaiQuantsSetOptions เพราะ AmiBroker จะทำการสแกน AFL SetOption รอบเดียว ในขณะที่ AmiBroker จะสแกน ThaiQuantsSetOptions หลายรอบ เท่ากับจำนวนหุ้นทั้งหมดที่อยู่ใน Filter + 1 Formula Verification ดังนั้นในตัวอย่างจงคอมเม้นบรรทัดที่ 2 ออกไป แล้วใช้ บรรทัดที่ 3 ถึง 11 แทน (อย่าลืมตั้งค่าตัวแปร TQMOP ให้ ThaiQuantsSetPositions ไว้ใช้ในบรรทัดที่ 30)
- ใช้ AmiBroker’s SetForeign & RestorePriceArrays แทน ThaiQuantsSetMarketIndicators เพราะตามที่ชี้แจงไว้ใน Example 8 และ 9 ว่า ThaiQuantsSetMarketIndicators สร้างตัวแปรถึง 8 ตัว จาก Market Index ซึ่งจริงๆแล้วกลยุทธ์ที่กำลังผู้พัฒนาอาจจะไม่ได้ใช้ทั้งหมด ดังนั้นหลังจากที่ได้ทำการสร้าง/ทดสอบระบบต้นแบบอย่างรวดเร็ว และได้ผลลัพธ์ที่พึงพอใจในเบื้องต้นแล้ว โค้ดในส่วน Market Section ควรถูกแก้ไขให้ใช้ AmiBroker’s SetForeign & RestorePriceArrays แทนเพื่อ Performance
- ในกรณีที่นักพัฒนาทำการ Backtest ด้วย Simulation อาจไม่จำเป็นต้องใช้ ThaiQuantsVerifyPrices เพราะผลการวิเคราะห์จาก Simulation ที่ค่าเฉลี่ย (50 percentile) และที่กรณีแย่ที่สุด (10 percentile) ควรจะได้ค่าใกล้เคียงกับกรณีที่ใช้ ThaiQuantsVerifyPrices ถ้ามีจำนวน _simRuns มากพอ เช่น 300 ครั้ง ดังนั้นในบรรทัดที่ 36 โค้ดจึงถูกคอมเม้นออกไป
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 |
{/*OPTION*/ //ThaiQuantsSetOptions(); TQMOP = 25; SetOption("InitialEquity", 10^6); SetOption("MaxOpenPositions", TQMOP); SetOption("MinShares", 100); RoundLotSize = 100; SetOption("CommissionMode", 1); SetOption("CommissionAmount", 0.16); SetTradeDelays(1, 1, 0, 0); BuyPrice = SellPrice = Open; } {//MARKET //ThaiQuantsSetMarketIndicators("SET"); SetForeign("SET"); TQMKadx = ADX(); TQMKpdi = PDI(); TQMKmdi = MDI(); RestorePriceArrays(); buyConMK = TQMKadx > 20 AND TQMKpdi > TQMKmdi; } {//SIGNAL Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) AND buyConMK; Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); } {/*POSITION*/ ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); } {/*STOP*/ ThaiQuantsApplyStops(); } {//SIMULATION ThaiQuantsSetRandoms(); //ThaiQuantsVerifyPrices(); Optimize("_simRuns", 1, 1, 30, 1); } |
แถมอีก Example X Minimum Code for Simulation Backtesting
ตัวอย่างแสดงโค้ดอย่างต่ำที่สามารถรัน Simulation Backtesting ได้ ซึ่งจะเห็นว่า ThaiQuantsSetMarketIndicators() และ ThaiQuantsVerifyPrices() ได้ถูกลบออกไป เพื่อทำการวัดประสิทธิภาพของกลยุทธ์การเทรด Buy, Sell, Position, และ Stops ล้วนๆ ไม่มี Market เข้ามาเกี่ยวข้อง อีกทั้งเพิ่ม Performance ในการทำ Backtesting ด้วยครับ (ก๊อปปี้โค้ด แล้วกดปุ่ม Optimization ใน AmiBroker ได้เลย)
1 2 3 4 5 6 7 8 |
ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1); Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); ThaiQuantsSetPositions( C*V/MA(C*V, 20) ); ThaiQuantsApplyStops(); ThaiQuantsSetRandoms(); Optimize("_simRuns", 1, 1, 30, 1); |
หมายเหตุสำคัญ ณ ความสามารถ Functionality เหมือนๆกันระหว่างโค้ดเองด้วย AFL กับ ใช้ฟังก์ชั่น TQU:
- ฟังก์ชั่น TQU ที่มีผลกระทบต่อระยะเวลาในการทำ Optimization: ThaiQuantsSetMarketIndicators() อันนี้หนักหน่อย และ ThaiQuantsVerifyPrices() อันนี้กลางๆ
- ฟังก์ชั่น TQU ที่ส่งผลดีต่อระยะเวลาในการทำ Optimization: ThaiQuantsAviodSplits() และ ThaiQuantsSetRandoms()
สรุป ThaiQuantsUtilities (TQU) มีทั้งหมด 7 ฟังก์ชั่น (ตามลำดับการเขียนโค้ด) คือ
- ThaiQuantsSetOptions() กำหนด options ในการทดสอบระบบ เช่น MaxOpenPositions, CommissionAmount, InitialEquity, RoundLotSize, BuyPrice/SellPrice, และ อื่นๆ
- ThaiQuantsSetMarketInicators(“SET”) ทำการสร้าง Market Indicators ตามชื่อ Index ที่ระบุไว้ โดยมี Indicators ทั้งหมด 8 ตัว ตามที่อธิบายไว้ใน Example 8
- ThaiQuantsAvoidSplits() สร้างเงื่อนไขซื้อขายเพิ่มเติมเพื่อหลีกเลี่ยงการถือหุ้นข้ามช่วงที่มีการ Split ตามที่อธิบายไว้ใน Example 4
- ThaiQuantsSetPositions( … ) ทำการรับค่า PositionScore จากนักพัฒนา แล้วสร้าง PositionSize อัตโนมัติตามค่าที่ถูกตั้งไว้ใน ข้อ 1 ThaiQuantsSetOptions() โดยมีค่า default เป็น 4% 0f Equity
- ThaiQuantsApplyStops() กำหนด Stop Loss/Trailing/Profit โดยใช้ค่า Defaults อธิบายใน Example 3
- ThaiQuantsSetRandoms() สุ่มความไม่แน่นอนให้กับ Slippage, Missing Trades, และ PositionScoreNoise เพื่อใช้สำหรับการทำ Simulation Backtesting อธิบายไว้ใน Example 5
- ThaiQuantsVerifyPrices() ทำการตรวจสอบราคาหุ้นและช่องราคาหุ้นตามระดับราคาของหุ้นนั้นๆ หลังที่ TQU ทำการ random ค่าต่างๆด้วย ThaiQuantsSetRandoms() ตามที่อธิบายไว้ใน Example 5 และ Example 6
หวังว่า ThaiQuantsUtilities จะเป็นประโยชน์ต่อนักลงทุนด้วยระบบ สาย Quant กันน่ะครับ แล้วไว้ปีหน้า 2019 ThaiQuants จะทำการแนะนำโปรแกรมที่พัฒนาขึ้นมาเอง ชื่อ ThaiQuantsSAZ Application ซึ่งเป็น AmiBroker-Fully-Integrated App มาให้ นศ ThaiQuants ลองใช้กันดู
One for All
ThaiQuants.com
1/8/18
ดาวน์โหลด ThaiQuantsUtilities.rar (TQU Application Folder)
- ดาวน์โหลด ThaiQuantsUtilities.rar จากปุ่มด้านล่าง
- ก๊อปปี้ ThaiQuantsUtilities.rar ไปไว้ในโฟลเดอร์ AmiBroker/Plugins
- คลิ๊กขวาที่ไฟล์ แล้วเลือก Extract Here ภายในโฟลเดอร์ AmiBroker/Plugins
ดาวน์โหลด ThaiQuantsUtilities.rar สำหรับ AmiBroker ทุกเวอร์ชั่น
หมายเหตุสำคัญ:
- จะต้องวาง “โฟลเดอร์ ThaiQuantsUtilities” ภายใน โฟลเดอร์ “AmiBroker/Plugins”
- TQU App ลงได้ 1 คนต่อ 1 เครื่อง ดังนั้นจึงควรลงเครื่องที่ใช้ทดสอบ Strategy (ส่วน TQU Plugin ลงกี่เครื่องก็ได้)
- ผู้ที่แชร์โพสสามารถเปลี่ยนเครื่องได้ภายหลัง 30 วันที่ลง/ใช้ App (เครื่องเดิมก็ยังคงใช้ได้ จนกว่า TQU Tokens จะหมด) โดยใช้ Facebook Account เดิมที่แชร์ (อย่าใช้/สร้าง Account ปลอม ไปลงอีกเครื่องหนึ่งเด็ดขาด)
- ThaiQuantsUtilities.exe สามารถทำงานกับ AmiBroker.exe โดยไม่จำเป็นต้องใช้ TQU Plugins
- ThaiQuantsUtilities.exe ทำงานกับ AmiBroker.exe แบบ Fully-Integrated ด้วยฟังก์ชั่น ThaiQuantsActivateApp() ใน Plugins
- ฟังก์ชั่น ThaiQuantsActivateApp() จะไม่ทำงาน ถ้า TQU Plugin หาโฟรเดอร์ ThaiQuantsUtilities ในโฟรเดอร์ AmiBroker/Plugins ไม่เจอ
Example for TQU App
1 2 3 4 5 6 7 8 9 10 |
ThaiQuantsActivateApp(); ThaiQuantsSetOptions(); Buy = MACD() > 0 AND C > Ref(HHV(C, 200), -1) ; Sell = MACD() < 0 ; ThaiQuantsAvoidSplits(); ThaiQuantsSetPositions( MFI() ); ThaiQuantsApplyStops(); ThaiQuantsSetRandoms(); //ThaiQuantsVerifyPrices(); Optimize("_simRuns", 1, 1, 5, 1); |
One for All
ThaiQuants.com
2/9/18
Videos