import sys from loguru import logger import finestock from finestock import APIProvider from finestock.comm.api_interface import AuthenticationProvider, MarketDataProvider, TradingProvider, AccountProvider # Configure logging logger.remove() logger.add(sys.stdout, level="INFO") def main(): finestock.print_version_info() # 1. Create API Instance # The 'api' object implements multiple interfaces (Authentication, MarketData, Realtime, etc.) api = finestock.create_api(APIProvider.KIWOOMV) # 2. Setup Authentication (Sync) # Type Hinting: View 'api' as AuthenticationProvider to see only auth-related methods auth_api: AuthenticationProvider = api if isinstance(auth_api, AuthenticationProvider): #APP_KEY = "YOUR_APP_KEY" #APP_SECRET = "YOUR_APP_SECRET" #APP_KEY = "PSgjLpp90XLhWexJYGL0P36oyzM3ne5kjhDW" #LSV #APP_SECRET = "htA3h9kULFPD75vtHAt0JaXyYAjsbf0b" #LSV #APP_KEY = "RSvh1vtzHj8Z5F15Ee7_rJ5znHuAKOF6A8v90TEkyBk" #APP_SECRET = "_7wuGnkD-Crf1TJKErJPYkQp7AVuh_gVOPgQ2Uyyh7k" APP_KEY = "5-7V0r97uwlzmPNFa_FnwFEZtnyhFAZ1qlnDXQH2rX4" APP_SECRET = "YOMvV7X1CwwST-_iFmRAPKXO7Wwr4zGGyTPX5gFcAqk" auth_api.set_oauth_info(APP_KEY, APP_SECRET) token = auth_api.oauth() print(token) # auth_api.oauth() # Perform actual login # or auth_api.set_access_token("TOKEN") # 3. Market Data (Sync) logger.info("Fetching Market Data (Sync)...") # Type Hinting: View 'api' as MarketDataProvider market_api: MarketDataProvider = api if isinstance(market_api, MarketDataProvider): try: # ohlcvs = market_api.get_ohlcv("005930", "20240101", "20240105") # print(f"Received {len(ohlcvs)} records") ohlcv = market_api.get_price("005930") print(f"Received {ohlcv}") exit() # Example: Parsing Price objects print(f"{'Date':<10} | {'Close':<10} | {'Volume':<10}") print("-" * 36) price: finestock.Price = ohlcv # Accessing fields of the Price dataclass print(f"{price.workday:<10} | {price.close:<10} | {price.volume:<10}") except Exception as e: logger.error(f"Market Data Error: {e}") exit() try: # ohlcvs = market_api.get_ohlcv("005930", "20240101", "20240105") # print(f"Received {len(ohlcvs)} records") ohlcvs = market_api.get_ohlcv("005930", "20240101", "20240105") print(f"Received {len(ohlcvs)} records") # Example: Parsing Price objects print(f"{'Date':<10} | {'Close':<10} | {'Volume':<10}") print("-" * 36) for price in ohlcvs: price: finestock.Price = price # Accessing fields of the Price dataclass print(f"{price.workday:<10} | {price.close:<10} | {price.volume:<10}") except Exception as e: logger.error(f"Market Data Error: {e}") try: logger.info("Fetching Stock List (KOSPI)...") # info_api = api # InfoProvider if hasattr(market_api, 'get_stock_list'): stocks = market_api.get_stock_list("0") # 0: KOSPI print(f"Received {len(stocks)} stocks for KOSPI") print(f"First 5 stocks:") for s in stocks[:5]: print(s) except Exception as e: logger.error(f"Stock List Error: {e}") try: logger.info("Fetching KOSDAQ Index List...") # market_api is typed as MarketDataProvider if using interface, but get_index_list is specific to Kiwoom or extended interface # Since market_api is actually the API instance, we can call it if available if hasattr(market_api, 'get_index_list'): indices = market_api.get_index_list("0") # 0: KOSPI print(f"Received {len(indices)} indices for KOSPI") print(f"First 5 indices:") for idx in indices[:5]: print(f"Code: {idx.code}, Name: {idx.name}, Market: {idx.market}, Group: {idx.group}") except Exception as e: logger.error(f"Index List Error: {e}") try: logger.info("Fetching KOSDAQ 150 Index Data...") # KOSDAQ 150 Code: 150 ohlcvs = market_api.get_index("150", "20260201", "20260213") print(f"Received {len(ohlcvs)} records for KOSDAQ 150") print(f"{'Date':<10} | {'Close':<10} | {'Volume':<10}") print("-" * 36) for price in ohlcvs: price: finestock.Price = price print(f"{price.workday:<10} | {price.close:<10} | {price.volume:<10}") except Exception as e: logger.error(f"KOSDAQ 150 Error: {e}") try: logger.info("Fetching Orderbook for Samsung Electronics (005930)...") orderbook = market_api.get_orderbook("005930") if orderbook: print(f"Orderbook for {orderbook.code}") print(f"Total Buy: {orderbook.total_buy}, Total Sell: {orderbook.total_sell}") print("Sell Side (Top 5):") for h in orderbook.sell[:5]: print(f" Price: {h.price}, Qty: {h.qty}") print("Buy Side (Top 5):") for h in orderbook.buy[:5]: print(f" Price: {h.price}, Qty: {h.qty}") else: print("Orderbook empty or failed.") except Exception as e: logger.error(f"Orderbook Error: {e}") # 4. Trading (Sync) logger.info("Trading Example...") trading_api: TradingProvider = api if isinstance(trading_api, TradingProvider): try: # Example: Buy Samsung Electronics (005930) 1 share at Market Price # trde_tp 3: Market Price, 0: Limit Price # In do_order, price=0 means Market Price (trde_tp="3") # Uncomment to execute # logger.info("Placing Buy Order for 005930 (1 qty, Market Price)...") #result = trading_api.do_order("005930", finestock.ORDER_FLAG.BUY, 0, 1) #result = trading_api.do_order("005930", finestock.ORDER_FLAG.BUY, 173000, 1) #result = trading_api.do_order("005930", finestock.ORDER_FLAG.BUY, 176000, 1) result = trading_api.do_order_cancel("0157069", "005930", 1) #result = trading_api.do_order("005930", finestock.ORDER_FLAG.SELL, 177200, 1) print(f"Order Result: {result}") #print("To place an order, uncomment the lines in the script.") # Example: Cancel Order # logger.info("Cancelling Order 0000140 for 005930 (1 qty)...") # result = trading_api.do_order_cancel("0000140", "005930", 1) # print(f"Cancel Result: {result}") except Exception as e: logger.error(f"Trading Error: {e}") # 5. Account (Sync) logger.info("Account Example...") account_api: AccountProvider = api if isinstance(account_api, AccountProvider): try: logger.info("Fetching Account Balance...") balance = account_api.get_balance() if balance: print(f"Account: {balance.account_num}") print(f"Deposit: {balance.deposit}") print(f"Next Deposit: {balance.next_deposit}") print(f"Pay Deposit: {balance.pay_deposit}") else: print("Failed to get balance.") logger.info("Fetching Account Holdings...") holds = account_api.get_holds() print(f"Received {len(holds)} holdings") if holds: print(f"{'Code':<10} | {'Name':<20} | {'Qty':<10} | {'Eval':<15}") print("-" * 60) for h in holds: print(f"{h.code:<10} | {h.name:<20} | {h.qty:<10} | {h.eval:<15}") else: print("No holdings or failed to fetch.") except Exception as e: logger.error(f"Account Error: {e}") if __name__ == "__main__": main()