พี่ชายยย… ฉันเหนื่อยฉันอยากรวย ขอตัวช่วย Trade หุ้นหน่อยสิจ๊ะ

Pleum164
botnoi-classroom
Published in
12 min readJan 5, 2021

Objective: บทความนี้เป็นส่วนหนึ่งของ Botnoi Classroom DSE#2 Week 4 “Time Series Forecasting Project”

Ad Hoc Members: ในส่วนของ Project นี้เราได้มีการรวมตัวกันระหว่างสมาชิก DSE 2 ที่มาจาก G5+G6+G10 ทั้งหมด 9 ท่าน ผู้ซึ่งยังมีไฟมีเวลาพร้อมจะลุยกันต่อไป

ผ่านมาแล้วเกินครึ่งทางแล้วครับสำหรับชาว DSE 2 โดย Project นี้เป็นผลงานชิ้นที่ 3 ของพวกเรา ในครั้งนี้เราจะใช้ความรู้ที่ร่ำเรียนมาจาก Week 4 “Time-Series Forecasting Model” มาสร้าง Model ทำนายหุ้น

โจทย์ของ Project: เลือกหุ้นจากกลุ่ม SET100 มา Run Model แล้วเลือกหุ้นที่ Model บอกว่าได้กำไรมากที่สุด ภายใน 1 Week มา 1 หุ้น

ความสนุกและตื่นเต้นของ Project นี้คือ จะมีการนำหุ้นที่ถูกเลือกไปซื้อขายจริง โดยทางทีมงาน Botnoi จะนำหุ้นที่ถูกเลือกไปหาซื้อที่ ATO (At the open หรือ ราคาหุ้นตอนเปิดตลาด) ในวันที่ 4 มกราคม 2563 และขายที่ ATO ในวันที่ 11 มกราคม 2563 โดยมีงบประมาณให้ที่ 20,000 บาท ลงทุนจริงได้จริงและเจ็บจริง ได้ฟังแค่นี้ก็เริ่มลุ้นแล้ว เอาล่ะเรามาดูกันว่าเส้นทางของความสนุกตื่นเต้นนี้จะเป็นอย่างไร ติดตามกันต่อเลยครับ

Caution!!

“การลงทุนมีความเสี่ยง โปรดอย่านำขั้นตอนการทำ Model รวมถึงผลลัพธ์ที่ได้ ไปใช้ในการซื้อ-ขาย โดยปราศจากการศึกษาและทำความเข้าใจพื้นฐานการ Trade หุ้น” … เตือนนนแล้วนะ!!

Highlights

  • การ Brainstorm ปัจจัยและที่จะมีผลกับหุ้น เลือกแหล่งข้อมูลที่สนใจ และวิธีการหาข้อมูล
  • การจัดการกับข้อมูลที่หามาได้ และ การเลือกใช้ Features ที่มีความสัมพันธ์กับหุ้น
  • การทำ Pre-processing และ Feature engineering เพื่อเตรียมข้อมูลไปใช้กับ Model
  • การใช้ Deep Learning Framework ที่เรียกว่า Keras มาเทรน Model โดยแบ่งออกเป็น Sequential Model และ Transformer Model
  • สิ่งที่พวกเราได้เรียนรู้ และ การนำเสนอหุ้นตามผลการวิเคราะห์จากผลลัพธ์ที่ได้

มาทำความรู้จัก Time-Series Forecasting Model

ข้อมูล Time Series หรือ อนุกรมเวลา คือ ข้อมูลที่เปลี่ยนแปลงไปตามเวลา เช่น เช่น ยอดขายสินค้าในปีหน้า ราคาทองคำ และ ราคาหุ้น เป็นต้น โดยการทำ Time-Series Forecasting คือการใช้อนุกรมเวลาของข้อมูลนั้นทำนายตัวเองในอนาคต แต่ก่อนอื่นต้องเข้าใจก่อนว่า ไม่ใช่ข้อมูลในอดีตทุกอย่าง จะทำนายอนาคตตัวมันเองได้ โดยทั่วไปแล้ว ข้อมูลในอดีตที่ทำได้ จะต้องมีคุณสมบัติดังนี้

  • แนวโน้ม (Trend) คือ การเคลื่อนไหวของข้อมูลที่ต่อเนื่องกันในระยะยาวอย่างชัดเจน ไม่ว่าจะขึ้นหรือลง และลักษณะแนวโน้ม นั้นอาจจะมีแนวโน้มเป็นเส้นตรงหรือเส้นโค้งก็ได้
  • ฤดูกาล (Seasonal) คือ การเปลี่ยนแปลงของข้อมูลที่เกิดขึ้นเนื่องจากอิทธิพลของ ฤดูกาล หรือช่วงเวลา ซึ่งจะเกิดขึ้นซ้ำ ๆ กัน ในช่วงเวลาเดียวกัน อาจจะเป็น รายเดือน รายไตรมาส หรือรายปีก็ได้
  • ความผิดปกติ (Remainder หรือ Residual) คือ การเคลื่อนไหวของข้อมูลที่ไม่มีรูปแบบแน่นอน หรือเป็นเหตุการณ์ที่ผิดไปจากปกติ โดยไม่ได้มีการคาดการณ์ไว้ล่วงหน้า

โดยที่ Trend และ Seasonal จะเป็นองค์ประกอบหลัก ซึ่งถ้าเกิดเจ้า 2 ตัวนี้ ก็จะไม่สามารถใช้ Time-Series Forecasting ได้

Ref: https://www.coraline.co.th/single-post/2018/03/11/forecasting-model-%E0%B8%94-%E0%B8%A7%E0%B8%A2-machine-learning

Fig 1: ตัวอย่างการทำ Decomposition กับข้อมูล ซึ่งถูกแยกมาเป็น Trend, Seasonal, และ Remainder

Source: https://blog.datath.com/time-series-forecasting/

โดยในปัจจุบันในส่วนของการทำ Trend Forecasting Model เราใช้สามารถใช้ทั้ง Machine Learning (ML) หรือ Deep Learning (DL) มาช่วยให้การทำนายมีความแม่นยำมากขึ้น ไม่ว่าจะเป็นการทำ Regression และ Pattern Recognition เป็นต้น แต่อย่างไรก็ตามไม่ว่าจะเป็น ML หรือ DL การเลือกเทคนิคที่เหมาะสมนั้น ก็ขึ้นอย่ากับประเภทของปัญหา และลักษณะ features ที่นำมาใช้ นอกจากนี้ยังต้องสามารถ Interpret Model ได้ชัดเจนตามจุดประสงค์ด้วย ในส่วน Project ของพวกเรา จะมีการใช้ Feature ตัวไหน หรือ Model อะไร ไปติดตามกันต่อได้เลยครับ

มาทำความรู้จัก SET100

หลายๆท่านอาจจะเคยได้ยินคำว่า SET100 ผ่านหูกันมาบ้าง โดยเบื้องต้นเราต้องเข้าใจคำว่าดัชนีเสียก่อน โดยดัชนี คือ การคำนวณค่าทางสถิติเพื่อให้ทราบถึงการเปลี่ยนแปลงในสิ่งที่เราสนใจ โดย SET100 คือกลุ่มหลักทรัพย์ที่มีมูลค่าตามราคาตลาด (Market Capitalization) และสภาพคล่องในการซื้อขายสูงสุด เป็น100 อันดับแรกในตลาดหลักทรัพย์แห่งประเทศ หรือที่เรียกสั้นๆว่า SET (The Stock Exchange of Thailand) ซึ่งถือได้ว่าหุ้นเหล่านี้มีผลต่อดัชนีของ SET อยู่ไม่น้อย อีกหนึ่งสิ่งที่กลุ่มเราได้เรียนรู้จากโจทย์สัปดาห์นี้คือ เวลาจะซื้อหุ้นแต่ละตัวในแต่ละครั้ง เราจะต้องซื้อขั้นต่ำ อย่างน้อย 100 หุ้น ดังนั้นข้อจำกัดคือเราจะไม่สามารถซื้อหุ้นที่มาราคาต่อหุ้นเกิน 200 บาทได้ โดยด้านล่างนี้คือรายชื่อหลักทรัพย์กลุ่ม SET 100 ที่เพิ่งจะ Update ไปหมาดๆ โดยมีผลเริ่มใช้งานเมื่อวันที่ 1 มกราคม 2564 ที่ผ่านมา หากสนใจศึกษาเพิ่มเติมจิ้มเข้าไปดูได้เลยครับ

Link: https://www.set.or.th/th/market/files/constituents/SET50_100_H1_2021.pdf

========================================

Pipeline: Stock Price Trend Forecasting

สำหรับขั้นตอนในการทำงาน แบ่งออกเป็น 6 ขั้นตอนหลัก ๆ ดังต่อไปนี้

Step 0: Understanding problem & brainstorming

อันดับแรกเรามาทำความเข้าใจโจทย์กันก่อน จะเห็นว่าระยะเวลาที่ทำการซื้อ-ขายหุ้นนั้น คือช่วงเวลาแค่ 1 Week ดังนั้นกลุ่มของเราจึงไม่ได้โฟกัส ข้อมูลสถานะทางการเงินของแต่ละบริษัท หรือ Financial Ratio รวมไปถึงปัจจัยชี้วัดสภาวะเศรษฐกิจไทยและต่างประเทศ เช่น GDP อัตราการว่างงาน และอัตราดอกเบี้ยต่าง ๆ เพราะส่วนใหญ่ข้อมูลประเภทนี้ จะออกมาเป็นรายไตรมาส หรือรายปี ซึ่งไม่น่าจะมีผลต่อการทำนายในระยะสั้น หลังจากการ Brainstorm อย่างเข้มข้น กลุ่มเราได้ข้อสรุปการเลือกข้อมูลและปัจจัยที่คาดว่ามีผลต่อราคาหุ้นในระยะสั้น โดยแบ่งออกเป็น 3 กลุ่มหลัก ดังนี้

  1. ข้อมูลราคาหรือการซื้อขายของหุ้นแต่ละตัวใน SET100 (Stock Price) เช่น ราคาปิด(Close, Adjusted Close), ราคาเปิด(Open), ปริมาณการซื้อขายของหุ้นแต่ละตัว (Volume)
  2. Technical Indicators ในปัจจัยทางเทคนิคเหล่านี้โดยทั่วไปแล้ว เป็นที่ได้รับความนิยมของนักลงทุนประเภททำกำไรระยะสั้น โดยเราจะการนำข้อมูลราคาหรือการซื้อขายของหุ้นแต่ละตัวใน SET100 มาสร้าง Feature สำหรับการทำ Technical Analysis เช่น MACD RSI และ EMA
  3. Indexของตลาดซื้อขายหลักทรัพย์ทั้งในประเทศไทย และในต่างประเทศ (Stock Market Index) เช่น SET, Dow Jones, NASDAQ, S&P500, Nikkei, Hang Seng, Shanghai และ Shenzhen

Step 1: Get data

สำหรับ Step การเก็บข้อมูล เราได้แบ่งออกเป็น 3 ส่วน โดยอ้างอิงจากการแบ่งประเภทของ Feature ใน Step 0

1.1 Stock Price

การหาข้อมูลในส่วนนี้ไม่ซับซ้อนมากเท่าไหร่ครับ เพราะเราใช้ Library: DataReader ทำการดึงข้อมูลจาก Yahoo finance โดยข้อมูลที่ได้จะเป็นข้อมูลราคาพื้นฐานทั้งหมดของหุ้นตัวนั้นๆตามกรอบระยะเวลาที่เราต้องการครับ

Fig 2: ตัวอย่าง การ Get Data ส่วนของ Stock Price Features

โดยราคาพื้นฐานที่ถูกนำมาใช้มีดังต่อไปนี้

  • High: ราคาสูงสุดในวันนั้นๆ
  • Low: ราคาต่ำสุดในวันนั้นๆ
  • Open: ราคา ณ เวลาเปิดตลาดในวันนั้นๆ
  • Close: ราคา ณ เวลาปิดตลาดในวันนั้นๆ
  • Volume: ปริมาณการซื้อขายในวันนั้นๆ (จำนวนหุ้น)

1.2 Technical Indicator

ทีนี้เพื่อเพิ่มความวุ่นวาย เอ้ย ความซับซ้อนของข้อมูล เราได้ทำการเพิ่มข้อมูลทางเทคนิค หรือก็คือพวก Technical Indicator (ชื่อเล่นน่ารักๆว่า Indi ก็คือเครื่องมือบ่งชี้ทางเทคนิคที่เกิดการนำราคาพื้นฐานไปคำนวนต่อยอดให้ได้เครื่องมือที่บ่งบอกสัญญาณการซื้อ-ขายออกมา) ซึ่ง Indicator ที่ถูกคิดค้นขึ้นมามีเยอะมากกกก (ก ไก่ล้านตัว)

ซึ่งต้องกราบบบบ Library TA-lib ที่ทางผู้พัฒนาได้รวบรวมเหล่า Indicator มากมายมาให้เรียกใช้อย่างสะดวกรวดเร็ว เราจึงประหยัดเวลาไปได้เยอะครับ เพราะไม่ต้องเขียนฟังก์ชันเพื่อคำนวนค่า indicator เอง ตัวอย่างการเรียนใช้งานก็ง่ายมากครับ เพียงป้อนข้อมูลราคาพื้นฐาน และเรียกใช้ฟังก์ชัน TA-lib ก็จะทำการคำนวนและคืนค่า Indicator นั้นๆกลับมาให้เราครับ

โดย Indicator ที่เราเลือกมาใช้ในขั้นแรกมีดังนี้ครับ (นี้คือเลือกแล้วนะ ไม่ได้เอามาทั้งหมดดด ><)

1.3 Stock Market Index

ในส่วนนี้ กลุ่มของพวกเราเลือกใช้ข้อมูลจาก www.investing.com ซึ่งเป็นเว็บไซต์ที่ได้รวบรวมข้อมูลดัชนีของตลาดต่างๆเข้าไว้ด้วยกันเรียบร้อยแล้ว (ถ้าต้องไปดึงข้อมูลจากเว็บไซต์ของแต่ละตลาดเลยน่าจะมีเหงื่อตกกันบ้างแหละเนอะ) รวมถึงมี Historical Data เพียงพอกับความต้องการในการใช้งานอีกด้วย แต่ประเด็นสำคัญเลยนั่นก็คือ มี Library ที่ชื่อว่า “investpy” ที่สามารถดึงข้อมูลจากเว็บนี้ได้เลย เย้!

Fig 3: ตัวอย่าง การ Get Data ส่วนของ Stock Market Index Features

Step 2: Understanding & dealing with data

ในส่วนของการจัดการข้อมูลที่ได้มา เราจะแบ่งการโฟกัส 2 ประเด็น

2.1 Dealing with Missing Values

2.1.1 Stock Price Features: ในส่วนนี้โชคดีมากที่เราไม่พบ Missing Value

2.1.2 Stock Market Index Features: ตอนดึงข้อมูล เนื่องจากแต่ละตลาดมีวันที่เปิด-ปิดไม่เหมือนกัน กลุ่มของเราจึงเลือกเอาวันที่เปิด-ปิดของ SET เป็นหลัก เนื่องจากจุดประสงค์คือการ Forecast ราคาของหุ้นใน SET100 ดังนั้นทำให้เกิด Missing Value ในข้อมูลของตลาดต่างประเทศบางจุด ในกรณีที่ตลาดนั้นๆปิดทำการ ในวันที่ SET เปิดทำการ ดังนั้นเราจึงแทนค่า Missing Value เหล่านั้นด้วย 0

2.2 Correlation of Features

2.2.1 Stock Price & Technical Indicator Features

หลังจากทดสอบเทรนโมเดลไประดับหนึ่ง บวกกับข้อจำกัดของเวลา เราจึงคิดว่าไม่สามารถใช้ทุก Indi ที่เลือกมาได้ คิดคร่าวๆคือถ้าเรามี Indi 25 Feature และใช้กรอบย้อนหลังในการเทรนโมเดล 4 วัน จะเท่ากับว่าเรามี 25x4 = 100 Feature ซึ่งอันนี้ยังไม่ได้รวมพวกราคาพื้นฐาน ดังนั้นเราจึงได้ไอเดียว่าจะทำการจัดหมวดหมู่ของ Indi แล้วทำการเลือกเพียงตัวเดียวจากแต่ละกลุ่ม โดยวิธีการจัดกลุ่ม เราใช้ Correlation เป็นเกณฑ์ หาก Indi มี Correlation กันมากกว่า 0.8 เราจะถือว่ามันมีความใกล้เคียงกัน และมีการเคลื่องที่ไปในทิศทางเดียวกันสูงมาก จะทำการจัดเป็นกลุ่มเดียวกัน

ซึ่งผลของการจัดกลุ่มก็จะได้ดังนี้ครับ

ซึ่งทางกลุ่มเราก็หวังว่าการลดจำนวน Feature ตรงส่วนนี้จะทำให้เราทำการเทรนโมเดลได้เร็วขึ้นโดยไม่เสียความหมายหลักของ Indi แต่ละกลุ่มไปมากนัก

2.2.2 Stock Market Index Features

หน้าตาข้อมูลที่ดึงมาได้ (ใช้ investpy.get_index_historical_data) ประกอบไปด้วย 6 Column ด้วยกัน ได้แก่ Date, Open, High, Low, Close และ Volume และเราได้ทำการเพิ่ม Feature เข้าไปอีก 1 ตัว ซึ่งก็คือ %change เพื่อเอาไว้ดู Trend ความแข็งแกร่งของตลาดนั้นๆในช่วงเวลาที่เราสนใจ โดยเราได้คำนวณจากสูตรต่อไปนี้

%change = ((close — close prev)/close)*100

เท่ากับว่าตอนนี้เรามี Feature อยู่เยอะมากๆ ดังนั้นจึงพยายามตัด Feature บางตัวออกโดยดูจากค่า Correlation

  • ขั้นตอนแรก จะดู correlation ระหว่าง feature ในตลาดเดียวกันก่อน ประกอบไปด้วย Open, High, Low, Close, Volume และ %change ซึ่งผลที่ได้พบว่า Open, High, Low และ Close มี correlation = 1 จึงเลือกใช้ Close เพียงอย่างเดียว ดังนั้น feature ที่เหลือสำหรับแต่ละตลาดคือ Close, Volume และ %change
  • ต่อมา ดู Correlation ของ Feature ระหว่างตลาดในประเทศเดียวกัน พบว่าข้อมูล DOW 30, NASDAQ, S&P 500 ซึ่งเป็นดัชนีของตลาดอเมริกา มีค่า Correlation ระหว่างกันมาก (>0.9) ส่วน Shanghai และ Shenzhen (SZSE) ซึ่งเป็นดัชนีของตลาดจีน มีค่า Correlation ระหว่างกันมาก (>0.8) เช่นเดียวกัน ดังนั้นจึงเลือกเพียง 1 ตัวเป็นตัวแทนของตลาดอเมริกา และ อีก 1 ตัวเป็นตัวแทนของตลาดจีน
  • วิธีการเลือกตัวแทนจะดู Correlation ของตลาดนั้นๆ เทียบกับ Adj close ของหุ้นใน SET ที่ทำการสุ่มขึ้นมาประมาณ 10 ตัว ผลที่ได้คือ เลือก DOW 30 เป็นตัวแทนของตลาดอเมริกา และ SZSE เป็นตัวแทนของตลาดจีน เนื่องจากมี Correlation กับ Adj close มากกว่าตัวอื่น

และจากประสบการณ์ของสมาชิกในกลุ่มมีความคิดเห็นว่า การดู Volume ในแง่ของราคาตลาดรวมอาจจะยังไม่เหมาะสม ควรดูที่รายหุ้นมากกว่า จึงตัด Features Volume ออก ดังนั้นจึงเหลือเพียง Close และ %change ของ SET, DOW 30, Nikkei 225, Hang Seng และ SZSE ซึ่งเป็นตัวแทนของตลาด ไทย, อเมริกา, ญี่ปุ่น, ฮ่องกง และจีน ตามลำดับ รวมทั้งหมด 10 Feature ด้วยกัน

เอาล่ะครับ ก่อนจะไปต่อใน Step 3–4–5 ขอให้แวะพักทำความเข้าใจสักนิสส ถึงความพิเศษของการทำ Model ของกลุ่มเรา เนื่องด้วยกลุ่มเรามี Main Dev ที่มีความสามารถและมี Passion ที่จะสร้างสรรค์ผลงานให้หลากหลาย ดังนั้นเราจึงขอนำเสนอ Stock Price Forecasting Model ถึง 2 รูปแบบโดยการใช้ DL Framework ที่เรียกว่า Keras มาเทรน Model โดยแบ่งออกเป็น

  • Sequential Model
  • Transformer Model

โดยเราจะขอบอกเล่าเรื่องราวของ Step 3–4–5 ให้จบทีละ Model เพื่อความไม่สับสนของผู้อ่าน เมื่อเข้าใจตรงกันแล้ว มาเริ่มเดินทางเข้าสู่ Modeling Path กันเลยครับ ลุย!!

== Model #1 Sequential Model ==

สำหรับ Framework ของ Model #1 เราจะแบ่ง Workflow ออกเป็น 3 ส่วนหลักๆ คือ Preparation, Building the model with Keras และ Prediction

Fig 4: Model #1 — Sequential Model Workflow

Step 3: Pre-processing & Feature Engineering

3.1 Preparation (Pre-processing)

  • เริ่มจากการคัดเลือกหุ้นจากกลุ่ม SET100 แต่เนื่องจากมีเงื่อนไขว่า Budget ต่อกลุ่มอยู่ที่ 20,000 บาท ดังนั้นเราจะตัดหุ้นที่ราคาเกิน 200 บาทออกก่อน จึงทำให้เหลือแค่ 98 หุ้น หลังจากนั้นเราสามารถ Get Data โดยใช้ pandas_datareader จาก yahoo โดยข้อมูลที่ Load มาได้เป็นรูปแบบตาราง ประกอบด้วย Column ดังนี้ [‘Date’, ‘High’, ‘Low’, ‘Open’, ‘Close’, ‘Volume’, ‘Adj Close’]
Fig 5: ตัวอย่างการ Get Data โดยใช้ pandas_datareader จาก Yahoo
  • เมื่อได้ข้อมูล หุ้น 98 ตัวมาแล้ว เราจะทำการหาค่า EMA10 และ EMA50 หากหุ้นตัวไหน มีค่า EMA10 > EMA50 เราจะเลือกเก็บไว้ ซึ่งเลือกมาได้ 44 หุ้น
  • จากนั้นนำหุ้นทั้ง 44 ตัว มาเช็คว่ามี Records จำนวน 10 ปีหรือไม่ พบว่า หลายหุ้นมีไม่ครบ เราจึงตัดออกอีกครั้ง จนเหลือหุ้น ที่จะนำไป ทำการ Train, Test และ Predict เพียง 21 หุ้น ดังนี้

[‘ADVANC’, ‘BBL’, ‘BH’, ‘KBANK’, ‘SCB’, ‘AOT’, ‘INTUCH’, ‘RATCH’, ‘KTC’, ‘KKP’, ‘KCE’, ‘PTT’, ‘TCAP’, ‘TVO’, ‘SPALI’, ‘AMATA’, ‘STEC’, ‘KTB’, ‘LH’, ‘THANI’, ‘TRUE’]

โดยเราพบว่าจำนวน Records ในช่วงวันที่ 1/1/2553 ถึง 29/12/2563 = 2,683 records หลังจากที่เราได้หุ้นมาแลัว 21 หุ้น เรามาเตรียม Feature ที่จะใช้กันต่อได้เลยครับ

3.2 Feature Engineering

เมื่อลองนำเอา [‘High’, ‘Low’, ‘Open’, ‘Close’, ‘Volume’, ‘Adj Close’] มาลองทำ Correlation ผลปรากฏว่า [‘High’, ‘Low’, ‘Open’, ‘Close’, ‘Adj Close’] Correlate กัน แต่ Volume ไม่ Correlate กับ ใครเลย จึงสามารถ เลือก ค่าใดค่าหนึ่งนำมา Train model ต่อไป ในที่นี้เราเลือก “Adj Close” กับ “Volume” มาใช้

Fig 6: ตัวอย่างการหา Correlation และ Plot ของ [‘High’, ‘Low’, ‘Open’, ‘Close’, ‘Adj Close’]

ในส่วนของ Feature อื่นๆ ที่เราได้เลือกสรรมาจาก Step 2 โดยเราจะขอเรียกว่า Main Feature (Mfeature) ซึ่งมีจำนวนทั้งหมด 18 Feature ดังต่อไปนี้

[‘High’, ‘Low’, ‘Open’, ‘Close’, ‘Volume’, ‘Adj Close’, ‘RSI’, ‘MACD’, ‘Close_SET’, ‘percent_change_Close_SET’, ‘Close_DOW_30’, ‘percent_change_DOW_30’, ‘Close_Nikkei_225’, ‘percent_change_Nikkei_225’, ‘Close_Hang_Seng’, ‘percent_change_Hang_Seng’, ‘Close_SZSE_component’, ‘percent_change_SZSE_component’]

จากนั้นทำการ Normalize Mfeature ยกเว้น Adj Close เนื่องจากเราจะใช้เป็น Target ของการ Predict เมื่อเสร็จแล้ว เรานำ Mfeature มาทำ Slide Window เพื่อสร้างเป็นข้อมูล Input ทั้ง Train และ Test โดย Windows ในที่นี้มีค่าเป็น 4 ตามภาพประกอบด้านล่าง

Fig 7: ตัวอย่างการ Slide Window ของ Mfeature

จากนั้นเราจะได้ข้อมูลไหมทั้งหมด 2,679 Records เพื่อมาแบ่ง เป็น Train data และ Test data โดย Xtrain = 2,600 Ytrain = 2,600 และ Xtest = 79 Ytest = 7

Step 4: Training-testing Model

ตอนนี้ก็มาถึงส่วนของการสร้าง Model โดยเทคนิคที่จะนำมาใช้สร้าง Model #1 ทางเราเลือกใช้ Keras API model แบบ Sequential (แบบต่อเนื่อง) ด้วยเหตุผลที่ว่าการทำงาน ของ Keras เป็น High-level API ที่อยู่บน Tensorflow ทำให้เราสร้าง Neuron Network ได้อย่างง่ายดายเพียงการเขียน Code ไม่กี่บรรทัด

ในขั้นตอนนี้เราได้แบ่งการทดลองออกเป็น 2 Model ย่อยๆ โดยแตกต่างกันที่ จำนวนของ Feature ที่อยู่ในตัวแปร Mfeature ของแต่ละ Model

4.1 Model #1.1

โดย Model #1.1 จะมี Feature สำหรับ Mfeature เพียง 1 ตัว นั่นคือ “Adj Close” ซึ่งจะมี

Input = 4 node, Hidden = 2 layers, 100 *2 nodes และ Output = 1 node ตามรูปด้านล่าง

Fig 8: โครงสร้างของ Model #1.1

โดยคำสั่งในการสร้าง Model #1.1 มีดังนี้

4.2 Model #1.2

โดย Model #1.2 จะมี Feature สำหรับ Mfeature จำนวน 18 Feature ประกอบไปด้วย Feature ที่ได้อธิบายไว้ใน Step 3.2 จากนั้น Mfeature มา slide windows จะได้ทั้งหมด 4*18 = 72 Feature ซึ่งจะมี Input = 72 nodes, Hidden = 2 layers, 100 *2 nodes และ Output = 1 node ตามรูปด้านล่าง

Fig 9: โครงสร้างของ Model #1.2

โดยคำสั่งในการสร้าง Model #1.2 มีดังนี้

4.3 Model #1.1 VS Model #1.2

ในขั้นตอนนี้เรานำหุ้น 21 ตัวที่ได้จากขั้นตอน Preparation มาทำการ Fit Model #1.1 และ Model #1.2 ซึ่งมี Features Input จำนวน 4 และ 72 ตามลำดับ โดยผลของค่า Loss ที่ได้เป็นดังนี้

  • ค่า Loss ของ Model #1.1 อยู่ในช่วง 0.01–0.05
  • ค่า Loss ของ Model #1.2 อยู่ในช่วง 4.00–8.00

จะเห็นได้ว่าค่า Loss ของ Model #1.1 มีค่าน้อยกว่ามากๆ เราจึงสรุปเบื้องต้นได้ว่าควรต้องใช้แค่ Adj Close เพียงค่าเดียวมาสร้าง Model ทำนายตัวเองจะดีที่สุด

จากนั้นเราจึงโฟกัสไปที่การนำ Model #1.1 มาปรับแต่งและทำนาย Adj close ใหม่และ Save Model ของหุ้นทั้ง 21 ตัวไว้ใช้สำหรับการทำนายค่าสังเคราะห์ และนำ Model ของหุ้นทั้ง 21 ตัว มาทำนาย Test data และดูผลค่า Error

Fig 10: กราฟแสดง Adj close ของหุ้น 21 ตัว

Step 5: Evaluation & Result

ในขั้นตอนนี้ เราเริ่มต้นที่การประเมินความแม่นยำของ Model #1.1 โดยตารางด้านล่าง แสดงค่า Error ที่ได้จากการทำนาย Test data ของหุ้น 21 ตัว โดยเรียงจากค่าน้อยไปมาก

จากนั้นเราทำการสังเคราะห์ข้อมูล Adj Close ของหุ้นทั้ง 21 ตัว โดยคำนวณไปข้างหน้า 14 Datapoint เพื่อทำนายราคาหุ้น ในช่วงวันที่เราจะซื้อขายว่าจะทำกำไรได้หรือไม่ และนำผลที่ทำนายมาหาค่าความชัน (Slope) ของหุ้นแต่ละตัว

  • ถ้าความชัน เป็น + ตลอด 14 Datapoint แสดงว่าหุ้นซื้อได้ และความเสี่ยงต่ำที่จะขาดทุน เนื่องจากเป็น Trend ราคาขาขึ้น
  • ถ้าความชันเป็น — หรือ ไม่มีความชัน ตลอด 14 Datapoint แสดงว่าเป็นหุ้นที่ไม่น่าซื้อ มีโอกาสขาดทุน เนื่องจากราคาเป็น Trend ขาลง หรือ ทรงๆตัว

ตารางด้านล่างแสดงผลค่า Slope ของหุ้นทั้ง 21 ตัว

จากตารางจะเห็นได้ว่า 10 อันดับแรกในตาราง ได้แก่ ADVANC, BBL, AOT, INTUCH, SCB, KBANK, TVO, RATCH, PTT, STEC มีความชันเป็น + โดยเรียงลำดับจากมากที่สุด-น้อยสุด ในช่วง 14 Datapoint ที่เราจะเข้าทำการซื้อขาย

Fig 11: กราฟแสดง Trend ค่า Adj close ของหุ้น 21ในช่วงที่จะทำการซื้อ-ขาย

== Model #2 Transformer Model ==

มาทำความรู้จัก Transformer Model

การที่ Main Dev ของเราเเบ่ง Model ออกไปถึง 2 Model เป็นเพราะว่าอยากได้ความหลากหลายของตัว Model เเละเทคนิค ในตอนเเรกระหว่างการศึกษาว่าเอ้ะ…เราจะใช้ตัวไหนมาทำดีนะ….LSTM ก็สามารถเอามาทำได้เเละน่าสนใจที่รับ Input เข้ามาได้เเบบ RNN เเต่ LSTM ก็คงใช้เวลานานพอสมควรทีเดียวเพราะไม่สามารถรันกันไปเเบบ Parallel ได้ (ต้องคอยให้ตัวก่อนหน้า Feed Output ออกมาก่อน) ระหว่างที่กำลังตัดสินใจอยู่นั้นทาง Main Dev ท่านหนึ่งก็ไปเจอ Model ที่ออกมาตอนประมาณปี 2017 ที่เข้ามาทำลายความเชื่อในเเบบเก่าๆในการทำ RNN ของ Deep Learning ไปพอสมควรเเละที่สำคัญคือโมเดลนี้สามารถรับ Input Features เข้าไปพร้อมๆกันหรือก็คือสามารถทำงานเเบบ Parallel ได้นั่นเอง ตัว Model นี้ก็คือ Transformer ครับ

พอเจอเเบบนี้ก็บอกเลยครับว่าน่าสนใจมากถึงเเม้ว่า Transformer นั้นถูกออกเเบบมาเพื่อเเก้ปัญหาทาง Text โดยเฉพาะเช่นการแปลภาษาต่างๆ หรือ Chatbot ก็ตามแต่ทาง Main Dev เชื่อมั่นว่ามันสามารถนำมาประยุกต์ใช้กับการทำนายราคาหุ้นได้เเน่นอนครับ

ก่อนจะเข้าสู่การทำนายหุ้นนั้นเรามาเข้าใจคร่าวๆกันก่อนดีกว่าครับว่า Transformer นั้นทำงานยังไงเเละทำไมมันถึงพิเศษนัก…..ขอให้ทุกคนตั้งใจให้ดีนะครับเพราะ Attention Is All You Need หลายคนที่เคยทำงานกับ Transformer มาคงคุ้นเคยกับประโยคนี้ที่คนชอบมันไปพูดกันเล่นพอสมควรเเต่สำหรับคนที่ไม่เคยได้ยิน ประโยค Attention Is All You Need นั้นไม่ได้สื่อถึงตัวผู้ทำครับเเต่สื่อถึง Paper ที่ออกมาโดย Google ในปี 2017 ในชื่อ Paper ว่า Attention Is All You Need ซึ่งเป็นนำหลักของ Self-attention เเละหลายๆเทคนิคเข้ามาร่วมกันเเก้ปัญหาครับ เรามาเริ่มจากตัว Transformer Architecture กันก่อนครับ

Fig 12: Transformer Architecture

ใครที่เพิ่งเคยเห็นครั้งเเรกเเล้วรู้สึกว่ามีอะไรเต็มไปหมดก็ขอให้ใจเย็นๆก่อนนะครับตัว Transformer นั้นสามารถเเบ่งออกไปได้เป็น 2 Layers นั้นคือ Encoder Layer(ด้านซ้ายทั้งหมด) กับ Decoder Layers(ด้านขวาทั้งหมด) โดยหน้าที่ของมันก็ตามชื่อเลยครับ โดยที่ตัว Layers พวกนี้ไม่จำเป็นต้องเป็นจำนวนเพียงตัวเดียวเเต่สามารถมีหลายตัวได้ถ้าอิงตาม Paper ใช้ 6 ตัวทั้ง 2 Layers ครับ

Fig 13: Multiple Layers of Encoder and Decoder

เเล้วใน Encoder Layers เนี่ยมันเกิดอะไรขึ้นกันเเน่ ในตัว Encoder ในก็จะประกอบไปด้วยหลายส่วนด้วยกัน

Fig 14: Main Components in Encoder

Input ของ Encoder Layer นั้นจะเข้ามาในรูปของ Vector ถ้าเป็น Word ก็จะถูก Word Embedding เปลี่ยนมาเป็น Vector ก่อนนั้นเองครับโดยที่คำที่เข้ามานั้นสามารถส่งเข้ามาเป็น Sequence ของ Word ในประโยคได้เลยครับ โดยเราจะใช้ Self-attention ในการดูความสัมพันธ์หรือความสำคัญของตัวนั้นๆกับ Sequence vector กับอื่นๆครับ โดยวิธีการก็คือการเเบ่งเเต่ละ Sequence Vector ออกไปเป็น Queries, Key, Values เเล้วเข้าสมการ Attention Scores ต่อครับ เเต่รายละเอียดในการหาเเละคำนวณส่วนนี้จะขออนุญาตข้ามไปครับไม่งั้นบทความนี้น่าจะยาวเกินไป 55555 (สามารถอื่นเพิ่มเติมได้จาก Ref. ที่อยู่ด้านล่างครับ)

Fig 15: Attention Scores Formula

หลายท่านที่อ่านมาถึงตรงนี้อาจจะสงสัยกันว่า เอ้ะ ในรูป Architecture นั้นตัว Attention มันชื่อ Multihead-attention ไม่ใช่ Self-attention สักหน่อย เอาจริงๆเเล้วมันก็คือ Self-attention หลายๆตัวนั่นเเหละครับ โดยที่มันจะมาช่วยเรื่องการเปิดภาพรวมใหญ่ๆให้ตัวโมเดลรวมถึงลดการ Donimate ค่าความสำคัญของตัวมันเองเวลาหาคะเเนนด้วยครับ

Fig 16: Multiple Attention Head

เเล้วหลังจากเข้า Mutihead-attention เเล้วจะออกมาในรูปเเบบประมาณไหน สามารถดูได้จากตัวอย่างง่ายๆด้านล่างครับ โดยสมมติว่าคำที่ป้อนเข้าไปใน input คือ “The animal didn’t cross the street because it was too tired” คำว่า it ในประโยคนี้หมายถึง Animal ใช่ไหมครับ คนเราสามารถเข้าใจได้ทันทีจากประสบการณ์ที่เราพูดบ่อยๆเเต่การที่จะทำให้โมเดลเข้าใจนั้นเราจึงหา Attention Scores ของเเต่ละคำครับ อย่างเช่นคำว่า it หลังจากเอาเข้า Multihead-attention เเล้วได้ Scores คำว่า it กับคำว่า The animal สูงเหมือนเวลาคนคิดเลยล่ะครับ

Fig 17: The Attention Scores from Each Word

ก็น่าจะพอได้ไอเดียเเล้วใช่ไหมครับ หลายคนอาจจะสงสัยอ่าวเเล้วเเบบนี้มันเร็วกว่า LSTM หรือ RNN ยังไง ในปกติเเล้ว LSTM กับ RNN จำเป็นจะต้องรอ Output จากตัวก่อนหน้าเพื่อนำมาคิดต่อในขณะที่ Transformer สามารถหา Scores ของทุกๆ Sequence ได้พร้อมๆกันเเล้วส่งต่อไปยัง Feed Forward Neural Network ได้พร้อมๆกันทันทีทำให้ไม่เกิดการรอเเล้วทำงานเเบบ Parallel ซึ่งเหมาะสมกับการทำงานของ GPU ปัจจุบันที่ Design มาเหมาะสมกับการทำงานเเบบ Parallel ครับ โดยที่ตัว Feed Forward Neural Network นี้มี Layer Norm ประกอบอยู่ด้วยครับ

Fig 18: Parallel Input to Feed Forward Neural Network

How to apply Transformer to predict the stock

หลังจากพอจะทราบไอเดียของ Encoder กันมาเเล้วลองมาดูกันครับว่ามันสามารถเอามาประยุกต์ได้อย่างไร เเต่หลายคนอาจจะสงสัยอยู่ใช่ไหมครับว่า เอ้ะ เเล้ว Decoder Layer ไม่อธิบายเหรอ เดียวคำตอบนี้จะถูกตอบจากการอธิบายการนำมาประยุกต์นะครับ

ก่อนอื่นเลยจากโจทย์ เราต้องทำนายราคาในอนาคตของหุ้นซึ่งสามารถทำได้โดยการใน Input Sequence ที่เรียงตามวันเข้าไปในโมเดลของเรา เเล้วไล่ตามขั้นตอนใน Encoder Layers จนไปถึง Dense Layers ขั้นสุดท้ายจนสามารถสร้างเป็น Model ออกมาได้หรืออีกนัยนึงก็หมายความว่าในการประยุกต์นี้เราไม่จำเป็นต้องมี Decoder Layer นั่นเองครับ

ตามปกติเเล้วถ้าเราใช้ Word เป็น Input ของโมเดล Word นั้นจะต้องถูกเปลี่ยนออกมาเป็น Vector เเล้วตามด้วย Position Encoding เพื่อบอกความสำคัญของลำดับของคำนั้นๆ เเต่ในปัญหาของเรานั้นเราใส่ค่าเข้าไปเป็นตัวเลขอยู่เเล้วโดยที่ตัวเลขนี้ก็เรียงลำดับตามวันอีกด้วย เเต่ เอ้ะ เราจะสามารถบอกความสำคัญของเวลาได้อย่างไรกัน เพราะว่าราคาของหุ้นเมื่อ 10 ปีที่เเล้วนั้นก็ไม่ควรจะมีผลกระทบเเต่ราคาหุ้นของวันนี้เท่ากับราคาของวันเมื่อวานถูกไหมล่ะครับ ดังนั้นเเล้วเราขอแนะนำให้ทุกท่านได้รู้จักกับเทคนิคที่ชื่อ Time2Vector ครับ

Time2Vector นั้นสามารถเรียนรู้ Vector ของ Time ได้นั่นเองครับโดยหลักๆเเล้วเจ้า Time2Vector นี้จะสามารถนำมาใช้ได้โดย 2 เงื่อนไข

  1. ตัว Data เวลาของเรานั้นมีความหมายเเละ Patterns ทั้งในรูปแบบของ Periodic เเละ Non-periodic Patterns
  2. เวลาในข้อมูลนั้นไม่แปรเปลี่ยนไปตามการปรับขนาดของเวลา (Invariance to Time Rescaling) อย่างเช่น วันเเละชั่วโมงครับ

โดยที่ข้อมูลของเรานั้นตรงตามกฎ 2 ข้อนี้ทุกประการดังนั้นเราจึงสามารถนำมาใช้ได้ครับ โดยที่สูตรการใช้ Time2Vector สามารถดูได้จากด้านล่างครับ

สมการอันเเรกนั้นเอาจริงๆเเล้วก็คือสมการเส้นตรง y = mx + c นั่นเองครับซึ่งเอามาใช้กับ Non-periodic Patterns ในชุดข้อมูล ส่วนสมการที่ 2 นั้นก็เป็นสมการเส้นตรงซึ่งถูกมาเอา Functions (ส่วนใหญ่ใช้ Sine Functions) เพื่อเอามาใช้ Periodic Patterns ในชุดข้อมูลนั่นเองครับ

Fig 19: Graph of Linear Formula
Fig 20: Graph of Sine Function

โดยที่จากการทดลองของ LSTM ที่เป็น Time Series ที่ใช้ Time2Vector กับ ไม่ใช้จะสามารถเห็นได้ชัดเลยครับว่าการนำ Time2Vector มาใช้นั้นส่งผลที่ดีกว่า (สีเเดงคือมี Time2Vector ซึ่งให้ความเเม่นยำที่สูงกว่าสีนำ้เงินที่ไม่ได้ใช้ Time2Vector)

Fig 21:Comparison between Using and Not Using Time2Vectors

เอาล่ะ หลังจากที่ได้ Input พร้อมเข้าโมเดลเเล้วเราก็สามารถคำนวณหา Query, Key กับ Values เพื่อเข้า Self-attention Layers ได้เเล้วครับเเต่ในเราใช้ 3 Self-attention Layers หรือก็ถือเป็น Multihead-attention เพื่อที่จะหา Attention Scores นั่นเองครับ

หลังจากนั้นที่ได้ Attention Scores เเล้วเรานำไปเข้า Feed Forwarding Layers เเล้วหลังจากนั้นเราจะนำ Output ไปตาม Flow ด้านล่างเลยครับ

Fig 22: Overall Flow Of This Project

หลังจากที่ได้ Output ของ Transformer Encoder มาเเล้วเราจะนำไปเข้า Transformer Encoder เเบบนี้อีก 3 รอบหรือก็คือใช้ 3 Encoder ต่อกันนั่นเองครับ โดยที่หลังจากผ่าน Encoder Layers ทั้ง 3 ตัวมาเเล้วเราจะนำเข้า GlobalAveragePooling1D เเล้วมันเข้า Dropout Layers กับ Dense อีก 2 รอบเเล้วสุดท้ายก็จะได้ผลลัพธ์สุดท้ายที่เราตั้งใจจะ Predict นั้นเองครับ

เเหม่ ลงทฤษฎีให้พอเห็นภาพกันไปพอสมควรเเล้วเราลองมาดูของจริงกันดีกว่าครับว่าใช้ data เเบบไหนเเล้วมี features อะไรบ้าง

Step 3: Pre-processing & Feature Engineering

3.1 Pre-processing

Fig 23: Raw Stocks Data

อันนี้เป็นข้อมูลตัวอย่างหุ้นกับ Feature ที่เราลองนำมาใช้กับโมเดลเรานะครับ จะมี Date, Open, Close, High, Low, Volume ในระยะเวลา 10 ปีครับ โดยตัวที่เราจะลอง Predict ก็คือราคา Close ในอนาคตนั่นเองครับ โดยหลายท่านอาจจะสงสัยว่า อ้าวทำไมใช้ Feature เเค่นี้ทำไมไม่ดึง Feature ที่เตรียมใน Step 2 เข้าไปด้วย สาเหตุหลักๆนะคือเรื่องของเวลาครับ การ Train Model นี้ใช้เวลานานมากพอสมควรโดยถ้าผมใช้ข้อมูลทุกๆ Feature ที่เตรียมมานั้นอาจใช้เวลา Train เกินกว่า 24 ชั่วโมงเลยครับ เพราะต้อง Train หลายหุ้นด้วย เเล้วในระยะเวลาที่ Train อยู่นั้นก็คงจะไม่ทันเวลาในการส่งชื่อหุ้นให้ทาง Botnoi ดังนั้นทาง Main Dev จึงขอลดจำนวน Feature เหลือเเค่ Feature พื้นฐานครับ

เราเริ่มจากการนำ Simple Moving Average Smoothing (Window Size = 10) เข้าไปในข้อมูลเพื่อให้ผลการทำนายนั้นเเม่นยำมากขึ้น (มาจากการทดลองเเก้ไขข้อมูลตามผลลัพธ์ที่ได้)

เราทำการเปลี่ยนข้อมูลดิบๆให้เป็น %change หรือการเปลี่ยนแปลงของราคาจากวันก่อนหน้าครับ ถ้าเพิ่มขึ้นก็จะเป็นบวกเเต่ถ้าลดลงก็จะเป็นลบ

Fig 24: Rolling Up and Find the Percentage Change

หลักจากนั้นเราก็จะ Min-Max Normalization ต่อครับ ชุดข้อมูลจึงจะออกมาประมาณด้านล่างครับ

Fig 25: After Min-Max Normalization

3.2 Feature Engineering

เราต้องทำนายข้อมูลราคาในอนาคต ซึ่งคือวันที่ 4/1/2564 เเละ วันที่ 11/1/2564 เเล้วดูว่าหุ้นตัวไหนใน SET100 ตัวที่มีเเนวโน้มจะขึ้น(ดูจากค่า EMA) เรานำหลักการปกติของ Time Seires ซึ่งใช้ตัวโมเดล Train ด้วยข้อมูลในอดีตเเล้วทำนายปัจจุบันมาปรับเปลี่ยนโดยการ Train โมเดลด้วยข้อมูลปัจจุบันเเต่ทำนาย Target ของ n วันข้างหน้านั่นเองครับ (โดยที่ n เป็นจำนวนวันในอนาคตที่เราอยากได้) ซึ่งวันที่ Train โมเดลคือวันที่ 28/12/2564 ดังนั้นเพื่อที่จะทำนายราคาของวันที่ 4/1/2564 กับ 11/1/2564 เราจึงปรับ n เป็น 7 เเละ 14 ตามลำดับครับ

หุ้นที่มีเเนวโน้มขึ้นได้เเก่ ‘ADVANC’, ‘AEONTS’, ‘BBL’, ‘BH’, ‘KBANK’, ‘PTTEP’, ‘TISCO’, ‘SCB’, ‘AOT’, ‘INTUCH’, ‘RATCH’, ‘CPN’, ‘KTC’, ‘TOP’, ‘KKP’, ‘KCE’, ‘PTT’, ‘BJC’, ‘IVL’, ‘TCAP’, ‘TVO’, ‘MINT’, ‘CENTEL’, ‘BDMS’, ‘BCP’, ‘SPALI’, ‘AMATA’, ‘GFPT’, ‘STEC’, ‘KTB’, ‘SGP’, ‘LH’, ‘AP’, ‘ESSO’, ‘BEC’, ‘THANI’, ‘IRPC’, ‘TRUE’, ‘JAS’, ‘GUNKUL’, ‘QH’, ‘TMB’, ‘SUPER’, ‘SIRI’

Step 4: Training-testing Model

ในการเเบ่ง Train, Validation เเละ Test นั้นเราเเบ่งดังนี้

  • 70% ของชุดข้อมูลให้เป็น Train data
  • 20% ของชุดข้อมูลเป็น Validation
  • 10% ของชุดข้อมูลเป็น Test data

โดยการ Train ของเรานั้นเราใช้ข้อมูล Feature ทั้งหมดต่อกันครั้งละ 28 วันเพื่อทำนาย Target เป็นราคา Close ในอีก 7 วันข้างหน้าในชุดข้อมูลนั่นเองครับ

Step 5: Evaluation & Result

เราให้โมเดลรันเเต่ละหุ้นใน 44 ตัวนี้ 30 Epoch โดยที่ Batch Size คือ 64 ครับ ถึงเเม้ว่า Epoch จะดูไม่เยอะเเต่เเค่นี้ก็ใช้เวลาถึง 8–9 ชั่วโมงในการหาค่าในอนาคตครบทั้ง 44 ตัวครับ เเต่ว่าเราต้องการหาค่าในอนาคต 2 ค่าคือของวันที่ 4/1/2564 กับ 11/1/2564 ทำให้เราต้อง Train โมเดลนี้ 2 รอบดังนั้นจึงใช้เวลากว่าจะได้คำตอบนานถึง 16–18 ชั่วโมงกันเลยทีเดียวครับ (นี้ขนาดใช้เเค่ 5 feature นะเนี่ย) ที่นานขนาดนี้อาจจะเพราะเราเลือกจะข้อมูลถึง 10 ปีด้วยเเหละครับ ตัวอย่างด้านล่างเป็นการใช้ข้อมูลของหุ้น IBM เพียงตัวเดียวเพื่อมาโชว์ผลการทำงานครับ

Fig 26: Training Process
Fig 27: IBM Stock Training Results
Fig 28: IBM Stock ValidationsResults
Fig 29: IBM Stock Loss, MAP and MAPE of Training, Validation, and Testing
Fig 30: IBM Stock Testing Results

หลังจากที่เรา Train เเต่ละ Model จนครบเเล้วตัวโมเดลก็ได้ให้ผลลัพธ์ที่ดีที่สุดออกมาโดยการที่เรานำค่าของวันที่ 11/1/2564 ไปลบ 4/1/2564 เเล้วดูว่าอันไหนจะมีการเติบโตที่ดีขึ้นนั่นเองครับ

Fig 31: Index of Best Stocks
Fig 32: The Best Top 10 Stocks that will Give High Profit From Low to High

โดยชื่อหุ้นทั้งหมดนี้คือ Top 10 หุ้นใน SET100 ที่น่าจะได้กำไรดีที่สุดไล่จากล่างขึ้นบนครับ

ไล่มายืดยาวเเละใช้เวลาอย่างยาวนานสุดท้ายก็ได้คำตอบออกมาครับ เเต่งานนี้จะไม่มีทางเกิดขึ้นได้ถ้าขาดผู้เชี่ยวชาญในด้านนี้ ขอขอบคุณ Reference จากทุกๆแหล่งครับ

Ref:

https://towardsdatascience.com/stock-predictions-with-state-of-the-art-transformer-and-time-embeddings-3a4485237de6

http://jalammar.github.io/illustrated-transformer/

https://arxiv.org/abs/1808.08946

Summary & Findings

หลังจากที่ใช้เวลาทำเเละ Develop Model ทั้ง 2 กันไปอย่างยาวนานในที่สุดเราก็ได้ชุดคำตอบของหุ้นจาก SET100 ที่น่าจะให้กำไรเราสูงที่สุดถ้าซื้อวันที่ 4/1/2564 เเละ ขายในวันที่ 11/1/2564 มาเเล้วครับ โดยที่ผลลัพธ์หุ้น Top 10 ตัวที่น่าจะให้กำไรดีที่สุดมีดังนี้ โดยเรียงลำดับจากซ้ายไปขวา

Model #1: ADVANC, BBL, AOT, INTUCH, SCB, KBANK, TVO, RATCH, PTT, STEC

Model #2: TMB, KBANK, TOP, KKP, KTB, GFPT, SIRI, MINT, STEC, SGP

หุ้นทั้งหมดนี้ที่ออกมามีเเนวโน้มว่าจะขึ้นจาก Indicator จะเห็นได้ว่าจาก Model #1 ใช้นำ Keras เข้ามาประยุกต์ใช้กับ Slidewindow เเบบ RNN กับ Model #2 ที่ใช้ Transformer Neural Network นั้นเสนอตัวที่เหมือนกันอยู่ 2 หุ้นครับนั้นคือ KBANK กับ STEC

ถึงเเม้ว่าตัวที่ได้ผลกำไรอันดับ 1 ของทั้ง 2 Model นี้จะไม่เหมือนกันก็ตามเเต่คงน่าเสียดายใช่ไหมครับถ้าเกิดว่าจะเลือกใช้เเค่อันดับ 1 ของ Model อันใดอันนึง ดังนั้นทางกลุ่มของเราจึงขอเลือกใช้ KBANK ซึ่งเป็นตัวที่ให้กำไรสูงเป็นอันดับ 6 ของ Model #1 เเละ อันดับ 2 ของ Model #2 ครับ ซึ่งค่า Error จาก Model #1 เป็น 2.08 เเละ MAE จาก Model #2 เป็น 0.1 ครับ

ก็ต้องรอลุ้นกันเเล้วครับว่าในวันที่ 11/1/2564 นี้ราคาหุ้นจะเพิ่มขึ้นหรือไม่จากราคาที่ซื้อไปในวันที่ 4/1/2564 คือ 101.5 ครับ ถึงเเม้ว่าตัว Model ที่เราทำกันมาทั้ง 2 อันนี้จะยังไม่ได้ใช้ Feature อื่นๆเพราะเนื่องด้วยข้อจำกัดของเวลาในการ Train เเละ Deadline เเต่ถึงกระนั้นทั้ง 2 Model นี้ก็สามารถนำไปสร้างต่อได้ไม่ว่าจะเป็นการใส่ Feature ที่เป็น Indicator เพิ่มหรือว่าจะเป็นการใช้ NLP Technique ในการใส่ข่าวต่างๆที่น่าจะเกี่ยวข้องกับราคาหุ้นเข้าไปในตัว Model เพื่อทำให้ Model มองปัญหาได้ในหลากหลายมิติมากขึ้น เพราะเพียงเเค่ค่าตัวเลขอย่างเดียวนั่นคงไม่เพียงพอเพราะราคาหุ้นนั้นมีการผันผวนตามข่าวต่างสะส่วนมาก ดังนั้นในอนาคตถ้า Model ของเรานั้นสามารถอ่านข่าวเเล้วดูเเนวโน้มที่จะเกิดขึ้นต่อไปได้นั่นราคาที่จะคาดเดานั่นน่าจะมีความเเม่นยำขึ้นพอสมควรครับ

ก็มาถึงช่วงสุดท้ายจริงๆของบทความนี้เเล้วนะครับ จากการฝึกทำโปรเจ็คนี้มาก็ทำให้ทราบครับว่าตัว Model มันสามารถเข้ามาช่วยกรองหุ้นเเละคัดเลือกให้เราได้พอสมควรเเต่ถึงกระนั้นการจะทำ Model พวกนี้นั้นก็ไม่สามารถขาดความรู้เเละประสบการณ์ในด้านหุ้นไปได้ ดังนั้นถึง Model เราจะให้ผลที่ดีมากมาเราก็ยังต้องคอยระวังในการลงทุนเเละคอยหมั่นหาความรู้เเละติดตามข่าวสารครับ

Colab Links

  • All about Step 1+2 of Stock Price & Technical Indicator Features

https://colab.research.google.com/drive/119kkGKQh6OVjeGvz1hHbE8trIIC8OnH1#scrollTo=NnvTeFarrsHm&uniqifier=2

  • All about Step 1+2 of Stock Market Index Features

https://colab.research.google.com/drive/1SHjypBl3DI4dup6IlpouJP_R0cJ7-f8k?usp=sharing

  • All about Model #1

https://colab.research.google.com/drive/1E07XoOpNEsnJdNiBh7wgywR8BdKM5q_V?usp=sharing

  • All about Model #2

https://colab.research.google.com/drive/1DujpInS_M6x3FFZKphTbGI8gOoNyawkG?usp=sharing

https://colab.research.google.com/drive/1r8U9neMs50GQqZCiRPwINUTqSFRakjCh?usp=sharing

https://colab.research.google.com/drive/1hast9MILjWrrJJIfpqzsthjYfZxtfnTo?usp=sharing

--

--