Skip to content
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

Feature/#367 - 주, 월, 년 봉 데이터를 새벽 업데이트 이후에서 16시까지 갱신하지 않도록 변경 #368

Merged
merged 3 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion packages/backend/src/scraper/openapi/api/openapiLiveData.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { openApiConfig } from '../config/openapi.config';
import { isOpenapiLiveData } from '../type/openapiLiveData.type';
import { TR_IDS } from '../type/openapiUtil.type';
import { getOpenApi } from '../util/openapiUtil.api';
import { Json } from '@/scraper/openapi/queue/openapi.queue';
import { Json, OpenapiQueue } from '@/scraper/openapi/queue/openapi.queue';
import { Stock } from '@/stock/domain/stock.entity';
import { StockLiveData } from '@/stock/domain/stockLiveData.entity';

Expand All @@ -15,6 +15,7 @@ export class OpenapiLiveData {
'/uapi/domestic-stock/v1/quotations/inquire-ccnl';
constructor(
private readonly datasource: DataSource,
private readonly openapiQueue: OpenapiQueue,
@Inject('winston') private readonly logger: Logger,
) {}

Expand Down Expand Up @@ -76,6 +77,16 @@ export class OpenapiLiveData {
return stockData;
}

insertLiveDataRequest(stockId: string) {
const query = this.makeLiveDataQuery(stockId);
this.openapiQueue.enqueue({
url: this.url,
query,
trId: TR_IDS.LIVE_DATA,
callback: this.getLiveDataSaveCallback(stockId),
});
}

Comment on lines +80 to +89
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리팩토링 수고하셨습니다!

async connectLiveData(stockId: string, config: typeof openApiConfig) {
const query = this.makeLiveDataQuery(stockId);

Expand Down
44 changes: 16 additions & 28 deletions packages/backend/src/scraper/openapi/liveData.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,6 @@ export class LiveData {
});
}

private async openapiSubscribe(stockId: string) {
const config = (await this.openApiToken.configs())[0];
const result = await this.openapiLiveData.connectLiveData(stockId, config);
try {
const stockLiveData = this.openapiLiveData.convertResponseToStockLiveData(
result.output,
stockId,
);
if (stockLiveData) {
await this.openapiLiveData.saveLiveData(stockLiveData);
}
} catch (error) {
this.logger.warn(`Subscribe error in open api : ${error}`);
}
}

isSubscribe(stockId: string) {
return Object.keys(this.subscribeStocks).some((val) => val === stockId);
}
Expand Down Expand Up @@ -105,6 +89,22 @@ export class LiveData {
}
}

@Cron('0 2 * * 1-5')
connect() {
this.websocketClient.forEach((socket, idx) => {
socket.connectFacade(
this.initOpenCallback(idx),
this.initMessageCallback,
this.initCloseCallback,
this.initErrorCallback,
);
});
}

private async openapiSubscribe(stockId: string) {
this.openapiLiveData.insertLiveDataRequest(stockId);
}

private initOpenCallback =
(idx: number) => (sendMessage: (message: string) => void) => async () => {
this.logger.info('WebSocket connection established');
Expand Down Expand Up @@ -160,18 +160,6 @@ export class LiveData {
return dateMinutes <= startMinutes || dateMinutes >= endMinutes;
}

@Cron('0 2 * * 1-5')
connect() {
this.websocketClient.forEach((socket, idx) => {
socket.connectFacade(
this.initOpenCallback(idx),
this.initMessageCallback,
this.initCloseCallback,
this.initErrorCallback,
);
});
}

private convertObjectToMessage(
config: typeof openApiConfig,
stockId: string,
Expand Down
40 changes: 34 additions & 6 deletions packages/backend/src/stock/dto/stockData.response.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { StockData } from '@/stock/domain/stockData.entity';
import {
StockDaily,
StockData,
StockWeekly,
} from '@/stock/domain/stockData.entity';
import { StockLiveData } from '@/stock/domain/stockLiveData.entity';
import { getToday } from '@/utils/date';

export class PriceDto {
@ApiProperty({
Expand Down Expand Up @@ -37,10 +43,10 @@ export class PriceDto {

constructor(stockData: StockData) {
this.startTime = stockData.startTime;
this.open = stockData.open;
this.high = stockData.high;
this.low = stockData.low;
this.close = stockData.close;
this.open = Number(stockData.open);
this.high = Number(stockData.high);
this.low = Number(stockData.low);
this.close = Number(stockData.close);
}
}

Expand All @@ -61,7 +67,7 @@ export class VolumeDto {

constructor(stockData: StockData) {
this.startTime = stockData.startTime;
this.volume = stockData.volume;
this.volume = Number(stockData.volume);
}
}

Expand Down Expand Up @@ -95,4 +101,26 @@ export class StockDataResponse {
this.volumeDtoList = volumeDtoList;
this.hasMore = hasMore;
}

renewLastData(stockLiveData: StockLiveData, entity: new () => StockData) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어흑 수고하셨습니다...

const lastIndex = this.priceDtoList.length - 1;
this.priceDtoList[lastIndex].close = Number(stockLiveData.currentPrice);
this.priceDtoList[lastIndex].high =
stockLiveData.high > this.priceDtoList[lastIndex].high
? stockLiveData.high
: this.priceDtoList[lastIndex].high;
this.priceDtoList[lastIndex].low =
stockLiveData.low < this.priceDtoList[lastIndex].low
? stockLiveData.low
: this.priceDtoList[lastIndex].low;

this.priceDtoList[lastIndex].startTime =
entity !== StockWeekly
? getToday()
: this.priceDtoList[lastIndex].startTime;
this.volumeDtoList[lastIndex].volume =
entity === StockDaily
? stockLiveData.volume
: this.volumeDtoList[lastIndex].volume + stockLiveData.volume;
}
}
42 changes: 35 additions & 7 deletions packages/backend/src/stock/stockData.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { OpenapiPeriodData } from '@/scraper/openapi/api/openapiPeriodData.api';
import { Period } from '@/scraper/openapi/type/openapiPeriodData.type';
import { NewDate } from '@/scraper/openapi/util/newDate.util';
import { StockDataCache } from '@/stock/cache/stockData.cache';
import { StockLiveData } from '@/stock/domain/stockLiveData.entity';
import { getFormattedDate, isTodayWeekend } from '@/utils/date';

type StockData = {
Expand Down Expand Up @@ -108,7 +109,30 @@ export class StockDataService {
lastStartTime,
);
}
return await this.getChartDataFromDB(entity, stockId, lastStartTime);
const response = await this.getChartDataFromDB(
entity,
stockId,
lastStartTime,
);
const time = new Date();
if (!lastStartTime && time.getHours() < 16 && time.getHours() >= 9) {
return await this.renewResponse(response, entity, stockId);
}
return response;
}

private async renewResponse(
response: StockDataResponse,
entity: new () => StockData,
stockId: string,
) {
const liveData = await this.dataSource.manager.findOne(StockLiveData, {
where: { stock: { id: stockId } },
});
if (liveData) {
response.renewLastData(liveData, entity);
}
return response;
}

private async getChartDataFromDB(
Expand Down Expand Up @@ -157,17 +181,21 @@ export class StockDataService {
if (period === 'D') return lastDate.isSameDate(current);
if (period === 'M') {
return (
lastDate.isSameWeek(current) &&
lastDate.isSameYear(current) &&
lastDate.isSameDate(current) &&
lastDate.isSameDate(current)
lastDate.isSameMonth(current) &&
(lastDate.isSameDate(current) ||
(current.getHours() < 16 && current.getHours() > 1))
);
}
if (period === 'Y')
return lastDate.isSameYear(current) && lastDate.isSameDate(current);
return (
lastDate.isSameYear(current) &&
(lastDate.isSameDate(current) ||
(current.getHours() < 16 && current.getHours() > 1))
);
return (
lastDate.isSameWeek(current) &&
lastData.createdAt.getDate() === current.getDate()
(lastData.createdAt.getDate() === current.getDate() ||
(current.getHours() < 16 && current.getHours() > 1))
);
}

Expand Down
8 changes: 8 additions & 0 deletions packages/backend/src/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ export function isTodayWeekend() {
const day = today.getDay();
return day === 0 || day === 6;
}

export function getToday() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const day = now.getDate();
return new Date(year, month, day);
}
Loading