หุ้นไทยใช้ SMA Crossover คู่ไหนโหดสุด พาไปหาคำตอบด้วยโค้ด Python 3 บรรทัด!!

TongTanapat
4 min readSep 4, 2020

--

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

เป็นปัญหาถกเถียงกันมานาน เรื่องเส้นสายไฟที่พันกันมั่วในบ้านเรา …. ล้อเล่นครับ มา เอาใหม่ครับ

เป็นปัญหาที่เทรดเดอร์หรือนักลงทุนเถียงกันมานานนนนนนน ตั้งแต่สมัยผมเป็น Marketing พานักลงทุนซื้อขายหุ้นเมื่อหลายปีที่ผ่านมา ต้องบอกว่า เนื่องจากการนำเส้นค่าเฉลี่ยมาใช้เป็นตัวประกอบการตัดสินใจนั้น มีที่มาที่ไปจากการทำความเข้าใจกับตัว Indicator ประเภทนี้ได้ไม่ยากนัก เพียงนำค่าเฉลี่ยย้อนหลังตามจำนวนวันที่กำหนดมาพลอตเทียบคู่กันดู (Overlaping Indicator) ก็สามารถเห็นภาพและชี้นำจิตใจเราได้ง่าย เห็นได้ชัดเลยว่าราคาปัจจุบัน สูงหรือต่ำกว่าค่าเฉลี่ย X วัน ก่อนที่จะถูกนำมาใช้ในการตัดสินใจเข้าเป็นจุดซื้อขาย เริ่มจากการนำเพียงเส้นเดียวเข้ามาใช้กับราคาปัจจุบัน ก็มีการสร้างเส้น Fast ขึ้นมาใช้กับเส้น Slow เช่น เส้น 5 วัน กับเส้น 50 วัน (SMA Crossover) แต่จากที่ทำงานมาหรือจากงานวิจัยด้านการลงทุน โดยมากแล้วตามกลุ่มนักลงทุนสถาบันมักนิยมใช้เส้น 200 เพื่อดูภาพของเทรนด์ขนาดใหญ่มากกว่า และไม่ได้ใช้ในการตัดสินใจเข้าซื้อหรือขาย แต่จะถูกนำไปใช้เพื่อกำหนดช่วงของ Risk มากกว่า เช่นถูกนำไปใช้เป็น Metric ที่ใช้ในการตัดสินว่า ขณะนี้ ตลาดอยู่ในช่วง Risk On หรือ Risk Off เพื่อกำหนด Position กันอีกที

แต่เนื่องจากมันเป็น Indicator ที่ดูง่าย และหลายคนก็บอกว่าใช้แล้วประสบความสำเร็จ บางคนบอกว่าแม่น บางคนบอกไม่เวิร์ค แล้วถ้ามันเวิร์ค มันน่าจะต้องมีสักเส้นที่เราหาเจอสิ แต่ถ้าจะให้ลองดูทีละเส้นสองเส้นเพื่อทดสอบเอง หรือเขียนโค้ดไล่ Logic แล้วยังต้องเขียนโค้ดเพื่อใช้วัดผลอีก ถ้าฟังแบบนี้ มือใหม่อาจขอ Say no แล้วถ้ามันยากแบบนั้น ก็มีแต่คนเขียนโค้ดเก่ง ๆ ทำได้สิ…

แต่วันนี้ ปัญหาเหล่านั้นจะหมดไป เพียงแค่คุณรู้จักกับ Library

FastQuant

กับ Slogan เท่ห์ ๆ ที่ว่า

“Bringing backtesting to the mainstream”

ต้องขอบคุณเจ้าของ Repo นี้ที่สร้างเจ้า Fastquant ขึ้นมา เค้าอาจเข้าใจหัวอกเทรดเดอร์อย่างเรา ๆ แล้วก็อยากรู้จนสร้าง Library นี้ขึ้นมา แล้วยังใจดีเผื่อแผ่ให้กับเพื่อน ๆ ชาว Dev อีกด้วย รู้อย่างนั้นแล้ว ผมจะเก็บไว้ใช้คนเดียวทำไม เค้าก็อยากทำให้ Backtest มัน Mainstream ผมเองก็อยากทำ Quant ให้ Pop วันนี้เลยมาสอนทำกันในเวอร์ชั่นภาษาไทยให้ทุกคนได้ลองใช้กันเลยครับ และนี่คือคำอธิบายสั้น ๆ เกี่ยวกับ Library นี้จากเจ้าของครับ

Fastquant allows you to easily backtest investment strategies with as few as 3 lines of python code. Its goal is to promote data driven investments by making quantitative analysis in finance accessible to everyone.

แปลง่าย ๆ ว่า Fastquant จะทำให้คุณทำ Backtest กลยุทธ์ได้ด้วย Python เพียง 3 บรรทัดเท่านั้น ที่ทำไปทั้งหมดก็เพราะอยากให้ทุกคนเข้าถึงการทำ Quant analysis ได้อย่างทั่วถึงนั่นเอง

เดี๋ยวผมจะพาไปเห็น Code 3 บรรทัดนั้นกัน

results = backtest("smac", df,                          # 1
fast_period=fast_periods, # 2
slow_period=slow_periods) # 3

แต่เวลาผมเขียนใช้งาน ผมเขียนในรูปแบบนี้นะ

results = backtest("smac", 
df,
fast_period=fast_periods,
slow_period=slow_periods,
verbose=False,
plot=False
)

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

อย่างที่หลาย ๆ คนน่าจะทราบกันดีครับ ว่ากว่าจะมาเขียน 3 บรรทัดนั้นได้ ขั้นตอนแรกที่เราขาดไม่ได้คือการตัดตั้ง Library กันก่อน แล้วผ่านการเรียกข้อมูล จัดการ Data และสร้างตัวแปรต่าง ๆ ก่อน กว่าจะถึงขั้นตอน Fastquant กันได้ แต่ไม่เป็นไรครับ วันนี้ทุกท่านจะสามารถนำไปทดสอบได้เลย ผมจะพาดึงข้อมูลจาก Yahoo กันด้วยเลย เนื่องจาก yahoo เองก็มีข้อมูลหุ้นไทยให้ทดสอบกันครับ จะได้ไม่ต้องหาข้อมูลกันยาก

อันดับแรก ติดตั้ง Library ที่จำเป็นครับ

!pip install fastquant

จบแล้วครับ จริง ๆ ความว้าวอีกอย่างหนึ่งของ Library ตัวนี้คือ เค้าผูกกับตัว Library อื่น ๆ ที่จำเป็นไว้ให้อยู่แล้วด้วยครับ ทั้ง Backtest, Yahoofinance และตัวที่ใช้ในการแสดงผลภาพออกมาไว้ให้แล้วด้วย ดังนั้น เมื่อติดตั้งตัวนี้แล้ว แทบไม่ต้องลงอะไรเพิ่มเลยครับ

*** เว้นแต่ว่าหากระหว่างติดตั้งแล้วแจ้ง Error ว่าไม่มี Lib ตัวไหน ก็ติดตั้งเพิ่มเติมได้เลยครับ แต่ของผมไม่เจอปัญหานี้ เพราะลงมาหลายตัวแล้วครับ 555

หลังจากรอสักพักใหญ่ ๆ เมื่อติดตั้งเรียบร้อยแล้ว เราก็มาลองเรียกข้อมูลดูครับ ถ้าใครเคยใช้ Yfinance มาก่อน ก็จะคุ้นกับ Syntax เป็นอย่างดีแน่นอนครับ

from fastquant import get_stock_data  
# เลือกใช้ Function get_stock_dataเพื่อดึงราคาหุ้น
df = get_stock_data("PTT.BK", "2015-01-01", "2020-08-30")
# ตั้งตัวแปรชื่อ df เพื่อเก็บข้อมูลหุ้นที่เราเรียก โดยกำหนดช่วงระยะเวลาที่ต้องการ
print(df.head())
# แสดงผลเฉพาะข้อมูล 5 แถวแรกของข้อมูล

ผลลัพธ์ที่ได้จากการที่ผมเรียกข้อมูลหุ้น PTT จากช่วงระยะเวลา 2015 ถึง เดือนสิงหาคมที่ผ่านมาจะได้ภาพแบบนี้ครับ

เราได้ข้อมูลหุ้นไทยแล้ว หลายคนมาถึงขั้นนี้คงตื่นเต้นแล้ว วิธีก็ง่าย ๆ ครับ พิมพ์ชื่อหุ้นไทย ตามด้วย “.BK” เราก็จะได้หุ้นไทยมาแล้วครับ แต่ก็อาจมีปัญหากับบางตัว และราคาที่คลาดเคลื่อนไปบ้าง เนื่องจาก Yfinance จะมีการปรับราคาปิดตาม Algo ของตัว library เองครับ ดังนั้น เพื่อความมั่นใจอีกที หากหาข้อมูลที่น่าเชื่อได้มากกว่า ก็แนะนำให้ใช้ข้อมูลจากแหล่งนั้นครับ

ต่อมา ลองมาทดสอบสมมติฐานของเรากันดูก่อนครับ หากผมเชื่อว่าเส้น SMA 5 ตัดเส้น 50 ขึ้นแล้วผมซื้อ กลับกัน ถ้าเส้น 5 ตัดเส้น 50 ลงแล้วผมขาย กลยุทธ์นี้จะให้ผลตอบแทนผมดีมั้ย จากโค้ดด้านล่างเลยครับ

*** เพิ่มเติม : กลยุทธ์จากโค้ด Defualt จะทดสอบด้วยเงิน 100,000 และหักค่าคอม 0.0075 และการซื้อขายกำหนดโดยเส้นสั้นตัดเส้นยาวขึ้น = Buy, และเส้นสั้นตัดเส้นยาวลง = Sell แบบนี้ไปเรื่อย ๆ ตลอดช่วงระยะเวลาข้อมูลเราครับ

ทดสอบเส้นในใจของเราง่าย ๆ ได้แบบนี้ครับ

from fastquant import backtest  
# เรียกใช้งานฟังก์ Backtest
backtest('smac', df, fast_period=5, slow_period=50)
# จากตัว Backtest กำหนดตัวแปรลงไป
# จากภาพ 'smac' = กลยุทธ์ Simple Moving Average Crossover
# df = ข้อมูลหุ้นที่เรากำหนดไว้ตอนเรียกก่อนหน้า
# fast_period = เส้น SMA เส้นสั้น ผมกำหนดไว้ที่ 5 วัน
# slow_period = เส้น SMA เส้นยาว ผมกำหนดไว้ที่ 50 วัน

ผลลัพธ์ที่ได้ จะมีออกมาให้ดู 2 ส่วนหลัก ๆ ครับ

Backtest PTT : SMA 5 > 50

ส่วนแรกคือ Detail ที่บอกมูลค่าเงินต้น จำนวนไม้ที่ซื้อ ค่าคอมมิชชั่น วันที่ทำการเข้าซื้อ ขายออก และจำนวนกำไรแต่ละครั้งที่เข้าซื้อขายครับ

ละเอียดมากกกกกก เพียง 2 บรรทัดก็ทำได้ขนาดนี้เลยทีเดียว มาดูอีกส่วนสำคัญที่เหลือครับ

Visualisation แบบ Interactive จาก Plotly
  1. จากภาพหากดูจากแถบด้านบนสุดที่มีสีน้ำเงิน คือช่วงที่มีการเข้าซื้อตามกลุยทธ์และแสดงการเติบโตของผลกำไรหรือขาดทุน
  2. จุดน้ำเงิน และแดง = หากเข้าแล้วมีกำไรในไม้นั้น จะแสดงจุดสีน้ำเงินตรงจุดที่ทำการขายออก กลับกัน จุดสีแดงคือเข้าแล้วขาดทุนไม้นั้นครับ
  3. กราฟราคาพร้อมเส้น SMA และมีลูกศรบอกจุดเข้า-ออกกันแบบไม้ต่อไม้
  4. ค่า 1 และ -1 = 1หมายถึง ซื้อ และ -1 คือการขายออกครับ

และบรรทัดสุดท้าย ยังบอกผลตอบแทนกับค่า Sharpe ratio กับเราอีกด้วย

เป็นยังไงครับ ง่าย ครบ จบที่เดียวกันไปเลย

และวัตถุประสงค์ของ Fastquant ก็ไม่ได้ให้เรามาใช้งานกันแค่นี้ มาต่อกันที่การ Optimize หาสองเส้นพิชิต PTT กันเลย

fast_periods = np.arange(5,21,1, dtype=int)
slow_periods = np.arange(60,201,5, dtype=int)

จากโค้ดด้านบน ผมสร้างตัวแปร fast_periods โดยที่เติม “s” เพราะผมได้ใส่ค่า SMA ระยะสั้นเข้าไปเยอะมาก โดยเริ่มจากเส้น 5 วัน ไปจนถึง 20 วัน และเพิ่มไปทีละ 1 วัน และกำหนดให้ประเภทของข้อมูลเป็นเลขจำนวนเต็ม “int” ครับ

กลับกันเช่นเคย slow_periods ก็คือเส้นระยะยาวที่ผมต้องการนำมาทดสอบครับ เริ่มจากเส้น 60 วัน ไปจนถึงเส้น 200 และเพิ่มไปทีละ 5 ครับ

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

results = backtest("smac", 
df,
fast_period=fast_periods,
slow_period=slow_periods
)

จากนั้นก็รอ ขึ้นอยู่กับความเร็วของเครื่องกับความเยอะของจำนวนตัวแปรที่เราทดสอบครับ

ระหว่างรอก็มีข้อมูลให้เราดูด้วย

เมื่อเสร็จแล้ว โดยดูจากเครื่องหมาย “ * ” หลังคำว่า In หน้าแถบ Code ก็มาลองเรียกดูผลลัพธ์กันได้เลย

results

เราจะได้ตารางที่บอกผลตอบแทนจากทุกเส้นที่เราใส่ไปในการทดสอบได้เลย

จากภาพจะเห็นว่า คู่ของ SMA ที่ให้ผลตอบแทนดีที่สุดคือเส้น……..

เส้น Fast = 12

เส้น Slow = 195

ซึ่งจากช่วงเวลาดังกล่าว การใช้สองเส้นนี้ ให้ผลตอบแทนสูงถึง 44% กันเลยทีเดียว

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

backtest('smac', df, fast_period=12, slow_period=195)

จะได้ภาพนี้ครับ

ผลตอบแทนกลยุทธ์ SMA 12>195 บนราคา PTT

จะเห็นว่ามีการเข้าซื้อทั้งหมด 5 ครั้ง โดยกำไรคำใหญ่ ๆ มาจากช่วงแรก ๆ ของสัญญาณ ซึ่งเป็นช่วงขาขึ้นของกราฟ PTT รอบใหญ่ก็ว่าได้

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

แต่มุมกลับกัน ผมก็มองว่าสัญญาณนี้ อาจเหมาะกับเทรนด์ขาขึ้นรอบใหญ่ ในขณะที่ช่วงขาลง ถึงแม้จะเทรดพลาด แต่หากดูช่วงที่สัญญาณเข้าซื้อและขายออก ก็เป็นช่วงสั้น ๆ ทำให้มองว่าสามารถจำกัดความเสี่ยงการขาดทุนได้เร็วเช่นกัน แต่ทั้งนี้ทั้งนั้น ก็ขึ้นอยู่กับข้อมูลด้วย ผมเชื่อว่าหากเราใช้ข้อมูลที่ยาวกว่านี้ หรือสั้นกว่านี้ ค่าที่ได้ก็อาจจะเปลี่ยนไป หากปัจจุบันคือช่วงปี 2017 เราทดสอบกันแบบนี้ เชื่อว่า 12 > 195 เราจะเห็นเพียงแค่ภาพกำไรเป็นกอบเป็นกำแน่นอน ฉะนั้นผมก็ไม่อยากให้หลาย ๆ ท่านทำการทดลองแล้วนำไปใช้จริงเพียงแค่บนข้อมูลที่มี เพราะเมื่อนำไปเทรดจริง จะต้องมีเรื่องของตัวแปรอื่น ๆ เข้ามาเกี่ยวข้อง ไม่ว่าจะเป็นค่าคอมมิชชั่น หรือบางท่านนำไปใช้กับ TFEX ก็ยังไม่ได้รวมในส่วนของ Leverage การทดสอบนี้จึงเป็นเพียงการหา Signal เบื้องต้น ก่อนที่จะนำไปใช้จริง จึงควรมีเรื่องการวางแผนความเสี่ยงให้ครอบคลุมกับกลยุทธ์ที่เราใช้เพื่อปกป้องเงินต้นของเรานั่นเอง ซึ่งต่อจากนี้ผมจะอัพโค้ดขึ้น Github ให้ เพื่อที่ทุกท่านจะได้นำไปทดสอบต่อยอดกลยุทธ์ของตัวเอง มีการแบ่งช่วงอัพเทรนด์ ไซด์เวย์ ดาวน์เทรนด์ เพื่อทดสอบแต่ละเส้นแบบเบื้องต้นกันได้ครับ

หวังว่าทุกคนจะชอบนะครับ มาลองเล่นกันเยอะ ๆ ครับ แล้วทำให้ Quant Pop กัน

:)

Cr.ขอบคุณผู้ร่วมอุดมการณ์ท่านนี้เป็นอย่างสูงครับ

Tanapat Kamsaiin : Quantitative Investment Strategist @ Finnomena

--

--