update forecast ai page
This commit is contained in:
parent
57fa0224bf
commit
fa70a10672
@ -41,10 +41,10 @@
|
|||||||
AI Score Definition
|
AI Score Definition
|
||||||
</h3>
|
</h3>
|
||||||
<div class=" p-2">
|
<div class=" p-2">
|
||||||
Revenue, also called sales, is the amount of money a company
|
The AI Score uses fundamental and technical indicators, along
|
||||||
receives from its business activities, such as sales of products
|
with statistical data, to predict if a stock will be bullish in
|
||||||
or services. Revenue does not take any expenses into account and
|
the next quarter. It ranges from 1 to 10, with higher scores
|
||||||
is therefore different from profits.
|
indicating a greater likelihood of the prediction being correct.
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="px-2">
|
<div class="px-2">
|
||||||
@ -67,10 +67,10 @@
|
|||||||
AI Trend Forecast Definition
|
AI Trend Forecast Definition
|
||||||
</h3>
|
</h3>
|
||||||
<div class=" p-2">
|
<div class=" p-2">
|
||||||
Revenue, also called sales, is the amount of money a company
|
The AI Trend Model forecasts stock trends by analyzing
|
||||||
receives from its business activities, such as sales of products
|
historical price data. It detects patterns, seasonality, and
|
||||||
or services. Revenue does not take any expenses into account and
|
trends to predict future price movements, making it useful for
|
||||||
is therefore different from profits.
|
predicting price targets for the next 12 months.
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
<div class="px-2">
|
<div class="px-2">
|
||||||
|
|||||||
@ -16,35 +16,46 @@
|
|||||||
return `Q${quarter} '${year}`;
|
return `Q${quarter} '${year}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const price = data?.getStockQuote?.price?.toFixed(2) || 0;
|
|
||||||
|
|
||||||
const calculatePriceChange = (targetPrice) =>
|
const calculatePriceChange = (targetPrice) =>
|
||||||
targetPrice && price ? ((targetPrice / price - 1) * 100)?.toFixed(2) : 0;
|
targetPrice && price ? ((targetPrice / price - 1) * 100)?.toFixed(2) : 0;
|
||||||
|
|
||||||
const avgPriceTarget = data?.getPriceAnalysis?.avgPriceTarget || 0;
|
function prepareDataset() {
|
||||||
const medianPriceTarget = data?.getPriceAnalysis?.medianPriceTarget || 0;
|
price = data?.getStockQuote?.price?.toFixed(2) || 0;
|
||||||
const lowPriceTarget = data?.getPriceAnalysis?.lowPriceTarget || 0;
|
|
||||||
const highPriceTarget = data?.getPriceAnalysis?.highPriceTarget || 0;
|
|
||||||
|
|
||||||
const lowChange = calculatePriceChange(lowPriceTarget);
|
avgPriceTarget = data?.getPriceAnalysis?.avgPriceTarget || 0;
|
||||||
const medianChange = calculatePriceChange(medianPriceTarget);
|
medianPriceTarget = data?.getPriceAnalysis?.medianPriceTarget || 0;
|
||||||
const avgChange = calculatePriceChange(avgPriceTarget);
|
lowPriceTarget = data?.getPriceAnalysis?.lowPriceTarget || 0;
|
||||||
const highChange = calculatePriceChange(highPriceTarget);
|
highPriceTarget = data?.getPriceAnalysis?.highPriceTarget || 0;
|
||||||
|
|
||||||
|
lowChange = calculatePriceChange(lowPriceTarget);
|
||||||
|
medianChange = calculatePriceChange(medianPriceTarget);
|
||||||
|
avgChange = calculatePriceChange(avgPriceTarget);
|
||||||
|
highChange = calculatePriceChange(highPriceTarget);
|
||||||
|
|
||||||
// Assume data.getHistoricalPrice contains objects with a "time" field (e.g. "2015-01-02")
|
// Assume data.getHistoricalPrice contains objects with a "time" field (e.g. "2015-01-02")
|
||||||
const historicalData = data?.getHistoricalPrice || [];
|
historicalData = data?.getHistoricalPrice || [];
|
||||||
|
|
||||||
const backtestList = data?.getAIScore?.backtest || [];
|
backtestList = data?.getAIScore?.backtest || [];
|
||||||
|
|
||||||
// Append the latest historical date (using "time") if available. Note that this entry may not include a score.
|
// Append the latest historical date (using "time") if available. Note that this entry may not include a score.
|
||||||
if (historicalData && historicalData.length) {
|
if (historicalData && historicalData?.length) {
|
||||||
const latest = historicalData.at(-1);
|
const latest = historicalData?.at(-1);
|
||||||
backtestList.push({ date: latest.time });
|
backtestList?.push({ date: latest.time });
|
||||||
|
|
||||||
|
const seenDates = new Set();
|
||||||
|
backtestList = backtestList?.filter((item) => {
|
||||||
|
// Check if the date is already seen
|
||||||
|
if (seenDates?.has(item?.date)) {
|
||||||
|
// If yes, skip this duplicate (delete the last one)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Otherwise, record the date and keep the item
|
||||||
|
seenDates?.add(item?.date);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each backtest entry, find the historical price with the closest available time.
|
processedData = backtestList?.map((item) => {
|
||||||
// Then, if a score exists, attach a marker and data label based on the score.
|
|
||||||
const processedData = backtestList?.map((item) => {
|
|
||||||
const dateStr = item.date;
|
const dateStr = item.date;
|
||||||
const targetTime = new Date(dateStr).getTime();
|
const targetTime = new Date(dateStr).getTime();
|
||||||
let closestPoint = historicalData[0];
|
let closestPoint = historicalData[0];
|
||||||
@ -102,18 +113,18 @@
|
|||||||
return dataPoint;
|
return dataPoint;
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableDates = processedData
|
tableDates = processedData
|
||||||
?.slice(0, -1)
|
?.slice(0, -1)
|
||||||
?.map((item) => formatDateToQuarter(item.x));
|
?.map((item) => formatDateToQuarter(item?.x));
|
||||||
|
|
||||||
const tableScore = processedData
|
tableScore = processedData
|
||||||
?.slice(0, -1)
|
?.slice(0, -1)
|
||||||
?.map((item) => item?.dataLabels?.format);
|
?.map((item) => item?.dataLabels?.format);
|
||||||
|
|
||||||
// Compute percentage change
|
// Compute percentage change
|
||||||
const tableQuarterChange = processedData
|
tableQuarterChange = processedData
|
||||||
?.slice(0, -1)
|
?.slice(0, -1)
|
||||||
.map((item, index, arr) => {
|
?.map((item, index, arr) => {
|
||||||
const prevY = arr[index - 1]?.y; // Get the previous value
|
const prevY = arr[index - 1]?.y; // Get the previous value
|
||||||
if (prevY == null || item.y == null) return null; // Handle missing values
|
if (prevY == null || item.y == null) return null; // Handle missing values
|
||||||
const change = ((item.y - prevY) / prevY) * 100; // Calculate percentage change
|
const change = ((item.y - prevY) / prevY) * 100; // Calculate percentage change
|
||||||
@ -125,7 +136,7 @@
|
|||||||
?.filter(Boolean); // Remove null values
|
?.filter(Boolean); // Remove null values
|
||||||
|
|
||||||
// Compute Average Return
|
// Compute Average Return
|
||||||
const returns = processedData
|
returns = processedData
|
||||||
?.slice(1) // Skip the first value since there's no previous value for it
|
?.slice(1) // Skip the first value since there's no previous value for it
|
||||||
?.map((item, index) => {
|
?.map((item, index) => {
|
||||||
const prevY = processedData[index]?.y;
|
const prevY = processedData[index]?.y;
|
||||||
@ -135,9 +146,42 @@
|
|||||||
})
|
})
|
||||||
.filter(Boolean); // Remove null values
|
.filter(Boolean); // Remove null values
|
||||||
|
|
||||||
const avgReturn =
|
avgReturn =
|
||||||
returns?.reduce((sum, returnPercentage) => sum + returnPercentage, 0) /
|
returns?.reduce((sum, returnPercentage) => sum + returnPercentage, 0) /
|
||||||
returns?.length;
|
returns?.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
let price;
|
||||||
|
|
||||||
|
let avgPriceTarget;
|
||||||
|
let medianPriceTarget;
|
||||||
|
let lowPriceTarget;
|
||||||
|
let highPriceTarget;
|
||||||
|
|
||||||
|
let lowChange;
|
||||||
|
let medianChange;
|
||||||
|
let avgChange;
|
||||||
|
let highChange;
|
||||||
|
|
||||||
|
let historicalData;
|
||||||
|
|
||||||
|
let backtestList;
|
||||||
|
|
||||||
|
// For each backtest entry, find the historical price with the closest available time.
|
||||||
|
// Then, if a score exists, attach a marker and data label based on the score.
|
||||||
|
let processedData = [];
|
||||||
|
|
||||||
|
let tableDates;
|
||||||
|
|
||||||
|
let tableScore;
|
||||||
|
|
||||||
|
// Compute percentage change
|
||||||
|
let tableQuarterChange;
|
||||||
|
|
||||||
|
// Compute Average Return
|
||||||
|
let returns;
|
||||||
|
|
||||||
|
let avgReturn;
|
||||||
|
|
||||||
function getAIScorePlot() {
|
function getAIScorePlot() {
|
||||||
const solidData = processedData.slice(0, -1);
|
const solidData = processedData.slice(0, -1);
|
||||||
@ -422,7 +466,8 @@
|
|||||||
let configScore = null;
|
let configScore = null;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($mode) {
|
if ($stockTicker || $mode) {
|
||||||
|
prepareDataset();
|
||||||
configScore = getAIScorePlot() || null;
|
configScore = getAIScorePlot() || null;
|
||||||
config = getPriceForecastChart() || null;
|
config = getPriceForecastChart() || null;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user