ข้อจำกัดของการกระจายความเสี่ยงและการทำประกันพอร์ตการลงทุน
Portfoilo optimization ด้วย PYTHON
ทุกคนน่าจะทราบกันอยู่แล้วว่าการกระจายการลงทุนสามารถช่วยลดความเสี่ยงในการลงทุน แต่ในสถาณการณ์ที่เราต้องการลดความเสี่ยงมากที่สุดอย่างช่วงที่เกิดวิกฤตเศรษฐกิจ การกระจายการลงทุนกลับให้ผลลัพธ์น้อยลง เราพบว่าค่า Coleration ของสินทรัพย์มักเพิ่มขึ้นเมื่อเกิดวิกฤตเศรษฐกิจ
จากชุดข้อมูลผลตอบแทนอุตสาหกรรม https://github.com/nutdnuy/Portfolio_optimization_with_Python/blob/master/data/ind30_m_ew_rets.csv
การดูความสัมพันธ์โดยเฉลี่ยระหว่างอุตสาหกรรมทั้งหมดในช่วงเวลา 3 ปี เริ่มต้นด้วยการสร้างชุดความสัมพันธ์ตามช่วงเวลาในช่วงเวลา 36 เดือน
ts_corr = ind_return.rolling(window=36).corr()
ในการคำนวณสหสัมพันธ์แบบ rolling เราจำเป็นต้องจัดกลุ่มแถวทั้งหมดสำหรับวันที่เดียวกันจากนั้นคำนวณค่าเฉลี่ยของรายการทั้งหมดใน dataframe
เราจำเป็นต้องคำนวณค่าเฉลี่ยของค่าทั้งหมดของ dataframe ไม่ใช่ค่าเฉลี่ยของแต่ละคอลัมน์ เราสามารถคำนวณค่าเฉลี่ยของค่าเฉลี่ย แต่มันง่ายกว่าที่จะเรียกฟังก์ชันของเราเองในเมทริกซ์สหสัมพันธ์ แม้ว่าเราจะสามารถสร้างฟังก์ชั่นเพื่อคำนวณสิ่งนี้ได้ แต่ก็มักจะให้ฟังก์ชั่นpandas ซึ่งเป็นฟังก์ชั่นการใช้งานง่ายเพียงครั้งเดียวจึงไม่มีชื่อ มันเป็นฟังก์ชั่นมาตรฐานของpandas
เราทำดังต่อไปนี้:
ind_tr36corr = ts_corr.groupby(level='date').apply(lambda cormat: cormat.values.mean())tmi_tr36rets.plot(secondary_y=True, legend=True, label="Tr 36 mo return", figsize=(12,6))ind_tr36corr.plot(legend=True, label="Tr 36 mo Avg Correlation")
เห็นได้ชัดว่าทั้งสองซีรี่ส์มีความสัมพันธ์เป็นลบซึ่งอธิบายว่าทำไมการกระจายความเสี่ยงจึงล้มเหลวเมื่อเกิดวิกฤตเศรษตกิจ ซึ่งเราต้องการลดความเสี่ยงมากที่สุดดังนั้นเราต้องมีการทำประกันขาลงของพอร์ตการลงทุน
Constant Proportion Portfolio Insurance (CPPI)
การทำประกันพอร์ตการลงทุนหรือ Constant Proportion Portfolio Insurance (CPPI)ถูกนำเสนอโดย Fischer Black และ Robert W. Jones ในปี 1987 เป็นกลยุทธ์การลงทุน เพื่อปกป้องความเสี่ยงขาลงและมีศักยภายในการรับผลตอบแทนเมื่อเป็นขาขึ้น ผลลัพธ์ของกลยุทธ์ CPPI นั้นค่อนข้างคล้ายกับการซื้อ call option แต่ไม่ได้ซื้อสัญญา option ดังนั้นบางครั้ง CPPI จึงถูกเรียกว่า“concave strategy”
การบริหารเงินลงทุนด้วยเทคนิค CPPI จะให้น้ำหนักการลงทุนในสินทรัพย์ที่มีความเสี่ยงสูงและสินทรัพย์ที่มีความเสี่ยงต่ำซึ่งปรับเปลี่ยนไปในแต่ละวัน เพื่อตอบสนองกับภาวะตลาดที่เปลี่ยนแปลงไป (Dynamic Asset Allocation)โดย สัดส่วนการลงทุนในสินทรัพย์เสี่ยงจะถูกปรับเพิ่มขึ้นในภาวะตลาดช่วงขาขึ้น (Bullish Market) และถูกปรับลดลงในภาวะตลาดช่วงขาลง (Bearish Market)
สมมติว่าต้องการระดับการรักษามูลค่าที่ 80% หากเงินลงทุนมีมูลค่าเพิ่มขึ้น ระดับการรักษามูลค่าจะปรับเพิ่มขึ้นเป็น 80% ของเงินลงทุนสูงสุดเท่าที่เคยมีมาในช่วงตลอดระยะเวลาการลงทุน ยกตัวอย่างเช่น หากเงินลงทุนเริ่มแรกเท่ากับ 100 บาท ผู้ลงทุนจะได้ระดับการรักษามูลค่าเงินลงทุนที่ 80% หรือ 80 บาท หากต่อมาเงินลงทุนมีมูลค่าเพิ่มขึ้นเป็น 110 บาท ระดับการรักษามูลค่าเงินลงทุนจะขยับขึ้นเท่ากับ 88 บาท ซึ่งคิดเป็น 80% ของมูลค่าเงินลงทุนใหม่ หลังจากนั้นหากเงินลงทุนปรับตัวลดลงเท่ากับ 90 บาท ระดับการรักษามูลค่าเงินลงทุนจะเท่ากับระดับการรักษามูลค่าเงินลงทุนสูงสุดที่ผ่านมาหรือเท่ากับ 88 บาท ทั้งนี้ระดับการรักษามูลค่าเงินลงทุนมีโอกาสเพิ่มขึ้นมากกว่า100% ของเงินลงทุนเริ่มแรกได้ หากเงินลงทุนสูงสุดตลอดระยะเวลาการลงทุน มีมูลค่ามากกว่า125 บาท (80% ของ 125 บาท = 100 บาท)
ตัวแปรใน CPPI
- Bond floor
Bond floor คือมูลค่าขั้นตํ่าของ CPPI พอร์ตฟอร์ลิโอที่เราจะให้ลดลงไปตํ่าสุด เพื่อให้สามารถชำระกระแสเงินสดที่จะเกิดขึ้นในอนาคตทั้งหมดได้
- Multiplier
ใช้เพื่อกำหนดจำนวนความเสี่ยงที่ผู้ลงทุนยินดีที่จะดำเนินการ โดยที่เมื่อตัวคูณสูงขึ้นพอร์ตจะปรับเร็วขึ้น
- Gap
การวัดสัดส่วนของส่วนทุนเมื่อเทียบกับเบาะหรือ (CPPI-bond floor) / equity ในทางทฤษฎีสิ่งนี้ควรเท่ากับ 1 / ตัวคูณและนักลงทุนใช้การปรับสมดุลพอร์ตของพอร์ตเป็นระยะเพื่อพยายามรักษาสิ่งนี้ไว้
ตัวอย่างการใช้ CPPI
ถ้ากำหนดให้เงินลงทุนเริ่มต้น 1,000,000 บาท ตัวคูณเท่ากับ 2.5 ฯลฯ ส่วนมูลค่าขั้นต่ำที่นักลงทุนต้องการคือ 800,000 บาท จะได้สัดส่วนที่ต้องถือสินทรัพย์เสี่ยงเท่ากับ 2.5 x ( 1,000,000–800,000) = 500,000 บาท หลังจากนั้นเมื่อมูลค่าพอร์ตเปลี่ยนไปตามราคาตลาด เราจะค่อยๆปรับพอร์ตตามสูตรดังกล่าวไปเรื่อยๆ
ซึ่งจากตารางสามารถอธิบายได้ดังนี้
- ในวันที่ 1 ก.พ. เงินลงทุนในหุ้นเพิ่มขึ้น 4.82% ซึ่งเท่ากับ 524,100 บาท ทำให้มูลค่า พอร์ตเพิ่มเป็น 1,048,200 บาท จากสูตรเราต้องถือหุ้นเท่ากับ 2.5 x (1,048,200– 800,000) = 620,500 บาท ดังนั้น จึงต้องนำเงินสดมาซื้อหุ้นเพิ่มอีก 120,500 บาท ทำให้เงินสดในมือเหลือ 379,500 บาท
- ต่อมาในวันที่ 1 มี.ค. เงินลงทุนในหุ้นลดลง 8.00% ซึ่งเท่ากับ 482,172 บาท ทำให้มูลค่าพอร์ตลดลงเป็น 964,344 บาท เราต้องถือหุ้นเท่ากับ 2.5 x (964,344– 800,000) = 410,860 บาท ดังนั้นจึงต้องขายหุ้นออกมา 209,640 บาท ทำให้เงินสดในมือเพิ่มขึ้นเป็น 589,140 บาท
- ในวันที่ 1 เม.ย. เงินลงทุนในหุ้นเพิ่มขึ้น 20.3% ซึ่งเท่ากับ 580,053 บาท ทำให้มูลค่าพอร์ตเพิ่มขึ้นเป็น 1,160,106 บาท เราต้องถือหุ้นเท่ากับ 2.5 x (1,160,106– 800,000) = 900,265 บาท ดังนั้นจึงต้องนำเงินสดมาซื้อหุ้น เพิ่มอีก 489,405 บาท
อัลกอริทึม CPPI ใน Python นั้นใช้งานง่าย อินพุตมีเพียงผลตอบแทนของสินทรัพย์ที่มีความเสี่ยงและสินทรัพย์ที่ปลอดภัยพร้อมกับความมั่งคั่งเริ่มแรกที่จะลงทุนเมื่อเริ่มต้นพร้อมกับมูลค่าขั้นตํ่า
ind_tr36corr = ts_corr.groupby(level='date').apply(lambda cormat: cormat.values.mean())tmi_tr36rets.plot(secondary_y=True, legend=True, label="Tr 36 mo return", figsize=(12,6))ind_tr36corr.plot(legend=True, label="Tr 36 mo Avg Correlation")
เราจะมาคำนวณค่าต่างๆคือ:
- cushion (asset value minus floor)
- สัดส่วน alocation (based on the multiplier)
- มูลค่าของสินทรัพย์
โดยในที่นี้เราจะสมมุติว่าผลตอบแทนปราศจากความเสี่ยงคือ 3% เงินลงทุนเริ่มต้น 1000 บาท มูลค่าตํ่าสุด 0.8
risky_r = ind_return["2000":][["Steel","Rtail", "Beer "]]safe_r = pd.DataFrame().reindex_like(risky_r)safe_r.values[:] = 0.03/12 # fast way to set all values to a numberstart = 1000 # start at $1000floor = 0.80 # set the floor to 80 percent of the starting value
หลังจากนั้นเราต้องตั้งค่าตัวสำหรับ CPPI และตัว mutipler
dates = risky_r.indexn_steps = len(dates)account_value = startfloor_value = start*floorm = 3 #mutipler
ตั้งค่า DataFrames บางตัวสำหรับบันทึกค่ากลาง
account_history = คือมูลค่าการลงทุน
risky_w_history = คือนํ้าหนักของสินทรัพย์เสี่ยง
cushion_history = (account_value — floor_value)/account_value
## set up some DataFrames for saving intermediate valuesaccount_history = pd.DataFrame().reindex_like(risky_r)risky_w_history = pd.DataFrame().reindex_like(risky_r) cushion_history = pd.DataFrame().reindex_like(risky_r)
ใช้ for loop เพื่อคำนวณค่าที่เราประกาศไว้
for step in range(n_steps):cushion = (account_value - floor_value)/account_valuerisky_w = m*cushionrisky_w = np.minimum(risky_w, 1)risky_w = np.maximum(risky_w, 0)safe_w = 1-risky_wrisky_alloc = account_value*risky_wsafe_alloc = account_value*safe_w
คำนวณมูลค่าเงินลงทุน
account_value = risky_alloc*(1+risky_r.iloc[step]) + safe_alloc*(1+safe_r.iloc[step])
สร้างกราฟ
cushion_history.iloc[step] = cushionrisky_w_history.iloc[step] = risky_waccount_history.iloc[step] = account_valuerisky_wealth = start*(1+risky_r).cumprod()risky_w_history.plot()
จะเห็นสัดส่วนของสินทรัพย์ทั้งสามกับสินทรัพย์ปราศจากความเสี่ยงเมื่อเราใช้กลยุทธ์ CPPI และให้มีมูลค่าตํ่าสุดคือ 0.8 ของมูลค่าเงินเริ่มต้น เราสามารถสร้างฟังชั่นเพื่อหา CPPI ได้ดังนี้
แต่เราสามารถข้อจำกัดของเราคือ ขาดทุนจากจุดสูงสุดได้เช่นกัน เราสามารถหาจุดขาดทุนสูงสุดหรือ drawdown
โดยเปลี่ยน code
if drawdown is not None:
peak = np.maximum(peak, account_value)
floor_value = peak*(1-drawdown)
เราสามารถดูค่า สถิติต่างๆของพอร์ตการลงทุน ได้โดยใช้ค่าปกติในตอนอื่นๆ ผมเคยทำไว้แล้วสามารถหาดูได้เลยครับ
อ่านตอนอื่นๆได้ที่
- การคำนวณผลตอบแทนการลงทุนด้วย Python
- การหาความผันผวนของพอร์ตการลงทุนด้วย Python
- การหา Max Drawdown ด้วย Python
- การวัด การเบี่ยงเบนของผลตอบแทนด้วย Python
- การวัด SemiDeviation ด้วย Python
- การวัด VaR. และ CVaR. ด้วย Python
- รีวิวการใช้ ffn. ใน Python
- การหา Top Drawdown ด้วย Python
- การหาค่า Sharpe ratio ด้วย Python
- การหากลุ่มหลักรัพย์ที่เส้นประสิทธิภาพ Efficient Frontier ด้วย Python
- การหา shape ratio สูงสุดและเส้น CML ด้วย Python
- การสร้างมูลค่าตลาดแบบถ่วงน้ำหนักด้วย PYTHON
- ข้อจำกัดของการกระจายความเสี่ยงและการทำประกันพอร์ตการลงทุน
- การจำลอง ผลตอบแทนด้วย RANDOM WALK Generation และ Montecarlo simulation
- Sharpe Style Analysis
- Factor Investing ด้วย Python
- วิเคราะห์ ประเภทกองทุนรวมด้วย Python
- การทำ Portfolio optimization
- สร้างแนวรับแนวต้านวิเคราะห์หุ้นด้วย Python