{
  "id": "RKd0EbChCPktKCHH",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Crypto Coin Crash Tracker",
  "tags": [],
  "nodes": [
    {
      "id": "c0f118de-5de0-4aca-88ae-6e33a6c804e5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1168,
        -896
      ],
      "parameters": {
        "width": 480,
        "height": 752,
        "content": "## Automated Crypto Coin Crash Tracker\n\n### How it works\n\n1. The workflow triggers on a schedule to monitor digital assets.\n2. Price data is fetched and analyzed against crash thresholds.\n3. Recent market news is retrieved if volatility is detected.\n4. An AI agent synthesizes the price and news data into insights.\n5. A summary is sent to Slack as an alert.\n\n### Setup steps\n\n- Configure the Schedule Trigger with your desired monitoring interval.\n- Update the Config node with your target asset, ticker, and threshold percentages.\n- Set up HTTP Request credentials for CoinGecko and Marketaux APIs.\n- Connect your Google Gemini credentials for the AI Market Analyst agent.\n- Configure your Slack credentials and target channel for notifications.\n\n### Customization\n\nAdjust the crash thresholds in the Config node or modify the AI prompt to change the depth of market analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "67e05bbe-2ccd-43b0-8775-18233f19e19f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -608,
        -896
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Schedule and configuration setup\n\nTriggers the workflow and initializes configuration parameters."
      },
      "typeVersion": 1
    },
    {
      "id": "1f4bce4a-b032-4617-87a3-c04ee395a007",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 272,
        "content": "## Fetch and analyze price data\n\nAnalyzes metrics to evaluate crash thresholds."
      },
      "typeVersion": 1
    },
    {
      "id": "d605deb4-675e-4b42-92a2-f6fb9460cc2d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 272,
        "content": "## Fetch and extract market news\n\nRetrieves recent news for AI analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "6e17cb68-11f2-4e1f-9546-4ba65a7f764f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        -896
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 512,
        "content": "## AI market analyst agent\n\nUses Gemini to formulate market insights."
      },
      "typeVersion": 1
    },
    {
      "id": "2a678869-32d3-4674-8e34-4764c62b6da1",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 272,
        "content": "## Format and send Slack alert\n\nSends formatted notification to Slack channel."
      },
      "typeVersion": 1
    },
    {
      "id": "e07024af-efba-4807-b767-db5fbecb6b7c",
      "name": "Every 4 Hours Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -560,
        -768
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 4
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "4e7a77b2-0c85-4d71-a75b-a1794780593e",
      "name": "Set Asset Parameters",
      "type": "n8n-nodes-base.set",
      "position": [
        -336,
        -768
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "2a6f090d-4225-4eba-9f2a-4527c3f92ab5",
              "name": "Asset",
              "type": "string",
              "value": "bitcoin"
            },
            {
              "id": "0db3d8b8-35ca-4013-9b83-8eaab24d37ef",
              "name": "Ticker",
              "type": "string",
              "value": "BTC"
            },
            {
              "id": "3a3b9f1f-60ad-4d64-9056-2126bdea2ac6",
              "name": "Crash_threshold",
              "type": "string",
              "value": "65000"
            },
            {
              "id": "8f2c1e3a-1234-4abc-9d56-1a2b3c4d5e6f",
              "name": "Percent_drop_threshold",
              "type": "string",
              "value": "5"
            },
            {
              "id": "9a3d2f4b-2345-4bcd-8e67-2b3c4d5e6f7a",
              "name": "News_limit",
              "type": "string",
              "value": "15"
            }
          ]
        }
      },
      "typeVersion": 3.5
    },
    {
      "id": "0411e241-bdde-4bd7-b5be-4bc9e273345d",
      "name": "Fetch Current Asset Price",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -112,
        -768
      ],
      "parameters": {
        "url": "=https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&ids={{ $json.Asset }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "ecd58163-35b9-4db8-9212-e99df3fdee8a",
      "name": "Fetch 24h Market Data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        112,
        -768
      ],
      "parameters": {
        "url": "=https://api.coingecko.com/api/v3/coins/{{ $('Set Asset Parameters').item.json.Asset }}/market_chart",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "vs_currency",
              "value": "usd"
            },
            {
              "name": "days",
              "value": "1"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "dbb0b1da-ef1b-4d6d-9ec4-d0aa8763b3eb",
      "name": "Calculate Crash Severity",
      "type": "n8n-nodes-base.code",
      "position": [
        336,
        -768
      ],
      "parameters": {
        "jsCode": "// Pull current price + full 24h chart, compute real stats, and decide crash severity.\nconst currentPrice = $('Fetch Current Asset Price').item.json[$('Set Asset Parameters').item.json.Asset].usd;\nconst chart = $input.first().json;\nconst prices = chart.prices;\n\nif (!prices || prices.length === 0) {\n  throw new Error('No price data returned from CoinGecko market_chart endpoint');\n}\n\nconst priceValues = prices.map(p => p[1]);\nconst periodHigh = Math.max(...priceValues);\nconst periodLow = Math.min(...priceValues);\nconst price24hAgo = priceValues[0];\n\nconst percentChange24h = ((currentPrice - price24hAgo) / price24hAgo) * 100;\nconst percentDropFromHigh = ((periodHigh - currentPrice) / periodHigh) * 100;\n\nconst crashThreshold = parseFloat($('Set Asset Parameters').item.json.Crash_threshold);\nconst percentDropThreshold = parseFloat($('Set Asset Parameters').item.json.Percent_drop_threshold);\n\n// Crash if: price fell below the absolute floor, OR it dropped more than X% off its 24h high\nconst isCrash = (currentPrice < crashThreshold) || (percentDropFromHigh >= percentDropThreshold);\n\n// Normal days: downsample to ~24 points so we don't burn tokens sending 288 raw entries to the LLM.\n// Crash days: send the FULL raw series so the LLM can actually see the shape of the move.\nconst toPoint = ([ts, price]) => ({\n  time: new Date(ts).toISOString(),\n  price: Math.round(price * 100) / 100\n});\n\nlet llmPriceData;\nif (isCrash) {\n  llmPriceData = prices.map(toPoint);\n} else {\n  const sampleEvery = Math.max(1, Math.floor(prices.length / 24));\n  llmPriceData = prices.filter((_, idx) => idx % sampleEvery === 0).map(toPoint);\n}\n\nreturn [{\n  json: {\n    asset: $('Set Asset Parameters').item.json.Asset,\n    ticker: $('Set Asset Parameters').item.json.Ticker,\n    current_price: Math.round(currentPrice * 100) / 100,\n    period_high_24h: Math.round(periodHigh * 100) / 100,\n    period_low_24h: Math.round(periodLow * 100) / 100,\n    price_24h_ago: Math.round(price24hAgo * 100) / 100,\n    percent_change_24h: Math.round(percentChange24h * 100) / 100,\n    percent_drop_from_high: Math.round(percentDropFromHigh * 100) / 100,\n    crash_threshold: crashThreshold,\n    percent_drop_threshold: percentDropThreshold,\n    is_crash: isCrash,\n    is_full_data: isCrash,\n    raw_point_count: prices.length,\n    llm_price_data: llmPriceData\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c182e71d-21e4-4917-8346-5d9d6e89ed9b",
      "name": "If Crash Threshold Met",
      "type": "n8n-nodes-base.if",
      "position": [
        560,
        -768
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "83dfe7bd-e6de-4cbf-8656-2768d3312534",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.is_crash }}",
              "rightValue": true
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "34ffc839-6e09-4e1c-bfd3-c04c0cd200c8",
      "name": "Prepare Slack Message",
      "type": "n8n-nodes-base.set",
      "position": [
        1616,
        -768
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1b2c3d4-1111-4aaa-9111-111111111111",
              "name": "slack_message",
              "type": "string",
              "value": "=\ud83d\udea8 *{{ $('Calculate Crash Severity').item.json.ticker }} Crash Alert* \ud83d\udea8\n\n*Current Price:* ${{ $('Calculate Crash Severity').item.json.current_price }}\n*24h Change:* {{ $('Calculate Crash Severity').item.json.percent_change_24h }}%\n*Drop from 24h High:* {{ $('Calculate Crash Severity').item.json.percent_drop_from_high }}%\n*24h Range:* ${{ $('Calculate Crash Severity').item.json.period_low_24h }} - ${{ $('Calculate Crash Severity').item.json.period_high_24h }}\n\n*AI Assessment \u2014 {{ $json.output.severity }}*\n{{ $json.output.headline }}\n\n{{ $json.output.summary }}\n\n*Key Drivers:*\n{{ $json.output.key_drivers.map(k => '\u2022 ' + k).join('\\n') }}\n\n*Recommendation:* {{ $json.output.recommendation }}\n\n*Top Headlines:*\n{{ $('Extract News Articles').item.json.titles_formatted }}"
            }
          ]
        }
      },
      "typeVersion": 3.5
    },
    {
      "id": "a4a701e4-0f62-48bb-bddc-fe13a3034ac0",
      "name": "Post Message to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1840,
        -768
      ],
      "parameters": {
        "text": "={{ $json.slack_message }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0B8VH1M5PX",
          "cachedResultName": "general"
        },
        "otherOptions": {
          "mrkdwn": true
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "1047b84a-d68f-4992-ade8-7d4a5fc81fc7",
      "name": "Google Gemini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1248,
        -544
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-3.1-flash-lite"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "85dde7b0-3a55-406a-8883-b007efe4c838",
      "name": "Define Output Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1376,
        -544
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"headline\": { \"type\": \"string\", \"description\": \"One-line summary of what's happening\" },\n    \"severity\": { \"type\": \"string\", \"enum\": [\"watch\", \"moderate\", \"severe\"] },\n    \"summary\": { \"type\": \"string\", \"description\": \"2-3 sentence market summary\" },\n    \"key_drivers\": { \"type\": \"array\", \"items\": { \"type\": \"string\" }, \"description\": \"Top news-driven factors, max 3\" },\n    \"recommendation\": { \"type\": \"string\", \"description\": \"One sentence suggested watch item or action\" }\n  },\n  \"required\": [\"headline\", \"severity\", \"summary\", \"key_drivers\", \"recommendation\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "6e6be94c-14e1-4269-8776-0e08a532616c",
      "name": "Fetch Market News",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        784,
        -768
      ],
      "parameters": {
        "url": "https://api.marketaux.com/v1/news/all",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "symbols",
              "value": "={{ $('Set Asset Parameters').item.json.Ticker }}"
            },
            {
              "name": "language",
              "value": "en"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "23d163fd-9ac0-4798-81d9-c099e6fb0613",
      "name": "Market Analyst Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1232,
        -768
      ],
      "parameters": {
        "text": "=Analyze this Bitcoin market move and the related news headlines. Decide whether this is a genuinely significant event worth alerting a trading team about, or just normal volatility.\n\nPRICE DATA:\nCurrent Price: ${{ $('Calculate Crash Severity').item.json.current_price }}\n24h Change: {{ $('Calculate Crash Severity').item.json.percent_change_24h }}%\nDrop from 24h High: {{ $('Calculate Crash Severity').item.json.percent_drop_from_high }}%\n24h Range: ${{ $('Calculate Crash Severity').item.json.period_low_24h }} - ${{ $('Calculate Crash Severity').item.json.period_high_24h }}\nFull tick-level data included: {{ $('Calculate Crash Severity').item.json.is_full_data }}\n\nRECENT NEWS HEADLINES:\n{{ $json.titles_formatted }}",
        "options": {
          "systemMessage": "You are a crypto market analyst. Be factual and concise. If the news doesn't clearly explain the price move, say so plainly instead of guessing. Do not exaggerate severity."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "b01c2ce9-40ec-48b6-ab46-c30422578cb3",
      "name": "Extract News Articles",
      "type": "n8n-nodes-base.code",
      "position": [
        1008,
        -768
      ],
      "parameters": {
        "jsCode": "// Grab the top articles + metadata for the LLM and for the Slack message.\nconst response = $input.first().json;\nconst items = response.data || [];\n\n// Limit to a maximum of 5 posts, or less if specified in Config\nconst configLimit = parseInt($('Set Asset Parameters').item.json.News_limit, 10) || 5;\nconst newsLimit = Math.min(configLimit, 5);\n\nconst articles = items.slice(0, newsLimit).map(article => {\n  // Extract description and truncate to 200 characters\n  let desc = article.description || \"No description available.\";\n\n  if (desc.length > 200) {\n    desc = desc.substring(0, 200) + \"...\";\n  }\n\n  return {\n    title: article.title,\n    description: desc,\n    url: article.url,\n    source: article.source || \"Unknown\",\n    published_at: article.published_at,\n  };\n});\n\n// Format titles and descriptions for the AI prompt\nconst titlesFormatted = articles\n  .map(\n    (a, i) =>\n      `${i + 1}. ${a.title} (${a.source})\\nSummary: ${a.description}`\n  )\n  .join(\"\\n\\n\");\n\nreturn [\n  {\n    json: {\n      articles,\n      article_count: articles.length,\n      titles_formatted:\n        titlesFormatted || \"No recent headlines found.\",\n    },\n  },\n];"
      },
      "typeVersion": 2
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "f183a649-91ca-4626-9e18-258e67b2bc59",
  "nodeGroups": [],
  "connections": {
    "Fetch Market News": {
      "main": [
        [
          {
            "node": "Extract News Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Model": {
      "ai_languageModel": [
        [
          {
            "node": "Market Analyst Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Define Output Schema": {
      "ai_outputParser": [
        [
          {
            "node": "Market Analyst Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Market Analyst Agent": {
      "main": [
        [
          {
            "node": "Prepare Slack Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Asset Parameters": {
      "main": [
        [
          {
            "node": "Fetch Current Asset Price",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every 4 Hours Trigger": {
      "main": [
        [
          {
            "node": "Set Asset Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract News Articles": {
      "main": [
        [
          {
            "node": "Market Analyst Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch 24h Market Data": {
      "main": [
        [
          {
            "node": "Calculate Crash Severity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Slack Message": {
      "main": [
        [
          {
            "node": "Post Message to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Crash Threshold Met": {
      "main": [
        [
          {
            "node": "Fetch Market News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Crash Severity": {
      "main": [
        [
          {
            "node": "If Crash Threshold Met",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Current Asset Price": {
      "main": [
        [
          {
            "node": "Fetch 24h Market Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}