반응형
SMALL

 

주식 투자 A to Z: 초보자를 위한 완벽 가이드

주식투자
A부터 Z
완벽가이드 (주식)

주식 투자를 시작하고 싶지만 어디서부터 접근해야 할지 막막하신가요? 이 글에서는 주식의 기본 개념부터 시장 분석, 투자 전략까지 단계별로 알려드립니다. 특히 최근 시장 동향과 함께 실전에서 바로 활용할 수 있는 팁을 담았어요. 주식 투자의 세계를 함께 탐험해볼까요?

주식 투자 첫걸음: 기본 개념 이해

주식 투자 첫걸음: 기본 개념 이해 (watercolor 스타일)

주식은 회사의 일부를 소유한다는 의미예요. 주식을 구매하면 해당 기업의 주주가 되어 이익 분배권과 의결권을 얻을 수 있죠. 예를 들어 삼성전자 주식을 보유하면 삼성의 성장에 따른 이익을 나눠받을 수 있어요.

주식 투자의 핵심 원리는 단순해 보이지만 실행이 어려워요. 바로 ‘싸게 사서 비싸게 판다’는 기본 원칙이죠. 하지만 주가 변동에는 기업 실적, 경제 상황, 투자 심리 등 다양한 요소가 복합적으로 작용합니다. 따라서 단순한 직관보다 체계적인 분석이 필요해요.

초보 투자자라면 소액으로 시작하는 것이 좋아요. 10만원 정도로도 국내 주식 투자가 가능합니다. 특히 분산 투자를 통해 위험을 줄이고, 장기적인 관점으로 접근하는 것이 성공의 열쇠예요.

KRX 한국거래소

주식 시장의 작동 원리

주식 시장은 공급과 수요에 따라 가격이 결정돼요. 많은 사람이 사려는 주식은 가격이 오르고, 팔려는 사람이 많으면 가격이 내려갑니다. 이 과정에서 증권사 호가 창을 통해 매매가 이루어지죠.

2024년 주식 시장 현황 분석

2024년 주식 시장 현황 분석 (watercolor 스타일)

최근 주식 시장은 롤러코스터 같은 등락을 반복하고 있어요. 미국 나스닥 지수가 12% 급등한 반면, 국내 코스피는 2400선을 오르내리며 불안정한 모습을 보였습니다. 특히 기술주 중심의 변동성이 두드러지고 있죠.

주요 지표를 살펴보면 미국의 실질임금 상승이 눈에 띄어요. 명목 임금 4.3% 상승에 물가상승률 2.8%로 실질임금이 1.5% 증가했어요. 이는 소비 여력 증가로 이어져 기업 실적 향상이 기대되는 상황입니다.

하지만 미중 무역 갈등과 금리 변동성은 여전히 리스크 요인이에요. 투자 시 업종별 차별화된 접근이 필요한 시점입니다. 4분기에는 반도체, AI 관련주가 주목받을 전망이에요.

국내외 주요 지표 비교

미국 S&P500의 PER은 20배대로 낮아진 반면, 국내 코스피 PER은 12배 수준입니다. 이 같은 차이는 환율과 경제 성장률 차이에서 비롯되죠. 투자 시 글로벌 시장 연관성을 고려해야 하는 이유예요.

현명한 투자 전략 3가지

현명한 투자 전략 3가지 (popart 스타일)

성공적인 투자를 위한 첫 번째 전략은 ‘분할 매수’예요. 특히 나스닥 지수 하락 시 낙폭이 큰 우량주를 단계적으로 매수하는 방법이 효과적이죠. 테슬라 같은 종목은 50% 이상 하락했을 때 기회로 볼 수 있어요.

두 번째는 배당 성장주 포트폴리오 구성이에요. 시가총액 100억 이상, PER 4-8배, 배당수익률 5% 이상인 기업을 선별해 투자하는 방법입니다. 키움증권의 스크리닝 기능으로 쉽게 검색할 수 있죠.

마지막으로 ETF를 활용한 분산 투자도 추천해요. 특정 산업이나 테마에 집중된 ETF를 선택하면 개별 종목 분석 부담을 줄일 수 있습니다. 특히 해외 ETF는 환헤지 상품을 고려해보세요.

키움증권 바로가기

단기 vs 장기 투자 비교

단기 트레이딩은 시장 타이밍이 중요해요. 반면 장기 투자는 기업의 근본적 가치(Fundamental) 분석에 집중해야 합니다. 자신의 성향에 맞는 전략을 선택하는 것이 가장 중요하죠.

주가 변동의 5대 요인

주가 변동의 5대 요인 (illustration 스타일)

경제 상황이 주가에 미치는 영향은 지대해요. 금리 인상은 기업의 자금 조달 비용을 증가시켜 주가 하락 요인이 됩니다. 반면 금리 인하는 유동성을 증가시켜 주식 시장에 긍정적이죠.

기업 실적은 가장 직접적인 영향 요소예요. 예상치를 상회하는 분기 실적은 주가 급등의 계기가 됩니다. 최근 삼성전자의 반도체 사업 호조 소식이 주가 상승으로 이어진 사례가 대표적이죠.

정치적 불안정과 국제 분쟁도 무시할 수 없어요. 우크라이나 사태 당시 국내 방산주가 상승한 반면, 해외 의존도 높은 기업들은 타격을 입었습니다.

투자 심리의 중요성

공포와 탐욕 지수(Fear & Greed Index)를 주시하세요. 지나친 공포는 매수 기회, 과도한 탐욕은 매도 신호로 해석할 수 있어요. 투자 심리 지표를 활용하면 시장 전환점을 예측하는 데 도움이 됩니다.

투자 심리 관리법 5계명

투자 심리 관리법 5계명 (illustration 스타일)

첫째, 미리 투자 원칙을 수립하세요. ‘10% 하락시 추가 매수’, ‘20% 수익 시 부분 매도’ 등 구체적인 기준을 세워두는 게 중요해요. 이렇게 하면 감정에 휩쓸리지 않을 수 있죠.

둘째, 분산 투자를 철저히 하세요. 단일 종목에 모든 자금을 투자하는 것은 위험합니다. 업종별, 지역별로 자산을 분배하면 리스크를 줄일 수 있어요.

셋째, 정보 과부하를 경계하세요. 주가 체크는 하루 2-3회로 제한하는 게 좋아요. 지나친 모니터링은 오히려 잘못된 판단을 유발할 수 있죠.

넷째, 손실을 인정할 줄 아는 용기가 필요해요. 모든 투자가 성공할 수는 없습니다. 초기 투자금의 10%만 테스트 용도로 사용해보는 것도 방법이에요.

다섯째, 투자 일기를 작성하세요. 매매 이유와 결과를 기록하면 향후 투자에 귀중한 자료가 됩니다. 특히 실패 사례를 분석하는 것이 중요하죠.

명상의 효과

하루 10분 명상이 투자 결정력 향상에 도움을 줍니다. 연구에 따르면 규칙적인 명상이 충동적 결정을 30% 이상 줄인다고 해요. 투자 전 명상으로 마음을 가다듬어보세요.

주식 투자 필수 세금 공략

주식 투자 필수 세금 공략 (watercolor 스타일)

양도소득세는 주식 매매 이익에 부과되는 세금이에요. 1주당 매수 가격과 매도 가격 차액에 대해 과세되며, 보유 기간에 따라 세율이 달라집니다.

배당소득세는 15.4%의 분리과세가 적용돼요. 다만, 배당금이 연간 200만원 이하일 경우 비과세되는 점 기억하세요. 배당 지급일 전후로 주가가 조정되는 패턴도 확인해야 합니다.

증여세는 주식 증여 시 발생해요. 1억원 이하는 10% 세율이 적용되며, 직계존속에게 증여할 경우 공제 한도가 더 넓어요. 증여 전 전문가와 상담하는 것이 좋습니다.

세금 절약 팁

장기 보유 시 세율 혜택을 받을 수 있어요. 특히 3년 이상 보유한 주식은 양도세율이 인하됩니다. 또한 퇴직연금 계좌(IRP)를 활용하면 과세 이연 효과를 누릴 수 있죠.

2024년 하반기 투자 전망

2024년 하반기 투자 전망 (illustration 스타일)

AI와 반도체 산업이 여전히 핵심 테마예요. 특히 생성형 AI 관련 기업들의 실적 성장이 기대됩니다. 엔비디아, AMD 같은 글로벌 기업뿐 아니라 국내 2차 전지 업체도 주목받고 있죠.

미국 연준의 금리 정책이 중요한 변수예요. 인플레이션이 안정화되면 금리 인하 가능성이 높아지며, 이는 주식 시장에 긍정적일 전망입니다. 특히 기술주 중심의 반등이 예상되요.

국내에서는 정부의 기업 가치 제고 정책이 주목할 만해요. 저평가된 우량 기업들의 주가 회복이 기대되는 시점입니다. 특히 4분기에는 연말 행군 효과로 시장이 활성화될 가능성이 있죠.

신흥 시장 기회

베트남, 인도 등 신흥 시장의 성장 가능성이 주목받고 있어요. 글로벌 공급망 재편에 따른 수혜를 볼 수 있는 시장입니다. 특히 베트남 ETF는 안정적인 성장이 예상되는 투자처예요.

주식 투자 성공을 위한 마음가짐

주식 투자 성공을 위한 마음가짐 (cartoon 스타일)

주식 투자는 마라톤과 같아요. 단기적인 등락에 일희일비하지 않고 장기적인 관점을 유지하는 것이 중요합니다. 특히 초보자는 첫 1년을 학습 기간으로 삼는 것이 좋아요.

실패를 두려워하지 마세요. 모든 성공한 투자자에게는 실패 경험이 있습니다. 중요한 건 실수로부터 배우는 것이죠. 매매일지를 꾸준히 작성하면 투자 실력이 자연스럽게 향상될 거예요.

마지막으로, 투자와 삶의 균형을 잊지 마세요. 주식 시장에만 매몰되면 오히려 판단력이 흐려질 수 있습니다. 적당한 거리를 유지하는 현명한 투자자가 되시길 바랍니다.

지속 가능한 투자 습관

매월 투자 계획을 세우고 검토하는 루틴을 만들어보세요. 수익률보다 과정에 집중하면 자연스럽게 좋은 결과가 따라옵니다. 주식 투자는 결국 자기 관리의 연장선이에요.

자주 묻는 질문

주식 투자를 시작하기 전에 가장 먼저 알아야 할 것은 무엇인가요?

주식의 기본적인 개념과 투자 원리를 이해하는 것이 중요합니다. 주식은 회사의 일부분을 나타내는 증서이며, 주주가 되면 배당금과 의결권을 가질 수 있습니다.

주식 투자 시 가장 중요한 원칙은 무엇인가요?

싸게 사서 비싸게 파는 것이 기본 원리이지만, 언제 사고팔지 결정하기 어렵습니다. 회사의 재무 상태와 성장 가능성을 꼼꼼히 분석하는 것이 중요합니다.

주식 시장의 변동성에 어떻게 대응해야 하나요?

장기적인 관점을 유지하고, 분산 투자를 통해 위험을 줄이는 것이 중요합니다. 또한, 시장 상황을 꾸준히 모니터링하고 전문가의 의견을 참고하는 것이 좋습니다.

주식 투자 시 감정적인 결정을 피하는 방법은 무엇인가요?

미리 투자 원칙을 정해두고 객관적인 데이터를 바탕으로 판단하는 것이 중요합니다. 예를 들어, 주가가 특정 비율로 하락하면 추가 매수하거나, 목표 수익률에 도달하면 일부 매도하는 기준을 설정할 수 있습니다.

주식 투자와 관련된 세금에는 어떤 종류가 있나요?

주식 양도소득세, 배당소득세, 증권거래세 등이 있습니다. 주식 증여 시에는 증여세도 고려해야 하며, 세무 전문가와 상담하여 정확한 세금 정보를 확인하는 것이 좋습니다.

반응형

'정보' 카테고리의 다른 글

주식 자동화 매매의 모든 것  (0) 2025.04.11
주식거래검색기3탄  (0) 2025.04.11
felo.ai 검색엔진에 모든것  (0) 2025.03.27
신규주식상장및비상장정보확인  (0) 2025.03.26
한국투자증권 자동매매 프로그램  (1) 2025.03.22
반응형
SMALL

반응형
반응형
SMALL

반응형
반응형
SMALL

 

한국투자증권 자동매매 프로그램

API 정보 입력

종목 정보 입력

주문 결과

 

 

계좌 정보

잔고:
보유 주식:

신규 상장 기업

    오늘의 주가 및 거래량

    종목명 현재가 변동률 거래량

    기업별 세무 신고액

    ----------------------------------------------------------------코드소스----------------------------------------------------
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>한국투자증권 자동매매 프로그램</title>
        <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
        <style>
            body {
                font-family: 'Inter', sans-serif;
            }
            /* 추가 스타일 */
            #realtime-stock-table {
                border-collapse: collapse;
                width: 100%;
                margin-top: 20px;
            }
            #realtime-stock-table th, #realtime-stock-table td {
                border: 1px solid #ddd;
                padding: 8px;
                text-align: left;
            }
            #realtime-stock-table th {
                background-color: #f0f0f0;
            }
            .up {
                color: red;
            }
            .down {
                color: blue;
            }
            .even {
                color: black;
            }
        </style>
        <script>
            tailwind.config = {
                theme: {
                    extend: {
                        fontFamily: {
                            'inter': ['Inter', 'sans-serif'],
                        },
                    },
                },
            }
        </script>
    </head>
    <body class="bg-gray-100 p-4">
        <div class="container mx-auto p-6 bg-white rounded-lg shadow-md">
            <h1 class="text-2xl font-semibold text-center text-gray-800 mb-6">한국투자증권 자동매매 프로그램</h1>

            <div id="api-info" class="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">API 정보 입력</h2>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div class="mb-2">
                        <label for="account-number" class="block text-gray-700 text-sm font-bold mb-2">계좌번호:</label>
                        <input type="text" id="account-number" placeholder="계좌번호를 입력하세요" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                    <div class="mb-2">
                        <label for="access-token" class="block text-gray-700 text-sm font-bold mb-2">Access Token:</label>
                        <input type="text" id="access-token" placeholder="Access Token을 입력하세요" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                    <div class="mb-2">
                        <label for="app-key" class="block text-gray-700 text-sm font-bold mb-2">App Key:</label>
                        <input type="text" id="app-key" placeholder="App Key를 입력하세요" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                    <div class="mb-2">
                        <label for="app-secret" class="block text-gray-700 text-sm font-bold mb-2">App Secret:</label>
                        <input type="text" id="app-secret" placeholder="App Secret을 입력하세요" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                </div>
            </div>

            <div id="stock-info" class="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">종목 정보 입력</h2>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div class="mb-2">
                        <label for="stock-code" class="block text-gray-700 text-sm font-bold mb-2">종목 코드:</label>
                        <input type="text" id="stock-code" placeholder="종목 코드를 입력하세요" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                    <div class="mb-2">
                        <label for="quantity" class="block text-gray-700 text-sm font-bold mb-2">매수/매도 수량:</label>
                        <input type="number" id="quantity" value="1" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                     <div class="mb-2">
                        <label for="price" class="block text-gray-700 text-sm font-bold mb-2">매수/매도 가격 (지정가):</label>
                        <input type="number" id="price" placeholder="매수/매도 가격을 입력하세요 (선택 사항)" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                </div>
            </div>

            <div id="transaction-buttons" class="flex justify-center space-x-4 mb-6">
                <button id="buy-button" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">매수</button>
                <button id="sell-button" class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">매도</button>
                <button id="cancel-button" class="bg-yellow-500 hover:bg-yellow-700 text-gray-800 font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">취소</button>
            </div>

            <div id="order-results" class="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">주문 결과</h2>
                <div id="result-message" class="text-gray-700"></div>
            </div>

            <div id="account-info" class="p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">계좌 정보</h2>
                <div id="account-balance" class="text-gray-700 mb-2">잔고: </div>
                <div id="stock-holdings" class="text-gray-700">보유 주식: </div>
            </div>

            <div id="new-listings" class="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">신규 상장 기업</h2>
                <ul id="new-listings-list" class="list-disc list-inside text-gray-700">
                    </ul>
            </div>

            <div id="realtime-stock-info" class="p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">오늘의 주가 및 거래량</h2>
                <table id="realtime-stock-table">
                    <thead>
                        <tr>
                            <th>종목명</th>
                            <th>현재가</th>
                            <th>변동률</th>
                            <th>거래량</th>
                        </tr>
                    </thead>
                    <tbody>
                        </tbody>
                </table>
            </div>

            <div id="tax-info" class="p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h2 class="text-lg font-semibold text-gray-700 mb-4">기업별 세무 신고액</h2>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div class="mb-2">
                        <label for="company-code" class="block text-gray-700 text-sm font-bold mb-2">회사 코드:</label>
                        <input type="text" id="company-code" placeholder="회사 코드를 입력하세요" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                    <div class="mb-2">
                        <label for="year" class="block text-gray-700 text-sm font-bold mb-2">년도:</label>
                        <input type="number" id="year" value="2023" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
                    </div>
                </div>
                <button id="show-tax-button" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">세무 신고액 조회</button>
                <div id="tax-result" class="mt-4 text-gray-700"></div>
            </div>
        </div>

        <script>
            const accountNumberInput = document.getElementById('account-number');
            const accessTokenInput = document.getElementById('access-token');
            const appKeyInput = document.getElementById('app-key');
            const appSecretInput = document.getElementById('app-secret');
            const stockCodeInput = document.getElementById('stock-code');
            const quantityInput = document.getElementById('quantity');
            const priceInput = document.getElementById('price');
            const buyButton = document.getElementById('buy-button');
            const sellButton = document.getElementById('sell-button');
            const cancelButton = document.getElementById('cancel-button');
            const resultMessage = document.getElementById('result-message');
            const accountBalanceDisplay = document.getElementById('account-balance');
            const stockHoldingsDisplay = document.getElementById('stock-holdings');
            const newListingsList = document.getElementById('new-listings-list');
            const realtimeStockTable = document.getElementById('realtime-stock-table').getElementsByTagName('tbody')[0];
            const companyCodeInput = document.getElementById('company-code');
            const yearInput = document.getElementById('year');
            const showTaxButton = document.getElementById('show-tax-button');
            const taxResultDisplay = document.getElementById('tax-result');

            // 실제 API 호출 시에는 HTTPS를 사용해야 합니다.
            const API_BASE_URL = 'https://openapi.koreainvestment.com:9443'; // 실전 투자 URL
            // const API_BASE_URL = 'https://openapivts.koreainvestment.com:29443'; // 모의 투자 URL

            let accessToken = '';

            // Access Token 발급 함수 (실제 사용 시에는 보안에 유의하여 서버에서 처리해야 합니다.)
            async function getAccessToken() {
                const appKey = appKeyInput.value;
                const appSecret = appSecretInput.value;

                const tokenUrl = `${API_BASE_URL}/oauth2/token`;

                const requestBody = new URLSearchParams();
                requestBody.append('grant_type', 'client_credentials');
                requestBody.append('appkey', appKey);
                requestBody.append('appsecret', appSecret);

                try {
                    const response = await fetch(tokenUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded',
                        },
                        body: requestBody,
                    });

                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    const data = await response.json();
                    accessToken = data.access_token;
                    console.log('Access Token 발급 성공:', accessToken);
                    return accessToken;

                } catch (error) {
                    console.error('Access Token 발급 실패:', error);
                    resultMessage.textContent = `Access Token 발급 실패: ${error.message}`;
                    return null;
                }
            }

            // 주식 주문 함수
            async function placeOrder(orderType) {
                const accountNumber = accountNumberInput.value;
                const stockCode = stockCodeInput.value;
                const quantity = quantityInput.value;
                const price = priceInput.value; // 지정가 주문 가격
                const accessToken = await getAccessToken();

                 if (!accessToken) {
                    resultMessage.textContent = "Access Token이 없습니다. 발급 후 다시 시도해주세요.";
                    return;
                 }

                const orderUrl = `${API_BASE_URL}/uapi/domestic-stock/v1/trading/order`;
                const header = {
                    'Content-Type': 'application/json; charset=utf-8',
                    'Authorization': `Bearer ${accessToken}`,
                    'appkey': appKeyInput.value,
                    'appsecret': appSecretInput.value,
                    'tr_id': orderType === 'buy' ? (price ? 'TTTC0801U' : 'TTTC0802U') : (price ? 'TTTC0803U' : 'TTTC0804U'), // 매수: TTTC0801U(지정가), TTTC0802U(시장가), 매도: TTTC0803U(지정가), TTTC0804U(시장가)
                    'custtype': 'P',
                };

                const body = {
                    'CANO': accountNumber.substring(0, 8), // 계좌번호 앞 8자리
                    'ACNT_PRDT_CD': accountNumber.substring(8), // 계좌번호 뒤 2자리
                    'PDNO': stockCode,
                    'ORD_QTY': quantity,
                    'ORD_TYPE': price ? '01' : '00', // 00: 시장가, 01: 지정가
                    'ORD_PRICE': price || '', // 지정가인 경우에만 가격 설정
                };

                try {
                    const response = await fetch(orderUrl, {
                        method: 'POST',
                        headers: header,
                        body: JSON.stringify(body),
                    });

                    if (!response.ok) {
                        const errorData = await response.json(); // 에러 응답을 JSON 형태로 파싱
                        let errorMessage = `주문 실패: ${response.status}`;
                        if (errorData && errorData.rt_msg) { // 에러 메시지가 있다면 추가
                            errorMessage += ` - ${errorData.rt_msg}`;
                        }
                        throw new Error(errorMessage);
                    }

                    const data = await response.json();
                    console.log('주문 성공:', data);
                    resultMessage.textContent = `주문 성공: ${data.msg1 || '성공적으로 처리되었습니다.'}`;

                } catch (error) {
                    console.error('주문 실패:', error);
                    resultMessage.textContent = `주문 실패: ${error.message}`;
                }
            }

            // 주문 취소 함수
            async function cancelOrder() {
                 const accountNumber = accountNumberInput.value;
                const stockCode = stockCodeInput.value;
                const accessToken = await getAccessToken();

                 if (!accessToken) {
                    resultMessage.textContent = "Access Token이 없습니다. 발급 후 다시 시도해주세요.";
                    return;
                 }

                const cancelUrl = `${API_BASE_URL}/uapi/domestic-stock/v1/trading/ordercancel`;
                const header = {
                    'Content-Type': 'application/json; charset=utf-8',
                    'Authorization': `Bearer ${accessToken}`,
                    'appkey': appKeyInput.value,
                    'appsecret': appSecretInput.value,
                    'tr_id': 'TTTC0805U', // 주문 취소 TR_ID
                    'custtype': 'P',
                };

                // 주문 취소 시 필요한 정보.  원 주문 번호(org_no)를 알아야 함.
                // 여기서는 예시로 임의의 주문 번호를 사용. 실제로는 주문 체결 내역 조회 API 등을 통해 얻어야 함.
                const body = {
                    'CANO': accountNumber.substring(0, 8),
                    'ACNT_PRDT_CD': accountNumber.substring(8),
                    'KRX_FWDG_ORD_NO': '1234567890',  // !!! 실제 주문 번호로 변경 필요 !!!
                    'PDNO': stockCode,
                    'ORD_QTY': quantityInput.value,
                };

                try {
                    const response = await fetch(cancelUrl, {
                        method: 'POST',
                        headers: header,
                        body: JSON.stringify(body),
                    });

                    if (!response.ok) {
                        const errorData = await response.json();
                        let errorMessage = `주문 취소 실패: ${response.status}`;
                        if (errorData && errorData.rt_msg) {
                             errorMessage += ` - ${errorData.rt_msg}`;
                        }
                        throw new Error(errorMessage);
                    }

                    const data = await response.json();
                    console.log('주문 취소 성공:', data);
                    resultMessage.textContent = `주문 취소 성공: ${data.msg1 || '성공적으로 처리되었습니다.'}`;

                } catch (error) {
                    console.error('주문 취소 실패:', error);
                    resultMessage.textContent = `주문 취소 실패: ${error.message}`;
                }
            }

            // 계좌 잔고 조회 함수
            async function getAccountBalance() {
                const accountNumber = accountNumberInput.value;
                const accessToken = await getAccessToken();

                if (!accessToken) {
                    resultMessage.textContent = "Access Token이 없습니다. 발급 후 다시 시도해주세요.";
                    return;
                }

                const balanceUrl = `${API_BASE_URL}/uapi/domestic-stock/v1/account/balance`;
                const header = {
                    'Content-Type': 'application/json; charset=utf-8',
                    'Authorization': `Bearer ${accessToken}`,
                    'appkey': appKeyInput.value,
                    'appsecret': appSecretInput.value,
                    'tr_id': 'TTTC8434R', // 잔고 조회 TR_ID
                    'custtype': 'P',
                };

                const body = {
                    'CANO': accountNumber.substring(0, 8),
                    'ACNT_PRDT_CD': accountNumber.substring(8),
                    'AFHR_FLUI_ID': '0', // 0: 출금가능금액, 1: 총평가금액
                    'OFL_YN': 'N',
                };

                try {
                    const response = await fetch(balanceUrl, {
                        method: 'GET',
                        headers: header,
                        body: JSON.stringify(body),
                    });

                    if (!response.ok) {
                        const errorData = await response.json();
                        let errorMessage = `잔고 조회 실패: ${response.status}`;
                         if (errorData && errorData.rt_msg) {
                            errorMessage += ` - ${errorData.rt_msg}`;
                        }
                        throw new Error(errorMessage);
                    }

                    const data = await response.json();
                    console.log('계좌 잔고 조회 성공:', data);

                    // 잔고 정보 표시
                    if (data.output && data.output.length > 0) {
                        accountBalanceDisplay.textContent = `잔고: ${parseInt(data.output[0].hldg_sbl_amt).toLocaleString()} 원`;
                    } else {
                        accountBalanceDisplay.textContent = '잔고 정보 없음';
                    }


                } catch (error) {
                    console.error('잔고 조회 실패:', error);
                    resultMessage.textContent = `잔고 조회 실패: ${error.message}`;
                }
            }

            // 계좌 보유 주식 조회 함수
            async function getStockHoldings() {
                const accountNumber = accountNumberInput.value;
                const accessToken = await getAccessToken();
                 if (!accessToken) {
                    resultMessage.textContent = "Access Token이 없습니다. 발급 후 다시 시도해주세요.";
                    return;
                }

                const holdingsUrl = `${API_BASE_URL}/uapi/domestic-stock/v1/account/stock`;
                const header = {
                    'Content-Type': 'application/json; charset=utf-8',
                    'Authorization': `Bearer ${accessToken}`,
                    'appkey': appKeyInput.value,
                    'appsecret': appSecretInput.value,
                    'tr_id': 'TTTC8436R', // 보유 주식 조회 TR_ID
                    'custtype': 'P',
                };

                const body = {
                    'CANO': accountNumber.substring(0, 8),
                    'ACNT_PRDT_CD': accountNumber.substring(8),
                    'AFHR_FLUI_ID': '0',
                    'OFL_YN': 'N',
                    'PRCS_DVSN': '01', // 01: 주식 잔고, 02: 펀드 잔고
                };

                try {
                    const response = await fetch(holdingsUrl, {
                        method: 'GET',
                        headers: header,
                        body: JSON.stringify(body),
                    });

                    if (!response.ok) {
                        const errorData = await response.json();
                        let errorMessage = `보유 주식 조회 실패: ${response.status}`;
                        if (errorData && errorData.rt_msg) {
                            errorMessage += ` - ${errorData.rt_msg}`;
                        }
                        throw new Error(errorMessage);
                    }

                    const data = await response.json();
                    console.log('계좌 보유 주식 조회 성공:', data);

                    // 보유 주식 정보 표시
                    if (data.output && data.output.length > 0) {
                        let holdingsText = '보유 주식: ';
                        data.output.forEach(stock => {
                            holdingsText += `${stock.pdnm}(${stock.hldg_qty}주), `;
                        });
                        holdingsText = holdingsText.slice(0, -2); // 마지막 ', ' 제거
                        stockHoldingsDisplay.textContent = holdingsText;
                    } else {
                        stockHoldingsDisplay.textContent = '보유 주식 정보 없음';
                    }

                } catch (error) {
                    console.error('보유 주식 조회 실패:', error);
                    resultMessage.textContent = `보유 주식 조회 실패: ${error.message}`;
                }
            }

            // 신규 상장 기업 조회 함수 (실제 API 연동 필요)
            async function getNewListings() {
                // 실제로는 한국투자증권 API 또는 다른 데이터 소스를 통해 신규 상장 기업 정보를 가져와야 합니다.
                // 여기서는 임시로 더미 데이터를 사용합니다.
                const newListings = [
                    { name: 'A기업', date: '2024-07-24' },
                    { name: 'B기업', date: '2024-07-25' },
                    { name: 'C기업', date: '2024-07-26' },
                ];

                // Get new listings from OpenDart
                try {
                    const response = await fetch('https://opendart.fss.or.kr/api/existed.json?crp_cd=00126380&bsns_year=2023&api_key=YOUR_API_KEY');
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }
                    const data = await response.json();
                    console.log("OpenDart API 호출 결과", data);
                    //신규상장기업 데이터 처리 로직
                    if (data && Array.isArray(data.list)) {
                        newListingsList.innerHTML = '';
                        data.forEach(item => {
                            const li = document.createElement('li');
                            li.textContent = `${item.crp_nm} (${item.est_dt})`;
                            newListingsList.appendChild(li);
                        });
                    }

                } catch (error) {
                    console.error("신규상장기업 조회 실패", error);
                    resultMessage.textContent = `신규 상장 기업 조회 실패: ${error.message}`;
                }

                // 신규 상장 기업 목록 표시
                newListings.forEach(item => {
                    const li = document.createElement('li');
                    li.textContent = `${item.name} (${item.date})`;
                    newListingsList.appendChild(li);
                });
            }

            // 실시간 주가 조회 함수 (Web Socket API필요)
            async function getRealtimeStockPrice() {
                // 실제로는 한국투자증권 Web Socket API를 사용하여 실시간 주가를 받아와야 합니다.
                // 여기서는 임시로 더미 데이터를 생성하여 표시합니다.
                const dummyStocks = [
                    { name: '삼성전자', currentPrice: 70000, changeRate: 0.5, volume: 1000000 },
                    { name: 'LG전자', currentPrice: 150000, changeRate: -1.2, volume: 500000 },
                    { name: 'SK하이닉스', currentPrice: 120000, changeRate: 0, volume: 800000 },
                ];

                // Clear the table
                realtimeStockTable.innerHTML = '';

                dummyStocks.forEach(stock => {
                    const row = realtimeStockTable.insertRow();
                    const nameCell = row.insertCell();
                    const priceCell = row.insertCell();
                    const changeRateCell = row.insertCell();
                    const volumeCell = row.insertCell();

                    nameCell.textContent = stock.name;
                    priceCell.textContent = stock.currentPrice.toLocaleString();
                    changeRateCell.textContent = `${stock.changeRate.toFixed(2)}%`;
                    changeRateCell.className = stock.changeRate > 0 ? 'up' : stock.changeRate < 0 ? 'down' : 'even';
                    volumeCell.textContent = stock.volume.toLocaleString();
                });
            }

            // 기업별 세무 신고액 조회 함수 (Open Dart API 활용)
            async function getCompanyTaxReport() {
                const companyCode = companyCodeInput.value;
                const year = yearInput.value;
                const apiKey = 'YOUR_API_KEY'; // 여기에 발급받은 API 키를 입력하세요.

                if (!companyCode) {
                    taxResultDisplay.textContent = "회사 코드를 입력해주세요.";
                    return;
                }

                const apiUrl = `https://opendart.fss.or.kr/api/taxReport.json?crp_cd=${companyCode}&bsns_year=${year}&api_key=${apiKey}`;

                try {
                    const response = await fetch(apiUrl);
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }
                    const data = await response.json();
                    console.log('세무 신고액 조회 결과:', data);

                    // 결과 표시
                    if (data && data.list && data.list.length > 0) {
                        let resultText = `
                            <p>회사 코드: ${data.list[0].crp_cd}</p>
                            <p>회사 이름: ${data.list[0].crp_nm}</p>
                            <p>사업 연도: ${data.list[0].bsns_year}</p>
                            <p>법인세액 (천원): ${data.list[0].corp_tax_amt}</p>
                            <p>총 납부액 (천원): ${data.list[0].ttl_pay_amt}</p>
                        `;
                        taxResultDisplay.innerHTML = resultText;
                    } else {
                        taxResultDisplay.textContent = "해당하는 세무 신고 내역이 없습니다.";
                    }

                } catch (error) {
                    console.error('세무 신고액 조회 실패:', error);
                    taxResultDisplay.textContent = `세무 신고액 조회 실패: ${error.message}`;
                }
            }

            // 이벤트 리스너 등록
            buyButton.addEventListener('click', () => placeOrder('buy'));
            sellButton.addEventListener('click', () => placeOrder('sell'));
            cancelButton.addEventListener('click', cancelOrder);
            showTaxButton.addEventListener('click', getCompanyTaxReport);

            // 페이지 로드 시 계좌 정보, 잔고, 신규 상장 기업 정보 및 실시간 주가 조회
            window.onload = async () => {
                if (accountNumberInput.value) {
                    await getAccountBalance();
                    await getStockHoldings();
                }
                await getNewListings();
                getRealtimeStockPrice(); // 최초 1회 호출

                // 5초마다 실시간 주가 갱신 (실제로는 Web Socket을 사용해야 함)
                setInterval(getRealtimeStockPrice, 5000);
            };
        </script>
    </body>
    </html>
    반응형

    + Recent posts