PyPortfolioOpt เป็นไลบรารีที่ใช้วิธีการเพิ่มประสิทธิภาพพอร์ตโฟลิโอ ซึ่งรวมถึงเทคนิคการเพิ่มประสิทธิภาพความแปรปรวนเฉลี่ยแบบคลาสสิก และการจัดสรร Black-Litterman ตลอดจนการพัฒนาล่าสุดในสาขา เช่น การหดตัวและความเท่าเทียมกันของความเสี่ยงตามลำดับชั้น
มี ความหลากหลาย แต่ สามารถขยายได้ ง่าย และมีประโยชน์สำหรับนักลงทุนทั่วไปหรือมืออาชีพที่กำลังมองหาเครื่องมือสร้างต้นแบบที่ใช้งานง่าย ไม่ว่าคุณจะเป็นนักลงทุนที่เน้นพื้นฐานซึ่งระบุตัวเลือกที่มีมูลค่าต่ำไปจำนวนหนึ่ง หรือเทรดเดอร์ที่มีอัลกอริทึมซึ่งมีกลยุทธ์มากมาย PyPortfolioOpt สามารถช่วยคุณรวมแหล่งที่มาอัลฟ่าของคุณได้อย่างมีประสิทธิภาพความเสี่ยง
PyPortfolioOpt ได้รับการตีพิมพ์ใน Journal of Open Source Software ?
ขณะนี้ PyPortfolioOpt ได้รับการดูแลโดย Tuan Tran
ไปที่ เอกสารประกอบใน ReadTheDocs เพื่อดูรายละเอียดโปรเจ็กต์แบบเจาะลึก หรือดูตำราอาหารเพื่อดูตัวอย่างที่แสดงกระบวนการทั้งหมดตั้งแต่การดาวน์โหลดข้อมูลไปจนถึงการสร้างพอร์ตโฟลิโอ
หากคุณต้องการเล่นกับ PyPortfolioOpt แบบโต้ตอบในเบราว์เซอร์ของคุณ คุณสามารถเปิด Binder ได้ที่นี่ การตั้งค่าจะใช้เวลาสักครู่ แต่ช่วยให้คุณลองใช้สูตรตำราอาหารได้โดยไม่ต้องจัดการกับข้อกำหนดทั้งหมด
หมายเหตุ: ผู้ใช้ macOS จะต้องติดตั้งเครื่องมือบรรทัดคำสั่ง
หมายเหตุ: หากคุณใช้ Windows คุณต้องติดตั้ง C++ ก่อน (ดาวน์โหลด ติดตั้งคำแนะนำ)
โครงการนี้มีอยู่ใน PyPI ซึ่งหมายความว่าคุณสามารถ:
pip install PyPortfolioOpt
(คุณอาจต้องปฏิบัติตามคำแนะนำในการติดตั้งแยกต่างหากสำหรับ cvxopt และ cvxpy)
อย่างไรก็ตาม แนวทางปฏิบัติที่ดีที่สุดคือใช้ตัวจัดการการขึ้นต่อกันภายในสภาพแวดล้อมเสมือน คำแนะนำปัจจุบันของฉันคือเตรียมบทกวีให้ตัวเองแล้วค่อยวิ่ง
poetry add PyPortfolioOpt
มิฉะนั้น ให้โคลน/ดาวน์โหลดโปรเจ็กต์และรันในไดเร็กทอรีโปรเจ็กต์:
python setup.py install
PyPortfolioOpt รองรับนักเทียบท่า สร้างคอนเทนเนอร์แรกของคุณด้วย docker build -f docker/Dockerfile . -t pypfopt
คุณสามารถใช้อิมเมจเพื่อทำการทดสอบหรือแม้กระทั่งเปิดเซิร์ฟเวอร์ Jupyter
# iPython interpreter:
docker run -it pypfopt poetry run ipython
# Jupyter notebook server:
docker run -it -p 8888:8888 pypfopt poetry run jupyter notebook --allow-root --no-browser --ip 0.0.0.0
# click on http://127.0.0.1:8888/?token=xxx
# Pytest
docker run -t pypfopt poetry run pytest
# Bash
docker run -it pypfopt bash
สำหรับข้อมูลเพิ่มเติม โปรดอ่านคู่มือนี้
หากคุณต้องการทำการเปลี่ยนแปลงที่สำคัญเพื่อรวมสิ่งนี้เข้ากับระบบที่เป็นกรรมสิทธิ์ของคุณ มันอาจจะสมเหตุสมผลที่จะโคลนพื้นที่เก็บข้อมูลนี้และใช้เพียงซอร์สโค้ดเท่านั้น
git clone https://github.com/robertmartin8/PyPortfolioOpt
หรือคุณสามารถลอง:
pip install -e git+https://github.com/robertmartin8/PyPortfolioOpt.git
นี่คือตัวอย่างข้อมูลหุ้นในชีวิตจริง ซึ่งแสดงให้เห็นว่าการค้นหาพอร์ตการลงทุนแบบยาวเท่านั้นที่จะเพิ่มอัตราส่วน Sharpe ให้สูงสุด (การวัดผลตอบแทนที่ปรับตามความเสี่ยง) ได้ง่ายเพียงใด
import pandas as pd
from pypfopt import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
# Read in price data
df = pd . read_csv ( "tests/resources/stock_prices.csv" , parse_dates = True , index_col = "date" )
# Calculate expected returns and sample covariance
mu = expected_returns . mean_historical_return ( df )
S = risk_models . sample_cov ( df )
# Optimize for maximal Sharpe ratio
ef = EfficientFrontier ( mu , S )
raw_weights = ef . max_sharpe ()
cleaned_weights = ef . clean_weights ()
ef . save_weights_to_file ( "weights.csv" ) # saves to file
print ( cleaned_weights )
ef . portfolio_performance ( verbose = True )
สิ่งนี้ให้ผลลัพธ์น้ำหนักต่อไปนี้:
{'GOOG': 0.03835,
'AAPL': 0.0689,
'FB': 0.20603,
'BABA': 0.07315,
'AMZN': 0.04033,
'GE': 0.0,
'AMD': 0.0,
'WMT': 0.0,
'BAC': 0.0,
'GM': 0.0,
'T': 0.0,
'UAA': 0.0,
'SHLD': 0.0,
'XOM': 0.0,
'RRC': 0.0,
'BBY': 0.01324,
'MA': 0.35349,
'PFE': 0.1957,
'JPM': 0.0,
'SBUX': 0.01082}
Expected annual return: 30.5%
Annual volatility: 22.2%
Sharpe Ratio: 1.28
สิ่งนี้น่าสนใจแต่ไม่ได้มีประโยชน์ในตัวเอง อย่างไรก็ตาม PyPortfolioOpt มีวิธีการที่ช่วยให้คุณสามารถแปลงน้ำหนักต่อเนื่องข้างต้นเป็นการจัดสรรจริงที่คุณสามารถซื้อได้ เพียงป้อนราคาล่าสุด และขนาดพอร์ตโฟลิโอที่ต้องการ ($10,000 ในตัวอย่างนี้):
from pypfopt . discrete_allocation import DiscreteAllocation , get_latest_prices
latest_prices = get_latest_prices ( df )
da = DiscreteAllocation ( weights , latest_prices , total_portfolio_value = 10000 )
allocation , leftover = da . greedy_portfolio ()
print ( "Discrete allocation:" , allocation )
print ( "Funds remaining: ${:.2f}" . format ( leftover ))
12 out of 20 tickers were removed
Discrete allocation: {'GOOG': 1, 'AAPL': 4, 'FB': 12, 'BABA': 4, 'BBY': 2,
'MA': 20, 'PFE': 54, 'SBUX': 1}
Funds remaining: $ 11.89
ข้อจำกัดความรับผิดชอบ: ไม่มีสิ่งใดเกี่ยวกับโครงการนี้ที่ถือเป็นคำแนะนำในการลงทุน และผู้เขียนจะไม่รับผิดชอบต่อการตัดสินใจลงทุนครั้งต่อไปของคุณ โปรดดูใบอนุญาตสำหรับข้อมูลเพิ่มเติม
บทความในปี 1952 ของ Harry Markowitz ถือเป็นผลงานคลาสสิกที่ไม่อาจปฏิเสธได้ ซึ่งเปลี่ยนการเพิ่มประสิทธิภาพพอร์ตโฟลิโอจากงานศิลปะมาเป็นวิทยาศาสตร์ ข้อมูลเชิงลึกที่สำคัญคือการรวมสินทรัพย์ที่มีผลตอบแทนและความผันผวนที่คาดหวังไว้ที่แตกต่างกัน เราสามารถตัดสินใจเกี่ยวกับการจัดสรรที่เหมาะสมทางคณิตศาสตร์ซึ่งจะช่วยลดความเสี่ยงในการได้รับผลตอบแทนตามเป้าหมาย ชุดของพอร์ตการลงทุนที่เหมาะสมที่สุดดังกล่าวทั้งหมดเรียกว่า ขอบเขตที่มีประสิทธิภาพ
แม้ว่าจะมีการพัฒนาไปมากในเรื่องนี้ แต่กว่าครึ่งศตวรรษต่อมา แนวคิดหลักของ Markowitz ยังคงมีความสำคัญขั้นพื้นฐาน และเห็นได้จากการนำไปใช้ในชีวิตประจำวันในบริษัทจัดการพอร์ตโฟลิโอหลายแห่ง ข้อเสียเปรียบหลักของการปรับค่าความแปรปรวนเฉลี่ยให้เหมาะสมคือ การรักษาทางทฤษฎีต้องอาศัยความรู้เกี่ยวกับผลตอบแทนที่คาดหวังและลักษณะความเสี่ยงในอนาคต (ความแปรปรวนร่วม) ของสินทรัพย์ แน่นอนว่าหากเรารู้ว่าผลตอบแทนที่คาดหวังของหุ้นคงง่ายกว่ามาก แต่โดยรวมแล้วผลตอบแทนของหุ้นนั้นยากที่จะคาดการณ์อย่างฉาวโฉ่ เพื่อทดแทน เราสามารถรับค่าประมาณของผลตอบแทนที่คาดหวังและความแปรปรวนร่วมตามข้อมูลในอดีต แม้ว่าเราจะสูญเสียการรับประกันทางทฤษฎีที่ Markowitz ให้ไว้ แต่ยิ่งการประมาณการของเราใกล้เคียงกับมูลค่าที่แท้จริงมากเท่าใด ผลงานของเราก็จะยิ่งดีขึ้นเท่านั้น
ดังนั้นโปรเจ็กต์นี้จึงมีชุดฟังก์ชันหลักสี่ชุด (แต่แน่นอนว่ามันเกี่ยวข้องกันอย่างใกล้ชิด)
เป้าหมายการออกแบบที่สำคัญของ PyPortfolioOpt คือ ความเป็นโมดูล ผู้ใช้ควรจะสามารถสลับส่วนประกอบของตนได้ในขณะที่ยังคงใช้เฟรมเวิร์กที่ PyPortfolioOpt มอบให้
ในส่วนนี้ เราจะให้รายละเอียดเกี่ยวกับฟังก์ชันการทำงานบางอย่างที่พร้อมใช้งานของ PyPortfolioOpt มีตัวอย่างเพิ่มเติมในสมุดบันทึก Jupyter ที่นี่ แหล่งข้อมูลที่ดีอีกแหล่งหนึ่งคือการทดสอบ
สามารถดูเวอร์ชันที่ครอบคลุมกว่านี้ได้บน ReadTheDocs รวมถึงส่วนขยายที่เป็นไปได้สำหรับผู้ใช้ขั้นสูง
เมทริกซ์ความแปรปรวนร่วมไม่เพียงแต่เข้ารหัสความผันผวนของสินทรัพย์เท่านั้น แต่ยังรวมถึงความสัมพันธ์ของสินทรัพย์กับสินทรัพย์อื่นๆ ด้วย นี่เป็นสิ่งสำคัญเนื่องจากเพื่อที่จะเก็บเกี่ยวผลประโยชน์จากการกระจายความเสี่ยง (และเพิ่มผลตอบแทนต่อหน่วยความเสี่ยง) สินทรัพย์ในพอร์ตโฟลิโอไม่ควรมีความสัมพันธ์กันมากที่สุด
sklearn.covariance
constant_variance
, single_factor
และ constant_correlation
sklearn.covariance
(พล็อตนี้ถูกสร้างขึ้นโดยใช้ plotting.plot_covariance
)
ef = EfficientFrontier ( mu , S , weight_bounds = ( - 1 , 1 ))
efficient_risk
และ efficient_return
นั้น PyPortfolioOpt มีตัวเลือกในการสร้างพอร์ตโฟลิโอที่เป็นกลางทางตลาด (เช่น น้ำหนักรวมเป็นศูนย์) สิ่งนี้เป็นไปไม่ได้สำหรับพอร์ตโฟลิโอ Sharpe สูงสุดและพอร์ตโฟลิโอที่มีความผันผวนขั้นต่ำ เนื่องจากในกรณีเหล่านั้น เนื่องจากพอร์ตโฟลิโอเหล่านี้ไม่แปรผันตามเลเวอเรจ ความเป็นกลางของตลาดต้องมีน้ำหนักติดลบ: ef = EfficientFrontier ( mu , S , weight_bounds = ( - 1 , 1 ))
ef . efficient_return ( target_return = 0.2 , market_neutral = True )
ef = EfficientFrontier ( mu , S , weight_bounds = ( 0 , 0.1 ))
ปัญหาหนึ่งของการปรับค่าความแปรปรวนเฉลี่ยให้เหมาะสมคือ ทำให้มีน้ำหนักเป็นศูนย์หลายค่า แม้ว่าสิ่งเหล่านี้จะเป็นตัวอย่างที่ "เหมาะสมที่สุด" แต่ก็มีงานวิจัยจำนวนมากที่แสดงให้เห็นว่าคุณลักษณะนี้ทำให้พอร์ตโฟลิโอที่มีความแปรปรวนเฉลี่ยมีประสิทธิภาพต่ำกว่านอกกลุ่มตัวอย่าง ด้วยเหตุนี้ ฉันได้แนะนำฟังก์ชันวัตถุประสงค์ที่สามารถลดจำนวนน้ำหนักเล็กน้อยสำหรับฟังก์ชันวัตถุประสงค์ใดๆ ได้ โดยพื้นฐานแล้ว จะเพิ่มการลงโทษ (กำหนดพารามิเตอร์ด้วย gamma
) สำหรับน้ำหนักขนาดเล็ก โดยมีคำที่ดูเหมือนการทำให้ L2 เป็นมาตรฐานในการเรียนรู้ของเครื่อง อาจจำเป็นต้องลองใช้ค่า gamma
หลายๆ ค่าเพื่อให้ได้น้ำหนักที่ไม่สามารถละเลยได้ตามจำนวนที่ต้องการ สำหรับพอร์ตทดสอบ 20 หลักทรัพย์ gamma ~ 1
ก็เพียงพอแล้ว
ef = EfficientFrontier ( mu , S )
ef . add_objective ( objective_functions . L2_reg , gamma = 1 )
ef . max_sharpe ()
ในเวอร์ชัน 0.5.0 ขณะนี้เรารองรับการจัดสรรสินทรัพย์ของ Black-Litterman ซึ่งช่วยให้คุณสามารถรวมการประมาณการผลตอบแทนก่อนหน้า (เช่น ผลตอบแทนโดยนัยของตลาด) เข้ากับมุมมองของคุณเองเพื่อสร้างการประมาณการในภายหลัง ซึ่งส่งผลให้ประมาณการผลตอบแทนที่คาดหวังได้ดีกว่าการใช้ผลตอบแทนเฉลี่ยในอดีตมาก ตรวจสอบเอกสารสำหรับการอภิปรายเกี่ยวกับทฤษฎี รวมถึงคำแนะนำเกี่ยวกับการจัดรูปแบบอินพุต
S = risk_models . sample_cov ( df )
viewdict = { "AAPL" : 0.20 , "BBY" : - 0.30 , "BAC" : 0 , "SBUX" : - 0.2 , "T" : 0.131321 }
bl = BlackLittermanModel ( S , pi = "equal" , absolute_views = viewdict , omega = "default" )
rets = bl . bl_returns ()
ef = EfficientFrontier ( rets , S )
ef . max_sharpe ()
คุณลักษณะข้างต้นส่วนใหญ่เกี่ยวข้องกับการแก้ปัญหาการหาค่าเหมาะที่สุดสำหรับความแปรปรวนเฉลี่ยผ่านการเขียนโปรแกรมกำลังสอง (แม้ว่าสิ่งนี้จะได้รับการดูแลโดย cvxpy
ก็ตาม) อย่างไรก็ตาม เรามีเครื่องมือเพิ่มประสิทธิภาพที่แตกต่างกันเช่นกัน:
โปรดดูเอกสารประกอบสำหรับข้อมูลเพิ่มเติม
การทดสอบเขียนด้วย pytest (ใช้งานง่ายกว่า unittest
และตัวแปรต่างๆ ในความคิดของฉัน) และฉันได้พยายามให้แน่ใจว่าครอบคลุมเกือบ 100% รันการทดสอบโดยไปที่ไดเร็กทอรีแพ็กเกจและเรียกใช้ pytest
บนบรรทัดคำสั่ง
PyPortfolioOpt จัดเตรียมชุดข้อมูลทดสอบผลตอบแทนรายวันสำหรับ 20 ตัวย่อ:
[ 'GOOG' , 'AAPL' , 'FB' , 'BABA' , 'AMZN' , 'GE' , 'AMD' , 'WMT' , 'BAC' , 'GM' ,
'T' , 'UAA' , 'SHLD' , 'XOM' , 'RRC' , 'BBY' , 'MA' , 'PFE' , 'JPM' , 'SBUX' ]
สัญลักษณ์เหล่านี้ได้รับการคัดเลือกอย่างไม่เป็นทางการเพื่อให้ตรงตามเกณฑ์หลายประการ:
ในปัจจุบัน การทดสอบยังไม่ได้สำรวจกรณี Edge ทั้งหมดและการรวมกันของฟังก์ชันวัตถุประสงค์และพารามิเตอร์ อย่างไรก็ตาม แต่ละวิธีและพารามิเตอร์ได้รับการทดสอบว่าทำงานได้ตามที่ตั้งใจไว้
หากคุณใช้ PyPortfolioOpt สำหรับงานตีพิมพ์ โปรดอ้างอิงเอกสาร JOSS
สตริงการอ้างอิง:
Martin, R. A., (2021). PyPortfolioOpt: portfolio optimization in Python. Journal of Open Source Software, 6(61), 3066, https://doi.org/10.21105/joss.03066
บิบเท็กซ์::
@article { Martin2021 ,
doi = { 10.21105/joss.03066 } ,
url = { https://doi.org/10.21105/joss.03066 } ,
year = { 2021 } ,
publisher = { The Open Journal } ,
volume = { 6 } ,
number = { 61 } ,
pages = { 3066 } ,
author = { Robert Andrew Martin } ,
title = { PyPortfolioOpt: portfolio optimization in Python } ,
journal = { Journal of Open Source Software }
}
ผลงาน ได้รับการต้อนรับมากที่สุด ดูคู่มือการมีส่วนร่วมสำหรับข้อมูลเพิ่มเติม
ฉันอยากจะขอบคุณทุกคนที่มีส่วนร่วมใน PyPortfolioOpt นับตั้งแต่เปิดตัวในปี 2018 ขอขอบคุณเป็นพิเศษสำหรับ: