-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
filter 삭제, 핵심함수 private 삭제, 우선순위 큐 만들기, websocket 데이터 등록 관련 구조 변경 (#233)
- Loading branch information
Showing
18 changed files
with
497 additions
and
271 deletions.
There are no files selected for viewing
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 |
---|---|---|
|
@@ -58,3 +58,5 @@ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |
# vscode setting | ||
.vscode | ||
|
||
# remote | ||
.remote |
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
33 changes: 0 additions & 33 deletions
33
packages/backend/src/scraper/openapi/Decorator/openapiException.filter.ts
This file was deleted.
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
120 changes: 28 additions & 92 deletions
120
packages/backend/src/scraper/openapi/api/openapiLiveData.api.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 |
---|---|---|
@@ -1,100 +1,36 @@ | ||
import { Inject } from '@nestjs/common'; | ||
import { EntityManager } from 'typeorm'; | ||
import { Logger } from 'winston'; | ||
import { openApiConfig } from '../config/openapi.config'; | ||
import { StockData, parseStockData } from '../type/openapiLiveData.type'; | ||
import { decryptAES256 } from '../util/openapiUtil.api'; | ||
import { openApiToken } from './openapiToken.api'; | ||
import { KospiStock } from '@/stock/domain/kospiStock.entity'; | ||
import { Injectable } from '@nestjs/common'; | ||
import { DataSource } from 'typeorm'; | ||
import { StockLiveData } from '@/stock/domain/stockLiveData.entity'; | ||
|
||
@Injectable() | ||
export class OpenapiLiveData { | ||
public readonly TR_ID: string = 'H0STCNT0'; | ||
private readonly WEBSOCKET_MAX: number = 40; | ||
constructor( | ||
@Inject('winston') private readonly logger: Logger, | ||
private readonly manager: EntityManager, | ||
) {} | ||
|
||
public async getMessage(): Promise<string[]> { | ||
const kospi = await this.getKospiStockId(); | ||
const config = openApiToken.configs; | ||
const configLength = config.length; | ||
const ret: string[] = []; | ||
|
||
for (let i = 0; i < configLength; i++) { | ||
const stocks = kospi.splice( | ||
i * this.WEBSOCKET_MAX, | ||
(i + 1) * this.WEBSOCKET_MAX, | ||
); | ||
for (const stock of stocks) { | ||
ret.push(this.convertObjectToMessage(config[i], stock.id!)); | ||
} | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
private convertObjectToMessage( | ||
config: typeof openApiConfig, | ||
stockId: string, | ||
): string { | ||
const message = { | ||
header: { | ||
approval_key: config.STOCK_WEBSOCKET_KEY!, | ||
custtype: 'P', | ||
tr_type: '1', | ||
'content-type': 'utf-8', | ||
}, | ||
body: { | ||
input: { | ||
tr_id: this.TR_ID, | ||
tr_key: stockId, | ||
}, | ||
}, | ||
}; | ||
return JSON.stringify(message); | ||
} | ||
|
||
private async getKospiStockId() { | ||
const kospi = await this.manager.find(KospiStock); | ||
return kospi; | ||
} | ||
|
||
private async saveLiveData(data: StockLiveData) { | ||
await this.manager.save(StockLiveData, data); | ||
} | ||
|
||
private convertLiveData(message: string[]): StockLiveData { | ||
const stockData: StockData = parseStockData(message); | ||
const stockLiveData = new StockLiveData(); | ||
stockLiveData.currentPrice = parseFloat(stockData.STCK_PRPR); | ||
stockLiveData.changeRate = parseFloat(stockData.PRDY_CTRT); | ||
stockLiveData.volume = parseInt(stockData.CNTG_VOL); | ||
stockLiveData.high = parseFloat(stockData.STCK_HGPR); | ||
stockLiveData.low = parseFloat(stockData.STCK_LWPR); | ||
stockLiveData.open = parseFloat(stockData.STCK_OPRC); | ||
stockLiveData.previousClose = parseFloat(stockData.WGHN_AVRG_STCK_PRC); | ||
stockLiveData.updatedAt = new Date(); | ||
|
||
return stockLiveData; | ||
constructor(private readonly datasource: DataSource) {} | ||
|
||
async saveLiveData(data: StockLiveData[]) { | ||
await this.datasource.manager | ||
.getRepository(StockLiveData) | ||
.createQueryBuilder() | ||
.insert() | ||
.into(StockLiveData) | ||
.values(data) | ||
.execute(); | ||
} | ||
|
||
public async output(message: Buffer, iv?: string, key?: string) { | ||
const parsed = message.toString().split('|'); | ||
if (parsed.length > 0) { | ||
if (parsed[0] == '1' && iv && key) | ||
parsed[4] = decryptAES256(parsed[4], iv, key); | ||
if (parsed[1] !== this.TR_ID) return; | ||
const stockData = parsed[4].split('^'); | ||
const length = stockData.length / parseInt(parsed[3]); | ||
const size = parseInt(parsed[2]); | ||
const i = 0; | ||
while (i < size) { | ||
const data = stockData.splice(i * length, (i + 1) * length); | ||
const liveData = this.convertLiveData(data); | ||
this.saveLiveData(liveData); | ||
} | ||
} | ||
convertLiveData(messages: Record<string, string>[]): StockLiveData[] { | ||
const stockData: StockLiveData[] = []; | ||
messages.map((message) => { | ||
const stockLiveData = new StockLiveData(); | ||
stockLiveData.currentPrice = parseFloat(message.STCK_PRPR); | ||
stockLiveData.changeRate = parseFloat(message.PRDY_CTRT); | ||
stockLiveData.volume = parseInt(message.CNTG_VOL); | ||
stockLiveData.high = parseFloat(message.STCK_HGPR); | ||
stockLiveData.low = parseFloat(message.STCK_LWPR); | ||
stockLiveData.open = parseFloat(message.STCK_OPRC); | ||
stockLiveData.previousClose = parseFloat(message.WGHN_AVRG_STCK_PRC); | ||
stockLiveData.updatedAt = new Date(); | ||
stockData.push(stockLiveData); | ||
}); | ||
return stockData; | ||
} | ||
} |
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
Oops, something went wrong.