Technical Indicator Rule-Based Event Finder

General Information & Data Input

Enter sequential closing prices. More data provides more robust indicator calculations (at least 2x your longest indicator period is recommended).

Indicator Settings

User-Defined Rule Setup for "Observations"

Define Rule for "Potential Buy Observation"

Define Rule for "Potential Sell Observation"

Important Interpretation Note: The "observations" or "events" highlighted by this tool are based SOLELY on the historical data you provided and the simple rules you defined. They are NOT financial advice, predictions, or buy/sell signals. Technical indicators have limitations, can produce false signals, and past patterns do not guarantee future results. This tool is for educational and illustrative purposes to explore how such rules might apply to past data. Always conduct comprehensive research, use multiple forms of analysis, and implement robust risk management strategies before making any investment decisions. Consult with a qualified financial advisor for personalized advice.

No rule-based events found with current settings and data.

'; } else { tiApp.analysis.eventLog.forEach(logEntry => { const p = document.createElement('p'); p.textContent = logEntry; logContent.appendChild(p); }); } }; tiApp.downloadPDF = function() { console.log("TI_APP_SCRIPT: downloadPDF called."); if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined' || typeof (new window.jspdf.jsPDF()).save !== 'function') { alert('PDF library (jsPDF) is not fully loaded. Please ensure the complete library code is embedded in the script.'); return; } if (tiApp.analysis.processedData.length === 0) { alert("Please analyze data first to generate a PDF."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); const data = tiApp.analysis; let yPos = 15; const lineH = 7; const sectionH = 10; const indent = 15; const pageWidth = doc.internal.pageSize.getWidth(); doc.setFontSize(16); doc.text(`Technical Indicator Event Analysis`, pageWidth / 2, yPos, { align: 'center' }); yPos += lineH; doc.setFontSize(12); doc.text(`Asset: ${data.assetName || 'N/A'} | Period: ${data.analysisPeriodLabel || 'N/A'}`, pageWidth / 2, yPos, { align: 'center' }); yPos += lineH; doc.setFontSize(10); doc.text(`Analysis Date: ${new Date().toLocaleDateString()}`, indent, yPos); yPos += sectionH * 1.5; doc.setFontSize(11); doc.setFont(undefined, 'bold'); doc.text("Indicator Settings Used:", indent, yPos); yPos += lineH * 1.2; doc.setFont(undefined, 'normal'); doc.setFontSize(9); doc.text(`- SMA Period: ${data.smaPeriod}`, indent + 5, yPos); yPos += lineH; doc.text(`- RSI Period: ${data.rsiPeriod}`, indent + 5, yPos); yPos += sectionH; doc.setFontSize(11); doc.setFont(undefined, 'bold'); doc.text("User-Defined Rules for Observations:", indent, yPos); yPos += lineH * 1.2; doc.setFont(undefined, 'normal'); doc.setFontSize(9); doc.text("Buy Observation Rule:", indent + 5, yPos); yPos += lineH * 0.8; doc.text(` - Price crosses ABOVE SMA(${data.smaPeriod}): ${data.rules.buyPriceAboveSma ? 'Yes' : 'No'}`, indent + 10, yPos); yPos += lineH * 0.8; if(data.rules.buyPriceAboveSma && data.rules.buyRsiBelow) {doc.text(` - Operator: ${data.rules.buyOperator}`, indent + 10, yPos); yPos += lineH * 0.8;} doc.text(` - RSI(${data.rsiPeriod}) is BELOW ${data.rules.buyRsiLevel}: ${data.rules.buyRsiBelow ? 'Yes' : 'No'}`, indent + 10, yPos); yPos += lineH; doc.text("Sell Observation Rule:", indent + 5, yPos); yPos += lineH * 0.8; doc.text(` - Price crosses BELOW SMA(${data.smaPeriod}): ${data.rules.sellPriceBelowSma ? 'Yes' : 'No'}`, indent + 10, yPos); yPos += lineH * 0.8; if(data.rules.sellPriceBelowSma && data.rules.sellRsiAbove) { doc.text(` - Operator: ${data.rules.sellOperator}`, indent + 10, yPos); yPos += lineH * 0.8;} doc.text(` - RSI(${data.rsiPeriod}) is ABOVE ${data.rules.sellRsiLevel}: ${data.rules.sellRsiAbove ? 'Yes' : 'No'}`, indent + 10, yPos); yPos += sectionH; if (yPos > 240) { doc.addPage(); yPos = 20;} doc.setFontSize(11); doc.setFont(undefined, 'bold'); doc.text("Rule-Based Event Log:", indent, yPos); yPos += lineH * 1.2; doc.setFont(undefined, 'normal'); doc.setFontSize(9); if (data.eventLog.length > 0) { data.eventLog.forEach(log => { if (yPos > 275) { doc.addPage(); yPos = 20;} const logLines = doc.splitTextToSize(log, pageWidth - (indent * 2) - 10); doc.text(logLines, indent + 5, yPos); yPos += lineH * logLines.length * 0.8; }); } else { doc.text("No specific rule-based events found with current settings and data.", indent + 5, yPos); } yPos += sectionH; if (yPos > 255) { doc.addPage(); yPos = 20;} doc.setFontSize(9); doc.setFont(undefined, 'bold'); doc.text("Important Interpretation Note:", indent, yPos); yPos += lineH; doc.setFont(undefined, 'normal'); doc.setFontSize(8); doc.setTextColor(80); const notes = [ "- The 'observations' or 'events' highlighted are based SOLELY on historical data and user-defined rules.", "- They are NOT financial advice, predictions, or buy/sell signals.", "- Technical indicators have limitations, can produce false signals, and past patterns do not guarantee future results.", "- This tool is for educational/illustrative purposes to explore rule application on past data.", "- Always use multiple forms of analysis and risk management. Consult a financial advisor." ]; notes.forEach(note => { if (yPos > 275) { doc.addPage(); yPos = 20;} const splitText = doc.splitTextToSize(note, pageWidth - (indent * 2) - 5); doc.text(splitText, indent, yPos); yPos += (lineH * 0.7) * splitText.length + 1; }); doc.save(`Technical_Indicator_Events_${(data.assetName || 'Analysis').replace(/[^a-z0-9]/gi, '_')}.pdf`); }; document.addEventListener('DOMContentLoaded', function() { console.log("TI_APP_SCRIPT: DOMContentLoaded event listener has fired."); // Initial UI state const resultsSectionEl = document.getElementById('tiResultsSection'); const downloadBtnEl = document.getElementById('tiDownloadPdfBtn'); const statusMsgEl = document.getElementById('tiStatusMessage'); if(resultsSectionEl) resultsSectionEl.style.display = 'none'; if(downloadBtnEl) downloadBtnEl.style.display = 'none'; if(statusMsgEl) statusMsgEl.style.display = 'none'; // Add listeners to update period display in rules const smaPeriodInput = el_TI('tiSmaPeriod'); const rsiPeriodInput = el_TI('tiRsiPeriod'); if(smaPeriodInput) smaPeriodInput.addEventListener('input', tiApp.updateRulePeriodDisplays); if(rsiPeriodInput) rsiPeriodInput.addEventListener('input', tiApp.updateRulePeriodDisplays); // Add listeners to rule checkboxes to toggle AND/OR dropdown ['buyPriceAboveSma', 'buyRsiBelow', 'sellPriceBelowSma', 'sellRsiAbove'].forEach(id => { const el = document.getElementById(id); if (el) el.addEventListener('change', tiApp.updateRulePeriodDisplays); }); tiApp.updateRulePeriodDisplays(); // Initial call to set periods and operator visibility console.log("TI_APP_SCRIPT: Initial setup complete."); }); console.log("TI_APP_SCRIPT: Script block finished parsing.");
Scroll to Top