-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#6] 3.02 주식차트 정보 기능 구현 #32
Merged
Merged
Changes from 16 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
08312cd
⚙️ chore: merge conflict 해결
sieunie 4390c3c
✨ feat: stock websocket gateway 구현 #6
sieunie 3a777d6
✨ feat: 주가 그래프 웹소켓 구현 #6
sieunie ad2b3e6
✨ feat: 주가 지수 값 웹소켓 구현 #6
sieunie 5ef98b0
✨ feat: 주가 지수 그래프 및 값 API 구현 #6
sieunie 2796724
📝 docs: 주가 지수 API 명세 추가
sieunie bad5bb0
⚙️ chore: ws 라이브러리 설치
sieunie c9a16a1
♻️ refactor: cron 로직 service 단으로 이동
sieunie 7117aac
♻️ refactor: dto 파일 분리
sieunie c219c6d
✨ feat: 주가 지수 소켓 통신으로 변경
sieunie 335686b
♻️ refactor: return type dto로 변경
sieunie 6aafebe
♻️ refactor: 주가 정보 관련 interface 생성 및 적용 #6
sieunie 60c03e1
🔧 fix: 타입 버그 수정
sieunie e2a14e8
➕ add: module layer 추가 #6
sieunie 93141c4
➕ add: 코스피200, KSQ150 지수 정보 추가 #6
sieunie 9e72aff
⚙️ chore: 린트 오류 해결
sieunie cc860a5
Merge branch 'back/main' into feature/api/stockindex-#6
sieunie File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
BE/src/stock/index/dto/stock.index.list.chart.element.dto.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class StockIndexListChartElementDto { | ||
constructor(time: string, value: string) { | ||
this.time = time; | ||
this.value = value; | ||
} | ||
|
||
@ApiProperty({ description: 'HHMMSS', example: '130500' }) | ||
time: string; | ||
|
||
@ApiProperty({ description: '주가 지수' }) | ||
value: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { StockIndexListChartElementDto } from './stock.index.list.chart.element.dto'; | ||
|
||
export class StockIndexListElementDto { | ||
constructor(code: string, chart: StockIndexListChartElementDto[]) { | ||
this.code = code; | ||
this.chart = chart; | ||
} | ||
|
||
@ApiProperty({ | ||
description: '코스피: 0001, 코스닥: 1001, 코스피200: 2001, KSQ150: 3003', | ||
}) | ||
code: string; | ||
|
||
@ApiProperty({ type: [StockIndexListChartElementDto] }) | ||
chart: StockIndexListChartElementDto[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { StockIndexListElementDto } from './stock.index.list.element.dto'; | ||
import { StockIndexValueElementDto } from './stock.index.value.element.dto'; | ||
|
||
export class StockIndexResponseDto { | ||
constructor( | ||
indexList: StockIndexListElementDto[], | ||
indexValue: StockIndexValueElementDto[], | ||
) { | ||
this.indexList = indexList; | ||
this.indexValue = indexValue; | ||
} | ||
|
||
@ApiProperty({ | ||
description: '주가 지수 차트 정보 (코스피, 코스닥, 코스피200, KSQ150)', | ||
type: [StockIndexListElementDto], | ||
}) | ||
indexList: StockIndexListElementDto[]; | ||
|
||
@ApiProperty({ | ||
description: '주가 지수 실시간 값 정보 (코스피, 코스닥, 코스피200, KSQ150)', | ||
type: [StockIndexValueElementDto], | ||
}) | ||
indexValue: StockIndexValueElementDto[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class StockIndexValueElementDto { | ||
constructor( | ||
code: string, | ||
value: string, | ||
diff: string, | ||
diffRate: string, | ||
sign: string, | ||
) { | ||
this.code = code; | ||
this.value = value; | ||
this.diff = diff; | ||
this.diffRate = diffRate; | ||
this.sign = sign; | ||
} | ||
|
||
@ApiProperty({ | ||
description: '코스피: 0001, 코스닥: 1001, 코스피200: 2001, KSQ150: 3003', | ||
}) | ||
code: string; | ||
|
||
@ApiProperty({ description: '주가 지수' }) | ||
value: string; | ||
|
||
@ApiProperty({ description: '전일 대비 등락' }) | ||
diff: string; | ||
|
||
@ApiProperty({ description: '전일 대비 등락률' }) | ||
diffRate: string; | ||
|
||
@ApiProperty({ description: '부호... 인데 추후에 알아봐야 함' }) | ||
sign: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Controller, Get } from '@nestjs/common'; | ||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; | ||
import { StockIndexService } from './stock.index.service'; | ||
import { StockIndexResponseDto } from './dto/stock.index.response.dto'; | ||
|
||
@Controller('/api/stock/index') | ||
@ApiTags('주가 지수 API') | ||
export class StockIndexController { | ||
constructor(private readonly stockIndexService: StockIndexService) {} | ||
|
||
@Get() | ||
@ApiOperation({ | ||
summary: '주가 지수 차트 정보, 현재 값 조회 API', | ||
description: '주가 지수 차트 정보와 현재 값을 리스트로 반환한다.', | ||
}) | ||
@ApiResponse({ | ||
status: 200, | ||
description: '주가 지수 조회 성공', | ||
type: StockIndexResponseDto, | ||
}) | ||
async getStockIndex() { | ||
const stockLists = await Promise.all([ | ||
this.stockIndexService.getDomesticStockIndexListByCode('0001'), // 코스피 | ||
this.stockIndexService.getDomesticStockIndexListByCode('1001'), // 코스닥 | ||
this.stockIndexService.getDomesticStockIndexListByCode('2001'), // 코스피200 | ||
this.stockIndexService.getDomesticStockIndexListByCode('3003'), // KSQ150 | ||
]); | ||
|
||
const stockValues = await Promise.all([ | ||
this.stockIndexService.getDomesticStockIndexValueByCode('0001'), // 코스피 | ||
this.stockIndexService.getDomesticStockIndexValueByCode('1001'), // 코스닥 | ||
this.stockIndexService.getDomesticStockIndexValueByCode('2001'), // 코스피200 | ||
this.stockIndexService.getDomesticStockIndexValueByCode('3003'), // KSQ150 | ||
]); | ||
|
||
return new StockIndexResponseDto(stockLists, stockValues); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { StockIndexController } from './stock.index.controller'; | ||
import { StockIndexService } from './stock.index.service'; | ||
|
||
@Module({ | ||
imports: [], | ||
controllers: [StockIndexController], | ||
providers: [StockIndexService], | ||
exports: [StockIndexService], | ||
}) | ||
export class StockIndexModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { StockIndexListChartElementDto } from './dto/stock.index.list.chart.element.dto'; | ||
import { StockIndexListElementDto } from './dto/stock.index.list.element.dto'; | ||
import { StockIndexValueElementDto } from './dto/stock.index.value.element.dto'; | ||
|
||
@Injectable() | ||
export class StockIndexService { | ||
private accessToken: string; | ||
private expireDateTime: number; | ||
|
||
async getDomesticStockIndexListByCode(code: string) { | ||
const accessToken = await this.getAccessToken(); | ||
|
||
const url = | ||
'https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-index-timeprice'; | ||
const queryParams = `?FID_INPUT_HOUR_1=300&FID_COND_MRKT_DIV_CODE=U&FID_INPUT_ISCD=${code}`; | ||
|
||
const response = await fetch(url + queryParams, { | ||
method: 'GET', | ||
headers: { | ||
'content-type': 'application/json; charset=utf-8', | ||
authorization: `Bearer ${accessToken}`, | ||
appkey: process.env.APP_KEY, | ||
appsecret: process.env.APP_SECRET, | ||
tr_id: 'FHPUP02110200', | ||
custtype: 'P', | ||
}, | ||
}); | ||
|
||
const result: StockIndexChartInterface = await response.json(); | ||
if (result.rt_cd !== '0') throw new Error('유효하지 않은 토큰'); | ||
|
||
return new StockIndexListElementDto( | ||
code, | ||
result.output.map((element) => { | ||
return new StockIndexListChartElementDto( | ||
element.bsop_hour, | ||
element.bstp_nmix_prpr, | ||
); | ||
}), | ||
); | ||
} | ||
|
||
async getDomesticStockIndexValueByCode(code: string) { | ||
const accessToken = await this.getAccessToken(); | ||
|
||
const url = | ||
'https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-index-price'; | ||
const queryParams = `?FID_COND_MRKT_DIV_CODE=U&FID_INPUT_ISCD=${code}`; | ||
|
||
const response = await fetch(url + queryParams, { | ||
method: 'GET', | ||
headers: { | ||
'content-type': 'application/json; charset=utf-8', | ||
authorization: `Bearer ${accessToken}`, | ||
appkey: process.env.APP_KEY, | ||
appsecret: process.env.APP_SECRET, | ||
tr_id: 'FHPUP02100000', | ||
custtype: 'P', | ||
}, | ||
}); | ||
|
||
const result: StockIndexValueInterface = await response.json(); | ||
return new StockIndexValueElementDto( | ||
code, | ||
result.output.bstp_nmix_prpr, | ||
result.output.bstp_nmix_prdy_vrss, | ||
result.output.bstp_nmix_prdy_vrss, | ||
result.output.prdy_vrss_sign, | ||
); | ||
} | ||
|
||
private async getAccessToken() { | ||
if (!this.accessToken || this.expireDateTime <= Date.now()) { | ||
const url = 'https://openapivts.koreainvestment.com:29443/oauth2/tokenP'; | ||
const response = await fetch(url, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json; charset=UTF-8', | ||
}, | ||
body: JSON.stringify({ | ||
grant_type: 'client_credentials', | ||
appkey: process.env.APP_KEY, | ||
appsecret: process.env.APP_SECRET, | ||
}), | ||
}); | ||
const result: AccessTokenInterface = await response.json(); | ||
this.accessToken = result.access_token; | ||
this.expireDateTime = new Date( | ||
result.access_token_token_expired, | ||
).getTime(); | ||
return result.access_token; | ||
} | ||
|
||
return this.accessToken; | ||
} | ||
} | ||
|
||
// interfaces | ||
|
||
interface AccessTokenInterface { | ||
access_token: string; | ||
access_token_token_expired: string; | ||
token_type: string; | ||
expires_in: number; | ||
} | ||
|
||
interface StockIndexChartInterface { | ||
output: StockIndexChartElementInterface[]; | ||
rt_cd: string; | ||
msg_cd: string; | ||
msg1: string; | ||
} | ||
|
||
interface StockIndexChartElementInterface { | ||
bsop_hour: string; | ||
bstp_nmix_prpr: string; | ||
bstp_nmix_prdy_vrss: string; | ||
prdy_vrss_sign: string; | ||
bstp_nmix_prdy_ctrt: string; | ||
acml_tr_pbmn: string; | ||
acml_vol: string; | ||
cntg_vol: string; | ||
} | ||
|
||
interface StockIndexValueInterface { | ||
output: { | ||
bstp_nmix_prpr: string; | ||
bstp_nmix_prdy_vrss: string; | ||
prdy_vrss_sign: string; | ||
bstp_nmix_prdy_ctrt: string; | ||
acml_vol: string; | ||
prdy_vol: string; | ||
acml_tr_pbmn: string; | ||
prdy_tr_pbmn: string; | ||
bstp_nmix_oprc: string; | ||
prdy_nmix_vrss_nmix_oprc: string; | ||
oprc_vrss_prpr_sign: string; | ||
bstp_nmix_oprc_prdy_ctrt: string; | ||
bstp_nmix_hgpr: string; | ||
prdy_nmix_vrss_nmix_hgpr: string; | ||
hgpr_vrss_prpr_sign: string; | ||
bstp_nmix_hgpr_prdy_ctrt: string; | ||
bstp_nmix_lwpr: string; | ||
prdy_clpr_vrss_lwpr: string; | ||
lwpr_vrss_prpr_sign: string; | ||
prdy_clpr_vrss_lwpr_rate: string; | ||
ascn_issu_cnt: string; | ||
uplm_issu_cnt: string; | ||
stnr_issu_cnt: string; | ||
down_issu_cnt: string; | ||
lslm_issu_cnt: string; | ||
dryy_bstp_nmix_hgpr: string; | ||
dryy_hgpr_vrss_prpr_rate: string; | ||
dryy_bstp_nmix_hgpr_date: string; | ||
dryy_bstp_nmix_lwpr: string; | ||
dryy_lwpr_vrss_prpr_rate: string; | ||
dryy_bstp_nmix_lwpr_date: string; | ||
total_askp_rsqn: string; | ||
total_bidp_rsqn: string; | ||
seln_rsqn_rate: string; | ||
shnu_rsqn_rate: string; | ||
ntby_rsqn: string; | ||
}; | ||
rt_cd: string; | ||
msg_cd: string; | ||
msg1: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets'; | ||
import { Server } from 'socket.io'; | ||
|
||
@WebSocketGateway({ namespace: 'socket', cors: { origin: '*' } }) | ||
export class SocketGateway { | ||
@WebSocketServer() | ||
private server: Server; | ||
|
||
sendStockIndexListToClient(stockIndex) { | ||
this.server.emit('index', stockIndex); | ||
} | ||
|
||
sendStockIndexValueToClient(stockIndexValue) { | ||
this.server.emit('indexValue', stockIndexValue); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟢 이후에 이런 interface 어디서 관리하실 건가요?
저도 지금 service 계층에 그냥 두고 사용 중인데 나중에 분리가 필요하지 않을까 싶어서 질문드립니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앜 인터페이스 아마 각 도메인에 interface 디렉터리 두고 관리할 것 같아요! 추가로 파일 분리하면 자꾸 린트 오류 떠서 규칙도 수정해야할 것 같슴니당 참고자료