คนจะรวยช่วยไม่ได้ !!! มา Trade หุ้นด้วย Machine Learning กันเถอะ !!!

Peerat Pookpanich
botnoi-classroom
Published in
13 min readSep 15, 2020
The Wolf of Wall Street (2013)

Objective: บทความนี้เป็นส่วนหนึ่งของ Botnoi Classroom : Data Science Essential หัวข้อ Time Series Forecasting

Member: พลอย, บูม,เอก,ตั้ม,คอง, หมู, โอ, เมย์, เมษ, จั๊ว, ทราย, อ้อม, ทาขุ, ออน, ชัย, ไม้, วิน, เชษฐ์, เติ้ก, พีท, อีฟ

สวัสดีครับทุกคน ตอนนี้ก็มาถึงสัปดาห์ที่ 5 กันแล้วนะครับ

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

“ Trade หุ้นให้กำไรสูงสุด โดยใช้ Time Series & Stock forecasting”

ว่ากันง่าย ๆ ก็คือการใช้ข้อมูลย้อนหลังที่มีลักษณะเป็น Time Series หรืออนุกรมเวลา มาช่วยทำนายราคาหุ้นในกลุ่ม SET100 โดยการใช้ Machine Learning กันนะครับ ก่อนอื่นเรามาดู highlight ของบทความนี้กันก่อนเลยย

Highlights

- การ Brainstorm ปัจจัยที่จะมีผลกับหุ้น เลือกแหล่งข้อมูล และหาวิธีได้มาซึ่งข้อมูลนั้นๆด้วยวิธีที่หลากหลาย ทั้ง web scrapping, data loader,….

- การ Cleaning และ Pre-Processing Data เพื่อให้อยู่ในฟอร์มที่พร้อมนำไปวิเคราะห์ และ ทดสอบข้อมูลและตัวแปรที่เรา brainstorm กันมา

- การประยุกต์ใช้ความรู้ที่เรียนมา ทั้งในการดึงข้อมูลด้วย beautiful soup การแปลงข้อมูลที่เป็นข้อความด้วยเทคนิคการทำ NLP และ การประยุกต์ใช้ Models ที่อาจารย์สอน ทั้ง regression, time series และต่อยอดไปถึงการทำลอง Automated forecasting จาก Facebook

- การ สร้าง models ใหม่ เพื่อหาผลลัพธ์ที่แตกต่างออกไป โดยสร้าง framework ขึ้นมาเองเพื่อมาทำนายราคาหุ้น

- สิ่งที่ทีมได้เรียนรู้ ทดลองทำจริง และ นำเสนอหุ้นตามผลการวิเคราะห์ที่ได้

ความท้าทายอยู่ที่หลังจากที่พวกเราสร้าง model ที่ (พวกเราคิดว่าน่าจะ) ดีที่สุด สำหรับใช้ในการทำนายราคาหุ้นแล้ว เราต้องเลือกหุ้นมา และทำการซื้อ-ขายจริง !!! เรียกได้ว่า.. เล่นจริง รวยจริงกันเลยครับ ^^!

สำหรับข้อมูลแบบ Time Series ก็คือข้อมูลที่มีการเปลี่ยนแปลง แปรผันตามช่วงเวลา เช่น ราคาหุ้น ราคาทองคำ ราคาพืชผลทางการเกษตร ซึ่งจะมีองค์ประกอบต่าง ๆที่เกี่ยวข้องกับเวลา ซึ่งสามารถแบ่งได้เป็น

  • Trend: เส้นที่มีรูปแบบการเพิ่มขึ้น หรือ ลดลง อย่างต่อเนื่อง
  • Seasonal: เส้นที่มีรูปแบบของความผันผวน ขึ้น/ลง เป็น Cycle ที่เกิดขึ้นเป็นประจำ เช่น ราคาที่เปลี่ยนแปลงตามรอบเดือน / ไตรมาส
  • Remainder (Residual): เส้นที่ไม่มีแบบแผน (ส่วนที่เหลือจาก Trend + Seasonal อาจเรียกว่าเป็น Error rate หรือ Noise ก็ได้)

ในปัจจุบันการทำ Trend Forecasting เราใช้สามารถใช้ทั้ง ML (Machine Learning) หรือ DL (Deep Learning) มาช่วยทำให้ผลลัพธ์ของการทำนายมีความแม่นยำมากขึ้น และนอกจากเฉพาะข้อมูลเบื้องต้นที่มาจากตัวข้อมูล Time Series เองแล้ว เรายังสามารถเพิ่ม Features หรือสิ่งที่เราคิดว่าน่าจะมีผลต่อการทำนายเข้าไปใน Model เพื่อให้เกิดการเรียนรู้ และ สามารถทำนายผลได้ดีขึ้นอีกด้วย

สำหรับการสร้าง Time-Series Forecasting Model นั้น เป็นการใช้ Machine Learning ในรูปแบบของ Supervised Learning (การเรียนรู้ที่เราต้องป้อนคำตอบเบื้องต้น เพื่อให้ Machine เรียนรู้ก่อน) ซึ่งโดยทั่วไป มักจะใช้สมการทางคณิตศาสตร์แบบ Regression เข้ามาช่วย โดย Model ที่เป็นที่นิยมก็ได้แก่ Simple Linear Regression, Multiple Linear Regression, Lasso Regression, ElasticNet Regression ฯลฯ แต่ในส่วนโปรเจคของเราจะใช้สมการตัวไหน หรือ Features อะไรบ้าง และด้วยเหตุผลอะไร ไปติดตามกันต่อเลยครับ !

Step 1 : Get Data

ข้อมูลและปัจจัยที่คาดว่ามีผลต่อราคาหุ้น (Stock Data and related factors)

จากโจทย์ที่เราจะต้องทำโมเดลเพื่อทายราคาหุ้นใน SET100 ขั้นตอนแรกเลยพวกเราก็ต้องมาระดมสมองกันว่า น่าจะมีข้อมูลอะไรบ้างที่น่าจะมีผลต่อการเปลี่ยนแปลงของราคาหุ้นไทย และเราจะหาข้อมูลเหล่านั้นได้จากที่ไหนบ้าง … แต่ข่าวร้ายคือ กลุ่มเราแทบไม่มีคนเล่นหุ้นเลยครับ ไม่มี Insight เลยว่าข้อมูลไหนน่าจะมีผลกับราคาหุ้นบ้าง … ก็เลยคุยกันว่างั้นเราก็ลิสต์ๆ มา เกี่ยวมากเกี่ยวน้อยเอามาให้หมด แล้วเดี๋ยวมาใช้ Model ช่วยตัดสินละกัน … ในส่วนของข้อมูลที่เลือกมาเราก็จะพยายามเลือกแหล่งที่มีข้อมูลย้อนหลังในช่วง 5–10 ปี … โดยรายละเอียดของข้อมูลและตัวแปรทั้งหมดที่รวบรวมมาจะแสดงอยู่ตามตารางนี้เลยครับ

ตัวอย่างข้อมูลที่เราคิดว่าน่าจะสามารถนำมาทำนายราคาหุ้นได้

สำหรับตารางข้อมูลเต็มๆ พร้อมแหล่งที่มาของข้อมูลรวมถึงวิธีที่ใช้ในการดึงข้อมูล สามารถคลิกที่ลิงค์นี้ได้เลยครับ Table : All Possible Features

ซึ่งจากข้อมูลทั้งหมด 100 กว่าตัว ที่พวกเราช่วยกันลิสต์ขึ้นมา ก็สามารถแบ่งเป็นกลุ่มๆ ได้ประมาณนี้ครับ

  • กลุ่มที่ 1 : ข้อมูลราคาหรือการซื้อขายของหุ้นแต่ละตัวใน SET100 โดยตรง เช่น ราคาปิด(Close, Adjusted Close), ราคาเปิด(Open), ปริมาณการซื้อขายของหุ้นแต่ละตัว (Volume) ซึ่งข้อมูลพวกนี้พวกเราคิดว่าน่าจะเอาไปทำ Feature Engineering เพื่อสร้างตัวแปรอื่นๆ สำหรับสาย Technical Analysis (สายอ่านกราฟ) เช่น MACD หรือ RSI ได้
  • กลุ่มที่ 2 : ข้อมูลสถานะทางการเงินของแต่ละบริษัท เช่น อัตราการเติบโตของรายได้, กำไร, เงินปันผล หรือ Key Financial Ratio ต่างๆ เช่น EPS, ROA, ROE, NPM แต่น่าเสียดายที่ข้อมูลพวกนี้ส่วนใหญ่จะเป็นรายปี หรือรายไตรมาส เลยทำให้มี Variation ของข้อมูลน้อย ซึ่งถ้าไม่ใช่ช่วงประกาศผลการดำเนินการของบริษัท ก็ไม่น่าจะมีผลสักเท่าไหร่ โดยเฉพาะสำหรับการลงทุนระยะสั้นแบบของพวกเรา เราเลยไม่ได้โฟกัสที่ข้อมูลส่วนนี้เยอะครับ
  • กลุ่มที่ 3 : ข้อมูลที่สามารถทำ Feature Engineering ได้จากวันที่ เช่น วัน, สัปดาห์, เดือน
  • กลุ่มที่ 4 : ดัชนีของตลาดซื้อขายหลักทรัพย์ทั้งในประเทศไทย และในต่างประเทศ เช่น SET Index, TFEX, MAI, Dow Jones, NASDAQ, Nikkei, Hang Seng
  • กลุ่มที่ 5 : ราคาสินค้าที่มีการซื้อขาย เก็งกำไรกันในตลาดโลก เช่น Crude Oil, Gold, Silver, Dollar Index
  • กลุ่มที่ 6 : ปัจจัยชี้วัดสภาวะเศรษฐกิจไทยและต่างประเทศ เช่น GDP หรือ อัตราการว่างงานของไทย หรือ สหรัฐอเมริกา แต่ข้อมูลที่เราหาได้ส่วนใหญ่จะเป็นรายปีหรือรายไตรมาส เราก็เลยไม่ได้โฟกัสที่ข้อมูลส่วนนี้เยอะครับ
  • กลุ่มที่ 7 : ปัจจัยอื่นๆ ที่อาจส่งผลต่อเศรษฐกิจและการลงทุน เช่น อัตราดอกเบี้ย, อัตราแลกเปลี่ยน, วันประชุมของคณะกรรมการนโยบายการเงิน ทั้งของไทย(กนง.) และของสหรัฐ (Fed Meeting)
  • กลุ่มที่ 8 : ราคาหรือดัชนี้ราคา (Consumer & Producer Price Index) ของสินค้าต่างๆ ในประเทศ ไม่ว่าจะเป็นสินค้าอุตสาหกรรม หรือสินค้าเกษตร เช่น ราคาน้ำมันในประเทศ, ดัชนีราคาวัสดุก่อสร้าง, ราคายางพารา, ราคาเนื้อหมู, ค่าแรง, ค่าไฟ, ดัชนีราคาสินค้าส่งออก โดยพวกเรามองว่าตัวแปรนี้อาจจะส่งผลในภาพรวมหรือกับแค่บางเฉพาะกลุ่มธุรกิจก็ได้ครับ
  • กลุ่มที่ 9 : ข่าวเกี่ยวกับหุ้นจากเว็บไซต์ต่างๆ ซึ่งเดิมเราตั้งใจจะรวบรวมจากหลายเว็บไซต์ แต่ด้วยเวลาที่จำกัด เราเลยดึงข้อมูลมาได้แค่เว็บไซต์เดียวครับ เราเลยเพิ่มข้อมูล Google Trend Index ของแต่ละหุ้นเข้ามา เพื่อแทนในส่วนของ Public Interest และเพิ่มข้อมูลว่าหุ้นแต่ละตัวถูกแนะนำหรือวิเคราะห์จาก Broker บ้างหรือไม่ในช่วงเวลาใกล้เคียง (ปล. เราอาจไม่ได้เลือก Broker เจ้าดังมากนะครับ … เพราะมันไม่ฟรีครับ !!! เราเน้นของฟรี )
ตัวอย่างข้อมูล Google Trend Index ที่เราเลือกมาใช้แสดง Public Interest ในประเทศไทย ต่อชื่อหุ้นแต่ละหัว แต่ข้อมูลนี้จะต้องใช้อย่างระมัดระวังเพราะค่า Index อาจเปลี่ยนแปลงได้ตลอดเวลา และหุ้นบางตัวมีชื่อที่พ้องกับคำธรรมดาๆ ในภาษาอังกฤษ เช่น BAY แต่เอาเป็นว่า เราเอามาใช้มองเป็นแนวโน้มละกันว่าคน ‘ค้นหา’ คำพวกนี้บ่อยมากขึ้นหรือน้อยลงแค่ไหนกับช่วงเวลาต่างๆ

การเก็บข้อมูล (Data Loading)

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

  • วิธีที่ 1 : สายเทพ เค้าต้องทำ Web Scraping สิ … จะธรรมดาได้ยังไง เราใช้ข้อมูลพวกนี้กับข้อมูลกลุ่มที่เป็นข่าวหุ้นครับ วิธีการนี้จะทำให้เราได้ข้อมูลจากเว็บไซต์เป้าหมายได้ตามต้องการ เพราะเราสามารถกำหนดจุดที่ต้องการสกัดข้อมูลบนหน้าเว็บไซต์ และสามารถที่จะสกัดพร้อมกันหลายๆเว็บไซต์ได้ในหนึ่งช่วงเวลา แน่นอนว่าเราต้องแลกมาด้วยความอึด ถึก ทน และองค์ความรู้ที่จำเป็น ไม่ว่าจะเป็นภาษา HTML ที่เป็นฉากหลังของหน้าเว็บไซต์ที่สวยงาม การใช้เครื่องมืออย่าง Browser Inspector เพื่อค้นหาว่าหน้าเว็บไซต์ฉากหลังมีการเขียนโค้ด HTML ไว้อย่างไร การใช้ library ต่างๆ เพื่อดูดหน้าเว็บไซต์ (Requests) และสกัดเว็บไซต์ (BeautifulSoup) โดยใน project นี้เราเลือกที่จะสกัดข้อมูลข่าวจากเว็บไซต์ http://thainewsstock.blogspot.com/ โดยเลือกเฉพาะข่าวที่มาจาก หนังสือพิมพ์ทันหุ้น
ตัวอย่างเว็บไซต์ https://www.set.or.th: ภาพซ้าย ฉากหน้าของเว็บไซต์ที่ทุกคนสามารถอ่านได้ง่าย และ ภาพขวา ฉากหลังที่เป็น HTML
ตัวอย่างของการใช้ Browser (Chrome) Inspector เพื่อหาโค้ด HTML ที่เป็นฉากหลังของหน้าเว็บไซต์
ตัวอย่างการใช้ Library Requests เพื่อดึงข้อมูลหน้าเว็บไซต์จาก https://www.set.or.th
ตัวอย่างการใช้ Library BeautifulSoup เพื่อสกัดข้อมูล SET100 Symbols
  • วิธีที่ 2 : Library / API ใน Internet ก็มีเยอะแยะ ทุ่นแรงด้วย Library / API ที่มีอยู่ในแล้วใน Internet กันเถอะ เช่น การดึงข้อมูลราคาหุ้นด้วย Yahoo Finance API, ข้อมูลดัชนีตลาดหุ้นและราคาสินค้าต่างๆ ด้วย Investpy (investing.com), ข้อมูล Google Trend Index ด้วย pytrends
  • วิธีที่ 3 : สายอยากเทพแต่อ่าน HTML ไม่เป็น งั้นเริ่มที่ ใช้สูตร IMPORTHTML ดึงข้อมูลตารางลงมาไว้ที่ Google Sheet แล้วค่อยดูดมาเข้า Python ทีหลังละกัน เช่น ข้อมูลการวิเคราะห์หุ้นหรือแนะนำหุ้นจาก Broker
Easy Web scraping : ตัวอย่างการใช้สูตร IMPORTHTML เพื่อดึงข้อมูลตารางจากเว็บไซต์ด้วย Google Sheet
  • วิธีที่ 4 : สาย Manual กด Download หรือ Copy ตารางด้วยมือ … ช้าหน่อยแต่ชัวร์นะ !! ส่วนใหญ่จะเป็นข้อมูลจากหน่วยงานในประเทศไทยครับ เช่น อัตราดอกเบี้ย, อัตราแลกเปลี่ยนจากธนาคารแห่งประเทศไทย ราคาหรือดัชนีราคาต่างๆ จากกระทรวงพาณิชย์ (ความจริงแล้วทั้งธนาคารแห่งประเทศไทย และกระทรวงพานิชย์มีก็มี API สำหรับข้อมูล แต่ด้วยระยะเวลาที่ทำให้เราไม่ได้ศึกษาเพื่อใช้งาน)

Tips & Tricks จากทั้ง 4 วิธีการ (รวมถึงข้อข้อควรระวัง)

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

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

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

Library ก็ไม่ได้สะดวกเสมอไป หลายๆครั้ง library ที่เราเลือกก็ใช้ยากเหลือเกิน เพราะ documents ไม่ชัดเจน community เพื่อหาคำตอบก็น้อย ซึ่งก็มาจากหลาย ๆ สาเหตุ

จากขั้นตอนดั่งกล่าวเราสามารถสรุปออกมาเป็น Data Pipeline ได้ตามนี้เลยครับ

Step 2 : Understanding Data & Dealing with Missing Value

Dealing with Missing Value (NaN)

เราแบ่งวิธีได้เป็น 3 แบบด้วยกันครับ

วิธีที่ 1: การแทนที่ NaN ด้วย Forward Fill (ffill) สำหรับข้อมูลที่มีลักษณะต่อเนื่อง เช่น ราคาของหุ้น หรือสินค้าต่างๆ รวมถึงดัชนีหุ้นหรือ ดัชนีราคาสินค้าต่างๆ ด้วย เพราะเรามองว่าการแทนที่ด้วยค่า 0 หรือค่าสถิติอื่นๆ อาจจะทำให้ Trend ของข้อมูลที่เป็น Time series ผิดเพี้ยนไปได้ การแทนที่ด้วย Forward Fill หรือข้อมูลเดียวกันของช่วงเวลาก่อนหน้า น่าจะเหมาะสมกว่า

ตัวอย่าง Code การแทนที่ข้อมูล Time-Series ด้วย Forward Fill (ffill)

วิธีที่ 2: การแทนที่ NaN ด้วยค่า 0 เช่น ข้อมูลข่าว หรือหุ้นที่ถูกแนะนำโดย Broker เพราะเรามองว่าการที่ไม่มีข้อมูลเกี่ยวกับหุ้นตัวใด ในวันนั้นๆ น่าจะแปลว่าไม่มีข่าวหรือไม่มีการพูดถึงหุ้นตัวนั้นเลย

วิธีที่ 3: ไม่แทนค่า NaN ด้วยค่าใดๆ เลย เพราะเป็นช่วงเวลาที่ไม่มีการเก็บข้อมูลนั้นๆ จริงๆ เช่น เราไม่มีข้อมูลการวิเคราะห์หุ้นจาก Broker ในช่วงก่อนปี 2013 เราก็เลือกที่จะไม่แทนที่ค่า NaN ด้วยค่าใดๆ เลย เพราะอาจจะทำให้ความหมายของข้อมูลผิดเพี้ยนไปได้ หรือราคาหุ้นบางตัวที่พึ่งเริ่ม Trade ในตลาดไม่กี่ปี โดยพวกเรามองว่าถ้าหุ้นตัวใด ไม่มีข้อมูลสำคัญบางอย่างในบางปี ก็อาจต้องพิจารณาตัดข้อมูลในช่วงปีนั้นทั้งหมด

ตัวอย่างข้อมูลการแนะนำหุ้นโดย Broker ซึ่งควรแทนที่ค่า NaN ด้วย 0 แต่จะระบุช่วงเวลาที่ไม่แทนที่ NaN ด้วยค่า 0 เพราะช่วงเวลาดังกล่าวยังไม่มีข้อมูลนี้

เรื่องที่ 2 : ลอง Detect Outliers ดู แต่สุดท้ายก็ขึ้นอยู่กับแต่ละ Model ว่าจะต้องทำหรือไม่

ในเบื้องต้นพวกเราได้ลองทำ Outliers Detection กับข้อมูลกลุ่มต่างๆ ดู พบว่าจากข้อมูลย้อนหลังในช่วง 10 ปี หรือนับเป็นมากกว่า 2000 Rows ของวันที่มีการซื้อขายหุ้น จะมีจำนวน Outliers อยู่บ้าง โดยจะเจอเยอะในข้อมูลที่เป็นราคาสินค้าเกษตรรายวันที่มีความผันผวนสูง กับข้อมูลมูลค่าการซื้อขายหุ้นในตลาดหลักทรัพย์ ส่วนข้อมูลที่มีลักษณะเป็น Index ของราคาสินค้าต่างๆ และข้อมูลที่เป็นรายเดือนจะแทบไม่มี Outliers เลย

โดยกลุ่มเราไม่ได้ทำการ Drop หรือ Replace ค่า Outliers ในทันที โดยเฉพาะกับข้อมูลราคาหุ้น เพราะเรามองว่าความผันผวนของเราก็น่าจะเป็นอีกหนึ่งปัจจัยที่ Model จะต้องเรียนรู้และพยายามมองหา Pattern ให้ได้

นอกจากนี้ หลังจากได้ทดลองสร้าง Model บางตัวและพิจารณาผลดูแล้ว เรายังมองว่าแม้ Year จะไม่ถูกบอกว่าเป็น Outliers จากการคำนวณทางคณิตศาตร์ แต่ระยะเวลาของข้อมูล (แกน Timeline) ที่ยาวนานเกินไปก็อาจจะเป็นเสมือน Outliers ในการสร้าง Model ทำนายราคาหุ้นได้

การกำจัดความซ้ำซ้อนของข้อมูลเนื่องจากปัญหาโครงสร้างหน้าเว็บไซต์

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

ตัวอย่างจากหน้าเว็บไซต์ข่าว http://thainewsstock.blogspot.com/ ซึ่งมีโครงสร้างหน้าเว็บต่างกัน

เรื่องที่ 4 : ความรู้สึกเสียดายที่จะต้องตัดบางข่าวทิ้งไปเพราะไม่มี Symbols ของหุ้นในข่าว

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

ตัวอย่างข่าวที่ไม่มี Symbols ของหุ้นอยู่ในเนื้อความ

Understanding Data

ตัดข้อมูลที่เป็นรายไตรมาสและรายปีเพราะมี Variation น้อย

หลังจากได้ข้อมูลทั้งหมดมาแล้ว กลุ่มเราก็เริ่มต้นด้วยการทำความเข้าใจข้อมูลของเรา โดยเบื้องต้นข้อมูลของเราจะอยู่ในรูปแบบรายวัน รายสัปดาห์ และรายเดือน ส่วนข้อมูลรายไตรมาสและรายปี พวกเราคิดว่าน่าจะมี Variation น้อยเกินไป ที่จะเอามาทำนายราคาหุ้นซึ่งเรากำหนดให้เป็นแบบรายวัน (Daily) เป็นหลัก ก็เลยเลือกที่จะไม่นำมาใส่ใน Model แต่จะดูข้อมูล Key Financial Performance ต่างๆ ประกอบภายหลัง

โฟกัสเฉพาะวันที่มีการซื้อขายหุ้นใน SET และใช้ Date เป็น Key Feature ในการ Merge ตารางข้อมูล

โดยในเบื้องต้นเราจะแยกข้อมูลออกเป็น 3 ส่วนครับ ได้แก่ ราคาหุ้น ปัจจัยต่างๆ ที่มีผลกับราคาหุ้นแต่ละตัว และ ปัจจัยที่น่าจะมีผลในภาพรวม โดยข้อมูลแต่ละส่วนก็จะมีวิธีที่จะต้องจัดการที่แตกต่างกันออกไป แต่เราจะใช้ ‘date’ หรือ วันที่ที่มีการซื้อขายหลักทรัพย์ใน SET ในช่วง 5–10 ปีที่ผ่านมาเป็น ‘Key Feature’ ในการรวมข้อมูลครับ (Ignore วันเสาร์ อาทิตย์และวันหยุดที่ไม่มีการซื้อขายหลักทรัพย์)

‘Adjusted Close Price’ VS ‘Open Price’ ใช้ตัวไหนเป็น Test Feature ดี

ถึงแม้โจทย์จะบอกให้เราทำ Model เพื่อทายราคาหุ้น แต่เมื่อพวกเราได้เห็นข้อมูลจริงก็พบว่า ราคาหุ้นนั้นมีกันหลายตัว ทั้ง Open, Close, Max, Min, และ Adjusted Close แล้วเราควรจะเลือกใช้ราคาตัวไหนมาเป็นตัว Test Feature ดี ??

หลังจากที่ได้ทำการถกเถียงกันเล็กน้อย เราก็ตัดสินใจเลือก Open Price เพราะทีมงาน BOTNOI ได้กำหนดให้เราซื้อหุ้นในราคาเปิดตลาด และขายหุ้นในราคาเปิดตลาด เช่นกัน เลือก Open Price ก็น่าจะตรงโจทย์ที่สุด

แต่เราก็พบว่ามีข้อจำกัดในการใช้ Open Price ครับ เราพบว่าหุ้นบางตัวใน SET100 เคยมีการแตกพาร์มาก่อน เช่น AOT ( ก.พ. 2016), PTT (เม.ย. 2018), GULF (เม.ย. 2020) ดังนั้นถ้าเราใช้ราคา Open ที่อาจจะยังไม่ถูก Adjust มาเป็น Test Feature ก็อาจจะมีช่วงที่ราคาลดลงอย่างผิดปกติ และมีผลกับ Model ได้ ดังนั้นเราจึงจำเป็นที่จะต้องใช้ Adjusted Close เท่านั้น

ตัวอย่างการแตกพาร์ของหุ้น PTT ซึ่งทำให้ราคาหุ้นลดลง 10 เท่า เราจึงจำเป็นต้องใช้ราคา Adjusted Close สำหรับ Prediction Model (Source : https://knowledge.bualuang.co.th/knowledge-base/faq-ptt/)

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

หลังจากลองทำความเข้าใจเกี่ยวกับข้อมูลดัชนีตลาดหุ้นต่างประเทศ และราคาสินค้าสำคัญในตลาดโลก พบว่าดัชนีของตลาดหุ้นในสหรัฐ เช่น Dow Jones Index, NASDAQ Composite (IXIC) และราคาสินค้าในตลาดโลก จะต้องใช้ข้อมูล Close Price ของวันก่อนหน้า เพราะในวันที่เดียวกัน ตลาดหุ้นในสหรัฐอเมริกาจะเปิดตลาดหลังจากตลาดหุ้นในไทย (SET) อย่างไรก็ตาม Model หนึ่งที่เราตั้งใจจะนำมาใช้คือ LSTM จะสามารถจัดการกับเรื่อง Time-Lag ได้ในตัวอยู่แล้ว

ส่วนดัชนีของตลาดหุ้น Asia เช่น Hang Seng (HSI) หรือ Nikkei 225 นั้นอาจจะต้องมีวิธีการนำไปใช้ที่แปลกๆ เล็กน้อย เพราะโดยปกตินักลงทุนใน SET จะมองดัชนีของตลาดหุ้น Asia ที่เปิดก่อน SET ว่าราคาเปิดตลาดเป็นบวกหรือลบถ้าเทียบกับราคาปิดของวันก่อนหน้า ดังนั้นเราจึงต้องสร้าง Feature ใหม่ สำหรับ Index พวกนี้ คือ OpenGap = OpenIndex (ของวันนี้) — CloseIndex (ของเมื่อวาน)

ตัวอย่าง Code ที่ใช้สร้าง OpenGap สำหรับดัชนีตลาดหุ้นใน Asia

มาทำความรู้จัก SET100 โจทย์ของเราในสัปดาห์นี้กันหน่อย

จำนวนหุ้นใน SET และ SET100 แบ่งตามประเภทธุรกิจ (Industry & Sector)

SET100 ถ้าตามนิยามก็คือ หุ้นที่มีมูลค่า Market Capitalization (มูลค่าบริษัท = จำนวนหุ้นทั้งหมดในตลาด X ราคาหุ้น) สูงที่สุด และมีสภาพคล่องในการซื้อขายที่ดี 100 ลำดับแรกจากใน 617หุ้น ในตลาดหลักทรัพย์แห่งประเทศไทย (Stock Exchange of Thailand : SET)

ที่น่าสนใจก็คือ ถ้ามองตามประเภทกลุ่มธุรกิจ จากหุ้น 100 ตัว ใน SET100 มีหุ้นถึง 25 ตัวที่มาจากกลุ่มพลังงานและสาธารณูปโภค ตามมาด้วยธุรกิจบริการ 24 หุ้น, อสังหาริมทรัพย์และก่อสร้าง 16 หุ้น, ธุรกิจการเงิน 15 หุ้น

อีกหนึ่งสิ่งที่มือใหม่อย่างพวกเราได้เรียนรู้จากโจทย์สัปดาห์นี้คือ เวลาจะซื้อหุ้นแต่ละตัวในแต่ละครั้ง เราจะต้องซื้อขั้นต่ำ อย่างน้อย 100 หุ้น นั่นแปลว่าจากโจทย์ที่ทาง BOTNOI บอกว่าจะลงทุนซื้อหุ้นให้เราจริงๆ ด้วย Budget 10,000 บาทต่อกลุ่ม … พวกเราจะไม่สามารถซื้อหุ้นใน SET100 ที่ราคาเกินกว่า 100 บาทได้ (เพราะไม่อย่างนั้นมูลค่ารวมจะเกิน 10,000 บาท) … ณ วันที่ 14 กันยายน 2020 ก็จะมีหุ้นที่พวกเราไม่สามารถซื้อได้ 8 ตัว เช่น ADVANC, BBL, SCC, TQM (หุ้นชื่อคุ้นๆ ทั้งนั้นเลย สำหรับมือใหม่อย่างพวกเรา)

มาลอง Plot ข้อมูล Time Series และ Decompose Graph ตามที่ทาง BOTNOI สอนมา !!

และเพื่อไม่ให้เป็นการ Bias ที่หุ้นตัวใดตัวหนึ่ง เราจะเริ่มด้วย Data ของ SET Index ในช่วง 10 ปีที่ผ่านมาก่อนครับ

เราพอจะสังเกตได้ว่า SET Index มีเทรนด์แบ่งได้เป็น 2 ช่วงใหญ่ๆ ด้วยกัน คือ ก่อนปี 2018 ที่ดูจะเป็นเทรนขาขึ้น (สลับกับลงบ้างเป็นบางปี) แต่หลังจากต้นปี 2018 เป็นต้นมา กราฟก็กลายเป็น Trend ขาลง

เพื่อความชัวร์ เราลอง Decompose กราฟของ SET Index ดู

Decomposition ข้อมูล SET Index ในช่วงปี 2010–2020

ระยะเวลาที่จะนำมาใช้ในการเทรนโมเดล น่าจะเป็นอีกหนึ่งเรื่องสำคัญที่ต้องตัดสินใจ สำหรับโจทย์ในครั้งนี้ เพราะถ้าระยะเวลายาวเกินไป Model อาจจะ Underfitted ในการใช้ทำนายราคาหุ้นในช่วงใกล้ๆ นี้ (ขาลง) แต่ถ้าสั้นเกินไปก็อาจจะ Bias หรือ Overfitted ทำให้ทำนายราคาหุ้นในช่วงตลาดขาลงได้ดี แต่ทำนายพลาดมากๆ ถ้าตลาดเปลี่ยนทิศทางกลับเป็นขาขึ้น

ตัวอย่าง Model ที่มีลักษณะ Underfitted (ทายไม่ค่อยแม่น) และ Overfitted (เก่งแต่กับเฉพาะข้อมูลบางอย่าง)

ส่วน Seasonal Pattern เราก็จะพอมองเห็นว่า SET Index นั้นมักจะต่ำสุดในช่วงต้นปี และมีแนวโน้มขาขึ้นในช่วงไตรมาสที่ 1 แล้วจึงเริ่มปรับตัวลดลงเรื่อยๆ ตั้งแต่ช่วงกลางๆ ไตรมาสที่ 2 ของปี จนลงไปต่ำสุดอีกครั้งในช่วงปลายปี

Note : จากกราฟของ SET Index … January Effect มีจริงไหมอ่ะกลุ่มเราไม่ชัวร์ แต่ First & Second Week Effect อ่ะมีอยู่จริงใน SET Index … ลองสังเกตตรงกราฟ Seasonal ในช่วงสัปดาห์ที่ 1–2 ของเดือนมกราคมดูสิ พุ่งสูงขึ้นทุกปีในช่วง 5 ปีที่ผ่านมา

จริงๆ January Effect ก็มี แต่จะชัดเจนจนถึงประมาณสัปดาห์ที่ 3 ของเดือน แล้วอาจพุ่งสูงขึ้นหรือตกลงในช่วงสัปดาห์ที่ 4 ของเดือนมกราคม ไม่แน่นอน) และ February ก็เป็นอีกหนึ่งเดือนที่น่าสนใจสำหรับการลงทุนเช่นกัน (ปล. ยกเว้น ปี 2020 ที่ T^T)

Step 3 : Features Engineering

จากตาราง Brainstorm ที่พวกเรามาช่วยกันรวม Idea ไว้ว่าน่าจะมี Features อะไรบ้างที่มีผลต่อราคาหุ้น สำหรับวิธีการหรือเทคนิคหลักๆ ที่เรานำมาใช้กับข้อมูลในครั้งนี้ ก็จะมีประมาณนี้ครับ

  • วิธีที่ 1 : สร้าง Features จาก Datetime และทำ One Hot Encoder

โดยหลังจากแปลงข้อมูล Date เป็น Datetime แล้ว เราก็ได้สร้าง Feature ที่เกี่ยวกับ Datetime เช่น วันที่ (day), เดือน (Month), ปี (Year), วันในสัปดาห์ (EnglishDay), ลำดับที่สัปดาห์ในแต่ละเดือน (d_WeekInMonth), ลำดับที่สัปดาห์ในแต่ละปี (d_WeekInYear)

โดยส่วนใหญ่แล้ว เราสร้าง Features พวกนี้เพิ่มเติม เผื่อในกรณีที่ราคาหุ้นแต่ละตัว อาจจะมี Seasonal Pattern เช่น January Effect หรืออย่างที่เราสังเกตเห็นว่า SET Index มักจะเป็นขาขึ้นในช่วงสัปดาห์แรกๆ ของปี

หลังจากที่เราได้ Features ในกลุ่ม Datetime แล้ว เราก็ใช้ One-Hot Encoder เพื่อให้ Features เหล่านี้กลายเป็น Dummy Features

  • วิธีที่ 2 : สร้าง Time-Lag Features

เพราะเราคิดว่าราคาหุ้นในวันนี้อาจจะเคลื่อนไหวตามราคาหุ้นในอดีตอย่างมี Pattern ก็ได้ เราเลยสร้าง ‘Adj Close-1day’ (ราคาหุ้นในวันก่อนหน้า) และ ‘Adj Close-5day’ (ราคาหุ้นในสัปดาห์ที่แล้ว) ขึ้นมาเป็นหลักสองตัว แต่สำหรับในบาง Model เราก็ไม่ได้ใช้ Feature ในกลุ่มนี้ เพราะตัว Model เองสามารถจัดการเรื่อง Time-Lag ได้อยู่แล้ว

  • วิธีที่ 3 : สร้าง Features พื้นฐานเกี่ยวกับ Technical Analysis

หลังจากที่รู้โจทย์ว่าต้องทำนายราคาหุ้น กลุ่มเรามีความคิดว่าถ้าทำตัวเป็น VI ดูแต่ปัจจัยพื้นฐานของบริษัท (Fundamental Analysis) อาจจะไม่พอ เพราะระยะซื้อ / ขายค่อนข้างสั้น แค่ 1 สัปดาห์ และช่วงนั้นก็ไม่น่าจะมีข่าวประกาศผลประกอบการของหุ้นไหนให้มาเล่นเป็นพิเศษ เราอาจจะต้องลองศึกษาเทคนิคการอ่านกราฟของสาย Technical Analysis ดู

หลังจากอ่านและพยายามทำความเข้าใจกันมาหลายเว็บ ดูไป Youtube ไปหลายคลิป เราก็ตกลงกันว่าจะสร้าง Features ต่างๆ เพิ่ม โดยแบ่งเป็นกลุ่มย่อยๆ ได้ประมาณนี้ครับ

[‘ema10’, ‘ema20’, ‘ema75’] = Exponential Moving Average (EMA) = ค่าเฉลี่ยราคาย้อนหลังด้วยวิธีการคำนวณแบบ Exponential Smoothing (การให้น้ำหนักข้อมูลที่ใกล้วันล่าสุดมากกว่าวันที่ห่างออกไป) สำหรับช่วงเวลา 10 วันทำการ (2 สัปดาห์), 20 วันทำการ (1 เดือน), 75 วันทำการ (1 ไตรมาส)

ตัวอย่างการอ่านเทรนของหุ้นจากกราฟ Moving Average

[‘macd’, ‘macd_signal_line’] = Moving Average Convergence/Divergence (MACD) = การดูเส้นกราฟค่าเฉลี่ยราคาที่ตัดกันเพื่อแสดงสัญญาณที่ควรซื้อหรือขายหุ้น

[‘rsi’, ‘rsi_ewma’] = Relative Strength Index (RSI) = Momentum oscillator หรือ เครื่องมือทางเทคนิคที่ใช้ในการวัดแรงซื้อแรงขาย เพื่อดูว่ามีการ Overbought (ซื้อมากเกิน) หรือ Oversold (ขายมากเกิน) ไปแล้วหรือยัง

[‘%K’, ‘%D’, ‘L14’, ‘H14’,] = Stochastic Oscillator = Momentum oscillator หรือ เครื่องมือทางเทคนิคที่ใช้อธิบายภาพรวมความผันผวนของราคา ณ ช่วงเวลาหนึ่ง โดยการอาศัยเส้นสัญญาณสองเส้น (%K, %D)

ตัวอย่าง Code เพื่อคำนวณค่า RSI
ตัวอย่าง Code การสร้าง Features ในกลุ่ม Technical Analysis

สำหรับใครที่สนใจเรื่อง Technical Analysis มันก็ไม่ยากครับ (เหรอออออออออ) มาลองเริ่มศึกษากันจากลิงค์พวกนี้ดูนะครับ

Source :

มือใหม่หัดเล่นหุ้น “Technical Analysis แบบง่าย กูรูเขาใช้กันยังไง”

Moving Average ถ้าอยากใช้ ต้องรู้อะไรบ้าง?

MACD เครื่องมือชี้จุดซื้อบอกจุดขาย พร้อมผลทดสอบความแม่นยำ 20 ปี

ซื้อมากเกิน ขายเยอะไป ดูจากนี่ไง RSI

Stochastic Oscillator คือ? : เทคนิคและการตั้งค่า Stochastic Forex

  • วิธีที่ 4 : การสร้าง Features เพื่อดึงชื่อหุ้น ออกมาจากข้อมูลที่เป็น Text

หลังจากที่เราได้ข้อมูลข่าวหุ้น และชื่อบทวิเคราะห์หุ้นจาก Broker ในแต่ละวันในรูปแบบ Text มาแล้ว เราก็ทำการสร้างคอลัมน์เพื่อเช็กว่าในแต่ละข่าว หรือชื่อบทวิเคราห์มี สัญลักษณ์ของหุ้นต่างๆ ปรากฎอยู่หรือไม่ โดยในตัวอย่างนี้จะเป็นการใช้คำสั่ง str.contains ร่วมกับ str.upper

ตัวอย่าง Code การสร้าง Dummy Features จากข้อมูลที่เป็น Text

นอกจากนี้ เราจะสังเกตได้ว่าข้อมูลในแต่ละวันอาจจะมีมากกว่า 1 ข่าวหรือ 1 บทวิเคราะห์ก็ได้ เราจึงต้องใช้คำสั่ง Groupby เพื่อ Sum จำนวนข่าวหรือบทวิเคราะห์ที่มีชื่อหุ้นในแต่ละวัน

  • วิธีที่ 5 : สร้าง Features ด้วยการวิเคราะห์ความรู้สึกจากข่าว (Sentiment Analysis with NLP)

ในครั้งนี้เราเลือกที่จะใช้องค์ความรู้ Machine Learning จากการเรียนในสัปดาห์ที่ 2–3 มาสร้าง Features เพิ่มเติมด้วย สิ่งที่เราดำเนินการคือ การประมวลผล Sentiment จากข่าวหุ้น ที่ได้จากการทำ Web Scraping เพื่อทำนายว่าข่าวนั้นส่งผลทางบวก หรือส่งผลทางลบต่อหุ้นแต่ละตัว เราเลือกใช้กระบวนการ NLP โดยการสร้าง LSTM Model และความพิเศษจาก Project ในสัปดาห์ที่ 2–3 (สอน AI ให้ทายประเภทหนัง มาดูกันว่าจะแม่นแค่ไหน?) ในครั้งนี้คือ การใช้ PyThaiNLP ซึ่งเป็น library ในการทำ NLP ภาษาไทย ซึ่งเราได้หยิบเฉพาะส่วนที่เป็น การตัดคำ (Tokenizer) มาใช้งาน รวมถึงมีการเพิ่มคำศัพท์เฉพาะทางหุ้น และสถานการณ์ปัจจุบันที่อาจส่งผลต่อหุ้น เมื่อเราได้ sentiment เราจะนำไป mapping กับชื่อหุ้นที่ถูกพูดถึงในเนื้อข่าว และสร้างเป็น features ขึ้นมาครับ

ตัวอย่างผลการประมวล Sentiment จากข่าวที่ได้จากการทำ Web Scraping
ตัวอย่าง Features ใหม่ที่ถูกสร้างขึ้นซึ่งจะเป็นตัวบอกว่ามีข่าวที่เป็นบวกหรือลบกับหุ้นแต่ละตัวในวันนั้นๆ

Source :

A Beginner’s Guide on Sentiment Analysis with RNN

Deep Learning LSTM for Sentiment Analysis in Tensorflow with Keras API

Python ตัดคำภาษาไทย ด้วย PyThaiNLP API ตัดคำ Word Tokenize ภาษาไทย ตัวอย่างการตัดคำภาษาไทย อัลกอริทึม deepcut, newmm, longest, pyicu, attacut — PyThaiNLP ep.2

  • วิธีที่ 6 : การ Rolling ข้อมูลบาง Features ที่ Effect ของมันอาจจะไม่ได้มีผลกับราคาหุ้นในวันเดียวกัน

กลุ่มของเรามองว่าข้อมูลบาง Features เช่น ข่าวหุ้น, บทวิเคราะห์ของ Broker, วันประชุมคณะกรรมการนโยบายทางการเงินของไทย (กนง.) หรือ วันประชุมของ Fed (เพื่อกำหนดนโยบาย QE และ ดอกเบี้ยนโยบายของสหรัฐ) อาจจะไม่ได้มีผลกระทบกับราคาหุ้นในวันนั้นทันที แต่อาจจะมีผลกับราคาหุ้นในวันถัดๆ ไป หรือ อาจจะมีผลกับราคาหุ้นล่วงหน้ามาแล้วก็ได้ (ตามการณ์คาดการณ์ของนักลงทุนหรือนักวิเคราะห์) ดังนั้นเราควรสร้างตัวแปรเพื่อทำ Forward Rolling และ Backward Rolling ข้อมูลเหล่านี้บางตัวเพื่อดูผลกระทบกับราคาหุ้นที่อาจจะเกิดขึ้นก่อนหรือหลังวันที่มีเหตุการณ์เกิดขึ้น

ตัวอย่าง Code การสร้าง Forward และ Backward Rolling ก่อนและหลังวันประชุมนโยบายทางการเงิน
  • วิธีที่ 7 : การทำ Feature Scaling เพราะข้อมูลมี Unit กับ ขนาดของตัวเลขแตกต่างกัน

เนื่องจากข้อมูลของเราค่อนหลากหลายและมีหน่วยที่แตกต่างกันออกไป รวมทั้งยังมีขนาดของตัวเลขที่ต่างกันออกไปด้วย เช่น ข้อมูลที่เป็น Dummy Features ก็เป็นแค่ข้อมูลในหน่วย 0–1, ดัชนีราคาสินค้าต่างๆ อาจจะอยู่ในช่วงหลักร้อย, ดัชนี้ตลาดหุ้นต่างๆ อาจจะอยู่ในช่วงหลักร้อย หลักพัน หรือหลักหมื่น, หรือมูลค่าการซื้อขายหุ้นโดยนักลงทุนกลุ่มต่างๆ ก็มีตัวเลขที่ใหญ่ถึงขนาดหลักหมื่นล้านในแต่ละวัน

Prediction Model บางอย่าง โดยเฉพาะ Model ที่ใช้ Regression เป็นพื้นฐาน จะมีปัญหากับข้อมูลที่มีขนาดของตัวเลขแตกต่างกันค่อนข้างมาก เพราะ Model จะพยายามให้น้ำหนักความสำคัญกับข้อมูลที่มีขนาดของตัวเลขค่อนข้างใหญ่มากกว่าตัวเลขที่มีขนาดเล็ก เช่น ในกรณีนี้อาจจะเป็น มูลค่าการซื้อขายหุ้นของนักลงทุนในแต่ละวัน ทั้งๆ ที่จริงๆ ตัวแปรนี้อาจจะไม่มีผลอะไรกับราคาหุ้นเลยก็ได้

ดังนั้นเราจึงต้องใช้เทคนิค Feature Scaling หรือการปรับขนาดของตัวเลขของตัวแปรทุกตัว ให้มาอยู่ในระดับที่ใกล้เคียงกัน เพื่อเพิ่มประสิทธิ์การทำนายของ Model ทำให้เราสามารถเปรียบเทียบค่าความสำคัญของแต่ละข้อมูลได้ง่ายขึ้น และยังช่วยทำให้ Model ประมวลผลได้เร็วขึ้นด้วย ซึ่ง Feature Scaling ก็มีด้วยกันหลายเทคนิค เช่น Mean normalization, Standardization, Scaling to unit length และ Min-Max normalization

สำหรับโปรเจคนี้กลุ่มของเราเลือกใช้ เทคนิค Min-Max Normalization เพราะเป็นเทคนิคที่เข้าใจง่ายและไม่ยุ่งยากซับซ้อนในการใช้งาน โดยเราจะแปลงข้อมูลแต่ละ Feature ให้อยู่ในรูป 0–1 เมื่อ 0 คือค่า Minimum และ 1 คือค่า Maximum ของแต่ละข้อมูล ตามสูตรนี้ครับ

สูตร Min-Max Scaling Source : https://www.glurgeek.com/education/feature-scaling/
ตัวอย่าง Code การทำ Min-Max Scaling

Step 4. Prediction model(s) คุยกันเรื่องการสร้าง model (s)

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

ขอเรียงลำดับตามความง่ายไปจนถึงยากนะครับ โดยเริ่มจากสองโมเดลยอดฮิตที่สอนในห้องเรียน คือ Regression และ Time Series ซึ่งน้อง ๆ ในทีมก็ฝึกฝนกัน รันตามที่ อ.ฮง และ อ.วิน สอน อาจจะได้ผลออกมาดีบ้างไม่ดีบ้าง

ในอีกด้านนึง เราก็มีการทดลองโมเดล ARIMA และ มีการใช้ package สำเร็จรูป ที่ชื่อว่า Prophet ซึ่งเป็น Time-series Forecasting จาก Facebook ด้วยครับ โดย Prophet จะสามารถสร้างโมเดลจำลองได้อย่างรวดเร็ว ทั้งการทำ Additive Regression Model และถ้าแบบ advance จริงๆก็เพิ่ม Regressors หรือทำ Hyperparameters ได้อีก ผลคร่าวๆของ Model ก็ตามรูปข้างล่างเลยครับ

ตัวอย่างการรับ Stock Price โดยใช้ Prophet Forecasting

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

จากรูปจะพบว่าเราเลือกใช้ LSTM หรือ Long Short-Term Memory คือการสร้างแบบจำลองเหมือนความจำของคน (Memory) ที่มีความจำอยู่น้อยนิด และมักจะลืมสิ่งที่เก่า ๆ หรือไม่ค่อยสำคัญออกไปบ้างมาเป็น Model ในการทำนายผล โดย LSTM ก็เหมือนกัน จะเน้นรับความทรงจำที่มีผล หรือมีความสำคัญเท่านั้น โดยเหตุการณ์ใหม่ ๆ ที่เข้ามา ที่ไม่สำคัญก็อาจจะไม่ได้เอามาใช้กับการทำนายก็ได้ เช่น ราคาทองที่มีขึ้นหรือลง อาจจะไม่มีผลกับราคาหุ้นของ รพ.กรุงเทพก็ได้ เพราะฉะนั้น โมเดลก็ไม่ต้องจำราคาทอง เมื่อจะพยากรณ์ราคาหุ้น รพ.กรุงเทพ เป็นต้น โดย LSTM เป็น Deep learning ในตระกูลของ RNN ( Recurrent Neural Network) ที่เน้นการเชื่อมต่อของข้อมูลที่เป็น Temporal Sequence หรือ เวลากับหุ้นนั้นเอง

และเนื่องจากเราได้สรรค์สร้าง Features เยอะมากจึงจำเป็นจะต้องดำเนินการทำ Features Selection โดยใช้เทคนิค Granger causality Testing ซึ่งเป็น การทดสอบ ความสัมพันธ์ ระหว่างตัวแปร x กับ y โดยเน้นประยุกต์ใช้กับข้อมูลอนุกรมเวลา การทดสอบนี้แนวคิดของ Granger ที่ต้องเปรียบเทียบของสองอนุกรมเวลา เช่น ราคาน้ำมัน กับ หุ้น ปตท และดูว่ามีความสัมพันธ์กันไหม

หลังจากที่เล่ามานาน ก็มาถึงพระเอกของโปรเจคนี้ครับ คือการนำ ทั้ง GC + LSTM หรือ เราเรียกว่า GCLSTM ครับ ซึ่งสามารถเข้าใจกระบวนทำงานได้แบบง่ายๆตามรูปเลยครับ

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

Time Series Forecasting: ARIMA vs LSTM vs PROPHET

การใช้ Granger Causality Test กับหุ้นไทย

การใช้ Granger Causality Test กับตลาดเอเชีย

Step 5. Test Model & Model Evaluation

สำหรับการรันโมเดลต่าง ๆ มีการ Test และ Evaluate โมเดลอยู่หลายรอบ ซึ่งจะแบ่งเป็นสองส่วน คือ การทดสอบแต่ละโมเดล เพื่อให้ได้ Parameter ที่ดีที่สุดของแต่ละโมเดล และเลือกเฉพาะโมเดลที่ดีที่สุดมาสู่ขั้นตอนการแนะนำหุ้นครับ

Regression & Time Series

สำหรับโปรเจคนี้ ขอไม่กล่าวถึงโมเดล Regression หรือ Time Series นะครับ เพราะรายละเอียดน่าจะอยู่ในทฤษฎีที่ อ.วิน สอนไปแล้ว จะขอข้ามไปที่การอธิบาย ARIMA ที่ทางทีมนำมาใช้เลยนะครับ

ซึ่งทางทีมได้ทำการวิเคราะห์ ARIMA แบบ Auto.ARIMA ซึ่งจะสามารถทำ Optimum p,d และ q สำหรับ model ได้เลยโดยไม่ต้องทำ Optimization แบบ Manual เพราะฉนั้น โมเดลนี้จะเป็น Model สุดท้ายของฝั่ง Autoregressive นะครับ (ตรงกันข้ามกับ Facebook Prophet ที่ใช้ Additive Regression) อ่านแล้วอย่าเพิ่งงงนะครับ เอาเป็นว่ามันต่างกันก็แล้วกัน ^^

Auto.ARIMA

มาถึงการทดลองของ Auto.ARIMA กันเลยครับ ทางทีมได้มีการทดลองในรอบแรก คือใส่ตัวแปรที่มีระยะเวลาที่ยาว หรือข้อมูล 10 ปีเข้าไปในโมเดลเลย และในที่นี้เราจะเรียกว่า Long period นะครับ(10 ปี = Jan 2010 — Sep 2020) นะครับ

ต่อมาด้วยสมมติฐานเกี่ยวกับพฤติกรรมของนักลงทุนที่อาจจะเปลี่ยนไปหลังจากตลาดหุ้นของไทยเปลี่ยนจากขาขึ้นมาเป็นขาลง เราก็ลดระยะลงเหลือ 3 ปี (Aug 2017 — Aug 2020), 2 ปี (Aug 2018 — Aug 2020), 20 เดือน (Jan 2019 — Sep 2020) และทดสอบในโมเดลเดียวกันอีกที (จริงๆ ต้องเรียกว่า multiple cycles ด้วย ^^)

โดยในขั้นตอนการรัน Model นี้เราจะต้องเลือกหุ้นมาหนึ่งตัวเพื่อมาทดลอง Model ก่อน เราตัดสินใจเลือกหุ้น ADVANC เพราะเป็นหุ้นที่ราคาเกิน 100 บาท พวกเราไม่สามารถซื้อได้ จะได้เป็นการไม่ Bias ตอนต้องมาเลือกหุ้นตัวใดตัวหนึ่งเพื่อซื้อทีหลังครับ

ผลของการรัน auto.ARIMA แบบ Long period vs Short period ได้ผลดังนี้ครับ

หลังจากที่เราได้ทดลอง Auto.ARIMA Model ของเรากับหุ้น ADVANCE สำหรับทั้งสองช่วงเวลา เราพบว่าค่า RMSE (ยิ่งน้อยยิ่งดี) ของ Short period สามารถพยากรณ์ได้ดีกว่า Long period พวกเราเลยคิดว่า สำหรับการ Train Model ในขั้นตอนถัดๆ ไป พวกเราก็ควรจะใช้ Short Period (Jan 2019 — Sep 2020) ต่อไป

โดย RMSE ย่อมาจาก “Root Mean Square Error” ซึ่งเป็นการถอดรูทของค่า Mean Square Error (MSE) เพื่อให้ค่า Loss ที่ได้จาก Prediction Regression Model มีหน่วยเดียวกับตัวแปรที่กำลังถูกทำนาย (MSE อยู่ในรูปยกกำลังสอง ทำให้ยากต่อการเปรียบเทียบ)

สูตรที่ใช้ในการคำนวณค่า RMSE
สูตรที่ใช้ในการคำนวณค่า RMSE

เหตุผลที่กลุ่มเราเลือก RMSE มาเป็น Measurement Metrics เพราะเป็น เมทริกซ์ที่สามารถแปลผลได้ง่าย สำหรับ Regression Model โดยสมมติ RMSE = 3.73 จะแปลว่า โดยเฉลี่ยโมเดลจะทำนายค่าสิ่งที่เรากำลังทำนายผิดไปประมาณ +/- 3.73 units (หน่วยเดียวกับตัวแปลที่กำลังทำนาย)

แปลว่าค่า RMSE นั้นยิ่งต่ำยิ่งดี โดยถ้าค่า RMSE = 0 จะหมายถึง Model นั้นทำนายค่าได้ถูกต้อง 100% ในทางปฏิบัติโอกาสที่จะเทรนโมเดลได้ loss = 0 เป็นไปได้ยากมาก เพราะอาจนำไปสู่ปัญหา Overfitted ได้

Source : อธิบาย 10 Metrics พื้นฐานสำหรับวัดผลโมเดล Machine Learning

Multivariate Multi-step LSTM

สำหรับการรัน LSTM ของทีมเราเป็นการรันแบบหลายตัวแปร หรือที่เรียกว่า Multivariate และยังเพิ่มการพยากรณ์ในอนาคต ไม่ใช่แค่ 1 วันแต่เป็นถึง 9 วันถัดไปอีกด้วย หรือ ในทางเทคนิค เค้าเรียกกันว่า Multivariate Multiple-step LSTM ครับ แต่เนื่องจากหุ้นแต่ละตัวมีความสัมพันธ์กับ Features ที่แตกต่างกัน เราจึงพยายามใช้ Granger Causality Testing เข้ามาช่วยในการเลือก Features ที่มีความสัมพันธ์สูงกับราคาหุ้นแต่ละตัว

การทำ Granger Causality Testing

การทดลองหาความสัมพันธ์ด้วย Granger Causality Testing ทางทีมก็จะนำ features ทั้งหมดมาทดสอบกับหุ้นแต่หละตัว โดย features ที่มีค่า p-value น้อยกว่า 0.05 แสดงว่า Feature นั้นมีผลต่อราคาหุ้น หรือ แสดงได้ดังรูปครับ

ตัวอย่างการรัน Granger Causality Testing ของทุก Features กับหุ้นบางตัวใน SET100

เนื่องด้วยเวลาที่จำกัด เพราะทีมของเราตัดสินใจรอข้อมูลของวันที่ 15 กันจนนาทีสุดท้าย เราเลยเหลือเวลาไม่มากนักสำหรับการรัน Granger Causality Testing ซึ่งเราก็พึ่งค้นพบว่าการรันหุ้น 1 ตัวใช้เวลาพอสมควร ซึ่งยังไม่นับการรัน Multivariate Multi-step LSTM จากข้อมูลที่ได้มาด้วย

เราจึงตัดสินใจว่าจะต้องเลือกหุ้นมาจำนวนหนึ่งด้วยวิธีการบางอย่าง และรัน GCT แค่เฉพาะหุ้นกลุ่มนี้ สุดท้ายพวกเราก็ตัดสินใจรันโมเดลที่ใช้เวลาไม่นาน อย่าง Prophet เพื่อสกรีนหุ้นที่มี %Growth สูงสุดในช่วง 5 วันข้างหน้า (T+7) มาจำนวน 15 หุ้น แล้วรัน GCT แค่เฉพาะ 15 หุ้นนั้น แต่ว่าจากหุ้น 15 ตัวกลับมีหุ้นที่ราคาเกิน 100 บาทอยู่ 3 ตัว เลยเหลือหุ้นมาให้เราทดลองรัน GCT แค่ 12 หุ้นครับ

และพวกเราได้กำหนดให้ Granger Causality Testing เลือก Features โดยการเรียงลำดับตามค่า P-Value แล้วเลือกแนะนำ Features ที่ดีที่สุดสำหรับหุ้นแต่ละตัว มาจำนวน 20 Features ครับ

สำหรับ 20 Features ที่ดีที่สุดของแต่ละหุ้นที่ GCT แนะนำให้ใช้สามารถดูได้จากตารางด้านล่างนี้นะครับ

เมื่อได้ Features ที่ดีที่สุดสำหรับหุ้นแต่ละตัวออกมาแล้ว เราจึงนำ Feature นั้นมาเป็น Input เพื่อรัน MM.LSTM Model แยกกันตามหุ้นแต่ละตัว ตาม Process ดังตัวอย่างในรูปด้านล่างครับ

ผลของการรัน MM.LSTM เปรียบเทียบกับ Model ที่เคยรันไปก่อนหน้าได้ผลดังนี้ครับ

จะได้ว่าผลที่ได้จาก Multivariate Multi-step LSTM (MM.LSTM) ในช่วงเวลาเดียวกัน นั้นมีค่า RMSE ต่ำกว่า Auto.ARIMA อยู่เล็กน้อย พวกเราจึงเลือกใช้ MM.LSTM ร่วมกับวิธีการเลือก Feature ที่สำคัญด้วยวิธี Granger Causality Testing ไปใช้เป็น Model หลักในการทำนายราคาหุ้นใน SET100 สำหรับโปรเจคนี้ของเรา

ราคาปิดตลาด (Close) ของหุ้น ADVANC เปรียบเทียบระหว่างราคาจริง และราคาที่ถูกทำนายด้วย LSTM Model (Short Period)

Summary & Interesting Findings

หลายคนคงรอบทสรุปจากการทดลองของกลุ่มเราว่า เราแนะนำให้ซื้อหุ้นตัวไหน แต่ก่อนจะไปถึงจุดนั้นขอทบทวนแนวทางที่คนส่วนใหญ่ใช้ในการตัดสินใจซื้อหุ้น ไม่ว่าจะเป็นแนว VI (Value Investment) หรือ แนวเทคนิค (Technical Analysis) ถ้าได้อ่านบทความของพวกเราตั้งแต่ต้นจนจบก็จะพบว่า สิ่งที่เราพยายามทำคือ การผสานแนวคิดทั้งสองแนวไว้ด้วยกัน โดยใช้เทคนิคอย่าง Machine Learning เข้ามาช่วยตัดสินใจ

ผลการทดลองของเราพบว่า MM.LSTM เป็น Model ที่มีค่า RMSE ที่ดีที่สุด และเมื่อนำมาใช้ในการทำนายผลทำให้เราได้หุ้นเด่นที่น่าสนใจดังตารางด้านล่างนี้

ตัวอย่างราคาของหุ้นที่ถูกเลือกจาก Prophet Model ที่พวกเรานำมาทดลองรันด้วย MM.LSTM ครับ

จริงๆ แล้วถ้าดู %Growth ที่ได้จากการซื้อหุ้นในราคาที่คาดการณ์ ในวันที่ 17 กันยายน (T+2) แล้วขายในวันที่ 24 กันยายน (T+7) หุ้นที่คาดว่าจะมี %Growth สูงสุด คือ ‘STA’ (16.25%)

อย่างไรก็ตาม High Return ก็มักจะมาคู่กับ High Risk เมื่อเราลองพิจารณาค่า Standard Deviation ของราคาคาดการณ์หุ้นทุกตัว เฉลี่ยในช่วง 7 วัน จะพบว่า ‘STA’ ก็มีค่า Standard Deviation สูงมากที่สุดเช่นกัน แปลง่ายๆ ได้ว่า หุ้นตัวนี้มีความผันผวนหรือความเสี่ยงสูงมากที่สุด

Note : Standard Deviation ส่วนเบี่ยงเบนมาตรฐาน วัดความผันผวนของราคา

High Risk, High Return ??

เนื่องจากพวกกลุ่มของพวกเราเป็นคนที่ค่อนข้างขี้กลัว ไม่ค่อยกล้ากับอะไรเสี่ยงๆ พวกเราเลยขอเลือกหุ้นที่ให้ผลตอบแทนเป็นบวก และมีความผันผวนของราคาที่ได้จากการทำนายค่อนข้างต่ำ อย่าง ‘CKP’ ดีกว่า นอกจากนี้ ‘CKP’ ยังเป็นหุ้นที่มีค่า Average Price / Stdev. (อัตราส่วนผลตอบแทนต่อความเสี่ยง) สำหรับราคาทำนายใน 7 วันข้างหน้าสูงที่สุดด้วย

นอกจาก ‘CKP’ แล้ว ถ้าพิจารณาค่า Average Price / Stdev. ก็ยังมีหุ้นอีกตัวหนึ่งที่ค่อนข้างน่าสนใจ คือ ‘HANA’ แต่แน่นอนครับถ้าคุณเป็นผู้รักความเสี่ยง ถือคติ High Risk, High Return เราก็ขอแนะนำให้คุณเลือก ‘STA’ โดยไม่ต้องลังเลครับ

แต่กลุ่มเราก็ต้องแอบยอมรับครับว่า ในขั้นตอนการเลือกหุ้นที่เราจะซื้อในจังหวะสุดท้าย ก่อนที่จะฟันธงออกมาเป็น ‘CKP’ เราก็ยังต้องแอบไปกระซิบถามกลุ่มคนที่เล่นหุ้นอยู่จริงๆ ว่าจากลิสต์และข้อมูลราคาคาดการณ์ของหุ้นที่เรามี ถ้าเป็นเค้า เค้าจะเลือกซื้อหุ้นตัวไหนบ้าง เป็นตัวเดียวกับที่พวกเราเล็งๆ ไว้หรือไม่

เพราะสุดท้ายแล้ว กระบวนการเลือกหุ้นในครั้งนี้ของพวกเรา ก็คงเหมือนกับ Concept พื้นฐานของ Data Science ที่จะต้องประกอบขึ้นมาจากความรู้และความเข้าใจใน 3 ส่วน คือ Computer Science, Maths & Statistics และ Domains & Business Knowledge

มีอะไรที่เราอยากลองทำ แต่ยังไม่ได้ทำบ้าง

นอกเหนือจาก Features ต่าง ๆ ที่เราได้เลือกมาใส่ใน Model หรือ Feature Engineering เทคนิคต่าง ๆ ที่เราทำไปแล้ว กลุ่มของเรายังมีความคิดที่จะลองสร้าง Features เพื่อนำมาใช้ทำนายราคาหุ้นเพิ่มเติมอีกครับ แต่ด้วยข้อจำกัดด้านเวลาและ Skill ในตอนนี้ ก็เลยยังไม่ได้ทำพวก Features เหล่านี้ เช่น

  • ทำ Web Scraping เพื่อรวบรวมข้อมูลการพูดถึงหุ้นต่าง ๆ จากเว็บไซต์ที่มีความเป็น Webboard ที่พูดคุยในเรื่องหุ้น เช่น ห้องสินธรใน Pantip.com หรือใน FB Group ต่าง ๆ ในเรื่องหุ้น เพื่อดูว่าถ้ามีคนเริ่มพูดถึงหุ้นนี้เพิ่มขึ้นในพื้นที่สาธารณะเหล่านี้ จะส่งผลให้หุ้นขึ้นหรือลงต่อไปหรือไม่
  • การนับจำนวนวันที่หุ้นแต่ละตัวขึ้นหรือลงติดต่อกัน แล้วอาจจะหาค่าเฉลี่ยหรือนำข้อมูลนี้มาทำเป็น Level แล้วเพิ่มเป็นอีกหนึ่ง Feature เพราะบางครั้งหุ้นอาจจะเกี่ยวข้องกับจิตวิทยาว่าถ้าหุ้นขึ้นติดต่อกันเกินกี่วันจะมีคนเริ่มขายทำกำไร หรือถ้าหุ้นลงต่อเนื่องกันเกินกี่วัน จะมีคนเริ่มคิดว่าราคาลงมาเพียงพอที่จะเข้าซื้ออีกครั้ง
  • นอกจากนี้การนับจำนวนว่าราคาขึ้นหรือลงติดต่อกันกี่วัน อาจจะนำไปประยุกต์ใช้กับราคาหรือดัชนีของตัวแปรอื่นๆ ไม่เฉพาะแค่ราคาหุ้นเท่านั้น
  • เราอาจจะต้องลองศึกษาเกี่ยวกับ Technical Analysis ให้มากขึ้น เพื่อให้สามารถนำเส้นเทรนด์ หรือ Indicator ต่างๆ จาก Technical Analysis มาใช้ได้หลากหลายรูปแบบมากยิ่งขึ้น เช่น ไม่ใส่ค่าของ Indicator ต่างๆ ไปเป็น Feature เลยโดดๆ แต่อาจจะคำนวณหาระยะค่า Gap ระหว่าง Indicator ต่างๆ เพิ่มเข้าไป เช่น นำ GAP = EMA75 — EMA20 เป็นต้น
  • พวกเราอยากลองทำให้ Process การรวบรวม Data เป็น Automatic มากขึ้น เช่น เว็บไซต์ไหนที่มี API อยู่แล้วก็อยากจะลองใช้ให้ได้ แล้วก็พยายามลดขั้นตอนที่เป็น Manual ให้มากที่สุด เพราะพวกนักลงทุนตัวจริงคงไม่สามารถเสียเวลาวันละหลายชั่วโมงในการหาข้อมูลแบบเราได้
  • นอกจากนี้ พวกเราอาจต้องพยายามหาวิธีลดเวลาในขั้นตอน Granger Causality Testing เพื่อให้สามารถรันโมเดลนี้กับหุ้นจำนวนมากๆ ได้ภายในระยะเวลาที่สั้นลง เพื่อให้เหมาะสมกับการนำไปใช้งานด้านการลงทุนจริงๆ

Related Colab :

Data to Merge (StockInfo, GeneralData, GGTrend, Broker)

Stock News from Web Scraping and Sentiment Analysis

Index and Commodities by InvestPy Library

Merge All DataSet

Prediction Model for SET100

--

--