البولينجر

import React, { useState } from 'react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; import Papa from 'papaparse'; import _ from 'lodash'; const BollingerBandsAnalyzer = () => { const [file, setFile] = useState(null); const [data, setData] = useState([]); const [bollingerData, setBollingerData] = useState([]); const [status, setStatus] = useState(''); const [prediction, setPrediction] = useState(null); const [isAnalyzing, setIsAnalyzing] = useState(false); const [showResults, setShowResults] = useState(false); const handleFileChange = (e) => { if (e.target.files[0]) { setFile(e.target.files[0]); setStatus('تم اختيار الملف: ' + e.target.files[0].name); setShowResults(false); } }; const calculateBollingerBands = (prices, period = 20, stdDev = 2) => { // التأكد من وجود بيانات كافية if (prices.length < period) { setStatus('عدد البيانات غير كافٍ لحساب البولينجر باند'); return []; } const result = []; for (let i = 0; i < prices.length; i++) { if (i < period - 1) { // لا يمكن حساب المتوسط المتحرك للعناصر الأولى result.push({ price: prices[i], middle: null, upper: null, lower: null }); } else { // حساب المتوسط المتحرك لفترة محددة const slice = prices.slice(i - period + 1, i + 1); const sma = slice.reduce((sum, price) => sum + price, 0) / period; // حساب الانحراف المعياري const squaredDifferences = slice.map(price => Math.pow(price - sma, 2)); const variance = squaredDifferences.reduce((sum, val) => sum + val, 0) / period; const standardDeviation = Math.sqrt(variance); // حساب النطاقات العليا والسفلى const upperBand = sma + (standardDeviation * stdDev); const lowerBand = sma - (standardDeviation * stdDev); result.push({ price: prices[i], middle: sma, upper: upperBand, lower: lowerBand }); } } return result; }; const predictNextPrice = (priceData) => { // استخدام آخر 5 أيام للتنبؤ const recentPrices = priceData.slice(-5).map(item => item.price); // حساب متوسط التغير let changes = []; for (let i = 1; i < recentPrices.length; i++) { changes.push(recentPrices[i] - recentPrices[i-1]); } const avgChange = changes.reduce((a, b) => a + b, 0) / changes.length; // آخر سعر + متوسط التغير const predictedPrice = recentPrices[recentPrices.length - 1] + avgChange; // الاتجاه العام const trend = avgChange > 0 ? 'صاعد' : avgChange < 0 ? 'هابط' : 'محايد'; // آخر حالة بولينجر const lastBollinger = bollingerData[bollingerData.length - 1]; let signal = 'محايد'; if (lastBollinger) { const lastPrice = lastBollinger.price; // إذا كان السعر فوق النطاق العلوي، فهناك احتمال بيع if (lastPrice > lastBollinger.upper) { signal = 'احتمال بيع'; } // إذا كان السعر تحت النطاق السفلي، فهناك احتمال شراء else if (lastPrice < lastBollinger.lower) { signal = 'احتمال شراء'; } } return { predictedPrice: predictedPrice.toFixed(2), trend, signal }; }; const analyzeBollingerBands = async () => { if (!file) { setStatus('الرجاء اختيار ملف CSV أولاً'); return; } setIsAnalyzing(true); setStatus('جاري تحليل البيانات...'); setShowResults(false); try { const fileContent = await new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => resolve(e.target.result); reader.readAsText(file); }); Papa.parse(fileContent, { header: true, skipEmptyLines: true, dynamicTyping: true, complete: (results) => { if (results.data && results.data.length > 0) { // محاولة العثور على عمود السعر const firstRow = results.data[0]; let priceColumn = ''; // البحث عن اسم العمود المحتمل الذي يمثل سعر الإغلاق const possibleColumns = ['إغلاق', 'Close', 'close', 'سعر الإغلاق', 'الإغلاق', 'Price', 'price', 'السعر']; for (const col of possibleColumns) { if (firstRow[col] !== undefined) { priceColumn = col; break; } } if (!priceColumn) { // إذا لم يتم العثور على عمود محدد، استخدم أول عمود رقمي for (const key in firstRow) { if (typeof firstRow[key] === 'number') { priceColumn = key; break; } } } if (!priceColumn) { setStatus('لم يتم العثور على بيانات السعر في الملف'); setIsAnalyzing(false); return; } // استخراج بيانات السعر والتاريخ const dateColumn = Object.keys(firstRow).find(key => key.toLowerCase().includes('date') || key.toLowerCase().includes('تاريخ') || key.toLowerCase().includes('يوم') ) || 'Date'; // ترتيب البيانات حسب التاريخ - من الأقدم إلى الأحدث const sortedData = [...results.data]; if (dateColumn in sortedData[0]) { sortedData.sort((a, b) => { if (typeof a[dateColumn] === 'string' && typeof b[dateColumn] === 'string') { return new Date(a[dateColumn]) - new Date(b[dateColumn]); } return 0; }); } // استخراج أسعار الإغلاق const prices = sortedData.map(row => parseFloat(row[priceColumn])).filter(price => !isNaN(price)); // حساب مؤشر البولينجر باند const bollingerResult = calculateBollingerBands(prices); // إضافة التاريخ إلى النتائج const formattedData = sortedData.map((row, index) => ({ date: row[dateColumn] || `Day ${index + 1}`, price: parseFloat(row[priceColumn]), ...(index < bollingerResult.length ? { middle: bollingerResult[index].middle, upper: bollingerResult[index].upper, lower: bollingerResult[index].lower } : {}) })); setData(formattedData); setBollingerData(bollingerResult); // التنبؤ بالسعر القادم const predictionResult = predictNextPrice(formattedData); setPrediction(predictionResult); setStatus('تم الانتهاء من التحليل'); setShowResults(true); } else { setStatus('لم يتم العثور على بيانات في الملف'); } setIsAnalyzing(false); }, error: (error) => { setStatus('حدث خطأ أثناء قراءة الملف: ' + error.message); setIsAnalyzing(false); } }); } catch (error) { setStatus('حدث خطأ: ' + error.message); setIsAnalyzing(false); } }; return (

محلل البولينجر باند (Bollinger Bands)

{status && (
{status}
)}
{showResults && (

نتائج التحليل

{prediction && (

توقعات الجلسة الحالية:

  • السعر المتوقع: {prediction.predictedPrice}
  • الاتجاه: {prediction.trend}
  • الإشارة: {prediction.signal}
)}

رسم بياني للبولينجر باند:

تحليل الحالة الراهنة:

{bollingerData.length > 0 && (
{(() => { const lastData = bollingerData[bollingerData.length - 1]; if (!lastData || !lastData.middle) return

لا توجد بيانات كافية للتحليل.

; const lastPrice = lastData.price; let analysis = []; // مقارنة السعر مع المتوسط المتحرك if (lastPrice > lastData.middle) { analysis.push("السعر فوق المتوسط المتحرك، مما يشير إلى اتجاه صاعد محتمل."); } else if (lastPrice < lastData.middle) { analysis.push("السعر تحت المتوسط المتحرك، مما يشير إلى اتجاه هابط محتمل."); } else { analysis.push("السعر قريب من المتوسط المتحرك، مما يشير إلى حالة تذبذب."); } // تحليل موقع السعر من نطاقات البولينجر if (lastPrice > lastData.upper) { analysis.push("السعر فوق النطاق العلوي للبولينجر باند، مما قد يشير إلى حالة تشبع شرائي وإمكانية حدوث ارتداد هبوطي."); } else if (lastPrice < lastData.lower) { analysis.push("السعر تحت النطاق السفلي للبولينجر باند، مما قد يشير إلى حالة تشبع بيعي وإمكانية حدوث ارتداد صعودي."); } else { // تحليل موقع السعر ضمن النطاقات const position = (lastPrice - lastData.lower) / (lastData.upper - lastData.lower); if (position > 0.66) { analysis.push("السعر في الثلث العلوي من نطاق البولينجر، مما يشير إلى قوة نسبية في الاتجاه الصعودي."); } else if (position < 0.33) { analysis.push("السعر في الثلث السفلي من نطاق البولينجر، مما يشير إلى قوة نسبية في الاتجاه الهبوطي."); } else { analysis.push("السعر في منتصف نطاق البولينجر، مما يشير إلى حالة توازن بين العرض والطلب."); } } // تحليل عرض النطاق const width = ((lastData.upper - lastData.lower) / lastData.middle) * 100; if (width > 4) { analysis.push("نطاق البولينجر واسع، مما يشير إلى تقلبات عالية في السوق."); } else if (width < 2) { analysis.push("نطاق البولينجر ضيق، مما قد يشير إلى اقتراب حركة سعرية قوية."); } else { analysis.push("عرض نطاق البولينجر متوسط، مما يشير إلى تقلبات معتدلة في السوق."); } return (
    {analysis.map((item, index) => (
  • {item}
  • ))}
); })()}
)}
)}

ملاحظة: هذا التحليل للأغراض التعليمية فقط وليس توصية استثمارية. يرجى استشارة مستشار مالي قبل اتخاذ أي قرار استثماري.

); }; export default BollingerBandsAnalyzer;

إرسال تعليق

أحدث أقدم

نموذج الاتصال

نموذج الاتصال