kispilot 0.1.2__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kispilot-0.2.0/PKG-INFO +98 -0
- kispilot-0.2.0/README.md +63 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/__init__.py +1 -1
- kispilot-0.2.0/src/kispilot/api/data/_mst.py +44 -0
- kispilot-0.2.0/src/kispilot/api/data/index_fo.py +22 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/data/master.py +10 -5
- kispilot-0.2.0/src/kispilot/api/data/night_future.py +33 -0
- kispilot-0.2.0/src/kispilot/api/data/night_option.py +33 -0
- kispilot-0.2.0/src/kispilot/api/futureoption/__init__.py +19 -0
- kispilot-0.2.0/src/kispilot/api/futureoption/futureoption_inquire_asking_price.py +142 -0
- kispilot-0.2.0/src/kispilot/api/futureoption/futureoption_inquire_daily_fuopchartprice.py +148 -0
- kispilot-0.2.0/src/kispilot/api/futureoption/futureoption_inquire_price.py +155 -0
- kispilot-0.2.0/src/kispilot/api/futureoption/futureoption_inquire_time_fuopchartprice.py +154 -0
- kispilot-0.2.0/src/kispilot/api/realtime/__init__.py +21 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_index_futures_asking_price.py +199 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_index_futures_ccnl.py +209 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_index_option_asking_price.py +199 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_index_option_ccnl.py +217 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_krx_ngt_futures_asking_price.py +199 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_krx_ngt_futures_ccnl.py +208 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_krx_ngt_option_asking_price.py +199 -0
- kispilot-0.2.0/src/kispilot/api/realtime/realtime_krx_ngt_option_ccnl.py +215 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/main.py +85 -6
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/css/base.css +7 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/api.js +4 -3
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/chart.js +5 -4
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/layout.js +1 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/live.js +3 -2
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/backtest.js +358 -4
- kispilot-0.2.0/src/kispilot/app/ui/assets/js/pages/fo.js +412 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/ui.js +4 -4
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/backtest.html +91 -7
- kispilot-0.2.0/src/kispilot/app/ui/fo.html +110 -0
- kispilot-0.2.0/src/kispilot/app/utils/backtest.py +585 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/utils/chart.py +93 -2
- kispilot-0.2.0/src/kispilot/app/utils/fo_board.py +320 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/utils/realtime_hub.py +23 -2
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/mcp_server/analysis_tools.py +177 -1
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/mcp_server/prompts.py +2 -1
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/mcp_server/server.py +26 -1
- kispilot-0.2.0/src/kispilot.egg-info/PKG-INFO +98 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot.egg-info/SOURCES.txt +19 -0
- kispilot-0.1.2/PKG-INFO +0 -262
- kispilot-0.1.2/README.md +0 -227
- kispilot-0.1.2/src/kispilot/api/data/_mst.py +0 -20
- kispilot-0.1.2/src/kispilot/api/realtime/__init__.py +0 -9
- kispilot-0.1.2/src/kispilot/app/utils/backtest.py +0 -347
- kispilot-0.1.2/src/kispilot.egg-info/PKG-INFO +0 -262
- {kispilot-0.1.2 → kispilot-0.2.0}/LICENSE +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/pyproject.toml +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/setup.cfg +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/__main__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/account_asset_balance.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/account_inquire_balance_rlz_pl.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/account_inquire_period_profit.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/account_inquire_period_rights.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/account_inquire_period_trade_profit.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/account/account_intgr_margin.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/config.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/data/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/data/kosdaq.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/data/kospi.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/data/sector.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_balance_sheet.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_financial_ratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_growth_ratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_income_statement.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_other_major_ratios.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_profit_ratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_search_stock_info.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/info/info_stability_ratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/oauth/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/oauth/kis_token.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_cash.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_credit.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_balance.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_credit_psamount.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_daily_ccld.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_psbl_order.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_psbl_sell.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_reserve.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_inquire_revise_cancel.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_reserve.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_reserve_revise_cancel.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/order/order_revise_cancel.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_asking_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_ccnl.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_daily_itemchartprice.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_daily_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_etf_component_stock_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_etf_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_investor.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_member.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_time_dailychartprice.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_time_itemchartprice.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_inquire_time_itemconclusion.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_nav_comparison_daily_trend.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_nav_comparison_time_trend.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price/price_nav_comparison_trend.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_daily_loan_trans.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_daily_short_sale.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_foreign_institution_total.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_frgnmem_pchs_trend.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_inquire_investor_daily_by_market.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_intstock_multprice.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_investor_program_trade_today.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_investor_trade_by_stock_daily.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_mktfunds.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_pbar_tratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_program_trade_by_stock.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/price_anal/price_anal_program_trade_by_stock_daily.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_credit_balance.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_disparity.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_exp_trans_updown.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_finance_ratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_fluctuation.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_market_cap.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_market_value.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_prefer_disparate_ratio.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_profit_asset_index.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_quote_balance.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_short_sale.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_volume_power.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/ranking_anal/ranking_anal_volume_rank.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/realtime/realtime_asking_price_total.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/realtime/realtime_ccnl_total.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/realtime/realtime_member_total.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/realtime/realtime_program_trade_total.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_exp_index_trend.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_exp_total_index.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_inquire_daily_indexchartprice.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_inquire_index_category_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_inquire_index_daily_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_inquire_index_price.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_inquire_index_timeprice.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/sector/sector_news_title.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/utils/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/utils/api_tracker.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/api/utils/http_session.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/backtest/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/backtest/custom_strategy.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/backtest/engine.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/backtest/indicators_lib.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/backtest/metrics.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/backtest/strategies.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/account.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/favicon.svg +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/chart-tools.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/indicators.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/account.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/dashboard.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/etf.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/market.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/ranking.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/stock-finance.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/stock-flow.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/stock.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/assets/js/pages/trade.js +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/etf.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/index.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/market.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/ranking.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/stock-finance.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/stock-flow.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/stock.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/ui/trade.html +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/utils/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/utils/news.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/app/utils/utils.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/cli.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/credentials.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/install.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/mcp_server/__init__.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/mcp_server/shaping.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot/paths.py +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot.egg-info/dependency_links.txt +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot.egg-info/entry_points.txt +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot.egg-info/requires.txt +0 -0
- {kispilot-0.1.2 → kispilot-0.2.0}/src/kispilot.egg-info/top_level.txt +0 -0
kispilot-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kispilot
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: 한국투자증권 Open API를 AI 에이전트(MCP)와 웹 콘솔에서 쓰기 위한 도구 모음 (비공식)
|
|
5
|
+
Author: Dong-Ju An
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dongju923/kispilot
|
|
8
|
+
Project-URL: Repository, https://github.com/dongju923/kispilot
|
|
9
|
+
Project-URL: Issues, https://github.com/dongju923/kispilot/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/dongju923/kispilot/releases
|
|
11
|
+
Keywords: kis,korea-investment,한국투자증권,mcp,trading,backtest,claude,agent
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Natural Language :: Korean
|
|
18
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: requests>=2.31
|
|
23
|
+
Requires-Dist: python-dotenv>=1.0
|
|
24
|
+
Requires-Dist: keyring>=25
|
|
25
|
+
Requires-Dist: platformdirs>=4
|
|
26
|
+
Requires-Dist: pandas>=2.2
|
|
27
|
+
Requires-Dist: numpy>=1.26
|
|
28
|
+
Requires-Dist: yfinance>=0.2.40
|
|
29
|
+
Requires-Dist: starlette>=0.37
|
|
30
|
+
Requires-Dist: uvicorn>=0.30
|
|
31
|
+
Requires-Dist: websockets>=12
|
|
32
|
+
Requires-Dist: aiohttp>=3.9
|
|
33
|
+
Requires-Dist: mcp<3,>=2.2
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# KISPilot
|
|
37
|
+
|
|
38
|
+
한국투자증권 Open API를 **AI 에이전트(MCP)** 와 **웹 콘솔**에서 쓰기 위한 도구 모음입니다.
|
|
39
|
+
|
|
40
|
+
> **비공식 프로젝트입니다.** 한국투자증권과 관계가 없으며, 한국투자증권이 만들거나 검증하지 않았습니다.
|
|
41
|
+
> 이 소프트웨어는 투자 조언이 아니며, 주문·백테스트 결과로 생긴 손실에 대해 책임지지 않습니다 (MIT 라이선스, 무보증).
|
|
42
|
+
> 실전 계좌로 쓰기 전에 모의투자로 충분히 확인하세요.
|
|
43
|
+
|
|
44
|
+
## 할 수 있는 것
|
|
45
|
+
|
|
46
|
+
- **조회** — 시세·호가·체결, 투자자·수급, 재무, 순위, 업종·지수, ETF, 계좌 잔고·손익 (KIS API 80여 개)
|
|
47
|
+
- **선물·옵션** — KOSPI200 선물·옵션(미니·위클리 포함) 주간·야간 전광판, 실시간 호가·체결, 차트
|
|
48
|
+
- **주문** — 현금·신용·예약 주문, 정정·취소 (에이전트는 모의투자가 기본, 실전은 2단계 확인)
|
|
49
|
+
- **차트** — 1분~년봉, 이동평균·볼린저·일목균형표 등 지표, 보조 차트 30여 종
|
|
50
|
+
- **백테스트** — 기본 전략 11종 + 지표 157개로 만드는 커스텀 전략, 여러 전략 비교, 여러 종목 포트폴리오
|
|
51
|
+
- **실시간** — KIS 웹소켓 체결·호가 (웹 콘솔)
|
|
52
|
+
|
|
53
|
+
## 빠른 시작
|
|
54
|
+
|
|
55
|
+
Python 3.11 이상이 필요합니다.
|
|
56
|
+
|
|
57
|
+
**1. 설치**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
uv tool install kispilot # 또는: pipx install kispilot / pip install kispilot
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**2. 키 등록 (처음 한 번)** — [KIS Developers](https://apiportal.koreainvestment.com)에서 앱키·앱시크릿을 발급받은 뒤:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
kispilot setup # 실전 / 모의투자 / 둘 다 선택 → 앱키·시크릿·계좌 입력
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
앱키는 OS 키체인에 저장됩니다. **키를 AI 채팅창에 붙여넣지 마세요.**
|
|
70
|
+
|
|
71
|
+
**3. 쓰는 방법 고르기**
|
|
72
|
+
|
|
73
|
+
| 이렇게 쓰려면 | 실행 |
|
|
74
|
+
|---|---|
|
|
75
|
+
| 웹 화면에서 직접 보기 | `kispilot ui` → http://127.0.0.1:8000 |
|
|
76
|
+
| Claude 등 AI 에이전트에게 맡기기 | `kispilot install claude-desktop` (Claude Code · Cursor · VS Code · Gemini CLI · Codex 도 지원) 후 앱 다시 시작 |
|
|
77
|
+
|
|
78
|
+
## 안내 문서
|
|
79
|
+
|
|
80
|
+
| 문서 | 이럴 때 보세요 |
|
|
81
|
+
|---|---|
|
|
82
|
+
| [설치 · 키 등록](https://github.com/dongju923/kispilot/blob/main/docs/install.md) | 업데이트·삭제, 소스 설치, 서버처럼 키체인이 없는 환경, 데이터 저장 위치 |
|
|
83
|
+
| [웹 콘솔](https://github.com/dongju923/kispilot/blob/main/docs/web-console.md) | 화면마다 무엇을 볼 수 있는지, 다른 기기에서 접속하기 |
|
|
84
|
+
| [선물 · 옵션](https://github.com/dongju923/kispilot/blob/main/docs/futures-options.md) | KOSPI200 선물·옵션 전광판, 주간/야간, 알아 둘 점 |
|
|
85
|
+
| [AI 에이전트 (MCP)](https://github.com/dongju923/kispilot/blob/main/docs/mcp.md) | 클라이언트별 등록, 도구·프롬프트 목록, 직접 설정, 주문 안전장치 |
|
|
86
|
+
|
|
87
|
+
버전별 변경 내용은 [Releases](https://github.com/dongju923/kispilot/releases) 에 있습니다.
|
|
88
|
+
|
|
89
|
+
## 데이터 출처 · 참고
|
|
90
|
+
|
|
91
|
+
- [한국투자증권 Open API](https://apiportal.koreainvestment.com) — 모든 시세·계좌·주문 기능은 이 API 를 호출합니다.
|
|
92
|
+
- [yfinance](https://github.com/ranaroussi/yfinance) — 주식 과거 일봉·분봉 (Yahoo Finance, 개인적·연구 목적 이용 권장). 최근 거래일은 KIS API로 보강
|
|
93
|
+
- [TradingView Lightweight Charts](https://github.com/tradingview/lightweight-charts) — 차트 (Apache-2.0)
|
|
94
|
+
- [koreainvestment/open-trading-api](https://github.com/koreainvestment/open-trading-api) — 백테스트 기본 전략 구성(프리셋 종류)과 종목 마스터 파일 형식(필드 폭·열 이름)을 참고했습니다.
|
|
95
|
+
|
|
96
|
+
## 라이선스
|
|
97
|
+
|
|
98
|
+
[MIT](https://github.com/dongju923/kispilot/blob/main/LICENSE)
|
kispilot-0.2.0/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# KISPilot
|
|
2
|
+
|
|
3
|
+
한국투자증권 Open API를 **AI 에이전트(MCP)** 와 **웹 콘솔**에서 쓰기 위한 도구 모음입니다.
|
|
4
|
+
|
|
5
|
+
> **비공식 프로젝트입니다.** 한국투자증권과 관계가 없으며, 한국투자증권이 만들거나 검증하지 않았습니다.
|
|
6
|
+
> 이 소프트웨어는 투자 조언이 아니며, 주문·백테스트 결과로 생긴 손실에 대해 책임지지 않습니다 (MIT 라이선스, 무보증).
|
|
7
|
+
> 실전 계좌로 쓰기 전에 모의투자로 충분히 확인하세요.
|
|
8
|
+
|
|
9
|
+
## 할 수 있는 것
|
|
10
|
+
|
|
11
|
+
- **조회** — 시세·호가·체결, 투자자·수급, 재무, 순위, 업종·지수, ETF, 계좌 잔고·손익 (KIS API 80여 개)
|
|
12
|
+
- **선물·옵션** — KOSPI200 선물·옵션(미니·위클리 포함) 주간·야간 전광판, 실시간 호가·체결, 차트
|
|
13
|
+
- **주문** — 현금·신용·예약 주문, 정정·취소 (에이전트는 모의투자가 기본, 실전은 2단계 확인)
|
|
14
|
+
- **차트** — 1분~년봉, 이동평균·볼린저·일목균형표 등 지표, 보조 차트 30여 종
|
|
15
|
+
- **백테스트** — 기본 전략 11종 + 지표 157개로 만드는 커스텀 전략, 여러 전략 비교, 여러 종목 포트폴리오
|
|
16
|
+
- **실시간** — KIS 웹소켓 체결·호가 (웹 콘솔)
|
|
17
|
+
|
|
18
|
+
## 빠른 시작
|
|
19
|
+
|
|
20
|
+
Python 3.11 이상이 필요합니다.
|
|
21
|
+
|
|
22
|
+
**1. 설치**
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv tool install kispilot # 또는: pipx install kispilot / pip install kispilot
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**2. 키 등록 (처음 한 번)** — [KIS Developers](https://apiportal.koreainvestment.com)에서 앱키·앱시크릿을 발급받은 뒤:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
kispilot setup # 실전 / 모의투자 / 둘 다 선택 → 앱키·시크릿·계좌 입력
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
앱키는 OS 키체인에 저장됩니다. **키를 AI 채팅창에 붙여넣지 마세요.**
|
|
35
|
+
|
|
36
|
+
**3. 쓰는 방법 고르기**
|
|
37
|
+
|
|
38
|
+
| 이렇게 쓰려면 | 실행 |
|
|
39
|
+
|---|---|
|
|
40
|
+
| 웹 화면에서 직접 보기 | `kispilot ui` → http://127.0.0.1:8000 |
|
|
41
|
+
| Claude 등 AI 에이전트에게 맡기기 | `kispilot install claude-desktop` (Claude Code · Cursor · VS Code · Gemini CLI · Codex 도 지원) 후 앱 다시 시작 |
|
|
42
|
+
|
|
43
|
+
## 안내 문서
|
|
44
|
+
|
|
45
|
+
| 문서 | 이럴 때 보세요 |
|
|
46
|
+
|---|---|
|
|
47
|
+
| [설치 · 키 등록](https://github.com/dongju923/kispilot/blob/main/docs/install.md) | 업데이트·삭제, 소스 설치, 서버처럼 키체인이 없는 환경, 데이터 저장 위치 |
|
|
48
|
+
| [웹 콘솔](https://github.com/dongju923/kispilot/blob/main/docs/web-console.md) | 화면마다 무엇을 볼 수 있는지, 다른 기기에서 접속하기 |
|
|
49
|
+
| [선물 · 옵션](https://github.com/dongju923/kispilot/blob/main/docs/futures-options.md) | KOSPI200 선물·옵션 전광판, 주간/야간, 알아 둘 점 |
|
|
50
|
+
| [AI 에이전트 (MCP)](https://github.com/dongju923/kispilot/blob/main/docs/mcp.md) | 클라이언트별 등록, 도구·프롬프트 목록, 직접 설정, 주문 안전장치 |
|
|
51
|
+
|
|
52
|
+
버전별 변경 내용은 [Releases](https://github.com/dongju923/kispilot/releases) 에 있습니다.
|
|
53
|
+
|
|
54
|
+
## 데이터 출처 · 참고
|
|
55
|
+
|
|
56
|
+
- [한국투자증권 Open API](https://apiportal.koreainvestment.com) — 모든 시세·계좌·주문 기능은 이 API 를 호출합니다.
|
|
57
|
+
- [yfinance](https://github.com/ranaroussi/yfinance) — 주식 과거 일봉·분봉 (Yahoo Finance, 개인적·연구 목적 이용 권장). 최근 거래일은 KIS API로 보강
|
|
58
|
+
- [TradingView Lightweight Charts](https://github.com/tradingview/lightweight-charts) — 차트 (Apache-2.0)
|
|
59
|
+
- [koreainvestment/open-trading-api](https://github.com/koreainvestment/open-trading-api) — 백테스트 기본 전략 구성(프리셋 종류)과 종목 마스터 파일 형식(필드 폭·열 이름)을 참고했습니다.
|
|
60
|
+
|
|
61
|
+
## 라이선스
|
|
62
|
+
|
|
63
|
+
[MIT](https://github.com/dongju923/kispilot/blob/main/LICENSE)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""마스터(.mst) 고정 폭 파일 파싱 공통부 — 종목 마스터는 앞부분(코드·이름) + 뒤쪽 고정 폭 필드로 이뤄진다."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import csv
|
|
5
|
+
import io
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import pandas as pd
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def parse_stock_mst(path: Path, tail_len: int, name_col: str, widths: list[int], columns: list[str]) -> pd.DataFrame:
|
|
13
|
+
"""한 줄 = [단축코드 9][표준코드 12][한글명 …][고정 폭 필드 tail_len] (cp949)."""
|
|
14
|
+
head, tail = [], []
|
|
15
|
+
with open(path, encoding="cp949") as f:
|
|
16
|
+
for row in f:
|
|
17
|
+
front = row[: len(row) - tail_len]
|
|
18
|
+
head.append((front[0:9].rstrip(), front[9:21].rstrip(), front[21:].strip()))
|
|
19
|
+
tail.append(row[-tail_len:])
|
|
20
|
+
df1 = pd.DataFrame(head, columns=["단축코드", "표준코드", name_col])
|
|
21
|
+
df2 = pd.read_fwf(io.StringIO("".join(tail)), widths=widths, names=columns)
|
|
22
|
+
return pd.merge(df1, df2, how="outer", left_index=True, right_index=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def parse_fixed_bytes_mst(path: Path, fields: list[tuple[str, int, Optional[int]]]) -> pd.DataFrame:
|
|
26
|
+
"""필드 위치가 cp949 바이트 기준으로 고정된 마스터. fields = [(열 이름, 시작, 끝)], 끝이 None 이면 줄 끝까지.
|
|
27
|
+
|
|
28
|
+
한글이 2바이트라 문자열로 디코딩한 뒤 문자 위치로 자르면 한글 이름이 있는 줄마다 뒤 필드가 밀린다.
|
|
29
|
+
그래서 줄을 바이트로 읽어 자른 뒤 필드마다 디코딩한다.
|
|
30
|
+
"""
|
|
31
|
+
rows = []
|
|
32
|
+
with open(path, "rb") as f:
|
|
33
|
+
for line in f:
|
|
34
|
+
line = line.rstrip(b"\r\n")
|
|
35
|
+
if line.strip():
|
|
36
|
+
rows.append([line[a:b].decode("cp949").strip() for _, a, b in fields])
|
|
37
|
+
return pd.DataFrame(rows, columns=[name for name, _, _ in fields])
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def parse_pipe_mst(path: Path, columns: list[str]) -> pd.DataFrame:
|
|
41
|
+
"""'|' 로 나뉜 마스터. 코드 앞자리 0 이 사라지지 않게 모든 값을 문자열로 읽는다."""
|
|
42
|
+
df = pd.read_csv(path, sep="|", header=None, names=columns, dtype=str, encoding="cp949",
|
|
43
|
+
keep_default_na=False, quoting=csv.QUOTE_NONE)
|
|
44
|
+
return df.apply(lambda col: col.str.strip())
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""지수선물옵션 종목 마스터(fo_idx_code_mts.mst) 파싱. 내려받기·갱신은 master.py 가 한다.
|
|
2
|
+
|
|
3
|
+
한 줄 = '|' 로 나뉜 9개 필드 (cp949). 예:
|
|
4
|
+
5|B01612610|KR4B016C6108|C 202612 610.0|2|00610.00| |2001|KOSPI200
|
|
5
|
+
|
|
6
|
+
열 이름은 한국투자증권 open-trading-api 의 stocks_info/domestic_index_future_code.py 예제를 따른다
|
|
7
|
+
(예제 열 이름 앞 공백은 뺐다). https://github.com/koreainvestment/open-trading-api
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import pandas as pd
|
|
14
|
+
|
|
15
|
+
from kispilot.api.data._mst import parse_pipe_mst
|
|
16
|
+
|
|
17
|
+
COLUMNS = ["상품종류", "단축코드", "표준코드", "한글종목명", "ATM구분",
|
|
18
|
+
"행사가", "월물구분코드", "기초자산단축코드", "기초자산명"]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def parse(mst: Path) -> pd.DataFrame:
|
|
22
|
+
return parse_pipe_mst(mst, COLUMNS)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""KIS 종목·업종 마스터 파일 — 내려받기, 하루 한 번 갱신, 검색.
|
|
2
2
|
|
|
3
3
|
한투가 매일 갱신하는 마스터(.mst.zip)를 받아 CSV 로 바꿔 사용자 데이터 폴더에 둔다.
|
|
4
|
-
<데이터 폴더>/data/kospi_code.csv · kosdaq_code.csv · idxcode.csv
|
|
4
|
+
<데이터 폴더>/data/kospi_code.csv · kosdaq_code.csv · idxcode.csv (주식 · 업종)
|
|
5
|
+
<데이터 폴더>/data/fo_idx_code_mts.csv (지수선물옵션 — 주간)
|
|
6
|
+
<데이터 폴더>/data/fo_cme_code.csv · fo_eurex_code.csv (KOSPI200 야간선물 · KRX연계 야간옵션)
|
|
5
7
|
|
|
6
8
|
갱신 규칙
|
|
7
9
|
- 하루에 한 번. 하루의 경계는 오전 7시 (장 시작 전 갱신분을 받도록).
|
|
@@ -21,14 +23,14 @@ import time
|
|
|
21
23
|
import zipfile
|
|
22
24
|
from datetime import datetime, timedelta
|
|
23
25
|
from pathlib import Path
|
|
24
|
-
from typing import Callable, Literal
|
|
26
|
+
from typing import Callable, Literal, get_args
|
|
25
27
|
|
|
26
28
|
import pandas as pd
|
|
27
29
|
import requests
|
|
28
30
|
|
|
29
31
|
from kispilot.paths import data_dir
|
|
30
32
|
|
|
31
|
-
Kind = Literal["kospi", "kosdaq", "sector"]
|
|
33
|
+
Kind = Literal["kospi", "kosdaq", "sector", "index_fo", "night_future", "night_option"]
|
|
32
34
|
|
|
33
35
|
_BASE_URL = "https://new.real.download.dws.co.kr/common/master/"
|
|
34
36
|
_DAY_STARTS_AT = 7 # 이 시각(로컬) 이전에 받은 파일은 하루 지난 것으로 본다
|
|
@@ -37,11 +39,14 @@ _log = logging.getLogger("kispilot.master")
|
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
def _parsers() -> dict[str, tuple[str, str, Callable[[Path], pd.DataFrame]]]:
|
|
40
|
-
from kispilot.api.data import kosdaq, kospi, sector
|
|
42
|
+
from kispilot.api.data import index_fo, kosdaq, kospi, night_future, night_option, sector
|
|
41
43
|
return {
|
|
42
44
|
"kospi": ("kospi_code.mst.zip", "kospi_code.csv", kospi.parse),
|
|
43
45
|
"kosdaq": ("kosdaq_code.mst.zip", "kosdaq_code.csv", kosdaq.parse),
|
|
44
46
|
"sector": ("idxcode.mst.zip", "idxcode.csv", sector.parse),
|
|
47
|
+
"index_fo": ("fo_idx_code_mts.mst.zip", "fo_idx_code_mts.csv", index_fo.parse),
|
|
48
|
+
"night_future": ("fo_cme_code.mst.zip", "fo_cme_code.csv", night_future.parse),
|
|
49
|
+
"night_option": ("fo_eurex_code.mst.zip", "fo_eurex_code.csv", night_option.parse),
|
|
45
50
|
}
|
|
46
51
|
|
|
47
52
|
|
|
@@ -86,7 +91,7 @@ def refresh(kind: Kind) -> Path:
|
|
|
86
91
|
|
|
87
92
|
_cache: dict[str, tuple[datetime, pd.DataFrame]] = {}
|
|
88
93
|
_fail_until: dict[str, float] = {}
|
|
89
|
-
_locks = {k: threading.Lock() for k in (
|
|
94
|
+
_locks = {k: threading.Lock() for k in get_args(Kind)}
|
|
90
95
|
|
|
91
96
|
|
|
92
97
|
def load(kind: Kind) -> pd.DataFrame:
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""KOSPI200 야간선물 종목 마스터(fo_cme_code.mst) 파싱. 내려받기·갱신은 master.py 가 한다.
|
|
2
|
+
|
|
3
|
+
예전 CME 연계 야간선물 자리라 파일 이름에 cme 가 남아 있다.
|
|
4
|
+
한 줄 = cp949 바이트 기준 고정 폭 (121바이트). 예:
|
|
5
|
+
1A01612 KR4A016C0004F 202612 … 00000.0012001 KOSPI200
|
|
6
|
+
|
|
7
|
+
열 이름은 한국투자증권 open-trading-api 의 stocks_info/domestic_cme_future_code.py 예제를 따른다.
|
|
8
|
+
예제의 row[63:72] 는 행사가(8)에 월물구분코드(1)까지 붙여 읽고 기초자산 코드도 한 칸 밀려 있어,
|
|
9
|
+
야간옵션 마스터(night_option.py)와 같은 꼬리 배치로 고쳐 잡았다.
|
|
10
|
+
https://github.com/koreainvestment/open-trading-api
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
import pandas as pd
|
|
17
|
+
|
|
18
|
+
from kispilot.api.data._mst import parse_fixed_bytes_mst
|
|
19
|
+
|
|
20
|
+
FIELDS = [
|
|
21
|
+
("상품종류", 0, 1),
|
|
22
|
+
("단축코드", 1, 10),
|
|
23
|
+
("표준코드", 10, 22),
|
|
24
|
+
("한글종목명", 22, 63),
|
|
25
|
+
("행사가", 63, 71),
|
|
26
|
+
("월물구분코드", 71, 72),
|
|
27
|
+
("기초자산단축코드", 72, 81),
|
|
28
|
+
("기초자산명", 81, None),
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def parse(mst: Path) -> pd.DataFrame:
|
|
33
|
+
return parse_fixed_bytes_mst(mst, FIELDS)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""KRX연계 야간옵션 종목 마스터(fo_eurex_code.mst) 파싱. 내려받기·갱신은 master.py 가 한다.
|
|
2
|
+
|
|
3
|
+
예전 Eurex 연계 야간옵션 자리라 파일 이름에 eurex 가 남아 있다.
|
|
4
|
+
한 줄 = cp949 바이트 기준 고정 폭 (121바이트). 예:
|
|
5
|
+
5B01610745KR4B016A7454C 202610 745.0 … 200745.00 2001 KOSPI200
|
|
6
|
+
|
|
7
|
+
필드 위치·열 이름은 한국투자증권 open-trading-api 의 stocks_info/domestic_eurex_option_code.py 예제를 따르되,
|
|
8
|
+
예제는 문자 위치로 자른 뒤 lstrip() 으로 어긋남을 메꾸므로 여기서는 바이트 위치로 고쳐 잡았다.
|
|
9
|
+
월물구분코드 자리(바이트 71)는 옵션이라 비어 있어 뺐다.
|
|
10
|
+
https://github.com/koreainvestment/open-trading-api
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
import pandas as pd
|
|
17
|
+
|
|
18
|
+
from kispilot.api.data._mst import parse_fixed_bytes_mst
|
|
19
|
+
|
|
20
|
+
FIELDS = [
|
|
21
|
+
("상품종류", 0, 1),
|
|
22
|
+
("단축코드", 1, 10),
|
|
23
|
+
("표준코드", 10, 22),
|
|
24
|
+
("한글종목명", 22, 59),
|
|
25
|
+
("ATM구분", 62, 63),
|
|
26
|
+
("행사가", 63, 71),
|
|
27
|
+
("기초자산단축코드", 72, 81),
|
|
28
|
+
("기초자산명", 81, None),
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def parse(mst: Path) -> pd.DataFrame:
|
|
33
|
+
return parse_fixed_bytes_mst(mst, FIELDS)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""국내선물옵션(주간 · 야간) API 모음.
|
|
2
|
+
|
|
3
|
+
from kispilot.api.futureoption import (
|
|
4
|
+
inquire_price, inquire_asking_price,
|
|
5
|
+
inquire_daily_fuopchartprice, inquire_time_fuopchartprice,
|
|
6
|
+
)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .futureoption_inquire_price import inquire_price
|
|
10
|
+
from .futureoption_inquire_asking_price import inquire_asking_price
|
|
11
|
+
from .futureoption_inquire_daily_fuopchartprice import inquire_daily_fuopchartprice
|
|
12
|
+
from .futureoption_inquire_time_fuopchartprice import inquire_time_fuopchartprice
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"inquire_price",
|
|
16
|
+
"inquire_asking_price",
|
|
17
|
+
"inquire_daily_fuopchartprice",
|
|
18
|
+
"inquire_time_fuopchartprice",
|
|
19
|
+
]
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# 선물옵션 시세호가[v1_국내선물-007]
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Literal, Optional
|
|
4
|
+
|
|
5
|
+
from kispilot.api.config import DOMAIN, REAL_APPKEY, REAL_APP_SECRET, PAPER_APPKEY, PAPER_APP_SECRET
|
|
6
|
+
from kispilot.api.oauth.kis_token import load_token
|
|
7
|
+
from kispilot.api.utils.http_session import get_session
|
|
8
|
+
|
|
9
|
+
URL = "/uapi/domestic-futureoption/v1/quotations/inquire-asking-price"
|
|
10
|
+
# ※ 실시간 데이터가 필요하면 웹소켓 API를 이용할 것.
|
|
11
|
+
|
|
12
|
+
_TR_ID = "FHMIF10010000" # 실전/모의 동일
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# ── DataClass 정의 ──────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ResponseBodyOutput1:
|
|
19
|
+
hts_kor_isnm: Optional[str] = None # HTS 한글 종목명
|
|
20
|
+
futs_prpr: Optional[str] = None # 선물 현재가
|
|
21
|
+
prdy_vrss_sign: Optional[str] = None # 전일 대비 부호 (1 상한, 2 상승, 3 보합, 4 하한, 5 하락)
|
|
22
|
+
futs_prdy_vrss: Optional[str] = None # 선물 전일 대비
|
|
23
|
+
futs_prdy_ctrt: Optional[str] = None # 선물 전일 대비율
|
|
24
|
+
acml_vol: Optional[str] = None # 누적 거래량
|
|
25
|
+
futs_prdy_clpr: Optional[str] = None # 선물 전일 종가
|
|
26
|
+
futs_shrn_iscd: Optional[str] = None # 선물 단축 종목코드
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class ResponseBodyOutput2:
|
|
31
|
+
futs_askp1: Optional[str] = None # 선물 매도호가1
|
|
32
|
+
futs_askp2: Optional[str] = None # 선물 매도호가2
|
|
33
|
+
futs_askp3: Optional[str] = None # 선물 매도호가3
|
|
34
|
+
futs_askp4: Optional[str] = None # 선물 매도호가4
|
|
35
|
+
futs_askp5: Optional[str] = None # 선물 매도호가5
|
|
36
|
+
futs_bidp1: Optional[str] = None # 선물 매수호가1
|
|
37
|
+
futs_bidp2: Optional[str] = None # 선물 매수호가2
|
|
38
|
+
futs_bidp3: Optional[str] = None # 선물 매수호가3
|
|
39
|
+
futs_bidp4: Optional[str] = None # 선물 매수호가4
|
|
40
|
+
futs_bidp5: Optional[str] = None # 선물 매수호가5
|
|
41
|
+
askp_rsqn1: Optional[str] = None # 매도호가 잔량1
|
|
42
|
+
askp_rsqn2: Optional[str] = None # 매도호가 잔량2
|
|
43
|
+
askp_rsqn3: Optional[str] = None # 매도호가 잔량3
|
|
44
|
+
askp_rsqn4: Optional[str] = None # 매도호가 잔량4
|
|
45
|
+
askp_rsqn5: Optional[str] = None # 매도호가 잔량5
|
|
46
|
+
bidp_rsqn1: Optional[str] = None # 매수호가 잔량1
|
|
47
|
+
bidp_rsqn2: Optional[str] = None # 매수호가 잔량2
|
|
48
|
+
bidp_rsqn3: Optional[str] = None # 매수호가 잔량3
|
|
49
|
+
bidp_rsqn4: Optional[str] = None # 매수호가 잔량4
|
|
50
|
+
bidp_rsqn5: Optional[str] = None # 매수호가 잔량5
|
|
51
|
+
askp_csnu1: Optional[str] = None # 매도호가 건수1
|
|
52
|
+
askp_csnu2: Optional[str] = None # 매도호가 건수2
|
|
53
|
+
askp_csnu3: Optional[str] = None # 매도호가 건수3
|
|
54
|
+
askp_csnu4: Optional[str] = None # 매도호가 건수4
|
|
55
|
+
askp_csnu5: Optional[str] = None # 매도호가 건수5
|
|
56
|
+
bidp_csnu1: Optional[str] = None # 매수호가 건수1
|
|
57
|
+
bidp_csnu2: Optional[str] = None # 매수호가 건수2
|
|
58
|
+
bidp_csnu3: Optional[str] = None # 매수호가 건수3
|
|
59
|
+
bidp_csnu4: Optional[str] = None # 매수호가 건수4
|
|
60
|
+
bidp_csnu5: Optional[str] = None # 매수호가 건수5
|
|
61
|
+
total_askp_rsqn: Optional[str] = None # 총 매도호가 잔량
|
|
62
|
+
total_bidp_rsqn: Optional[str] = None # 총 매수호가 잔량
|
|
63
|
+
total_askp_csnu: Optional[str] = None # 총 매도호가 건수
|
|
64
|
+
total_bidp_csnu: Optional[str] = None # 총 매수호가 건수
|
|
65
|
+
aspr_acpt_hour: Optional[str] = None # 호가 접수 시간 (HHMMSS)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@dataclass
|
|
69
|
+
class ResponseBody:
|
|
70
|
+
rt_cd: str # 성공 실패 여부
|
|
71
|
+
msg_cd: str # 응답코드
|
|
72
|
+
msg1: str # 응답메세지
|
|
73
|
+
output1: ResponseBodyOutput1 # 시세 요약
|
|
74
|
+
output2: ResponseBodyOutput2 # 매도/매수 5단계 호가 (문서는 배열이라 하지만 실제 응답은 객체 하나)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ── 요청 함수 ───────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
def inquire_asking_price(
|
|
80
|
+
code: str,
|
|
81
|
+
market_div: Literal["F", "O", "JF", "JO", "CF", "CM", "EU"],
|
|
82
|
+
mode: Literal["real", "paper"] = "real",
|
|
83
|
+
) -> ResponseBody:
|
|
84
|
+
"""선물옵션 시세호가(매도/매수 5단계 호가·잔량·건수)를 조회한다.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
code: 입력 종목코드(FID_INPUT_ISCD), 선물옵션 단축코드(ex A01612 KOSPI200 선물 2026년 12월물).
|
|
88
|
+
market_div: 조건 시장 분류 코드(FID_COND_MRKT_DIV_CODE). F:지수선물, O:지수옵션, JF:주식선물,
|
|
89
|
+
JO:주식옵션, CF:상품선물(금·국채·달러), CM:야간선물, EU:야간옵션.
|
|
90
|
+
mode: "real"(실전투자) 또는 "paper"(모의투자). 기본값 "real".
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
rt_cd/msg_cd/msg1과 시세 요약(output1), 매도/매수 호가(output2)를 담은 ResponseBody.
|
|
94
|
+
"""
|
|
95
|
+
token = load_token(mode)
|
|
96
|
+
if mode == "real":
|
|
97
|
+
app_key, app_secret = REAL_APPKEY, REAL_APP_SECRET
|
|
98
|
+
else:
|
|
99
|
+
app_key, app_secret = PAPER_APPKEY, PAPER_APP_SECRET
|
|
100
|
+
|
|
101
|
+
headers = {
|
|
102
|
+
"content-type": "application/json; charset=utf-8",
|
|
103
|
+
"authorization": f"Bearer {token}",
|
|
104
|
+
"appkey": app_key,
|
|
105
|
+
"appsecret": app_secret,
|
|
106
|
+
"tr_id": _TR_ID,
|
|
107
|
+
"custtype": "P",
|
|
108
|
+
}
|
|
109
|
+
params = {
|
|
110
|
+
"FID_COND_MRKT_DIV_CODE": market_div,
|
|
111
|
+
"FID_INPUT_ISCD": code,
|
|
112
|
+
}
|
|
113
|
+
response = get_session().get(DOMAIN[mode] + URL, headers=headers, params=params, timeout=10)
|
|
114
|
+
raw = response.json()
|
|
115
|
+
|
|
116
|
+
# 에러 응답(rt_cd != "0")은 output1/output2 키가 없거나 null일 수 있어 안전 파싱.
|
|
117
|
+
fields1 = set(ResponseBodyOutput1.__dataclass_fields__)
|
|
118
|
+
raw_output1 = raw.get("output1") or {}
|
|
119
|
+
output1 = ResponseBodyOutput1(**{k: v for k, v in raw_output1.items() if k in fields1})
|
|
120
|
+
|
|
121
|
+
fields2 = set(ResponseBodyOutput2.__dataclass_fields__)
|
|
122
|
+
raw_output2 = raw.get("output2") or {}
|
|
123
|
+
output2 = ResponseBodyOutput2(**{k: v for k, v in raw_output2.items() if k in fields2})
|
|
124
|
+
|
|
125
|
+
return ResponseBody(
|
|
126
|
+
rt_cd=raw.get("rt_cd", ""),
|
|
127
|
+
msg_cd=raw.get("msg_cd", ""),
|
|
128
|
+
msg1=raw.get("msg1", ""),
|
|
129
|
+
output1=output1,
|
|
130
|
+
output2=output2,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# ── 실행 ────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
result = inquire_asking_price(code="A01612", market_div="F")
|
|
138
|
+
if result.rt_cd != "0":
|
|
139
|
+
print(f"조회 실패: {result.msg_cd} - {result.msg1}")
|
|
140
|
+
else:
|
|
141
|
+
print(result.output1)
|
|
142
|
+
print(result.output2)
|