<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pythia Oracle</title>
    <description>The latest articles on DEV Community by Pythia Oracle (@pythiatheoracle).</description>
    <link>https://dev.to/pythiatheoracle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3843483%2F8086edfc-24fe-40c5-acea-ac552148da32.png</url>
      <title>DEV Community: Pythia Oracle</title>
      <link>https://dev.to/pythiatheoracle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pythiatheoracle"/>
    <language>en</language>
    <item>
      <title>How to Get AI Market Analysis On-Chain: Backtested Patterns Delivered to Your Smart Contract</title>
      <dc:creator>Pythia Oracle</dc:creator>
      <pubDate>Thu, 16 Apr 2026 14:32:39 +0000</pubDate>
      <link>https://dev.to/pythiatheoracle/how-to-get-ai-market-analysis-on-chain-backtested-patterns-delivered-to-your-smart-contract-3hll</link>
      <guid>https://dev.to/pythiatheoracle/how-to-get-ai-market-analysis-on-chain-backtested-patterns-delivered-to-your-smart-contract-3hll</guid>
      <description>&lt;p&gt;What if your smart contract could receive AI-generated market intelligence — not just a price, but a pattern analysis with confidence scores, indicator snapshots, and historical accuracy data — delivered on-chain through Chainlink?&lt;/p&gt;

&lt;p&gt;That's what Pythia Visions does. This post walks through the architecture, the on-chain interface, and a full Solidity example that reacts to AI analysis automatically.&lt;/p&gt;




&lt;h2&gt;The Problem: Smart Contracts Are Blind to Market Context&lt;/h2&gt;

&lt;p&gt;Price oracles tell your contract that BTC is $72,000. They don't tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this a capitulation sell-off or a normal dip?&lt;/li&gt;
&lt;li&gt;What do RSI, EMA, Bollinger Bands, and VWAP say right now?&lt;/li&gt;
&lt;li&gt;What happened historically when this exact pattern appeared?&lt;/li&gt;
&lt;li&gt;How confident should you be in a recovery?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For any of this, you'd need to run your own off-chain pipeline — data sources, indicator computation, pattern detection, historical backtesting. Most builders don't have the time or infrastructure for that.&lt;/p&gt;

&lt;p&gt;Pythia Visions solves this by running the full analysis pipeline off-chain and delivering structured, AI-calibrated results on-chain via Chainlink.&lt;/p&gt;




&lt;h2&gt;What a Vision Contains&lt;/h2&gt;

&lt;p&gt;A Vision is a structured payload fired on-chain when a historically significant pattern is detected. Here's what arrives in the &lt;code&gt;VisionFired&lt;/code&gt; event:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tokenId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bytes32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;keccak256("BTC")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;patternType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;0x11&lt;/code&gt; (CAPITULATION_STRONG)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;confidence&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;86&lt;/code&gt; (AI-calibrated, 55-89 range)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;direction&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;1&lt;/code&gt; (BULLISH)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint256&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;BTC price at detection (18 decimals)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;payload&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bytes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ABI-encoded: indicators, analysis, feeds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;payload&lt;/code&gt; bytes decode to a full analysis package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Indicator snapshot&lt;/strong&gt; — RSI, EMA gap, ATR, Bollinger position, VWAP distance, rate of change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern metadata&lt;/strong&gt; — historical accuracy, average return, sample size, data span&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI analysis&lt;/strong&gt; — 2-3 sentence explanation of what's happening&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feeds to watch&lt;/strong&gt; — which Pythia Feeds to monitor for confirmation (with thresholds)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;The Patterns (Backtested 2017-2026)&lt;/h2&gt;

&lt;p&gt;Six patterns validated against years of BTC history, covering four categories:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CAPITULATION_STRONG&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Severe sell-off with multiple confirming indicators&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CAPITULATION_BOUNCE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sell-off with early reversal signals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EMA_DIVERGENCE_STRONG&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Strong trend divergence with momentum confirmation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EMA_DIVERGENCE_SNAP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Trend divergence approaching snap-back threshold&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BOLLINGER_EXTREME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Price at extreme statistical deviation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OVERBOUGHT_CONTINUATION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Strong momentum with continuation bias&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each Vision carries its confidence score and the historical accuracy range for the detected pattern — your contract gets the full context to decide how to act.&lt;/p&gt;

&lt;p&gt;Browse available Visions at &lt;a href="https://pythia.c3x-solutions.com/visions/#available" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com/visions&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;The On-Chain Interface&lt;/h2&gt;

&lt;h3&gt;PythiaVisionRegistry&lt;/h3&gt;

&lt;p&gt;Deployed on Polygon mainnet at &lt;a href="https://polygonscan.com/address/0x39407eEc3Ba80746BC6156eD924D16C2689533Ed#code" rel="noopener noreferrer"&gt;&lt;code&gt;0x39407eEc3Ba80746BC6156eD924D16C2689533Ed&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;interface IPythiaVisionRegistry {
    /// @notice Emitted when AI detects a backtested pattern
    event VisionFired(
        bytes32 indexed tokenId,
        uint8   patternType,   // 0x11 = CAPITULATION_STRONG, etc.
        uint8   confidence,    // AI-calibrated, 55-89
        uint8   direction,     // 1 = BULLISH
        uint256 price,         // 18 decimals
        bytes   payload        // ABI-encoded full analysis
    );

    /// @notice Subscribe to Visions for a token. Free — no LINK.
    function subscribe(bytes32 tokenId) external;

    /// @notice Unsubscribe
    function unsubscribe(bytes32 tokenId) external;

    /// @notice Check subscription status
    function isSubscribed(address subscriber, bytes32 tokenId)
        external view returns (bool);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Visions are free.&lt;/strong&gt; &lt;code&gt;subscribe(keccak256("BTC"))&lt;/code&gt; — that's it. No LINK, no fees, no expiry.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;VisionFired&lt;/code&gt; events are public. Anyone can read them from the event log. Subscription is optional on-chain registration — useful for contracts that want to filter or for future automation.&lt;/p&gt;

&lt;h3&gt;Pattern Type Codes&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;// BTC pattern types
uint8 constant CAPITULATION_STRONG   = 0x11;
uint8 constant CAPITULATION_BOUNCE   = 0x10;
uint8 constant EMA_DIVERGENCE_STRONG = 0x21;
uint8 constant EMA_DIVERGENCE_SNAP   = 0x20;
uint8 constant BOLLINGER_EXTREME     = 0x30;
uint8 constant OVERBOUGHT_CONT      = 0x40;&lt;/code&gt;&lt;/pre&gt;




&lt;h2&gt;Reading Visions in Your Contract&lt;/h2&gt;

&lt;p&gt;The simplest integration: listen for &lt;code&gt;VisionFired&lt;/code&gt; events and act on the structured fields.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./interfaces/IPythiaVisionRegistry.sol";

contract SimpleVisionReader {
    IPythiaVisionRegistry public immutable visionRegistry;
    bytes32 public constant BTC = keccak256("BTC");

    uint8   public lastPattern;
    uint8   public lastConfidence;
    uint256 public lastPrice;
    uint64  public lastTimestamp;

    event VisionReceived(uint8 pattern, uint8 confidence, uint256 price);

    constructor(address _visionRegistry) {
        visionRegistry = IPythiaVisionRegistry(_visionRegistry);
    }

    /// @notice Call once after deployment — free, no LINK needed
    function subscribe() external {
        visionRegistry.subscribe(BTC);
    }

    /// @notice Called by a relay bot when VisionFired is detected
    function onVision(
        uint8 patternType,
        uint8 confidence,
        uint256 price
    ) external {
        lastPattern    = patternType;
        lastConfidence = confidence;
        lastPrice      = price;
        lastTimestamp   = uint64(block.timestamp);
        emit VisionReceived(patternType, confidence, price);
    }

    /// @notice Other contracts read this to check for active signals
    function hasRecentVision(uint64 maxAge) external view returns (bool) {
        return lastTimestamp &amp;gt; 0 &amp;amp;&amp;amp;
               block.timestamp - lastTimestamp &amp;lt;= maxAge;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Deploy on Polygon mainnet with &lt;code&gt;_visionRegistry = 0x39407eEc3Ba80746BC6156eD924D16C2689533Ed&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;Full Example: Vision-Driven Vault Guard&lt;/h2&gt;

&lt;p&gt;The real power of Visions is the &lt;strong&gt;feeds-to-watch&lt;/strong&gt; field. Each Vision tells you which Pythia Feeds to monitor for confirmation — with specific thresholds.&lt;/p&gt;

&lt;p&gt;For example, a capitulation Vision might include feeds like &lt;code&gt;btc_RSI_1H_14&lt;/code&gt; (watch for oversold exit), &lt;code&gt;btc_VWAP_24H&lt;/code&gt; (watch for VWAP reclaim), and &lt;code&gt;btc_EMA_1H_20&lt;/code&gt; (watch for EMA reclaim) — each with a specific condition and threshold tailored to the current market state.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;VisionVaultGuard&lt;/code&gt; contract automates this loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Vision fires&lt;/strong&gt; (free) — AI says "BTC capitulation detected, 86% confidence"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contract auto-subscribes&lt;/strong&gt; to the recommended Pythia Events (paid LINK) — "tell me when RSI crosses above 35"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Events fire&lt;/strong&gt; when thresholds are hit — confirmation arrives on-chain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contract transitions to CONFIRMED&lt;/strong&gt; — other contracts/bots read the state and act&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code&gt;State machine:

  IDLE → ALERT → WATCHING → CONFIRMED → IDLE
         (vision   (events     (enough        (auto-reset
          fires)    subscribed)  confirmations)  after cooldown)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's the core of the contract (full source at &lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;pythia-oracle-examples&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;contract VisionVaultGuard is ConfirmedOwner {
    enum State { IDLE, ALERT, WATCHING, CONFIRMED }

    IPythiaEventRegistry    public eventRegistry;
    IPythiaVisionRegistry   public visionRegistry;
    bytes32 public constant BTC = keccak256("BTC");

    State public state;
    uint8 public requiredConfirmations = 1;

    struct FeedWatch {
        string  feedName;    // e.g. "btc_RSI_1H_14"
        uint8   condition;   // 0=ABOVE, 1=BELOW
        int256  threshold;   // 8 decimals
    }

    /// @notice Relay bot calls this when VisionFired event is detected
    function processVision(
        uint8 patternType,
        uint8 confidence,
        uint8 direction,
        uint256 price,
        FeedWatch[] calldata feeds,
        string[] calldata meanings
    ) external onlyOwner {
        // Store vision data, transition to ALERT
        // ...

        // Auto-subscribe to each recommended feed as a Pythia Event
        for (uint256 i = 0; i &amp;lt; feeds.length; i++) {
            uint256 cost = eventRegistry.getCost(eventDays);
            LINK.approve(address(eventRegistry), cost);
            uint256 eventId = eventRegistry.subscribe(
                feeds[i].feedName,
                eventDays,
                feeds[i].condition,
                feeds[i].threshold
            );
            // Track subscription for confirmation matching
        }

        // Transition: ALERT → WATCHING
    }

    /// @notice Bot reports when a confirmation Event fires
    function reportConfirmation(uint256 eventId, int256 value) external onlyOwner {
        // Match eventId to tracked subscription, mark as fired
        // If enough confirmations → transition to CONFIRMED
    }

    /// @notice Other contracts read this
    function isActionReady() external view returns (bool) {
        return state == State.CONFIRMED &amp;amp;&amp;amp;
               block.timestamp &amp;lt; lastVision.receivedAt + confirmedTimeout;
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a &lt;strong&gt;Vision → Event → Action&lt;/strong&gt; loop where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visions (free) provide the intelligence — what happened and what to watch&lt;/li&gt;
&lt;li&gt;Events (paid LINK) provide the triggers — when confirmations arrive&lt;/li&gt;
&lt;li&gt;Your contract acts only when both the pattern AND the confirmations align&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full contract with 26 passing Hardhat tests: &lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;&lt;code&gt;06_VisionVaultGuard.sol&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;Deploying on Polygon Mainnet&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;Pythia Vision Registry: 0x39407eEc3Ba80746BC6156eD924D16C2689533Ed
Pythia Event Registry:  0x73686087d737833C5223948a027E13B608623e21
LINK Token:             0xb0897686c545045aFc77CF20eC7A532E3120E0F1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the VisionVaultGuard, fund the contract with LINK (for Event subscriptions). Visions themselves are free.&lt;/p&gt;




&lt;h2&gt;AI-Assisted Development&lt;/h2&gt;

&lt;p&gt;Explore Visions and Feeds programmatically:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Works with Claude, Cursor, Windsurf, or any MCP-compatible AI tool. Ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"What patterns does Pythia Visions detect for BTC?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Show me the VisionFired event interface"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"What feeds should I watch after a capitulation signal?"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or use LangChain:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install langchain-pythia&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;from langchain_pythia import PythiaToolkit

toolkit = PythiaToolkit()
tools = toolkit.get_tools()
# 7 tools: feeds, tokens, events, visions info, and more&lt;/code&gt;&lt;/pre&gt;




&lt;h2&gt;Why This Architecture&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why not just put AI on-chain?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running an LLM on-chain is impossible. But the output of an AI — a confidence score, a pattern classification, a set of indicator values — is just data. Data that Chainlink already knows how to deliver.&lt;/p&gt;

&lt;p&gt;Pythia's approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mechanical detection&lt;/strong&gt; (free, deterministic) decides IF something fires&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI calibration&lt;/strong&gt; (one cheap API call) adds nuance to HOW confident we are&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chainlink delivery&lt;/strong&gt; (trustless) gets it on-chain&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The AI is one step in the middle — not the foundation. If AI is down, Visions still fire with mechanical defaults. The patterns are the product; AI makes them better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why backtested patterns?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every pattern in production has been validated against years of BTC history. Patterns that looked strong on shorter windows but degraded on full history were dropped. Data decides what ships.&lt;/p&gt;




&lt;h2&gt;What You Can Build With This&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Risk management layers&lt;/strong&gt; — pause lending/vault operations when high-confidence capitulation is detected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated DCA strategies&lt;/strong&gt; — increase position size when AI confidence is above 80%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alert systems&lt;/strong&gt; — relay Vision data to Telegram/Discord bots for trading teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio rebalancing&lt;/strong&gt; — shift allocations based on detected market regime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeper-style bots&lt;/strong&gt; — watch for VisionFired events and execute strategies across protocols&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pythia Visions deliver AI-calibrated market intelligence on-chain via Chainlink&lt;/li&gt;
&lt;li&gt;6 backtested BTC patterns covering capitulations, divergences, extremes, and momentum&lt;/li&gt;
&lt;li&gt;Free subscription — &lt;code&gt;subscribe(keccak256("BTC"))&lt;/code&gt;, no LINK&lt;/li&gt;
&lt;li&gt;Structured payload: pattern type, confidence, indicators, analysis, feeds-to-watch&lt;/li&gt;
&lt;li&gt;VisionVaultGuard example: automated Vision → Event → Action loop&lt;/li&gt;
&lt;li&gt;Mainnet contract: &lt;a href="https://polygonscan.com/address/0x39407eEc3Ba80746BC6156eD924D16C2689533Ed#code" rel="noopener noreferrer"&gt;&lt;code&gt;0x39407eEc3Ba80746BC6156eD924D16C2689533Ed&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The intelligence is live. The patterns are firing. What you build on top is up to you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Explore: &lt;a href="https://pythia.c3x-solutions.com/visions/" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com/visions&lt;/a&gt; | MCP: &lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt; | Examples: &lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;github.com/pythia-the-oracle/pythia-oracle-examples&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>web3</category>
    </item>
    <item>
      <title>On-Chain Alerts for Smart Contracts Using a Pub-Sub Pattern</title>
      <dc:creator>Pythia Oracle</dc:creator>
      <pubDate>Thu, 09 Apr 2026 10:39:04 +0000</pubDate>
      <link>https://dev.to/pythiatheoracle/on-chain-alerts-for-smart-contracts-using-a-pub-sub-pattern-1jmd</link>
      <guid>https://dev.to/pythiatheoracle/on-chain-alerts-for-smart-contracts-using-a-pub-sub-pattern-1jmd</guid>
      <description>&lt;p&gt;Smart contracts are good at executing logic. They're terrible at knowing &lt;em&gt;when&lt;/em&gt; to execute it.&lt;/p&gt;

&lt;p&gt;If your contract needs to rebalance when RSI drops below 30, or pause deposits when volatility spikes above 8%, you have two options today: run an off-chain bot that polls an oracle every few minutes and calls your contract when conditions change, or set up a keeper network. Both require infrastructure you have to build, fund, and monitor.&lt;/p&gt;

&lt;p&gt;There's a third option that works the way publish-subscribe patterns work everywhere else in software: &lt;strong&gt;subscribe to a condition, get notified when it's true, done.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This tutorial shows how to build a smart contract that subscribes to on-chain indicator alerts using a pub-sub oracle — no bots, no keepers, no off-chain infrastructure. One transaction to subscribe. One event to listen for.&lt;/p&gt;

&lt;h2&gt;The Interface&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://pythia.c3x-solutions.com/events/" rel="noopener noreferrer"&gt;Pythia Event Registry&lt;/a&gt; exposes a minimal interface for subscribing to calculated indicator alerts (RSI, EMA, Bollinger Bands, VWAP, volatility) delivered through a Chainlink oracle node:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;interface IPythiaEventRegistry {
    /// Emitted when a subscription's condition is met
    event PythiaEvent(uint256 indexed eventId, int256 value);

    /// Subscribe to an indicator alert. Approve LINK spending first.
    function subscribe(
        string calldata feedName,   // e.g. "bitcoin_RSI_1D_14"
        uint16 numDays,             // 1-365 days to monitor
        uint8 condition,            // 0=ABOVE, 1=BELOW
        int256 threshold            // 8 decimals (RSI 30 = 3000000000)
    ) external returns (uint256 eventId);

    /// Cancel subscription. Remaining whole days refunded in LINK.
    function cancelSubscription(uint256 eventId) external;

    /// Check if a subscription is still active
    function isActive(uint256 eventId) external view returns (bool);

    /// Get the LINK cost for N days at current price
    function getCost(uint16 numDays) external view returns (uint256);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You call &lt;code&gt;subscribe()&lt;/code&gt; with a feed name, how long to monitor, the condition (above or below a threshold), and a threshold value. The oracle monitors the indicator every 5 minutes. When the condition is met, it fires &lt;code&gt;PythiaEvent&lt;/code&gt; on-chain with the triggering value and refunds your unused days in LINK.&lt;/p&gt;

&lt;p&gt;No API keys. No webhook endpoints. No keeper contracts. Everything happens on-chain through standard Solidity events.&lt;/p&gt;

&lt;h2&gt;The Subscriber Contract&lt;/h2&gt;

&lt;p&gt;Here's a complete contract that wraps the registry interface. This is production code from the &lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;Pythia examples repository&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import "./interfaces/IPythiaEventRegistry.sol";

contract EventSubscriber is ConfirmedOwner {
    LinkTokenInterface public immutable LINK;
    IPythiaEventRegistry public registry;

    uint256 public lastEventId;

    event Subscribed(uint256 indexed eventId, string feed, uint8 condition, int256 threshold);
    event Cancelled(uint256 indexed eventId);

    constructor(address _link, address _registry) ConfirmedOwner(msg.sender) {
        LINK = LinkTokenInterface(_link);
        registry = IPythiaEventRegistry(_registry);
    }

    /// @notice Subscribe to an indicator alert. Fund this contract with LINK first.
    /// @param feedName e.g. "pol_RSI_5M_14", "bitcoin_EMA_1H_20"
    /// @param numDays  1-365 — how long to monitor
    /// @param condition 0=ABOVE, 1=BELOW
    /// @param threshold 8 decimals (e.g. RSI 30 = 3000000000)
    /// @return eventId Listen for PythiaEvent(eventId) on the registry
    function subscribe(
        string calldata feedName,
        uint16 numDays,
        uint8 condition,
        int256 threshold
    ) external onlyOwner returns (uint256 eventId) {
        uint256 cost = registry.getCost(numDays);
        LINK.approve(address(registry), cost);
        eventId = registry.subscribe(feedName, numDays, condition, threshold);
        lastEventId = eventId;
        emit Subscribed(eventId, feedName, condition, threshold);
    }

    /// @notice Cancel a subscription. Remaining whole days refunded in LINK.
    function cancel(uint256 eventId) external onlyOwner {
        registry.cancelSubscription(eventId);
        emit Cancelled(eventId);
    }

    /// @notice Check if a subscription is still active
    function isActive(uint256 eventId) external view returns (bool) {
        return registry.isActive(eventId);
    }

    /// @notice Update registry address (e.g. after upgrade)
    function setRegistry(address _registry) external onlyOwner {
        registry = IPythiaEventRegistry(_registry);
    }

    /// @notice Withdraw LINK from this contract
    function withdrawLink() external onlyOwner {
        LINK.transfer(msg.sender, LINK.balanceOf(address(this)));
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The flow: fund the contract with LINK, call &lt;code&gt;subscribe()&lt;/code&gt; with your condition, store the &lt;code&gt;eventId&lt;/code&gt;, and listen for &lt;code&gt;PythiaEvent&lt;/code&gt; on the registry. When the oracle detects your condition is met, the event fires on-chain. Your bot (or another contract) catches it and reacts.&lt;/p&gt;

&lt;h2&gt;Threshold Scaling&lt;/h2&gt;

&lt;p&gt;Thresholds use &lt;strong&gt;8 decimal places&lt;/strong&gt; — not 18 like standard ERC-20 values. This is the most common mistake when setting up subscriptions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Indicator&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Threshold Value&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSI below 30&lt;/td&gt;
&lt;td&gt;30.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3000000000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSI above 70&lt;/td&gt;
&lt;td&gt;70.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;7000000000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EMA below $2,500&lt;/td&gt;
&lt;td&gt;2500.0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;250000000000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volatility above 5%&lt;/td&gt;
&lt;td&gt;0.05&lt;/td&gt;
&lt;td&gt;&lt;code&gt;500000000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two condition types are live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0 = ABOVE&lt;/strong&gt; — fires when the indicator value exceeds your threshold&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 = BELOW&lt;/strong&gt; — fires when the indicator value drops below your threshold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directional crossing conditions (CROSSES_ABOVE, CROSSES_BELOW) are accepted by the contract for forward compatibility but are not yet processed by the matcher.&lt;/p&gt;

&lt;h2&gt;Deploying to Testnet&lt;/h2&gt;

&lt;p&gt;The examples repo includes a Hardhat deploy script for both testnet and mainnet:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone https://github.com/pythia-the-oracle/pythia-oracle-examples
cd pythia-oracle-examples
npm install

# Deploy to Polygon Amoy testnet
npx hardhat run scripts/deploy-events.js --network amoy&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The script wires the correct LINK token and registry addresses automatically. After deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get test LINK&lt;/strong&gt; from &lt;a href="https://faucets.chain.link/polygon-amoy" rel="noopener noreferrer"&gt;faucets.chain.link/polygon-amoy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fund the contract&lt;/strong&gt; — transfer LINK to your deployed &lt;code&gt;EventSubscriber&lt;/code&gt; address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subscribe&lt;/strong&gt; — call &lt;code&gt;subscribe("bitcoin_RSI_1D_14", 3, 1, 3000000000)&lt;/code&gt; to monitor BTC RSI below 30 for 3 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note the eventId&lt;/strong&gt; from the &lt;code&gt;Subscribed&lt;/code&gt; event&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listen&lt;/strong&gt; for &lt;code&gt;PythiaEvent(eventId)&lt;/code&gt; on the registry contract&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Available feeds span multiple tokens (BTC, SOL, AAVE, UNI, MORPHO, CRV, COMP, and more) and indicators (EMA, RSI, Bollinger Bands, VWAP, volatility, liquidity) across timeframes from 5-minute to weekly.&lt;/p&gt;

&lt;h2&gt;What Happens When It Fires&lt;/h2&gt;

&lt;p&gt;The oracle monitors all active subscriptions every minute. When your condition matches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The matcher marks the subscription inactive&lt;/li&gt;
&lt;li&gt;A batch transaction calls &lt;code&gt;fireEvents()&lt;/code&gt; on the registry — one tx for multiple events&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PythiaEvent(eventId, value)&lt;/code&gt; is emitted with the triggering indicator value&lt;/li&gt;
&lt;li&gt;Remaining whole days are refunded in LINK to your contract&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your subscriber listens for the event:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;const myEventId = 42n;

// Real-time listener
registry.on("PythiaEvent", (eventId, value) =&amp;gt; {
    if (eventId === myEventId) {
        const rsi = Number(value) / 1e8;
        console.log(`RSI dropped to ${rsi} — condition met`);
        // Trigger rebalance, close position, notify team
    }
});

// Or backfill if your listener was offline — events are permanent
const filter = registry.filters.PythiaEvent(myEventId);
const events = await registry.queryFilter(filter, fromBlock, "latest");&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Gas cost per fired event on Polygon: approximately $0.0001. Batch firing 50 events in a single transaction costs under $0.01.&lt;/p&gt;

&lt;h2&gt;Why Pub-Sub Beats Polling&lt;/h2&gt;

&lt;p&gt;If your contract polls an oracle for data on a fixed schedule, you pay per request whether the condition is met or not. With pub-sub, you pay a flat daily rate and the oracle handles the monitoring:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Daily Cost&lt;/th&gt;
&lt;th&gt;Infrastructure&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Events (pub-sub)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1 LINK/day&lt;/td&gt;
&lt;td&gt;None — oracle monitors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Polling via Discovery&lt;/td&gt;
&lt;td&gt;2.88 LINK/day (288 req)&lt;/td&gt;
&lt;td&gt;Keeper or bot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Polling via Complete&lt;/td&gt;
&lt;td&gt;28.8 LINK/day (288 req)&lt;/td&gt;
&lt;td&gt;Keeper or bot&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Events cost 65% less than polling the cheapest tier, and 97% less than polling the complete tier. If the condition fires early, you get unused days refunded. If you change your mind, cancel and get the remaining days back.&lt;/p&gt;

&lt;p&gt;The pub-sub pattern also eliminates infrastructure: no server to run, no keeper to fund, no cron job to monitor. Your contract subscribes once and waits for the callback.&lt;/p&gt;

&lt;h2&gt;AI Agent Integration&lt;/h2&gt;

&lt;p&gt;If you're building autonomous DeFi agents, indicator subscriptions can be discovered and configured through AI tooling:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server&lt;/strong&gt; (works in Claude, Cursor, Windsurf):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;10 tools — discover available tokens, check feed health, look up contract addresses, get pricing, generate integration code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LangChain tools&lt;/strong&gt; (for agent frameworks):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install langchain-pythia&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;7 tools — &lt;code&gt;PythiaListTokensTool&lt;/code&gt;, &lt;code&gt;PythiaTokenFeedsTool&lt;/code&gt;, &lt;code&gt;PythiaHealthCheckTool&lt;/code&gt;, &lt;code&gt;PythiaContractsTool&lt;/code&gt;, &lt;code&gt;PythiaPricingTool&lt;/code&gt;, and Events tools for subscription info and integration guides.&lt;/p&gt;

&lt;p&gt;An AI agent can discover which indicators are available for a token, check current pricing, and generate the subscription parameters — all programmatically. The subscription itself is a single on-chain transaction that the agent (or human) approves.&lt;/p&gt;

&lt;h2&gt;Contract Addresses&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Network&lt;/th&gt;
&lt;th&gt;Contract&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Polygon Mainnet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event Registry&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x73686087d737833C5223948a027E13B608623e21&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Polygon Mainnet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LINK Token (ERC-677)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xb0897686c545045aFc77CF20eC7A532E3120E0F1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amoy Testnet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event Registry&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x931Aa640d29E6C9D9fB3002749a52EC7fb277f9c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Amoy Testnet&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LINK Token&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x0Fd9e8d3aF1aaee056EB9e802c3A762a667b1904&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;Pythia Oracle — live feeds, contracts, documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pythia.c3x-solutions.com/events/" rel="noopener noreferrer"&gt;Events — how subscriptions work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;Example contracts and tests on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MCP server: &lt;a href="https://pypi.org/project/pythia-oracle-mcp/" rel="noopener noreferrer"&gt;&lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LangChain tools: &lt;a href="https://pypi.org/project/langchain-pythia/" rel="noopener noreferrer"&gt;&lt;code&gt;pip install langchain-pythia&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Community: &lt;a href="https://t.me/pythia_the_oracle" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://x.com/pythia_oracle" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Pythia delivers pre-calculated technical indicators on-chain via standard Chainlink oracle interface — EMA, RSI, VWAP, Bollinger Bands, volatility, liquidity. Any token, any Chainlink-supported chain. Subscribe to conditions with Events, or request data directly. &lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>solidity</category>
      <category>chainlink</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Building an RSI-Gated DeFi Vault: Stop Deploying Capital Into Downtrends</title>
      <dc:creator>Pythia Oracle</dc:creator>
      <pubDate>Sat, 04 Apr 2026 18:10:38 +0000</pubDate>
      <link>https://dev.to/pythiatheoracle/building-an-rsi-gated-defi-vault-stop-deploying-capital-into-downtrends-538h</link>
      <guid>https://dev.to/pythiatheoracle/building-an-rsi-gated-defi-vault-stop-deploying-capital-into-downtrends-538h</guid>
      <description>&lt;p&gt;DeFi vaults are everywhere. Morpho, Kamino, Pendle, Yearn — billions in TVL running automated yield strategies. They rebalance on schedule, deploy capital on threshold triggers, and compound returns 24/7.&lt;/p&gt;

&lt;p&gt;But none of them can answer a simple question: &lt;strong&gt;is momentum working for or against this entry?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A human trader checks RSI before deploying capital. If daily RSI is 75 — overbought, momentum fading — they wait. If it's 28 — oversold, potential reversal — they enter. Your vault? It doesn't know. It executes on schedule regardless.&lt;/p&gt;

&lt;h2&gt;The Problem: Condition-Blind Vaults&lt;/h2&gt;

&lt;p&gt;Today, vault strategies trigger on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time&lt;/strong&gt; — weekly rebalance, regardless of market state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price thresholds&lt;/strong&gt; — rebalance when price moves ±5%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TVL ratios&lt;/strong&gt; — deploy when utilization drops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these factor in momentum. You can be perfectly right about an asset's fundamental value and still deploy capital at exactly the wrong time — RSI at 75, right before a 40% drawdown.&lt;/p&gt;

&lt;p&gt;The problem isn't the strategy logic. It's that &lt;strong&gt;RSI doesn't exist on-chain&lt;/strong&gt;. No smart contract can read it. Computing a 14-period RSI requires historical price data, resampling, and the Wilder smoothing formula — none of which is feasible in Solidity.&lt;/p&gt;

&lt;h2&gt;The Solution: An On-Chain RSI Oracle&lt;/h2&gt;

&lt;p&gt;What if your vault could read RSI directly from a Chainlink oracle — the same interface you already use for price feeds?&lt;/p&gt;

&lt;p&gt;That's what this tutorial builds: a vault with an &lt;strong&gt;RSI circuit breaker&lt;/strong&gt;. An oracle delivers pre-calculated RSI on-chain, and your contract checks it before allowing deposits. No off-chain server, no API keys, no centralized dependency.&lt;/p&gt;

&lt;p&gt;An RSI gate doesn't predict the future. It says: &lt;em&gt;don't deploy capital when momentum is strongly against you.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;The Architecture (Important: This is Async)&lt;/h2&gt;

&lt;p&gt;On-chain RSI through Chainlink's &lt;strong&gt;Direct Request&lt;/strong&gt; pattern is asynchronous — not like price feeds (&lt;code&gt;latestRoundData()&lt;/code&gt;). You request a value, the oracle computes it off-chain, and delivers it to a callback.&lt;/p&gt;

&lt;p&gt;This means the vault works in two phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Refresh phase&lt;/strong&gt;: A keeper (or Chainlink Automation) calls &lt;code&gt;refreshRSI()&lt;/code&gt; periodically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deposit phase&lt;/strong&gt;: Users call &lt;code&gt;deposit()&lt;/code&gt; — the contract checks the &lt;em&gt;cached&lt;/em&gt; RSI value and its age&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lifecycle:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Keeper → refreshRSI() → sends LINK → Chainlink request
  ↓
Oracle computes RSI from 4 data sources
  ↓
Chainlink → fulfill() → stores lastRSI + timestamp
  ↓
User → deposit() → checks lastRSI &amp;lt; threshold &amp;amp;&amp;amp; data &amp;lt; 2h old → allows&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;The Contract&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";

contract RSIGatedVault is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    // Pythia oracle config (Polygon mainnet)
    address private constant ORACLE = 0xAA37710aF244514691629Aa15f4A5c271EaE6891;
    address private constant LINK  = 0xb0897686c545045aFc77CF20eC7A532E3120E0F1;
    bytes32 private jobId;
    uint256 private constant FEE = (1 * LINK_DIVISIBILITY) / 100; // 0.01 LINK

    // RSI state
    uint256 public lastRSI;       // scaled 1e18 (e.g. 25.43 = 25430000000000000000)
    uint256 public lastUpdated;   // timestamp of last oracle fulfillment
    uint256 public constant FRESHNESS = 2 hours;
    uint256 public constant RSI_MAX   = 35 * 1e18; // gate: deposit only when RSI &amp;lt; 35

    // Vault accounting
    mapping(address =&amp;gt; uint256) public balances;
    uint256 public totalDeposited;

    string public feedName; // e.g. "uniswap_RSI_1D_14"

    event RSIUpdated(uint256 rsi, uint256 timestamp);
    event Deposited(address indexed user, uint256 amount, uint256 rsiAtDeposit);

    constructor(bytes32 _jobId, string memory _feedName)
        ConfirmedOwner(msg.sender)
    {
        _setChainlinkToken(LINK);
        _setChainlinkOracle(ORACLE);
        jobId    = _jobId;
        feedName = _feedName;
    }

    /// @notice Called by keeper or Chainlink Automation to refresh RSI
    function refreshRSI() external returns (bytes32) {
        Chainlink.Request memory req = _buildChainlinkRequest(
            jobId,
            address(this),
            this.fulfill.selector
        );
        req._add("feed", feedName);
        return _sendChainlinkRequest(req, FEE);
    }

    /// @notice Chainlink callback — stores updated RSI
    function fulfill(bytes32 _requestId, uint256 _value)
        public
        recordChainlinkFulfillment(_requestId)
    {
        lastRSI     = _value;
        lastUpdated = block.timestamp;
        emit RSIUpdated(_value, block.timestamp);
    }

    /// @notice Deposit POL — only allowed when RSI is below threshold
    function deposit() external payable {
        require(msg.value &amp;gt; 0, "Zero deposit");
        require(
            block.timestamp - lastUpdated &amp;lt;= FRESHNESS,
            "RSI data stale — keeper must refresh"
        );
        require(
            lastRSI &amp;lt; RSI_MAX,
            "RSI too high — waiting for oversold conditions"
        );

        balances[msg.sender] += msg.value;
        totalDeposited        += msg.value;
        emit Deposited(msg.sender, msg.value, lastRSI);
    }

    function withdraw(uint256 amount) external {
        require(balances[msg.sender] &amp;gt;= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        totalDeposited        -= amount;
        payable(msg.sender).transfer(amount);
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Deploying and Testing&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Get LINK on Polygon mainnet&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You need 0.01 LINK per RSI refresh. Get LINK at &lt;a href="https://bridge.chain.link" rel="noopener noreferrer"&gt;bridge.chain.link&lt;/a&gt; or via any Polygon DEX.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Get the Job ID&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the Pythia MCP server to discover available feeds and the job ID:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install pythia-oracle-mcp
# Then in Claude/Cursor/Windsurf:
# "What is the job ID for uniswap_RSI_1D_14?"&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Deploy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploy &lt;code&gt;RSIGatedVault&lt;/code&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_jobId&lt;/code&gt;: The Pythia job ID (bytes32, from MCP server)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_feedName&lt;/code&gt;: &lt;code&gt;"uniswap_RSI_1D_14"&lt;/code&gt; (or any available Pythia feed — EMA, RSI, VWAP, Bollinger, volatility, liquidity across multiple tokens and timeframes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Fund with LINK and call refreshRSI&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Transfer 0.1 LINK to the vault address, then:
vault.refreshRSI();
// Wait ~30 seconds for oracle fulfillment
// vault.lastRSI() now returns current RSI scaled by 1e18&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Automate with Chainlink Automation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Register the vault in &lt;a href="https://automation.chain.link" rel="noopener noreferrer"&gt;Chainlink Automation&lt;/a&gt; to call &lt;code&gt;refreshRSI()&lt;/code&gt; hourly. This keeps RSI data fresh without a centralized keeper.&lt;/p&gt;

&lt;h2&gt;Test Free with the Faucet&lt;/h2&gt;

&lt;p&gt;Before committing LINK, test with the Pythia Faucet on Polygon mainnet — pre-funded, no cost to you:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Faucet: 0x640fC3B9B607E324D7A3d89Fcb62C77Cc0Bd420A&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The faucet contract holds its own LINK balance. Each request costs 0.01 LINK from the faucet's balance — you don't need to hold any LINK yourself. Up to 5 requests per day. All feeds available. If the faucet runs dry, anyone can top it up by sending LINK (ERC-677) to the faucet address.&lt;/p&gt;

&lt;h2&gt;What the Data Looks Like&lt;/h2&gt;

&lt;p&gt;Pythia delivers RSI values scaled by 1e18 on-chain. Here's how to interpret them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;RSI Range&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Vault Behavior (threshold=35)&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0–30&lt;/td&gt;
&lt;td&gt;Oversold — momentum suggests potential reversal&lt;/td&gt;
&lt;td&gt;Deposits &lt;strong&gt;allowed&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30–35&lt;/td&gt;
&lt;td&gt;Approaching neutral from oversold&lt;/td&gt;
&lt;td&gt;Deposits &lt;strong&gt;allowed&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;35–70&lt;/td&gt;
&lt;td&gt;Neutral — no strong signal&lt;/td&gt;
&lt;td&gt;Deposits &lt;strong&gt;blocked&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70–100&lt;/td&gt;
&lt;td&gt;Overbought — momentum suggests potential pullback&lt;/td&gt;
&lt;td&gt;Deposits &lt;strong&gt;blocked&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example feeds available: &lt;code&gt;uniswap_RSI_1D_14&lt;/code&gt;, &lt;code&gt;aave_RSI_1D_14&lt;/code&gt;, &lt;code&gt;bitcoin_RSI_1H_14&lt;/code&gt;, &lt;code&gt;solana_RSI_1W_14&lt;/code&gt; — any token Pythia serves, across 6 timeframes (5M, 15M, 1H, 4H, 1D, 1W).&lt;/p&gt;

&lt;p&gt;When multiple DeFi tokens show oversold RSI simultaneously, the gate opens — precisely when technical analysis suggests momentum conditions favor entry.&lt;/p&gt;

&lt;h2&gt;Going Further&lt;/h2&gt;

&lt;p&gt;This is the simplest RSI gate. Production implementations might add:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-indicator confirmation:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Deposit only when RSI is oversold AND price is above EMA-20 (trend intact)
require(lastRSI &amp;lt; 35 * 1e18, "RSI too high");
require(lastPrice &amp;gt; lastEMA20, "Below trend — skip entry");&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Bollinger Band entries:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Request &lt;code&gt;uniswap_BOLLINGER_1D_LOWER&lt;/code&gt; — deposit only when price is within 2% of the lower band (double confirmation with RSI).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bundle requests — get all indicators at once:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;PythiaBundleConsumer&lt;/code&gt; to fetch EMA_20, EMA_50, RSI_14, BOLLINGER_UPPER, BOLLINGER_LOWER, VWAP, VOLATILITY, and LIQUIDITY in a single request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Analysis tier&lt;/strong&gt; (0.03 LINK) — 1H/1D/1W timeframes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed tier&lt;/strong&gt; (0.05 LINK) — 5M timeframe&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete tier&lt;/strong&gt; (0.10 LINK) — all 6 timeframes (5M, 15M, 1H, 4H, 1D, 1W)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Full indicator list:&lt;/strong&gt; EMA_20, EMA_50, RSI_14, BOLLINGER_UPPER, BOLLINGER_LOWER, VWAP, VOLATILITY, LIQUIDITY across 6 timeframes for tokens including BTC, SOL, AAVE, UNI, LDO, Morpho, and more — new tokens added on demand.&lt;/p&gt;

&lt;h2&gt;Contract Addresses (Polygon Mainnet)&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Contract&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;th&gt;Fee&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faucet (free trial)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x640fC3B9B607E324D7A3d89Fcb62C77Cc0Bd420A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-funded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discovery&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xeC2865d66ae6Af47926B02edd942A756b394F820&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.01 LINK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analysis (1H/1D/1W bundle)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x3b3aC62d73E537E3EF84D97aB5B84B51aF8dB316&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.03 LINK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed (5M bundle)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xC406e7d9AC385e7AB43cBD56C74ad487f085d47B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.05 LINK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complete (all timeframes)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x2dEC98fd7173802b351d1E28d0Cd5DdD20C24252&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.10 LINK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LINK token (ERC-677)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xb0897686c545045aFc77CF20eC7A532E3120E0F1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operator&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xAA37710aF244514691629Aa15f4A5c271EaE6891&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Live feeds and contracts: &lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MCP server (explore feeds in Claude/Cursor/Windsurf): &lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;LangChain integration: &lt;code&gt;pip install langchain-pythia&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Pythia delivers pre-calculated technical indicators (EMA, RSI, VWAP, Bollinger Bands, volatility, liquidity) on-chain via standard Chainlink interface. Any token, any Chainlink-supported chain. &lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>chainlink</category>
      <category>solidity</category>
      <category>tradefi</category>
    </item>
    <item>
      <title>On-Chain RSI: How to Read Live Technical Indicators From a Solidity Smart Contract</title>
      <dc:creator>Pythia Oracle</dc:creator>
      <pubDate>Thu, 02 Apr 2026 14:59:29 +0000</pubDate>
      <link>https://dev.to/pythiatheoracle/on-chain-rsi-how-to-read-live-technical-indicators-from-a-solidity-smart-contract-ghh</link>
      <guid>https://dev.to/pythiatheoracle/on-chain-rsi-how-to-read-live-technical-indicators-from-a-solidity-smart-contract-ghh</guid>
      <description>&lt;h2&gt;Why You Can't Calculate RSI On-Chain&lt;/h2&gt;

&lt;p&gt;RSI requires 14 periods of historical prices. For daily RSI, that's 14 days of data. For hourly, 14 hours.&lt;/p&gt;

&lt;p&gt;Storing and computing this in Solidity would cost thousands in gas per calculation. Floating-point math doesn't exist in EVM. It's not viable.&lt;/p&gt;

&lt;p&gt;The practical solution: deliver the pre-calculated value via oracle — computed off-chain, delivered on-chain through Chainlink.&lt;/p&gt;




&lt;h2&gt;How Pythia Feeds Work&lt;/h2&gt;

&lt;p&gt;Pythia uses Chainlink's &lt;strong&gt;Direct Request&lt;/strong&gt; model (not the AggregatorV3Interface used by price feeds). The pattern is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your contract calls &lt;code&gt;requestFeed("bitcoin_RSI_1D_14")&lt;/code&gt; and pays LINK&lt;/li&gt;
&lt;li&gt;Pythia's off-chain engine computes the indicator from 4 redundant data sources&lt;/li&gt;
&lt;li&gt;The Chainlink Operator delivers the result to your contract's &lt;code&gt;fulfill()&lt;/code&gt; callback&lt;/li&gt;
&lt;li&gt;Your contract stores the value and acts on it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is two transactions, not a &lt;code&gt;view&lt;/code&gt; call — the same async pattern used by Chainlink VRF and Any API.&lt;/p&gt;




&lt;h2&gt;The Indicators Available On-Chain&lt;/h2&gt;

&lt;p&gt;Pythia delivers pre-calculated technical indicators for 21 tokens across 4 timeframes (5M, 1H, 1D, 1W):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EMA&lt;/strong&gt; (20 and 50 periods)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RSI&lt;/strong&gt; (14 periods)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bollinger Bands&lt;/strong&gt; (upper and lower, 20-period, 2 std dev)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volatility&lt;/strong&gt; (24H)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VWAP&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Liquidity&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's 462 indicator instances on Polygon mainnet, all delivered through Chainlink.&lt;/p&gt;




&lt;h2&gt;Reading a Single Indicator (Discovery Tier)&lt;/h2&gt;

&lt;p&gt;The Discovery tier returns one indicator per request for 0.01 LINK. This is Pythia's actual deployed contract — &lt;a href="https://polygonscan.com/address/0xeC2865d66ae6Af47926B02edd942A756b394F820#code" rel="noopener noreferrer"&gt;verified on Polygonscan&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";

contract MyIndicatorReader is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    uint256 public lastValue;
    string public lastFeed;

    bytes32 private jobId;
    uint256 private fee;

    event FeedRequested(bytes32 indexed requestId, string feed);
    event FeedFulfilled(bytes32 indexed requestId, uint256 value);

    constructor(
        address _link,
        address _oracle,
        bytes32 _jobId
    ) ConfirmedOwner(msg.sender) {
        _setChainlinkToken(_link);
        _setChainlinkOracle(_oracle);
        jobId = _jobId;
        fee = (1 * LINK_DIVISIBILITY) / 100; // 0.01 LINK
    }

    /// @notice Request any single indicator from Pythia
    /// @param feed Feed name, e.g. "bitcoin_RSI_1D_14", "aave_EMA_5M_20"
    function requestFeed(string memory feed) public onlyOwner returns (bytes32) {
        Chainlink.Request memory req = _buildChainlinkRequest(
            jobId, address(this), this.fulfill.selector
        );
        req._add("feed", feed);
        bytes32 requestId = _sendChainlinkRequest(req, fee);
        lastFeed = feed;
        emit FeedRequested(requestId, feed);
        return requestId;
    }

    /// @notice Chainlink callback — stores the indicator value
    /// @param _value The indicator value with 18 decimal places
    function fulfill(
        bytes32 _requestId,
        uint256 _value
    ) public recordChainlinkFulfillment(_requestId) {
        lastValue = _value;
        emit FeedFulfilled(_requestId, _value);
    }

    function withdrawLink() external onlyOwner {
        LinkTokenInterface link = LinkTokenInterface(_chainlinkTokenAddress());
        require(link.transfer(msg.sender, link.balanceOf(address(this))));
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Deploy, fund with LINK, call &lt;code&gt;requestFeed("bitcoin_RSI_1D_14")&lt;/code&gt;. The result arrives in &lt;code&gt;fulfill()&lt;/code&gt; — scaled by 1e18 (so RSI of 42.72 comes back as &lt;code&gt;42720000000000000000&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;A Real Use Case: RSI-Gated Vault Deposits&lt;/h2&gt;

&lt;p&gt;Yield vaults typically accept deposits at any time. But depositing during extreme oversold conditions (RSI below 25) often means buying into a temporary panic — the market recovers and the vault captures the rebound.&lt;/p&gt;

&lt;p&gt;A vault can use Pythia's RSI feed to only accept deposits when conditions are favorable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;contract RSIGatedVault is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    uint256 public latestRSI;
    bool public depositsOpen;

    // RSI thresholds (scaled by 1e18)
    uint256 public constant RSI_OPEN = 40 * 1e18;   // Open deposits below RSI 40
    uint256 public constant RSI_CLOSE = 70 * 1e18;  // Close deposits above RSI 70

    bytes32 private jobId;
    uint256 private fee;

    constructor(address _link, address _oracle, bytes32 _jobId) ConfirmedOwner(msg.sender) {
        _setChainlinkToken(_link);
        _setChainlinkOracle(_oracle);
        jobId = _jobId;
        fee = (1 * LINK_DIVISIBILITY) / 100;
    }

    /// @notice Keeper calls this periodically to refresh RSI
    function refreshRSI() external returns (bytes32) {
        Chainlink.Request memory req = _buildChainlinkRequest(
            jobId, address(this), this.fulfillRSI.selector
        );
        req._add("feed", "bitcoin_RSI_1D_14");
        return _sendChainlinkRequest(req, fee);
    }

    function fulfillRSI(bytes32 _requestId, uint256 _value)
        public recordChainlinkFulfillment(_requestId)
    {
        latestRSI = _value;
        // Automatically gate deposits based on RSI
        if (_value &amp;lt; RSI_OPEN) {
            depositsOpen = true;
        } else if (_value &amp;gt; RSI_CLOSE) {
            depositsOpen = false;
        }
    }

    function deposit() external payable {
        require(depositsOpen, "Deposits closed — RSI too high");
        // ... vault deposit logic
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The keeper calls &lt;code&gt;refreshRSI()&lt;/code&gt; periodically. When RSI drops below 40 — indicating oversold conditions — deposits open automatically. When RSI rises above 70 — overbought — deposits close. No off-chain server needed for the decision logic.&lt;/p&gt;




&lt;h2&gt;Another Pattern: EMA Crossover Signal&lt;/h2&gt;

&lt;p&gt;EMA crossovers (short-term EMA crossing above long-term EMA) are one of the most common trading signals. With Pythia's bundle tier, you can get both EMAs in a single on-chain call:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/// @notice Request all indicators for a token (Analysis tier — 0.03 LINK)
function requestBundle(string memory token) public onlyOwner returns (bytes32) {
    Chainlink.Request memory req = _buildChainlinkRequest(
        bundleJobId, address(this), this.fulfillBundle.selector
    );
    req._add("token", token);
    req._add("mode", "bundle");
    return _sendChainlinkRequest(req, bundleFee);
}

function fulfillBundle(bytes32 _requestId, uint256[] memory _values)
    public recordChainlinkFulfillment(_requestId)
{
    // Bundle slot [2] = EMA 1H (20-period)
    // Bundle slot [13] = EMA 1D (20-period)
    // Bundle slot [14] = EMA 1W (20-period)
    uint256 ema1d20 = _values[13];
    // Compare with EMA 50 from a separate Discovery request, or
    // use the 1H vs 1D EMA spread as a momentum proxy
    lastBundle = _values;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The bundle returns all indicators for a token in one call. Slot positions are stable — new indicators are appended, never reordered.&lt;/p&gt;




&lt;h2&gt;Live Data — What the Feeds Return Right Now&lt;/h2&gt;

&lt;p&gt;Here's what Pythia returns on-chain as of April 2, 2026 (values from most recent oracle fulfillment):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Token&lt;/th&gt;
&lt;th&gt;Feed Name&lt;/th&gt;
&lt;th&gt;What It Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BTC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bitcoin_RSI_1D_14&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Daily RSI (14-period) x 1e18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BTC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bitcoin_EMA_1D_20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;20-day EMA price x 1e18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BTC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bitcoin_EMA_1D_50&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50-day EMA price x 1e18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BTC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bitcoin_BOLLINGER_1D_UPPER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Upper Bollinger Band x 1e18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SOL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;solana_RSI_1H_14&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hourly RSI x 1e18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AAVE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;aave_EMA_5M_20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5-minute EMA x 1e18&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Feed names follow the pattern: &lt;code&gt;{engine_id}_{INDICATOR}_{TIMEFRAME}_{PARAM}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;21 tokens available including BTC, SOL, AAVE, UNI, SUI, TAO, RENDER, ONDO, and more.&lt;/p&gt;




&lt;h2&gt;Try It Free (No Signup Required)&lt;/h2&gt;

&lt;p&gt;Pythia runs a free faucet on Polygon mainnet — &lt;a href="https://polygonscan.com/address/0x640fC3B9B607E324D7A3d89Fcb62C77Cc0Bd420A#writeContract" rel="noopener noreferrer"&gt;PythiaFaucet&lt;/a&gt;. No LINK needed, 5 requests per day per address. Call &lt;code&gt;requestIndicator("bitcoin_RSI_1D_14")&lt;/code&gt; directly on Polygonscan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For AI-assisted development:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use with Claude, Cursor, Windsurf, or any MCP-compatible AI tool. Ask your assistant &lt;em&gt;"What RSI feeds does Pythia have for Bitcoin?"&lt;/em&gt; — it calls &lt;code&gt;get_token_feeds("bitcoin")&lt;/code&gt; and returns every available feed name, timeframe, and contract address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solidity examples:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Full contract examples at &lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;github.com/pythia-the-oracle/pythia-oracle-examples&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You cannot calculate RSI, EMA, or Bollinger Bands on-chain economically&lt;/li&gt;
&lt;li&gt;Pythia delivers pre-calculated indicators via Chainlink's Direct Request pattern&lt;/li&gt;
&lt;li&gt;Your contract sends a request + LINK, receives the value in a &lt;code&gt;fulfill()&lt;/code&gt; callback&lt;/li&gt;
&lt;li&gt;All values scaled by 1e18. Feed names: &lt;code&gt;{engine_id}_{INDICATOR}_{TIMEFRAME}_{PARAM}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Real use cases: RSI-gated vaults, EMA crossover signals, volatility circuit breakers&lt;/li&gt;
&lt;li&gt;Free faucet on Polygon mainnet — no signup, no LINK needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The feeds are live. The only thing left is what you build with them.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Explore feeds: &lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt; | Docs: &lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>tradefi</category>
      <category>cryptocurrency</category>
      <category>chainlink</category>
    </item>
    <item>
      <title>Making Your Gamma LP Range Indicator-Aware with On-Chain Bollinger Bands</title>
      <dc:creator>Pythia Oracle</dc:creator>
      <pubDate>Wed, 01 Apr 2026 08:32:57 +0000</pubDate>
      <link>https://dev.to/pythiatheoracle/making-your-gamma-lp-range-indicator-aware-with-on-chain-bollinger-bands-55fg</link>
      <guid>https://dev.to/pythiatheoracle/making-your-gamma-lp-range-indicator-aware-with-on-chain-bollinger-bands-55fg</guid>
      <description>&lt;p&gt;Gamma Strategies' own research repository uses Bollinger Bands to calculate LP range bounds. The insight: a Bollinger Band is a statistical measure of how wide a price range needs to be to capture most of the volatility — which is exactly what you want for a Uniswap v3 LP position.&lt;/p&gt;

&lt;p&gt;The problem is that Gamma's implementation runs off-chain. The range computation happens in Python, then gets submitted to the Hypervisor contract via &lt;code&gt;rebalance()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This tutorial shows how to move that decision fully on-chain using Bollinger Band feeds, so a keeper contract can rebalance autonomously without any off-chain computation.&lt;/p&gt;

&lt;h2&gt;How Gamma positions work&lt;/h2&gt;

&lt;p&gt;A Gamma Hypervisor holds two simultaneous Uniswap v3 positions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base position&lt;/strong&gt; (&lt;code&gt;baseLower&lt;/code&gt; to &lt;code&gt;baseUpper&lt;/code&gt;) — straddles the current price, holds both tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit position&lt;/strong&gt; (&lt;code&gt;limitLower&lt;/code&gt; to &lt;code&gt;limitUpper&lt;/code&gt;) — one-sided, holds surplus of one token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;rebalance()&lt;/code&gt; call burns both positions, sets new tick bounds, and re-mints liquidity. The key function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function rebalance(
    int24 _baseLower, int24 _baseUpper,
    int24 _limitLower, int24 _limitUpper,
    address _feeRecipient,
    uint256[4] memory inMin,
    uint256[4] memory outMin
) external onlyOwner&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;From Bollinger Bands to Uniswap ticks&lt;/h2&gt;

&lt;p&gt;Uniswap v3 positions are defined in &lt;strong&gt;ticks&lt;/strong&gt;, where &lt;code&gt;price = 1.0001^tick&lt;/code&gt;. Uniswap provides &lt;code&gt;TickMath.getTickAtSqrtRatio(uint160 sqrtPriceX96)&lt;/code&gt; for this conversion — there's no direct price→tick helper. You compute &lt;code&gt;sqrtPriceX96&lt;/code&gt; first:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sqrtPriceX96 = sqrt(rawPrice) × 2^96 / 10000&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...where &lt;code&gt;rawPrice&lt;/code&gt; is the Pythia/Chainlink feed value scaled 1e8. Bollinger Bands give you upper and lower price bounds — convert each to &lt;code&gt;sqrtPriceX96&lt;/code&gt;, call &lt;code&gt;TickMath.getTickAtSqrtRatio()&lt;/code&gt;, round to tick spacing, and you have your LP range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note on token ordering:&lt;/strong&gt; Uniswap v3 prices are always &lt;code&gt;token1/token0&lt;/code&gt; sorted by address. Verify your pool's ordering — if inverted, use the reciprocal price.&lt;/p&gt;

&lt;h2&gt;The interface&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;interface IPythiaFeed {
    function latestAnswer() external view returns (int256);
}

interface IHypervisor {
    function rebalance(
        int24 _baseLower, int24 _baseUpper,
        int24 _limitLower, int24 _limitUpper,
        address _feeRecipient,
        uint256[4] memory inMin,
        uint256[4] memory outMin
    ) external;
    function baseLower()  external view returns (int24);
    function baseUpper()  external view returns (int24);
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;The keeper contract&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "@uniswap/v3-core/contracts/libraries/TickMath.sol";

contract BollingerKeeperGamma {
    IPythiaFeed public immutable bollingerUpper;
    IPythiaFeed public immutable bollingerLower;
    IPythiaFeed public immutable spotPrice;
    IHypervisor public immutable hypervisor;

    address public owner;
    int24   public tickSpacing;
    int24   public limitBuffer = 500;
    uint256 public rebalanceThresholdBps = 500; // 5%

    constructor(
        address _bollingerUpper, address _bollingerLower,
        address _spotPrice, address _hypervisor, int24 _tickSpacing
    ) {
        bollingerUpper = IPythiaFeed(_bollingerUpper);
        bollingerLower = IPythiaFeed(_bollingerLower);
        spotPrice      = IPythiaFeed(_spotPrice);
        hypervisor     = IHypervisor(_hypervisor);
        tickSpacing    = _tickSpacing;
        owner          = msg.sender;
    }

    /// @notice Calculate new tick ranges from current Bollinger Bands.
    function calculateRanges()
        public view
        returns (int24 baseLower, int24 baseUpper, int24 limitLower, int24 limitUpper)
    {
        int256 upper = bollingerUpper.latestAnswer();
        int256 lower = bollingerLower.latestAnswer();
        int256 spot  = spotPrice.latestAnswer();

        baseLower = (priceToTick(lower) / tickSpacing) * tickSpacing;
        baseUpper = ((priceToTick(upper) / tickSpacing) + 1) * tickSpacing;

        if (spot &amp;gt;= (upper + lower) / 2) {
            limitLower = baseUpper;
            limitUpper = baseUpper + limitBuffer * tickSpacing;
        } else {
            limitLower = baseLower - limitBuffer * tickSpacing;
            limitUpper = baseLower;
        }
    }

    /// @notice Returns true if the current range has drifted beyond threshold.
    function shouldRebalance() public view returns (bool) {
        (, int24 newBaseUpper,,) = calculateRanges();
        int24 currentUpper = hypervisor.baseUpper();
        int24 drift = newBaseUpper &amp;gt; currentUpper
            ? newBaseUpper - currentUpper
            : currentUpper - newBaseUpper;
        return uint256(uint24(drift)) * 10000 /
            uint256(uint24(currentUpper &amp;gt; 0 ? currentUpper : int24(1)))
            &amp;gt; rebalanceThresholdBps;
    }

    /// @notice Execute rebalance. Callable by keeper when shouldRebalance() is true.
    function rebalance() external {
        require(msg.sender == owner || shouldRebalance(), "not needed");
        (int24 bL, int24 bU, int24 lL, int24 lU) = calculateRanges();
        uint256[4] memory zeros;
        hypervisor.rebalance(bL, bU, lL, lU, owner, zeros, zeros);
    }

    /// @dev Uses Uniswap TickMath for accurate price→tick conversion.
    ///      sqrtPriceX96 = sqrt(rawPrice) * 2^96 / 10000  (for 1e8-scaled prices)
    function priceToTick(int256 price) public view returns (int24 tick) {
        require(price &amp;gt; 0, "invalid price");
        uint256 sqrtP = _sqrt(uint256(price));
        uint256 sqrtPriceX96 = (sqrtP * (2 ** 96)) / 10000;
        tick = TickMath.getTickAtSqrtRatio(uint160(sqrtPriceX96));
        tick = (tick / tickSpacing) * tickSpacing;
    }

    function _sqrt(uint256 x) internal pure returns (uint256 y) {
        if (x == 0) return 0;
        uint256 z = (x + 1) / 2;
        y = x;
        while (z &amp;lt; y) { y = z; z = (x / z + z) / 2; }
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Live Bollinger Bands right now&lt;/h2&gt;

&lt;p&gt;BTC Bollinger Bands (1D) are currently extremely tight: &lt;strong&gt;$67,335 to $67,790&lt;/strong&gt; — a $455 range. That's a Band squeeze, which typically precedes a breakout. A keeper running this contract would have set a narrow base position and widened the limit buffer to catch the move.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Read live Bollinger Bands on-chain (Discovery tier — 0.01 LINK per request)
requestIndicator("bitcoin_BOLLINGER_1D_UPPER");  // → fulfill() receives upper band x 1e18
requestIndicator("bitcoin_BOLLINGER_1D_LOWER");  // → fulfill() receives lower band x 1e18

// Free trial: use PythiaFaucet (0x640fC3...0A) — no LINK needed, 5 requests/day&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To discover all available Bollinger feeds before writing your contract, use the &lt;a href="https://pypi.org/project/pythia-oracle-mcp/" rel="noopener noreferrer"&gt;Pythia MCP server&lt;/a&gt; — it works with Claude, Cursor, Windsurf, and any MCP-compatible AI tool:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then ask your AI assistant: &lt;em&gt;"What Bollinger Band feeds does Pythia have for Bitcoin?"&lt;/em&gt; — it calls &lt;code&gt;get_token_feeds("bitcoin")&lt;/code&gt; and returns every available feed name, timeframe, and integration details.&lt;/p&gt;

&lt;h2&gt;Automating the keeper&lt;/h2&gt;

&lt;p&gt;Wire &lt;code&gt;rebalance()&lt;/code&gt; to Chainlink Automation or Gelato with &lt;code&gt;shouldRebalance()&lt;/code&gt; as the trigger condition. The keeper checks the Bollinger Band width against the current position and rebalances only when the range has drifted enough to matter. No off-chain Python, no subgraph queries.&lt;/p&gt;

&lt;h2&gt;What else is available&lt;/h2&gt;

&lt;p&gt;All feeds — EMA, RSI, VWAP, Bollinger Bands, volatility, liquidity — are available on-chain via &lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;Pythia&lt;/a&gt; as standard Chainlink-compatible feeds. 22 tokens, 4 timeframes, Polygon mainnet. Free testnet faucet, no signup.&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>gamma</category>
      <category>chainlink</category>
      <category>tradefi</category>
    </item>
    <item>
      <title>How to Get On-Chain RSI, EMA, and Bollinger Bands in Your AI Agent</title>
      <dc:creator>Pythia Oracle</dc:creator>
      <pubDate>Wed, 25 Mar 2026 16:38:00 +0000</pubDate>
      <link>https://dev.to/pythiatheoracle/how-to-get-on-chain-rsi-ema-and-bollinger-bands-in-your-ai-agent-247n</link>
      <guid>https://dev.to/pythiatheoracle/how-to-get-on-chain-rsi-ema-and-bollinger-bands-in-your-ai-agent-247n</guid>
      <description>&lt;p&gt;If you're building an AI agent that touches DeFi — a trading bot, a vault rebalancer, a risk monitor — you've probably hit this wall: &lt;strong&gt;you can get price data on-chain, but not the indicators traders actually use.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RSI, EMA, Bollinger Bands, VWAP, volatility — these all require historical price series and rolling calculations. Smart contracts can't do that natively, and most oracles only deliver spot prices.&lt;/p&gt;

&lt;p&gt;Pythia solves this. It's an Chainlink oracle that calculates technical indicators off-chain and delivers the results on-chain. hundreds of indicator feeds across a growing list of tokens, updated continuously.&lt;/p&gt;

&lt;p&gt;Here's how to use it in your AI agent or smart contract.&lt;/p&gt;




&lt;h2&gt;
  
  
  Option 1: MCP Server (for AI Agents)
&lt;/h2&gt;

&lt;p&gt;If you're building with Claude, Cursor, Windsurf, or any MCP-compatible AI agent, the fastest path is the MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pythia-oracle-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Claude Desktop
&lt;/h3&gt;

&lt;p&gt;Add to your &lt;code&gt;claude_desktop_config.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pythia-oracle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pythia-oracle-mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Claude Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add pythia-oracle &lt;span class="nt"&gt;--&lt;/span&gt; pythia-oracle-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cursor / Windsurf / VS Code
&lt;/h3&gt;

&lt;p&gt;Add to your MCP settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pythia-oracle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pythia-oracle-mcp"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once connected, your AI agent can query Pythia directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"What's the current RSI for Bitcoin?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Show me all indicator feeds for Solana"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Is the oracle healthy? Check uptime."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Give me a Solidity contract to consume the speed bundle"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MCP server exposes 7 tools: &lt;code&gt;list_tokens&lt;/code&gt;, &lt;code&gt;get_token_feeds&lt;/code&gt;, &lt;code&gt;get_market_summary&lt;/code&gt;, &lt;code&gt;check_oracle_health&lt;/code&gt;, &lt;code&gt;get_contracts&lt;/code&gt;, &lt;code&gt;get_pricing&lt;/code&gt;, and &lt;code&gt;get_integration_guide&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Option 2: LangChain (for Python Agents)
&lt;/h2&gt;

&lt;p&gt;If you're building with LangChain or LangGraph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain-pythia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_pythia&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PythiaOracleTool&lt;/span&gt;

&lt;span class="c1"&gt;# Create the tool
&lt;/span&gt;&lt;span class="n"&gt;pythia&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PythiaOracleTool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Use in any LangChain agent
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_tool_calling_agent&lt;/span&gt;
&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_tool_calling_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pythia&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool handles natural language queries about tokens, feeds, health, contracts, and integration code — same capabilities as the MCP server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Option 3: Direct Smart Contract Integration
&lt;/h2&gt;

&lt;p&gt;For on-chain consumption, your contract calls Pythia through Chainlink's oracle pattern. Here's the minimal Solidity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";contract MyDeFiAgent is ChainlinkClient {
    using Chainlink for Chainlink.Request;

    uint256 public btcRsi;

    // Pythia operator on Polygon
    address constant OPERATOR = 0x2b12c1eC4e1109D1D8f78CfA1b454a4903E8f68;

    function requestBtcRsi() external {
        Chainlink.Request memory req = _buildChainlinkRequest(
            "DISCOVERY_JOB_ID", // 0.01 LINK per request
            address(this),
            this.fulfill.selector
        );
        req._add("feed", "bitcoin_RSI_1H_14");
        _sendChainlinkRequestTo(OPERATOR, req, 0.01 ether);
    }

    function fulfill(bytes32 requestId, uint256 value) 
        public recordChainlinkFulfillment(requestId) 
    {
        btcRsi = value; // RSI scaled to 1e18
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pricing Tiers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Discovery&lt;/td&gt;
&lt;td&gt;0.01 LINK&lt;/td&gt;
&lt;td&gt;Single indicator per request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analysis&lt;/td&gt;
&lt;td&gt;0.03 LINK&lt;/td&gt;
&lt;td&gt;Category bundle (all EMAs, all RSIs, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;0.05 LINK&lt;/td&gt;
&lt;td&gt;All indicators for one timeframe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;td&gt;0.10 LINK&lt;/td&gt;
&lt;td&gt;Everything for a token&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There's also a &lt;strong&gt;free faucet contract&lt;/strong&gt; — 5 requests/day, no LINK needed. Perfect for testing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Indicators Are Available?
&lt;/h2&gt;

&lt;p&gt;Pythia calculates 5 indicator types across 4 timeframes for each token:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EMA&lt;/strong&gt; (Exponential Moving Average) — trend direction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RSI&lt;/strong&gt; (Relative Strength Index) — overbought/oversold&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bollinger Bands&lt;/strong&gt; (upper + lower) — volatility channels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volatility&lt;/strong&gt; — realized price volatility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;USD Price&lt;/strong&gt; — spot price baseline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Timeframes:&lt;/strong&gt; 5-minute, 1-hour, 1-day, 1-week&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Currently covering 20+ tokens&lt;/strong&gt; including BTC, SOL, TAO, RENDER, ONDO, FET, SUI, INJ, TIA, POL, AAVE, UNI, LINK, COMP, CRV, and more — with new tokens added regularly&lt;/p&gt;

&lt;p&gt;These aren't just price feeds — they're the same calculated metrics that quantitative traders and DeFi protocols need for automated decision-making.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters for AI Agents
&lt;/h2&gt;

&lt;p&gt;Most AI agents that interact with DeFi are flying blind. They can see prices, but they can't see momentum, volatility regimes, or mean-reversion signals without building their own indicator pipeline.&lt;/p&gt;

&lt;p&gt;With Pythia, your agent gets pre-calculated, on-chain-verified indicators with a single call. Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vault rebalancing&lt;/strong&gt; — trigger rebalance when RSI crosses 70 or Bollinger width expands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk monitoring&lt;/strong&gt; — alert when volatility spikes above threshold&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trading signals&lt;/strong&gt; — combine EMA crossovers with RSI for entry/exit logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio analysis&lt;/strong&gt; — real-time calculated metrics across all supported tokens&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server:&lt;/strong&gt; &lt;code&gt;pip install pythia-oracle-mcp&lt;/code&gt; (&lt;a href="https://pypi.org/project/pythia-oracle-mcp/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangChain:&lt;/strong&gt; &lt;code&gt;pip install langchain-pythia&lt;/code&gt; (&lt;a href="https://pypi.org/project/langchain-pythia/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solidity Examples:&lt;/strong&gt; &lt;a href="https://github.com/pythia-the-oracle/pythia-oracle-examples" rel="noopener noreferrer"&gt;pythia-oracle-examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live Feed Explorer:&lt;/strong&gt; &lt;a href="https://pythia.c3x-solutions.com" rel="noopener noreferrer"&gt;pythia.c3x-solutions.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/pythia-the-oracle" rel="noopener noreferrer"&gt;pythia-the-oracle&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building AI agents for DeFi, this is the missing data layer.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>chainlink</category>
      <category>solidity</category>
    </item>
  </channel>
</rss>
