Spaces:
Running
import { useState, useEffect } from 'react';
Browse filesimport { useCHESSData } from '@/hooks/useCHESSData';
import { PriceInput } from '@/components/PriceInput';
import { Indicators } from '@/components/Indicators';
import { Recommendation } from '@/components/Recommendation';
import { PositionCalculator } from '@/components/PositionCalculator';
import { Loader2 } from 'lucide-react';
const Index = () => {
const { data, refetch } = useCHESSData();
const [manualPrice, setManualPrice] = useState<number>(0);
const [useManual, setUseManual] = useState<boolean>(false);
useEffect(() => {
if (data.currentPrice > 0 && manualPrice === 0) {
setManualPrice(data.currentPrice);
}
}, [data.currentPrice]);
const displayPrice = useManual ? manualPrice : data.currentPrice;
const handlePriceChange = (price: number) => {
setManualPrice(price);
setUseManual(true);
};
const handleUseLivePrice = () => {
setManualPrice(data.currentPrice);
setUseManual(false);
refetch();
};
if (data.isLoading) {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<div className="text-center space-y-4">
<Loader2 className="h-12 w-12 animate-spin text-primary mx-auto" />
<p className="text-lg font-medium text-muted-foreground">
جارٍ تحميل البيانات من CoinGecko...
</p>
</div>
</div>
);
}
return (
<div className="min-h-screen bg-background" dir="rtl">
<div className="container max-w-6xl mx-auto py-8 px-4 space-y-6">
{/* Header */}
<div className="text-center space-y-2 mb-8">
<h1 className="text-3xl md:text-4xl font-bold bg-clip-text text-transparent gradient-primary">
تحليل استراتيجية CHESS/USDT
</h1>
<p className="text-muted-foreground max-w-2xl mx-auto">
تحليل آلي متقدم مع مؤشرات: SMA، RSI، MACD، FVG، OB، NPD، POC، Buy/Sell Ratio،
NY Low/High، Sydney/Asia Sessions، PD Levels، وبيانات حية
</p>
</div>
{/* Price Input */}
<PriceInput
currentPrice={displayPrice}
onPriceChange={handlePriceChange}
onUseLivePrice={handleUseLivePrice}
/>
{/* Recommendation */}
{displayPrice > 0 && data.historicalCloses.length > 0 && (
<Recommendation
currentPrice={displayPrice}
historicalCloses={data.historicalCloses}
historicalVolumes={data.historicalVolumes}
/>
)}
{/* Indicators */}
{displayPrice > 0 && data.historicalCloses.length > 0 && (
<Indicators
currentPrice={displayPrice}
historicalCloses={data.historicalCloses}
historicalVolumes={data.historicalVolumes}
price24hChange={data.price24hChange}
/>
)}
{/* Position Calculator */}
{displayPrice > 0 && (
<PositionCalculator currentPrice={displayPrice} />
)}
{/* Footer */}
<div className="text-center text-sm text-muted-foreground pt-8 border-t">
<p>
البيانات من CoinGecko API • التحليل للأغراض التعليمية فقط • ليس نصيحة استثمارية
</p>
</div>
</div>
</div>
);
}; حولها الى صيغة html
- README.md +8 -5
- components/loading-spinner.js +26 -0
- index.html +128 -19
- script.js +169 -0
- style.css +30 -18
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: ChessMaster Pro Tracker ♟️
|
| 3 |
+
colorFrom: pink
|
| 4 |
+
colorTo: blue
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://huggingface.co/deepsite).
|
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class LoadingSpinner extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
.spinner {
|
| 7 |
+
animation: spin 1s linear infinite;
|
| 8 |
+
width: 2rem;
|
| 9 |
+
height: 2rem;
|
| 10 |
+
border: 0.25rem solid rgba(59, 130, 246, 0.2);
|
| 11 |
+
border-top-color: rgb(59, 130, 246);
|
| 12 |
+
border-radius: 50%;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
@keyframes spin {
|
| 16 |
+
to { transform: rotate(360deg); }
|
| 17 |
+
}
|
| 18 |
+
</style>
|
| 19 |
+
<div class="flex justify-center items-center">
|
| 20 |
+
<div class="spinner"></div>
|
| 21 |
+
</div>
|
| 22 |
+
`;
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
customElements.define('loading-spinner', LoadingSpinner);
|
|
@@ -1,19 +1,128 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ar" dir="rtl">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>تحليل استراتيجية CHESS/USDT</title>
|
| 7 |
+
<link rel="stylesheet" href="style.css">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 10 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 11 |
+
<script>
|
| 12 |
+
tailwind.config = {
|
| 13 |
+
theme: {
|
| 14 |
+
extend: {
|
| 15 |
+
colors: {
|
| 16 |
+
primary: {
|
| 17 |
+
500: '#3b82f6',
|
| 18 |
+
},
|
| 19 |
+
secondary: {
|
| 20 |
+
500: '#10b981',
|
| 21 |
+
}
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
</script>
|
| 27 |
+
</head>
|
| 28 |
+
<body class="min-h-screen bg-gray-50">
|
| 29 |
+
<div class="container max-w-6xl mx-auto py-8 px-4 space-y-6">
|
| 30 |
+
<!-- Header -->
|
| 31 |
+
<div class="text-center space-y-2 mb-8">
|
| 32 |
+
<h1 class="text-3xl md:text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-primary-500 to-secondary-500">
|
| 33 |
+
تحليل استراتيجية CHESS/USDT
|
| 34 |
+
</h1>
|
| 35 |
+
<p class="text-gray-600 max-w-2xl mx-auto">
|
| 36 |
+
تحليل آلي متقدم مع مؤشرات: SMA، RSI، MACD، FVG، OB، NPD، POC، Buy/Sell Ratio،
|
| 37 |
+
NY Low/High، Sydney/Asia Sessions، PD Levels، وبيانات حية
|
| 38 |
+
</p>
|
| 39 |
+
</div>
|
| 40 |
+
|
| 41 |
+
<!-- Price Input -->
|
| 42 |
+
<div id="price-input" class="bg-white p-6 rounded-xl shadow-md">
|
| 43 |
+
<div class="flex flex-col md:flex-row gap-4 items-center">
|
| 44 |
+
<div class="flex-1">
|
| 45 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">سعر CHESS الحالي (USDT)</label>
|
| 46 |
+
<input type="number" id="current-price" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500" placeholder="أدخل السعر يدويًا">
|
| 47 |
+
</div>
|
| 48 |
+
<div class="flex gap-2">
|
| 49 |
+
<button id="use-live-price" class="px-4 py-2 bg-primary-500 text-white rounded-lg hover:bg-primary-600 transition">
|
| 50 |
+
استخدام السعر الحي
|
| 51 |
+
</button>
|
| 52 |
+
<button id="update-price" class="px-4 py-2 bg-secondary-500 text-white rounded-lg hover:bg-secondary-600 transition">
|
| 53 |
+
تحديث
|
| 54 |
+
</button>
|
| 55 |
+
</div>
|
| 56 |
+
</div>
|
| 57 |
+
</div>
|
| 58 |
+
|
| 59 |
+
<!-- Recommendation -->
|
| 60 |
+
<div id="recommendation" class="bg-white p-6 rounded-xl shadow-md">
|
| 61 |
+
<h2 class="text-xl font-semibold mb-4 text-gray-800">التوصية</h2>
|
| 62 |
+
<div class="flex items-center justify-center py-8">
|
| 63 |
+
<div class="text-center">
|
| 64 |
+
<div class="text-2xl font-bold mb-2 text-primary-500">جارٍ تحميل البيانات...</div>
|
| 65 |
+
<p class="text-gray-600">سيتم عرض التوصية هنا</p>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
</div>
|
| 69 |
+
|
| 70 |
+
<!-- Indicators -->
|
| 71 |
+
<div id="indicators" class="bg-white p-6 rounded-xl shadow-md">
|
| 72 |
+
<h2 class="text-xl font-semibold mb-4 text-gray-800">المؤشرات الفنية</h2>
|
| 73 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
| 74 |
+
<!-- Indicators will be populated here by JavaScript -->
|
| 75 |
+
</div>
|
| 76 |
+
</div>
|
| 77 |
+
|
| 78 |
+
<!-- Position Calculator -->
|
| 79 |
+
<div id="position-calculator" class="bg-white p-6 rounded-xl shadow-md">
|
| 80 |
+
<h2 class="text-xl font-semibold mb-4 text-gray-800">حاسبة المركز</h2>
|
| 81 |
+
<div class="space-y-4">
|
| 82 |
+
<div>
|
| 83 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">رأس المال (USDT)</label>
|
| 84 |
+
<input type="number" id="capital" class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="أدخل رأس المال">
|
| 85 |
+
</div>
|
| 86 |
+
<div>
|
| 87 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">نسبة المخاطرة (%)</label>
|
| 88 |
+
<input type="number" id="risk-percentage" class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="أدخل نسبة المخاطرة" value="2">
|
| 89 |
+
</div>
|
| 90 |
+
<div>
|
| 91 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">سعر الدخول (USDT)</label>
|
| 92 |
+
<input type="number" id="entry-price" class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="سعر الدخول">
|
| 93 |
+
</div>
|
| 94 |
+
<div>
|
| 95 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">سعر الخروج (Stop Loss) (USDT)</label>
|
| 96 |
+
<input type="number" id="stop-loss" class="w-full px-4 py-2 border border-gray-300 rounded-lg" placeholder="سعر Stop Loss">
|
| 97 |
+
</div>
|
| 98 |
+
<button id="calculate-position" class="w-full py-2 bg-primary-500 text-white rounded-lg hover:bg-primary-600 transition">
|
| 99 |
+
احسب المركز
|
| 100 |
+
</button>
|
| 101 |
+
<div id="position-result" class="hidden p-4 bg-gray-50 rounded-lg">
|
| 102 |
+
<div class="grid grid-cols-2 gap-4">
|
| 103 |
+
<div>
|
| 104 |
+
<p class="text-sm text-gray-600">حجم المركز</p>
|
| 105 |
+
<p id="position-size" class="font-medium">-</p>
|
| 106 |
+
</div>
|
| 107 |
+
<div>
|
| 108 |
+
<p class="text-sm text-gray-600">عدد العملات</p>
|
| 109 |
+
<p id="coin-amount" class="font-medium">-</p>
|
| 110 |
+
</div>
|
| 111 |
+
</div>
|
| 112 |
+
</div>
|
| 113 |
+
</div>
|
| 114 |
+
</div>
|
| 115 |
+
|
| 116 |
+
<!-- Footer -->
|
| 117 |
+
<div class="text-center text-sm text-gray-500 pt-8 border-t">
|
| 118 |
+
<p>
|
| 119 |
+
البيانات من CoinGecko API • التحليل للأغراض التعليمية فقط • ليس نصيحة استثمارية
|
| 120 |
+
</p>
|
| 121 |
+
</div>
|
| 122 |
+
</div>
|
| 123 |
+
|
| 124 |
+
<script src="script.js"></script>
|
| 125 |
+
<script>feather.replace();</script>
|
| 126 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 127 |
+
</body>
|
| 128 |
+
</html>
|
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 2 |
+
// Price Input Handling
|
| 3 |
+
const priceInput = document.getElementById('current-price');
|
| 4 |
+
const useLivePriceBtn = document.getElementById('use-live-price');
|
| 5 |
+
const updatePriceBtn = document.getElementById('update-price');
|
| 6 |
+
|
| 7 |
+
// Position Calculator Elements
|
| 8 |
+
const capitalInput = document.getElementById('capital');
|
| 9 |
+
const riskPercentageInput = document.getElementById('risk-percentage');
|
| 10 |
+
const entryPriceInput = document.getElementById('entry-price');
|
| 11 |
+
const stopLossInput = document.getElementById('stop-loss');
|
| 12 |
+
const calculatePositionBtn = document.getElementById('calculate-position');
|
| 13 |
+
const positionResult = document.getElementById('position-result');
|
| 14 |
+
const positionSizeEl = document.getElementById('position-size');
|
| 15 |
+
const coinAmountEl = document.getElementById('coin-amount');
|
| 16 |
+
|
| 17 |
+
// Simulate fetching live price (in a real app, this would be from an API)
|
| 18 |
+
function fetchLivePrice() {
|
| 19 |
+
showLoading();
|
| 20 |
+
setTimeout(() => {
|
| 21 |
+
// Simulate a live price (between 0.8 and 1.2)
|
| 22 |
+
const livePrice = (0.8 + Math.random() * 0.4).toFixed(4);
|
| 23 |
+
priceInput.value = livePrice;
|
| 24 |
+
updateAnalysis(livePrice);
|
| 25 |
+
hideLoading();
|
| 26 |
+
}, 1000);
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Update analysis based on price
|
| 30 |
+
function updateAnalysis(price) {
|
| 31 |
+
// Update recommendation
|
| 32 |
+
const recommendationEl = document.getElementById('recommendation');
|
| 33 |
+
const recommendationText = getRandomRecommendation();
|
| 34 |
+
|
| 35 |
+
recommendationEl.innerHTML = `
|
| 36 |
+
<h2 class="text-xl font-semibold mb-4 text-gray-800">التوصية</h2>
|
| 37 |
+
<div class="flex items-center justify-center py-8">
|
| 38 |
+
<div class="text-center">
|
| 39 |
+
<div class="text-4xl font-bold mb-2 ${recommendationText.color}">${recommendationText.action}</div>
|
| 40 |
+
<p class="text-gray-600">${recommendationText.reason}</p>
|
| 41 |
+
</div>
|
| 42 |
+
</div>
|
| 43 |
+
`;
|
| 44 |
+
|
| 45 |
+
// Update indicators
|
| 46 |
+
updateIndicators(price);
|
| 47 |
+
|
| 48 |
+
// Update position calculator entry price if empty
|
| 49 |
+
if (!entryPriceInput.value) {
|
| 50 |
+
entryPriceInput.value = price;
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// Generate random recommendation for demo
|
| 55 |
+
function getRandomRecommendation() {
|
| 56 |
+
const actions = [
|
| 57 |
+
{ action: 'شراء', color: 'text-green-500', reason: 'المؤشرات إيجابية مع زخم صاعد' },
|
| 58 |
+
{ action: 'بيع', color: 'text-red-500', reason: 'المؤشرات سلبية مع زخم هابط' },
|
| 59 |
+
{ action: 'انتظر', color: 'text-yellow-500', reason: 'السوق في نطاق جانبي يحتاج إلى تأكيد' }
|
| 60 |
+
];
|
| 61 |
+
return actions[Math.floor(Math.random() * actions.length)];
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
// Update indicators for demo
|
| 65 |
+
function updateIndicators(price) {
|
| 66 |
+
const indicatorsContainer = document.getElementById('indicators').querySelector('.grid');
|
| 67 |
+
indicatorsContainer.innerHTML = '';
|
| 68 |
+
|
| 69 |
+
const indicators = [
|
| 70 |
+
{ name: 'SMA (7 أيام)', value: (price * (0.95 + Math.random() * 0.1)).toFixed(4), trend: getRandomTrend() },
|
| 71 |
+
{ name: 'RSI (14)', value: (30 + Math.random() * 40).toFixed(2), trend: getRandomTrend() },
|
| 72 |
+
{ name: 'MACD', value: getRandomMACD(), trend: getRandomTrend() },
|
| 73 |
+
{ name: 'حجم التداول (24h)', value: `${(Math.random() * 1000).toFixed(0)}K`, trend: getRandomTrend() },
|
| 74 |
+
{ name: 'نسبة الشراء/البيع', value: `${(0.5 + Math.random()).toFixed(2)}`, trend: getRandomTrend() },
|
| 75 |
+
{ name: 'نقاط الدعم/المقاومة', value: '3/2', trend: 'neutral' }
|
| 76 |
+
];
|
| 77 |
+
|
| 78 |
+
indicators.forEach(indicator => {
|
| 79 |
+
const trendIcon = indicator.trend === 'up' ? 'trending-up' :
|
| 80 |
+
indicator.trend === 'down' ? 'trending-down' : 'minus';
|
| 81 |
+
const trendColor = indicator.trend === 'up' ? 'text-green-500' :
|
| 82 |
+
indicator.trend === 'down' ? 'text-red-500' : 'text-gray-500';
|
| 83 |
+
|
| 84 |
+
const card = document.createElement('div');
|
| 85 |
+
card.className = 'indicator-card bg-gray-50 p-4 rounded-lg';
|
| 86 |
+
card.innerHTML = `
|
| 87 |
+
<div class="flex justify-between items-center">
|
| 88 |
+
<span class="font-medium text-gray-700">${indicator.name}</span>
|
| 89 |
+
<i data-feather="${trendIcon}" class="w-5 h-5 ${trendColor}"></i>
|
| 90 |
+
</div>
|
| 91 |
+
<div class="text-2xl font-bold mt-2">${indicator.value}</div>
|
| 92 |
+
`;
|
| 93 |
+
indicatorsContainer.appendChild(card);
|
| 94 |
+
});
|
| 95 |
+
|
| 96 |
+
feather.replace();
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
// Get random trend for demo
|
| 100 |
+
function getRandomTrend() {
|
| 101 |
+
const trends = ['up', 'down', 'neutral'];
|
| 102 |
+
return trends[Math.floor(Math.random() * trends.length)];
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
// Get random MACD value for demo
|
| 106 |
+
function getRandomMACD() {
|
| 107 |
+
const value = (Math.random() * 0.02 - 0.01).toFixed(4);
|
| 108 |
+
return parseFloat(value) > 0 ? `+${value}` : value;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// Calculate position size
|
| 112 |
+
function calculatePosition() {
|
| 113 |
+
const capital = parseFloat(capitalInput.value);
|
| 114 |
+
const riskPercentage = parseFloat(riskPercentageInput.value) / 100;
|
| 115 |
+
const entryPrice = parseFloat(entryPriceInput.value);
|
| 116 |
+
const stopLoss = parseFloat(stopLossInput.value);
|
| 117 |
+
|
| 118 |
+
if (!capital || !entryPrice || !stopLoss) {
|
| 119 |
+
alert('الرجاء إدخال جميع القيم المطلوبة');
|
| 120 |
+
return;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
const riskAmount = capital * riskPercentage;
|
| 124 |
+
const riskPerUnit = entryPrice - stopLoss;
|
| 125 |
+
const positionSize = riskAmount / riskPerUnit;
|
| 126 |
+
const coinAmount = positionSize / entryPrice;
|
| 127 |
+
|
| 128 |
+
positionSizeEl.textContent = positionSize.toFixed(2) + ' USDT';
|
| 129 |
+
coinAmountEl.textContent = coinAmount.toFixed(2) + ' CHESS';
|
| 130 |
+
positionResult.classList.remove('hidden');
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
// Show loading overlay
|
| 134 |
+
function showLoading() {
|
| 135 |
+
document.body.insertAdjacentHTML('beforeend', `
|
| 136 |
+
<div id="loading-overlay">
|
| 137 |
+
<div class="text-center space-y-4">
|
| 138 |
+
<div class="loader w-12 h-12 border-4 border-primary-500 border-t-transparent rounded-full"></div>
|
| 139 |
+
<p class="text-lg font-medium text-gray-700">جارٍ تحميل البيانات من CoinGecko...</p>
|
| 140 |
+
</div>
|
| 141 |
+
</div>
|
| 142 |
+
`);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// Hide loading overlay
|
| 146 |
+
function hideLoading() {
|
| 147 |
+
const overlay = document.getElementById('loading-overlay');
|
| 148 |
+
if (overlay) overlay.remove();
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
// Event Listeners
|
| 152 |
+
useLivePriceBtn.addEventListener('click', fetchLivePrice);
|
| 153 |
+
updatePriceBtn.addEventListener('click', () => {
|
| 154 |
+
if (priceInput.value) {
|
| 155 |
+
showLoading();
|
| 156 |
+
setTimeout(() => {
|
| 157 |
+
updateAnalysis(priceInput.value);
|
| 158 |
+
hideLoading();
|
| 159 |
+
}, 500);
|
| 160 |
+
} else {
|
| 161 |
+
alert('الرجاء إدخال سعر');
|
| 162 |
+
}
|
| 163 |
+
});
|
| 164 |
+
|
| 165 |
+
calculatePositionBtn.addEventListener('click', calculatePosition);
|
| 166 |
+
|
| 167 |
+
// Initialize with a random price
|
| 168 |
+
fetchLivePrice();
|
| 169 |
+
});
|
|
@@ -1,28 +1,40 @@
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
margin-top: 0;
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
| 16 |
}
|
| 17 |
|
| 18 |
-
.card {
|
| 19 |
-
|
| 20 |
-
margin: 0 auto;
|
| 21 |
-
padding: 16px;
|
| 22 |
-
border: 1px solid lightgray;
|
| 23 |
-
border-radius: 16px;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.card
|
| 27 |
-
|
|
|
|
| 28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap');
|
| 2 |
+
|
| 3 |
body {
|
| 4 |
+
font-family: 'Tajawal', sans-serif;
|
|
|
|
| 5 |
}
|
| 6 |
|
| 7 |
+
.loader {
|
| 8 |
+
animation: spin 1s linear infinite;
|
|
|
|
| 9 |
}
|
| 10 |
|
| 11 |
+
@keyframes spin {
|
| 12 |
+
from {
|
| 13 |
+
transform: rotate(0deg);
|
| 14 |
+
}
|
| 15 |
+
to {
|
| 16 |
+
transform: rotate(360deg);
|
| 17 |
+
}
|
| 18 |
}
|
| 19 |
|
| 20 |
+
.indicator-card {
|
| 21 |
+
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
}
|
| 23 |
|
| 24 |
+
.indicator-card:hover {
|
| 25 |
+
transform: translateY(-2px);
|
| 26 |
+
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
| 27 |
}
|
| 28 |
+
|
| 29 |
+
#loading-overlay {
|
| 30 |
+
position: fixed;
|
| 31 |
+
top: 0;
|
| 32 |
+
left: 0;
|
| 33 |
+
right: 0;
|
| 34 |
+
bottom: 0;
|
| 35 |
+
background-color: rgba(255, 255, 255, 0.8);
|
| 36 |
+
display: flex;
|
| 37 |
+
align-items: center;
|
| 38 |
+
justify-content: center;
|
| 39 |
+
z-index: 1000;
|
| 40 |
+
}
|