frontend/src/lib/components/TARating.svelte
2024-09-14 13:18:17 +02:00

208 lines
7.6 KiB
Svelte

<script lang="ts">
import { taRatingComponent, stockTicker, etfTicker, cryptoTicker, assetType, getCache, setCache} from '$lib/store';
import SignalBar from '$lib/components/SignalBar.svelte'
import InfoModal from '$lib/components/InfoModal.svelte';
export let data;
let rawData = [];
let isLoaded = false;
let signalList = [];
let showFullStats = false;
let overallSignal = 'n/a'
let buyCount = 0;
let sellCount=0;
let neutralCount=0;
const modalContent = `
Momentum indicators gauge the speed at which a financial instrument's price is changing, indicating the strength of its recent price movements.<br><br>
On the other hand, trend indicators help identify the direction in which the price of an asset is moving over time, highlighting whether it's in an upward, downward, or sideways trend.<br><br>
Together, these indicators assist in evaluating the overall market sentiment and potential future price movements.
`;
async function getTaRating(ticker) {
const cachedData = getCache(ticker, 'getTaRating');
if (cachedData) {
rawData = cachedData;
} else {
try {
const response = await fetch(data?.apiURL+'/stock-rating', {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-API-KEY": data?.apiKey
},
body: JSON.stringify({ ticker })
});
rawData = await response.json();
setCache(ticker, rawData, 'getTaRating');
} catch (error) {
console.error('Failed to fetch swap data:', error);
rawData = {};
}
}
if (Object?.keys(rawData)?.length !== 0) {
$taRatingComponent = true;
}
else {
$taRatingComponent = false;
}
}
async function updateData() {
if (($assetType === 'stock' ? $stockTicker : $assetType === 'etf' ? $etfTicker : $cryptoTicker) && typeof window !== 'undefined') {
isLoaded = false;
const ticker = $assetType === 'stock' ? $stockTicker : $assetType === 'etf' ? $etfTicker : $cryptoTicker;
try {
await getTaRating(ticker);
showFullStats = false;
overallSignal = rawData?.overallSignal;
signalList = rawData?.signalList || [];
buyCount = 0;
sellCount = 0;
neutralCount = 0;
signalList?.forEach(item => {
switch (item?.signal) {
case "Strong Buy":
case "Buy":
buyCount++;
break;
case "Sell":
case "Strong Sell":
sellCount++;
break;
default:
neutralCount++;
}
});
isLoaded = true;
} catch (error) {
console.error("Error fetching data:", error);
}
}
}
$: if ($assetType || $stockTicker || $etfTicker || $cryptoTicker) {
updateData();
}
</script>
<section class="overflow-hidden w-full">
<main>
<div class="flex flex-row items-center">
<label for="technicalIndicatorInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
TA Indicators
</label>
<InfoModal
title={"TA Indicators"}
content={modalContent}
id={"technicalIndicatorInfo"}
/>
</div>
{#if isLoaded}
{#if signalList?.length !== 0}
{#if overallSignal !== 'n/a'}
<div class="text-white text-[1rem] sm:text-lg mt-3 mb-8 text-start">
Out of 11 indicators, <span class="font-semibold text-[#10DB06]">{buyCount}</span> indicates a Buy,
<span class="font-semibold text-[#F8901E]">{neutralCount}</span> are Neutral and <span class="font-semibold text-[#FF2F1F]">{sellCount}</span> indicate a Sell.
On average, the signal is to
{#if overallSignal === 'Buy' || overallSignal === 'Strong Buy'}
<span class="text-[#10DB06] sm:font-medium">
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill="none" stroke="#10db06" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5"><path d="m3 17l6-6l4 4l8-8"/><path d="M17 7h4v4"/></g></svg>
Buy.
</span>
{:else if overallSignal === 'Neutral'}
<span class="text-[#E57C34] sm:font-medium">
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#e57c34" d="m22 12l-4-4v3H3v2h15v3l4-4Z"/></svg>
Hold.
</span>
{:else if overallSignal === 'Sell' || overallSignal === 'Strong Sell'}
<span class="text-[#FF2F1F] sm:font-medium">
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path fill="#ff2f1f" d="M244 136v64a12 12 0 0 1-12 12h-64a12 12 0 0 1 0-24h35l-67-67l-31.51 31.52a12 12 0 0 1-17 0l-72-72a12 12 0 0 1 17-17L96 127l31.51-31.52a12 12 0 0 1 17 0L220 171v-35a12 12 0 0 1 24 0Z"/></svg>
Sell.
</span>
{:else}
<span class="text-[#FF2F1F] sm:font-medium">
n/a.
</span>
{/if}
</div>
{/if}
<!--Start Momentum Indicators-->
<div class="w-full overflow-x-scroll">
<table class="table table-sm table-compact w-full mb-5 mt-5">
<!-- head -->
<thead>
<tr>
<th class="text-white text-sm font-medium bg-[#09090B] font-semibold">Name</th>
<th class="text-white text-sm font-medium bg-[#09090B] font-semibold text-end">Value</th>
<th class="text-white text-sm font-medium bg-[#09090B] font-semibold text-end">Signal</th>
</tr>
</thead>
<tbody>
{#each (showFullStats ? signalList : signalList?.slice(0, 3)) as item,index}
<tr class="border-y border-gray-800 odd:bg-[#27272A] {index === 2 && !showFullStats && signalList?.length > 2 ? 'opacity-[0.3]' : '' }">
<td class="text-white text-sm sm:text-[1rem] whitespace-nowrap">
{item?.name}
</td>
<td class="text-white text-end">
<span class="text-white text-sm sm:text-[1rem] font-medium">
{item?.value}
</span>
</td>
<td class="text-white">
<SignalBar signal = {item?.signal} />
</td>
</tr>
{/each}
</tbody>
</table>
</div>
<label on:click={() => showFullStats = !showFullStats} class="{signalList?.length < 4 ? 'hidden' : ''} cursor-pointer m-auto flex justify-center items-center mt-5">
<svg class="w-10 h-10 transform {showFullStats ? 'rotate-180' : ''} " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#2A323C" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 13.5L7.5 11l1.42-1.41L12 12.67l3.08-3.08L16.5 11L12 15.5z"/></svg>
</label>
<!--End Momentum Indicators-->
{/if}
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<span class="loading loading-spinner loading-md"></span>
</label>
</div>
</div>
{/if}
</main>
</section>