-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathFAQ.html
More file actions
646 lines (593 loc) · 27.1 KB
/
Copy pathFAQ.html
File metadata and controls
646 lines (593 loc) · 27.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FAQ - KiwoomRestApi.Net</title>
<style>
:root {
--bg: #ffffff;
--surface: #f8f9fa;
--border: #e2e6ea;
--text: #1a1a2e;
--text-secondary: #5a6070;
--accent: #4361ee;
--accent-light: #eef1ff;
--green: #2d9e6a;
--orange: #e07c24;
--code-bg: #f1f3f5;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
color: var(--text);
background: var(--bg);
line-height: 1.6;
}
/* Top Navigation */
.topnav {
position: fixed;
top: 0; left: 0; right: 0;
height: 52px;
background: var(--bg);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 32px;
z-index: 100;
}
.topnav-brand {
font-size: 15px;
font-weight: 700;
color: var(--text);
text-decoration: none;
margin-right: 32px;
}
.topnav a {
font-size: 13px;
font-weight: 500;
color: var(--text-secondary);
text-decoration: none;
padding: 6px 14px;
border-radius: 4px;
transition: all 0.15s;
}
.topnav a:hover { color: var(--accent); background: var(--accent-light); }
.topnav a.active { color: var(--accent); font-weight: 600; }
/* Main */
.main {
max-width: 800px;
margin: 0 auto;
padding: 88px 32px 80px;
}
/* Page Header */
.page-header {
margin-bottom: 40px;
padding-bottom: 24px;
border-bottom: 1px solid var(--border);
}
.page-header h1 {
font-size: 28px;
font-weight: 700;
letter-spacing: -0.5px;
}
.page-header p {
color: var(--text-secondary);
margin-top: 8px;
font-size: 15px;
}
/* Category */
.category {
margin-bottom: 40px;
}
.category-title {
font-size: 14px;
font-weight: 600;
color: var(--accent);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid var(--border);
}
/* FAQ Item */
.faq-item {
border: 1px solid var(--border);
border-radius: 8px;
margin-bottom: 8px;
overflow: hidden;
transition: all 0.2s;
}
.faq-item:hover {
border-color: #c7cdd4;
}
.faq-question {
display: flex;
align-items: center;
gap: 12px;
padding: 16px 20px;
cursor: pointer;
user-select: none;
background: var(--bg);
transition: background 0.15s;
}
.faq-question:hover {
background: var(--surface);
}
.faq-question h3 {
font-size: 14px;
font-weight: 600;
flex: 1;
margin: 0;
}
.faq-icon {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: var(--text-secondary);
transition: transform 0.2s;
flex-shrink: 0;
}
.faq-item.open .faq-icon {
transform: rotate(45deg);
}
.faq-answer {
display: none;
padding: 0 20px 16px 52px;
font-size: 14px;
color: var(--text-secondary);
line-height: 1.7;
}
.faq-item.open .faq-answer {
display: block;
}
.faq-answer p {
margin-bottom: 12px;
}
.faq-answer p:last-child {
margin-bottom: 0;
}
/* Code inline */
code {
font-family: 'SF Mono', 'Cascadia Code', 'Consolas', monospace;
font-size: 13px;
padding: 2px 6px;
border-radius: 3px;
}
/* Code block */
.code-block {
background: var(--surface);
color: var(--text);
border-radius: 8px;
padding: 16px 20px;
margin: 12px 0;
overflow-x: auto;
white-space: pre;
}
/* Info boxes */
.info-box {
background: var(--accent-light);
border-left: 3px solid var(--accent);
border-radius: 0 6px 6px 0;
padding: 12px 14px;
margin: 12px 0;
font-size: 13px;
color: var(--text);
}
.info-box.warn {
background: #fff4e6;
border-left-color: var(--orange);
}
.info-box.tip {
background: #eef8f0;
border-left-color: var(--green);
}
/* Footer */
.footer {
margin-top: 60px;
padding-top: 20px;
border-top: 1px solid var(--border);
font-size: 12px;
color: var(--text-secondary);
}
/* Responsive */
@media (max-width: 768px) {
.main { padding: 72px 16px 60px; }
.faq-answer { padding-left: 20px; }
}
</style>
</head>
<body>
<!-- Top Navigation -->
<nav class="topnav">
<a class="topnav-brand" href="index.html">KiwoomRestApi.Net</a>
<a href="index.html">Home</a>
<a href="api-reference.html">API Reference</a>
<a href="tutorial.html">Tutorial</a>
<a href="FAQ.html" class="active">FAQ</a>
</nav>
<!-- Main Content -->
<main class="main">
<div class="page-header">
<h1>FAQ</h1>
<p>KiwoomRestApi.Net 사용 중 자주 묻는 질문과 답변입니다.</p>
</div>
<!-- ============ Getting Started ============ -->
<div class="category">
<div class="category-title">Getting Started</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>키움 OpenAPI 앱 키와 시크릿 키는 어떻게 발급받나요?</h3>
</div>
<div class="faq-answer">
<p>키움증권 영웅문 홈페이지의 Open API 섹션에서 앱 키를 발급받을 수 있습니다.</p>
<p>발급 절차:</p>
<p>1. 키움증권 홈페이지에 로그인<br>
2. Open API > API 신청 메뉴로 이동<br>
3. 앱 이름과 용도를 입력하여 신청<br>
4. 승인 후 앱 키(App Key)와 시크릿 키(Secret Key)를 확인</p>
<div class="info-box">
발급받은 키는 외부에 노출되지 않도록 안전하게 관리하세요. 환경 변수나 KeyVault 등을 활용하는 것이 좋습니다.
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>지원하는 .NET 버전은 무엇인가요?</h3>
</div>
<div class="faq-answer">
<p>.NET 6.0 이상을 지원합니다.</p>
<p>.NET STANDARD 2.0, 2.1, .NET 6, 7, 8, 10 모두 호환됩니다.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>NuGet 패키지는 어떻게 설치하나요?</h3>
</div>
<div class="faq-answer">
<p>다음 방법 중 하나로 설치할 수 있습니다:</p>
<p><strong>.NET CLI:</strong></p>
<div class="code-block"><code>dotnet add package KiwoomRestApi.Net</code></div>
<p><strong>NuGet 패키지 관리자 콘솔:</strong></p>
<div class="code-block"><code>PM> Install-Package KiwoomRestApi.Net</code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>모의투자와 실거래의 차이는 무엇인가요?</h3>
</div>
<div class="faq-answer">
<p>클라이언트 생성 시 <code>isMock</code> 파라미터로 구분합니다:</p>
<div class="code-block"><code><span style="color:#6a9955">/* 모의투자 (테스트용) */</span>
<span style="color:#3651d4">var</span> client = KiwoomRestApiClient.Create(appKey, secretKey, isMock: <span style="color:#3651d4">true</span>);
<span style="color:#6a9955">/* 실거래 */</span>
<span style="color:#3651d4">var</span> client = KiwoomRestApiClient.Create(appKey, secretKey, isMock: <span style="color:#3651d4">false</span>);</code></div>
<p>모의투자 모드에서는 일부 API(출금, 특정 계좌 조회 등)가 제한될 수 있습니다.</p>
<div class="info-box warn">
모의투자와 실거래는 각각 별도의 앱 키가 필요합니다.
</div>
</div>
</div>
</div>
<!-- ============ Authentication ============ -->
<div class="category">
<div class="category-title">Authentication</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>접근 토큰은 자동으로 관리되나요?</h3>
</div>
<div class="faq-answer">
<p>네. <code>KiwoomRestApiClient.Create</code> 또는 <code>CreateAsync</code>를 호출하면 자동으로 OAuth 2.0 접근 토큰이 발급됩니다. 클라이언트 내부에서 토큰을 관리하므로 별도로 처리할 필요가 없습니다.</p>
<div class="code-block"><code><span style="color:#6a9955">/* Create 시 자동으로 토큰 발급 */</span>
<span style="color:#3651d4">var</span> client = KiwoomRestApiClient.Create(appKey, secretKey, isMock: <span style="color:#3651d4">true</span>);
<span style="color:#6a9955">/* 토큰 수동 접근 */</span>
<span style="color:#3651d4">var</span> token = client.Token;</code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>토큰 만료 시 어떻게 되나요?</h3>
</div>
<div class="faq-answer">
<p>키움 REST API의 접근 토큰은 발급 후 일정 시간이 지나면 만료됩니다. 만료된 경우 새로운 클라이언트를 생성하거나 <code>GetAccessTokenAsync</code>를 호출하여 토큰을 재발급받아야 합니다.</p>
</div>
</div>
</div>
<!-- ============ API Usage ============ -->
<div class="category">
<div class="category-title">API Usage</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>페이지네이션은 어떻게 처리하나요?</h3>
</div>
<div class="faq-answer">
<p>대량의 데이터를 조회할 때는 응답의 <code>ContYn</code>과 <code>NextKey</code>를 사용하여 페이지네이션을 처리합니다:</p>
<div class="code-block"><code>
<span style="color:#3651d4">var</span> result = <span style="color:#3651d4">await</span> client.Chart.GetTickChartsAsync(<span style="color:#ea580c">"005930"</span>, 1, <span style="color:#3651d4">false</span>);
<span style="color:#3651d4">if</span> (result.ContYn)
{
client.ContYn = <span style="color:#3651d4">true</span>;
client.NextKey = result.NextKey;
<span style="color:#3651d4">var</span> nextPage = <span style="color:#3651d4">await</span> client.Chart.GetTickChartsAsync(<span style="color:#ea580c">""</span>, 1, <span style="color:#3651d4">false</span>);
}</code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>API 호출 속도 제한이 있나요?</h3>
</div>
<div class="faq-answer">
<p>키움 REST API에는 초당 호출 횟수 제한이 있습니다. 제한을 초과하면 에러가 반환됩니다.</p>
<p><code>PagingDelay</code> 속성을 사용하여 페이지네이션 시 자동으로 지연을 줄 수 있습니다:</p>
<div class="code-block"><code>client.PagingDelay = 1000; <span style="color:#6a9955">// 페이지 간 1초 지연</span></code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>어떤 Enum 타입을 사용해야 하나요?</h3>
</div>
<div class="faq-answer">
<p>모든 API 파라미터는 타입 안전한 Enum으로 제공됩니다. 각 API 메서드의 파라미터에 맞는 Enum을 사용하면 됩니다:</p>
<div class="code-block"><code><span style="color:#6a9955">/* 각 네임스페이스별 Enum */</span>
<span style="color:#3651d4">using</span> KiwoomRestApi.Net.Enums.Account;
<span style="color:#3651d4">using</span> KiwoomRestApi.Net.Enums.StockInfo;
<span style="color:#3651d4">using</span> KiwoomRestApi.Net.Enums.Order;
<span style="color:#3651d4">using</span> KiwoomRestApi.Net.Enums.Chart;
<span style="color:#6a9955">// ... 기타</span></code></div>
<p>전체 Enum 목록은 <a href="api-reference.html" style="color:var(--accent); text-decoration:none; border-bottom:1px dashed var(--accent);">API Reference</a>의 Enums 섹션에서 확인할 수 있습니다.</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>모의투자에서 사용할 수 없는 API가 있나요?</h3>
</div>
<div class="faq-answer">
<p>네, 일부 API는 모의투자 모드에서 지원되지 않습니다:</p>
<p><strong>모의투자 미지원 API 예시:</strong></p>
<p>• 출금 가능 금액 조회 (<code>GetAvailableWithdrawalAmountsAsync</code>)<br>
• 위탁계좌 체결내역 조회 (<code>GetConsignedTransactionsAsync</code>)<br>
• 신용융자주문 조회 (<code>GetCreditDepositOrdersAsync</code>)<br>
• 대출/신용 관련 API<br>
• 금현물 주문 (Gold Spot 주문/수정/취소)</p>
<div class="info-box">
API Reference에서 <code>no mock</code> 태그가 있는 API는 모의투자에서 사용할 수 없습니다.
</div>
</div>
</div>
</div>
<!-- ============ WebSocket ============ -->
<div class="category">
<div class="category-title">WebSocket / Real-time</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>WebSocket 실시간 데이터는 어떻게 시작하나요?</h3>
</div>
<div class="faq-answer">
<p>REST API 클라이언트에서 토큰을 가져와 WebSocket 클라이언트를 생성한 후, 구독할 서비스와 종목 코드를 지정합니다:</p>
<div class="code-block"><code><span style="color:#3651d4">var</span> socketClient = KiwoomSocketClient.Create(client.Token, isMock: <span style="color:#3651d4">true</span>);
<span style="color:#6a9955">/* 이벤트 핸들러 등록 */</span>
socketClient.OnRealtimeStockTradeReceived += (data) => {
<span style="color:#6a9955">// 체결 데이터 처리</span>
};
<span style="color:#6a9955">/* 구독 시작 */</span>
<span style="color:#3651d4">await</span> socketClient.WebSocket.SubscribeAsync(
serviceNames: [KiwoomWebSocketServiceName.StockTrade],
parameters: [<span style="color:#ea580c">"005930"</span>],
groupId: <span style="color:#ea580c">"1"</span>
);</code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>어떤 실시간 서비스를 사용할 수 있나요?</h3>
</div>
<div class="faq-answer">
<p>다음 실시간 서비스를 지원합니다:</p>
<p>• <strong>StockTrade</strong> — 주식 체결 데이터<br>
• <strong>OrderBook</strong> — 주식 호가<br>
• <strong>Balance</strong> — 잔고<br>
• <strong>OrderTrade</strong> — 주문 체결<br>
• <strong>ViEvent</strong> — VI 발동<br>
• <strong>EtfNav</strong> — ETF NAV<br>
• <strong>ElwTheoreticalPrice</strong> — ELW 이론가<br>
• <strong>ElwIndicator</strong> — ELW 지표<br>
• <strong>StockInfo</strong> — 주식 기본 정보<br>
• <strong>BestQuote</strong> — 우선호가<br>
• <strong>StockTrend</strong> — 주식 추이<br>
• <strong>ExpectedTrade</strong> — 예상 체결<br>
• <strong>IndustryIndex</strong> — 업종 지수<br>
• <strong>IndustryChange</strong> — 업종 등락<br>
• <strong>ProgramTransaction</strong> — 프로그램 매매<br>
• <strong>DailyBroker</strong> — 일중 증권사<br>
• <strong>MarketOpenTime</strong> — 장시작 시간<br>
• <strong>AfterMarketQuote</strong> — 주식시간외호가<br>
• <strong>InternationalGoldPrice</strong> — 국제금환산가격</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>WebSocket 연결이 끊어지면 어떻게 되나요?</h3>
</div>
<div class="faq-answer">
<p>WebSocket 연결이 끊어지면 이벤트 수신이 중단됩니다. 자동 재연결 로직을 직접 구현해야 합니다:</p>
<div class="code-block"><code><span style="color:#3651d4">try</span>
{
<span style="color:#3651d4">await</span> socketClient.WebSocket.SubscribeAsync(...);
}
<span style="color:#3651d4">catch</span> (WebSocketException)
{
<span style="color:#6a9955">// 재연결 로직</span>
<span style="color:#3651d4">await</span> Task.Delay(TimeSpan.FromSeconds(5));
socketClient = KiwoomSocketClient.Create(client.Token, isMock);
<span style="color:#3651d4">await</span> socketClient.WebSocket.SubscribeAsync(...);
}</code></div>
</div>
</div>
</div>
<!-- ============ Trading ============ -->
<div class="category">
<div class="category-title">Trading</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>시장가와 지정가 주문의 차이는 무엇인가요?</h3>
</div>
<div class="faq-answer">
<p><code>TransactionType</code> 파라미터로 구분합니다:</p>
<div class="code-block"><code><span style="color:#6a9955">/* 시장가 주문 - 즉시 체결 */</span>
<span style="color:#3651d4">await</span> client.Order.PlaceOrderAsync(
orderType: KiwoomOrderType.Buy,
domesticStockExchangeType: KiwoomOrderDomesticStockExchangeType.Krx,
stockCode: <span style="color:#ea580c">"005930"</span>,
orderQuantity: 10,
transactionType: KiwoomOrderTransactionType.Market
);
<span style="color:#6a9955">/* 지정가 주문 - 특정 가격에 체결 */</span>
<span style="color:#3651d4">await</span> client.Order.PlaceOrderAsync(
orderType: KiwoomOrderType.Buy,
domesticStockExchangeType: KiwoomOrderDomesticStockExchangeType.Krx,
stockCode: <span style="color:#ea580c">"005930"</span>,
orderQuantity: 10,
transactionType: KiwoomOrderTransactionType.Normal,
orderPrice: 75000
);</code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>주문을 취소하거나 수정할 수 있나요?</h3>
</div>
<div class="faq-answer">
<p>네, 미체결 주문에 대해 취소 및 수정이 가능합니다:</p>
<div class="code-block"><code><span style="color:#6a9955">/* 주문 취소 */</span>
<span style="color:#3651d4">await</span> client.Order.CancelOrderAsync(
domesticStockExchangeType: KiwoomOrderDomesticStockExchangeType.Krx,
originalOrderId: <span style="color:#ea580c">"주문번호"</span>,
stockCode: <span style="color:#ea580c">"005930"</span>,
cancelQuantity: 5
);
<span style="color:#6a9955">/* 주문 수정 (수량, 가격 변경) */</span>
<span style="color:#3651d4">await</span> client.Order.ModifyOrderAsync(
domesticStockExchangeType: KiwoomOrderDomesticStockExchangeType.Krx,
originalOrderId: <span style="color:#ea580c">"주문번호"</span>,
stockCode: <span style="color:#ea580c">"005930"</span>,
modifyQuantity: 15,
modifyPrice: 76000
);</code></div>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>금현물 거래도 지원하나요?</h3>
</div>
<div class="faq-answer">
<p>네, 금현물 거래를 완벽하게 지원합니다:</p>
<div class="code-block"><code><span style="color:#6a9955">/* 금현물 매수 */</span>
<span style="color:#3651d4">await</span> client.Order.GoldSpotPlaceOrderAsync(
orderType: KiwoomOrderType.Buy,
stockCode: KiwoomGoldSpotStockCode.MiniGold_100g,
orderQuantity: 1,
transactionType: KiwoomOrderGoldSpotTransactionType.Normal
);
<span style="color:#6a9955">/* 금현물 잔고 조회 */</span>
<span style="color:#3651d4">await</span> client.Account.GetGoldEvaluationBalancesAsync();</code></div>
<div class="info-box warn">
금현물 거래는 모의투자 모드에서 지원되지 않습니다.
</div>
</div>
</div>
</div>
<!-- ============ Troubleshooting ============ -->
<div class="category">
<div class="category-title">Troubleshooting</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>"접근토큰 발급에 실패했습니다" 오류가 발생합니다.</h3>
</div>
<div class="faq-answer">
<p>다음 사항을 확인하세요:</p>
<p>• 앱 키와 시크릿 키가 올바른지 확인<br>
• 모의투자/실거래에 맞는 키를 사용 중인지 확인<br>
• 키움증권에서 API 승인이 완료되었는지 확인<br>
• 앱 키에 공백이 포함되지 않았는지 확인</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>API 호출 시 "조회가능한 건수를 초과하였습니다" 에러가 발생합니다.</h3>
</div>
<div class="faq-answer">
<p>키움 REST API의 호출 횟수 제한을 초과한 경우입니다. 다음 방법으로 해결할 수 있습니다:</p>
<p>• API 호출 사이에 적절한 지연을 추가하세요<br>
• <code>PagingDelay</code> 속성을 사용하여 페이지네이션 간 지연을 설정하세요<br>
• 불필요한 API 호출을 줄이세요</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>응답 데이터가 null로 반환됩니다.</h3>
</div>
<div class="faq-answer">
<p>다음을 확인하세요:</p>
<p>• <code>IsSuccess</code>가 <code>true</code>인지 확인<br>
• 조회 조건(날짜, 종목 코드 등)이 올바른지 확인<br>
• 해당 날짜에 거래 데이터가 존재하는지 확인 (휴일, 장외 시간 등)<br>
• 모의투자 모드에서 지원되는 API인지 확인</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" onclick="toggleFaq(this)">
<div class="faq-icon">+</div>
<h3>WebSocket 이벤트가 수신되지 않습니다.</h3>
</div>
<div class="faq-answer">
<p>다음을 확인하세요:</p>
<p>• <code>SubscribeAsync</code>가 정상적으로 호출되었는지 확인<br>
• 이벤트 핸들러가 <code>SubscribeAsync</code> 호출 <strong>이전에</strong> 등록되었는지 확인<br>
• 종목 코드가 올바른지 확인<br>
• 장 시간 중인지 확인 (일부 서비스는 장 시간에만 동작)<br>
• REST API 클라이언트와 동일한 모의투자/실거래 모드인지 확인</p>
</div>
</div>
</div>
<div class="footer">
© 2025 KiwoomRestApi.Net Project. MIT Licensed.
</div>
</main>
<script>
function toggleFaq(el) {
const item = el.closest('.faq-item');
const wasOpen = item.classList.contains('open');
// Close all other items
document.querySelectorAll('.faq-item.open').forEach(openItem => {
openItem.classList.remove('open');
});
// Toggle current
if (!wasOpen) {
item.classList.add('open');
}
}
</script>
</body>
</html>