@tomei/live-price
Version:
Tomei live-price Package
243 lines (228 loc) • 7.93 kB
text/typescript
import { ClassError, ObjectBase } from '@tomei/general';
import { ApplicationLog } from '@tomei/log';
import { FeedHistoryRepository } from './feed-history.repository';
import { IFeedHistoryAttr } from '../../interfaces/price-feed-history-attr.interface';
import { Op, Sequelize } from 'sequelize';
import { SourceFeedName } from '../../enum/feed.enum';
export class FeedHistory extends ObjectBase implements IFeedHistoryAttr {
ObjectId: string;
ObjectName: string;
TableName: 'price_FeedHistory';
ObjectType: 'FeedHistory';
FeedName: SourceFeedName;
DateTime: Date;
Currency: string;
SourceFeedBuyPrice: number;
SourceFeedSellPrice: number;
FeedBuyPrice: number;
FeedSellPrice: number;
IsSourceFeedAvailableYN: string;
IsManualPriceActivatedYN: string;
IsManualCutOffYN: string;
IsCircuitBreakerActivatedYN: string;
private static logger = new ApplicationLog('live-price', 'FeedHistory');
private static _Repo = new FeedHistoryRepository();
get FeedHistoryId(): string {
return this.ObjectId;
}
set FeedHistoryId(value: string) {
this.ObjectId = value;
}
private constructor(feedHistoryAttr?: IFeedHistoryAttr) {
super();
if (feedHistoryAttr) {
this.FeedHistoryId = feedHistoryAttr.FeedHistoryId;
this.FeedName = feedHistoryAttr.FeedName;
this.DateTime = feedHistoryAttr?.DateTime;
this.Currency = feedHistoryAttr?.Currency;
this.SourceFeedBuyPrice = feedHistoryAttr?.SourceFeedBuyPrice;
this.SourceFeedSellPrice = feedHistoryAttr?.SourceFeedSellPrice;
this.FeedBuyPrice = feedHistoryAttr?.FeedBuyPrice;
this.FeedSellPrice = feedHistoryAttr?.FeedSellPrice;
this.IsSourceFeedAvailableYN = feedHistoryAttr?.IsSourceFeedAvailableYN;
this.IsManualPriceActivatedYN = feedHistoryAttr?.IsManualPriceActivatedYN;
this.IsManualCutOffYN = feedHistoryAttr?.IsManualCutOffYN;
this.IsCircuitBreakerActivatedYN =
feedHistoryAttr?.IsCircuitBreakerActivatedYN;
}
}
public static async init(dbTransaction: any, FeedHistoryId?: string) {
try {
if (FeedHistoryId) {
const feedHistory = await FeedHistory._Repo.findByPk(
FeedHistoryId,
dbTransaction,
);
if (feedHistory) {
return new FeedHistory(feedHistory);
} else {
const error = new ClassError(
'FeedHistory',
'FeedHistoryErrMsg00',
'FeedHistory Not Found',
);
await FeedHistory.logger.error({
error,
methodName: 'init',
transaction: dbTransaction,
});
throw error;
}
}
return new FeedHistory();
} catch (error) {
throw new ClassError(
'FeedHistory',
'FeedHistoryErrMsg00',
'FeedHistory To Initialize FeedHistory',
);
}
}
public async saveFeedPrice(priceData: IFeedHistoryAttr, dbTransaction: any) {
try {
const payload: IFeedHistoryAttr = {
FeedHistoryId: this.createId(),
...priceData,
};
//Set the feed history object properties with the provided price data.
this.FeedHistoryId = payload.FeedHistoryId;
this.FeedName = payload.FeedName;
this.DateTime = payload?.DateTime;
this.Currency = payload?.Currency;
this.SourceFeedBuyPrice = payload?.SourceFeedBuyPrice;
this.SourceFeedSellPrice = payload?.SourceFeedSellPrice;
this.FeedBuyPrice = payload?.FeedBuyPrice;
this.FeedSellPrice = payload?.FeedSellPrice;
this.IsSourceFeedAvailableYN = payload?.IsSourceFeedAvailableYN;
this.IsManualCutOffYN = payload?.IsManualCutOffYN;
this.IsCircuitBreakerActivatedYN = payload?.IsCircuitBreakerActivatedYN;
this.IsManualPriceActivatedYN = payload?.IsManualPriceActivatedYN;
const feedHistory = await FeedHistory._Repo.create(payload, {
transaction: dbTransaction,
});
if (feedHistory) {
return new FeedHistory(feedHistory);
} else {
const error = new ClassError(
'FeedHistory',
'FeedHistoryErrMsg01',
'FeedHistory Not Created',
);
await FeedHistory.logger.error({
error,
methodName: 'saveFeedPrice',
transaction: dbTransaction,
});
throw error;
}
} catch (error) {
await FeedHistory.logger.error({
error,
methodName: 'saveFeedPrice',
transaction: dbTransaction,
});
throw error;
}
}
public static async getLatestPrice(
feedName: string,
currency: string,
timestamp?: Date,
dbTransaction?: any,
): Promise<IFeedHistoryAttr> {
// Get latest price based on feedname, currency and optional timestamp
try {
// Part 1: Define Query Filter
// Create a query filter to search the price_FeedHistory table, ensuring the query includes:
// The feedname.
// The currency.
const queryFilter: any = {
FeedName: feedName,
Currency: currency,
};
const options: any = {
where: queryFilter,
order: [['DateTime', 'DESC']],
limit: 1,
transaction: dbTransaction,
};
// If a timestamp is provided, find records closest to the timestamp.
// If no timestamp is provided, use the current timestamp for the search.
if (timestamp) {
options.order = [
[
Sequelize.literal(
`ABS(TIMESTAMPDIFF(SECOND, DateTime, '${timestamp.toISOString()}'))`,
),
'ASC',
],
];
}
// Part 2: Search for Price Record
// Use the query filter to retrieve the closest matching price record.
// If timestamp is provided, adjust the filter to find the record closest to the provided timestamp.
// If no timestamp is provided, use the current timestamp and return the most recent record before or equal to this time.
const feedHistory = await FeedHistory._Repo.findOne(options);
// Part 3: Handle Response
// If a matching record is found, return the record.
// If no matching record is found:
// If searching with a timestamp, return the message: "No price record found for the specified timestamp."
// If searching with the current timestamp, return the message: "No latest price record found for the current timestamp."
if (feedHistory) {
return feedHistory;
} else {
return null;
}
} catch (error) {
await FeedHistory.logger.error({
error,
methodName: 'getLatestPrice',
transaction: dbTransaction,
});
throw error;
}
}
public static async findAll(
page: number,
row: number,
feedName: string,
search?: {
DateTime: {
startDate: Date;
endDate: Date;
};
},
dbTransaction?: any,
): Promise<{
rows: IFeedHistoryAttr[];
count: number;
}> {
try {
const queryObj: any = {
FeedName: feedName,
};
const options: any = {
transaction: dbTransaction,
limit: row,
offset: row * (page - 1),
order: [['DateTime', 'DESC']],
};
if (search) {
queryObj.DateTime = {
[Op.between]: [search.DateTime.startDate, search.DateTime.endDate],
};
}
return await FeedHistory._Repo.findAllWithPagination({
where: queryObj,
...options,
});
} catch (error) {
await FeedHistory.logger.error({
error,
methodName: 'getPaginatedHistory',
transaction: dbTransaction,
});
throw error;
}
}
}