สร้าง Report ผลตอบแทนของระบบเทรดด้วย Pyfolio จากโค้ด 1 บรรทัด

TongTanapat
3 min readAug 22, 2020

--

ไก่งามเพราะขน คนงามเพราะแต่ง การแสดงผลวิเคราะห์จากระบบเทรดก็ควรแสดงภาพให้ดูดีเข้าใจง่าย เช่นกัน

PIX1861 / 1070 images

นักพัฒนาระบบเทรดที่มีความคุ้นเคยกับภาษาอื่น ๆ เช่น MT4, MT5, Amibroker จะคุ้นเคยกับการแสดงผลที่มาพร้อมกับโปรแกรม แต่เมื่อย้ายมา Python กัน คำถามที่มักเจอบ่อย ๆ คือ จะแสดงผลได้ยังไง เพราะเห็นแค่ Print ค่าตัวเลขออกมา Python พอจะมีมาตรฐานในเรื่องการแสดงภาพผลตอบแทนบ้างหรือเปล่า ผมขอลองพาทุกท่านมาทำความรู้จักกับ Pyfolio Library หนึ่งใน Standard Visulization ของชาว Quant กันครับ

ก่อนจะไปรู้จักว่า Pyfolio คืออะไร ผมลองเอาโค้ดในการแสดงผลมาให้ชมกันก่อนครับ

pyfolio.create_full_tear_sheet(portfolio.mean(axis=1))

และเพียง 1 บรรทัดเท่านั้นจริง ๆ

มาลองทำความรู้จักกันก่อนว่า Pyfolio คืออะไร?

https://github.com/quantopian/pyfolio

pyfolio เป็น Python library ที่ใช้ในการวิเคราะห์ผลตอบแทนและความเสี่ยงจากระบบการลงทุน ถูกพัฒนาโดยทีมจาก Quantopian ซึ่งเป็นแพลตฟอร์มการทำ Backtest ชื่อดังอันดับต้น ๆ ของโลก ซึ่งนอกจาก pyfolio แล้วยังมีอีกหลาย library ที่ทาง Quantopian พัฒนาขึ้นมาให้นักพัฒนาระบบที่ใช้ python ได้ทำงานร่วมกันอีกหลายตัวไม่ว่าจะเป็น Zipline, FactSet data, Alphalens เป็นต้น

หัวใจหลักในการทำงานของ pyfolio คือการแสดงผลที่เรียกว่า tear sheet ซึ่งสามารถแสดงผลทั้งผลตอบแทนของระบบเทียบกับ Benchmark แสดงค่า Rolling Drawdown, Average return, Sharpe ratio และอื่น ๆ อีกมาก

มาลองทดสอบกันดูครับ

อันดับแรก เราต้องเรียกข้อมูลมาก่อนครับ

# Yahoo finance to get the data
from pandas_datareader import data
# สร้างกล่องเก็บข้อมูลหุ้นในรูปแบบ Dictionary
stock_data_dictionary = {}
for stock_name in stock_list:

# เรียกข้อมูลหุ้นจาก Yahoo
df = data.get_data_yahoo(stock_name, start_date, end_date)

# สร้างคอลัมผลตอบแทนในรูปแบบการเปลี่ยนแปลงรายวัน เพื่อนำไปคำนวณผลตอบแทน
df['daily_pct_change'] = df['Adj Close'].pct_change()
# ลบข้อมูลที่เป็น NaN ทิ้ง
df = df.dropna()
# เพิ่มข้อมูลลงในกล่องเก็บข้อมูล Dictionary ที่สร้างไว้
stock_data_dictionary.update({stock_name: df})

และต่อจากนั้นก็ตรวจสอบข้อมูลที่เราเรียกมาด้วยการแสดงผล

# กำหนดขนาดของภาพที่ต้องการแสดงผล โดยปกติผมจะใช้ขนาด 10, 7
plt.figure(figsize=(10, 7))
# เข้าถึงข้อมูลหุ้น AAPL ที่อยู่ใน Dictionary และคำนวณผลตอบแทนแสดงเป็นภาพ
(stock_data_dictionary['AAPL'].daily_pct_change+1).cumprod().plot()
# ตั้งชื่อภาพ และชื่อกำหนดแกน y และแสดงผลเป็นเส้นตาราง
plt.title('AAPL Returns')
plt.ylabel('Cumulative Returns')
plt.grid()
plt.show()
ผลตอบแทนแบบ Cumulative Returns ของหุ้น AAPL (Apple)

และเมื่อได้ข้อมูลมาถูกต้องแล้ว ก็มาทำการสร้างกลยุทธ์กันดูครับ

# สร้างกลยุทธ์ที่คำนวณด้วยการนำราคาปิดของวันล่าสุดเทียบกับ 20 วันก่อนหน้า 
# หากมากกว่า ก็ทำการเข้าซื้อ และขายเมื่อต่ำกว่า 20 วันก่อนหน้า
df['signal'] = df['Close'].shift(1) > df['Close'].shift(20)

ต่อมาให้เราทำการคำนวณผลตอบแทนด้วยการนำสัญญาณที่ได้ออกมาจากการคำนวณด้านบนออกมาในรูปของ 0,1 ไปคูณกับ %ผลตอบแทนรายวันของหุ้น

# คำนวณผลตอบแทนของกลยุทธ์ด้วยการนำสัญญาณคิดรวมกับผลตอบแทนรายวัน
df['strategy_returns'] = df.daily_pct_change * df.signal

จากนั้นก็ลองนำมาแสดงผลกันได้เลย ด้วยคำสั่งที่ได้เกริ่นไปตั้งแต่ต้น

pyfolio.create_full_tear_sheet(portfolio.mean(axis=1))

และต่อไปนี้คือสิ่งที่คุณจะได้รับครับ

ทุกสิ่งที่คุณเลือกหา ง่าย ครบ จบ ที่เดียว!!

สำหรับสิ่งที่ผมชอบที่สุด คือการบอกรายละเอียดในการซื้อ จำนวนวันที่เข้า ระยะเวลาการถือ, ค่า Drawdown , ค่าสถิติจากผลตอบแทนที่เป็นมาตรฐาน ไม่ว่าจะเป็น Sharpe ratio, Sortino ratio, Information Ratio เป็นต้น นอกจากนี้เรายังทราบผลตอบแทนของเราเทียบกับในช่วงวิกฤตต่าง ๆ อีกด้วย!

เอาล่ะครับ มาถึงบรรทัดนี้ คิดว่าหลาย ๆ คนคงอยากจะลองบ้างแล้ว จิ้มเข้ามาได้เลยครับที่ >>>Github PopQuants ลองทำตาม ลองปรับปรุงเพิ่ม แต่งหน้าตามาแลกเปลี่ยนกันชมได้นะครับ

แล้วมาทำ Quants ให้ Pop!! กันครับ

Tanapat Kamsaiin

Quantitative Investment Strategist @Finnomena

--

--