phase-8:server code enhancements.
This commit is contained in:
@@ -25,7 +25,7 @@ export class PortfolioAdvisor {
|
||||
resultMap[t.replace(/\./g, '-')] = r;
|
||||
}
|
||||
|
||||
const cryptoPrices = await this._cryptoPrices(holdings.filter((h) => h.type === 'crypto'));
|
||||
const cryptoPrices = await this.cryptoPrices(holdings.filter((h) => h.type === 'crypto'));
|
||||
|
||||
return holdings.map((holding) => {
|
||||
const type = (holding.type ?? 'stock').toLowerCase();
|
||||
@@ -36,35 +36,35 @@ export class PortfolioAdvisor {
|
||||
: (resultMap[holding.ticker.toUpperCase()]?.asset?.currentPrice ?? null);
|
||||
|
||||
return type === 'crypto'
|
||||
? this._row(holding, price, source, '—', '—', '—', this._cryptoAdvice(holding, price))
|
||||
: this._stockRow(holding, price, source, resultMap[holding.ticker.toUpperCase()]);
|
||||
? this.row(holding, price, source, '—', '—', '—', this.cryptoAdvice(holding, price))
|
||||
: this.stockRow(holding, price, source, resultMap[holding.ticker.toUpperCase()]);
|
||||
});
|
||||
}
|
||||
|
||||
private _stockRow(
|
||||
private stockRow(
|
||||
holding: PortfolioHolding,
|
||||
price: number | null,
|
||||
source: string,
|
||||
result: AssetResult | undefined,
|
||||
): AdviceRow {
|
||||
if (!result) {
|
||||
return this._row(holding, price, source, '—', '—', '—', {
|
||||
return this.row(holding, price, source, '—', '—', '—', {
|
||||
action: '⚪ Not screened',
|
||||
reason: 'No screener data available — Yahoo Finance may not support this ticker.',
|
||||
});
|
||||
}
|
||||
return this._row(
|
||||
return this.row(
|
||||
holding,
|
||||
price,
|
||||
source,
|
||||
result.signal,
|
||||
result.inflated.label,
|
||||
result.fundamental.label,
|
||||
this._advice(result.signal, holding, price),
|
||||
this.advice(result.signal, holding, price),
|
||||
);
|
||||
}
|
||||
|
||||
private _row(
|
||||
private row(
|
||||
holding: PortfolioHolding,
|
||||
currentPrice: number | null,
|
||||
source: string,
|
||||
@@ -73,7 +73,7 @@ export class PortfolioAdvisor {
|
||||
fundamental: string,
|
||||
{ action, reason }: AdviceOutput,
|
||||
): AdviceRow {
|
||||
const { marketValue, totalCost, gainLossPct } = this._position(holding, currentPrice);
|
||||
const { marketValue, totalCost, gainLossPct } = this.position(holding, currentPrice);
|
||||
return {
|
||||
ticker: holding.ticker,
|
||||
type: holding.type ?? 'stock',
|
||||
@@ -92,7 +92,7 @@ export class PortfolioAdvisor {
|
||||
};
|
||||
}
|
||||
|
||||
private _position(holding: PortfolioHolding, currentPrice: number | null): PositionCalc {
|
||||
private position(holding: PortfolioHolding, currentPrice: number | null): PositionCalc {
|
||||
return {
|
||||
totalCost: (holding.costBasis * holding.shares).toFixed(2),
|
||||
marketValue: currentPrice != null ? (currentPrice * holding.shares).toFixed(2) : null,
|
||||
@@ -103,8 +103,8 @@ export class PortfolioAdvisor {
|
||||
};
|
||||
}
|
||||
|
||||
private _cryptoAdvice(holding: PortfolioHolding, price: number | null): AdviceOutput {
|
||||
const { gainLossPct } = this._position(holding, price);
|
||||
private cryptoAdvice(holding: PortfolioHolding, price: number | null): AdviceOutput {
|
||||
const { gainLossPct } = this.position(holding, price);
|
||||
const g = parseFloat(gainLossPct ?? 'NaN');
|
||||
if (gainLossPct == null)
|
||||
return {
|
||||
@@ -127,8 +127,8 @@ export class PortfolioAdvisor {
|
||||
};
|
||||
}
|
||||
|
||||
private _advice(signal: Signal, holding: PortfolioHolding, price: number | null): AdviceOutput {
|
||||
const { gainLossPct } = this._position(holding, price);
|
||||
private advice(signal: Signal, holding: PortfolioHolding, price: number | null): AdviceOutput {
|
||||
const { gainLossPct } = this.position(holding, price);
|
||||
const gain = parseFloat(gainLossPct ?? '0');
|
||||
switch (signal) {
|
||||
case SIGNAL.STRONG_BUY:
|
||||
@@ -164,9 +164,7 @@ export class PortfolioAdvisor {
|
||||
}
|
||||
}
|
||||
|
||||
private async _cryptoPrices(
|
||||
holdings: PortfolioHolding[],
|
||||
): Promise<Record<string, number | null>> {
|
||||
private async cryptoPrices(holdings: PortfolioHolding[]): Promise<Record<string, number | null>> {
|
||||
const prices: Record<string, number | null> = {};
|
||||
for (const h of holdings) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user