{
  "name": "Crypto/Stock Price Volatility Alert",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes"
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "position": [
        240,
        304
      ]
    },
    {
      "parameters": {
        "url": "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd",
        "options": {}
      },
      "id": "fetch-price",
      "name": "Fetch Current Price",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        464,
        304
      ]
    },
    {
      "parameters": {
        "jsCode": "// Store price in static data for comparison\nconst staticData = $getWorkflowStaticData('global');\nconst currentTime = new Date().toISOString();\n\n// Ensure the path to 'price' matches your HTTP Request output (e.g., $input.first().json.bitcoin.usd)\nconst currentPrice = $input.first().json.price;\n\n// Store current price with timestamp\nstaticData.priceHistory = staticData.priceHistory || [];\nstaticData.priceHistory.push({\n  timestamp: currentTime,\n  price: currentPrice\n});\n\n// Keep only last 30 minutes of data (6 entries for 5-min intervals)\nif (staticData.priceHistory.length > 6) {\n  staticData.priceHistory = staticData.priceHistory.slice(-6);\n}\n\n// Return current data\nreturn [{\n  json: {\n    currentPrice: currentPrice,\n    timestamp: currentTime,\n    priceHistory: staticData.priceHistory\n  }\n}];"
      },
      "id": "store-price",
      "name": "Store Price History",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        688,
        304
      ]
    },
    {
      "parameters": {
        "jsCode": "// Calculate price change from 30 minutes ago\nconst data = $input.first().json;\nconst priceHistory = data.priceHistory;\nconst currentPrice = data.currentPrice;\n\n// Get price from 30 minutes ago (6th entry back)\nconst price30minAgo = priceHistory.length >= 6 ? priceHistory[0].price : null;\n\nif (!price30minAgo) {\n  // Return a \"Status\" object instead of an empty array\n  return [{\n    json: {\n      status: \"waiting_for_history\",\n      entries: priceHistory.length,\n      needed: 6\n    }\n  }];\n}\n\n// Calculate percentage change\nconst priceChange = currentPrice - price30minAgo;\nconst percentChange = (priceChange / price30minAgo) * 100;\n\nreturn [{\n  json: {\n    currentPrice: currentPrice,\n    price30minAgo: price30minAgo,\n    priceChange: priceChange,\n    percentChange: percentChange,\n    timestamp: data.timestamp\n  }\n}];"
      },
      "id": "calculate-change",
      "name": "Calculate Price Change",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        912,
        304
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "volatility-check",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ Math.abs($json.percentChange) }}",
              "rightValue": 5
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "check-volatility",
      "name": "Check Volatility Threshold",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1120,
        304
      ]
    },
    {
      "parameters": {
        "chatId": "@CryptostockVolatilityAlert",
        "text": "=🚨 **Price Volatility Alert** 🚨\n\n**Current Price:** ${{ $json.currentPrice }}\n**Price 30min ago:** ${{ $json.price30minAgo }}\n**Change:** ${{ $json.priceChange }} ({{ $json.percentChange.toFixed(2) }}%)\n\n**Timestamp:** {{ $json.timestamp }}\n\n⚠️ **This exceeds the 5% volatility threshold!**",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "send-alert",
      "name": "Send Volatility Alert",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        1344,
        208
      ],
      "webhookId": "18048994-617e-442c-9009-4615544864d9",
      "credentials": {
        "telegramApi": {
          "id": "0vnrBUm3coYjYkdp",
          "name": "Telegram account"
        }
      }
    },
    {
      "parameters": {},
      "id": "log-normal",
      "name": "Log Normal Activity",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1344,
        400
      ]
    }
  ],
  "pinData": {},
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Fetch Current Price",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Current Price": {
      "main": [
        [
          {
            "node": "Store Price History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Price History": {
      "main": [
        [
          {
            "node": "Calculate Price Change",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Price Change": {
      "main": [
        [
          {
            "node": "Check Volatility Threshold",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Volatility Threshold": {
      "main": [
        [
          {
            "node": "Send Volatility Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Normal Activity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all",
    "saveManualExecutions": true,
    "saveExecutionProgress": true,
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": true,
    "timeSavedMode": "fixed",
    "binaryMode": "separate"
  },
  "versionId": "a313689d-c915-47dc-bb7d-fa95ddd7d6ad",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "e09d1f0f8b9f78e80ac70b6dc8726dd263b0b6ffc4300b0eee3b58f6da316f29"
  },
  "id": "5YltNnChDDv7n8Ws",
  "tags": []
}