NIN API Docs
  • How to
    • πŸ‘¨β€πŸ’»Getting Started
    • πŸ”How to get API Keys?
    • Full API Documentation
    • πŸ’»OpenAPI Reference (Trade)
      • Authentication
      • Instruments
      • Orders
      • Portfolio
      • Margin
      • WebSocket
      • Models
      • Error Handling
      • Limits on API Requests
  • Use Cases
  • Algo Developers
    • Implementing BTC Points
  • Coming Soon
    • Automations Protocol
    • 🧩Widget Integration
      • Widget (Onramp)
      • Widget (Offramp)
      • Request Token
      • Check Token
Powered by GitBook
On this page
  • 1. High-Level Architecture
  • 2. Core Concepts & Protocol
  • 3. Built-In Node Types
  • 4. How to Build Any Use-Case
  1. Coming Soon

Automations Protocol

Below is a reference architecture and a simple, reusable execution protocol that will let you support any type of Automations use-cases with a single, consistent flow. Treat each flow as just a directed graph of nodes + edges, driven by a tiny β€œFlow Engine” that implements this protocol:


1. High-Level Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     user edits           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  β”‚   ────────────────▢      β”‚                β”‚
β”‚  React-Flow UI   β”‚   graph JSON (nodes &   β”‚  Graph Store   β”‚
β”‚  (Start/Indicatorβ”‚       edges + config)    β”‚  (DB / local)  β”‚
β”‚   /Action / etc) β”‚                          β”‚                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚                                             β–²
           β”‚ on β€œRun”                                  fetch
           β–Ό                                             β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    instantiate context    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  β”‚   ◀───────────────       β”‚                 β”‚
β”‚  Flow Engine     β”‚   nodes[] + edges[] +    β”‚  Connector &    β”‚
β”‚  (β€œrunner”)      β”‚    initial Context       β”‚  API Layer      β”‚
β”‚                  β”‚                          β”‚ (Market data,   β”‚
β”‚  β€’ load graph    β”‚                          β”‚  trading, news, β”‚
β”‚  β€’ for each node β”‚                          β”‚  notifications) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β”‚ emits
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  β”‚
β”‚   Log Bus /      β”‚
β”‚   WebSocket      β”‚
β”‚   UI Panel       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Core Concepts & Protocol

2.1. Graph Definition

Everything is a JSON object with two arrays:

type FlowGraph = {
  nodes: NodeDef[];
  edges: EdgeDef[];
};

type NodeDef = {
  id: string;
  type: string;          // e.g. "start","indicator","action","scheduler",…
  data: Record<string,any>; // user-configured params
  position?: { x:number; y:number };
};

type EdgeDef = {
  id: string;
  source: string;        // node.id
  target: string;        // node.id
};

2.2. Execution Context

A mutable object passed around:

interface Context {
  tickers: string[];        // from StartNode
  currentTicker?: string;   // being processed in loop
  variables: Record<string,any>; // for passing intermediate outputs
  logger: (msg:string) => void;
}

2.3. Node Handler Interface

Each type of node registers a handler:

interface NodeHandler {
  // Called once when engine β€œvisits” this node
  evaluate(node: NodeDef, ctx: Context): 
    Promise<{ 
      passed: boolean;           // should we follow outgoing edges?
      outputs?: Record<string,any>; // e.g. indicatorValue, loopIndex
    }>;
}
  • passed = whether the flow continues from this node

  • outputs get merged into ctx.variables

2.4. Flow Engine Loop (Pseudo-Code)

async function runFlow(graph: FlowGraph, ctx: Context) {
  // 1. Find your Start node(s)
  const starts = graph.nodes.filter(n => n.type === 'start');
  for (let start of starts) {
    // 2. Initialize tickers from StartNode.data
    ctx.tickers = parseTickers(start.data.tickers);
    for (let ticker of ctx.tickers) {
      ctx.currentTicker = ticker;
      ctx.logger(`β–Ά Processing ${ticker}`);
      
      // 3. Depth-first (or breadth-first) traverse edges
      await visitNode(start.id, ctx);
    }
  }

  async function visitNode(nodeId: string, ctx: Context) {
    const node = graph.nodes.find(n => n.id === nodeId)!;
    const handler = registry[node.type];
    const { passed, outputs } = await handler.evaluate(node, ctx);
    if (!passed) return;

    if (outputs) Object.assign(ctx.variables, outputs);

    // 4. Follow all outgoing edges
    const outs = graph.edges.filter(e => e.source === nodeId);
    for (let edge of outs) {
      await visitNode(edge.target, ctx);
    }
  }
}

3. Built-In Node Types

Type
Purpose
Key data.params

start

Seed the run – define tickers or cron trigger.

tickers: "AAPL,MSFT" or cron: "0 9 * * 1"

indicator

Compute & compare a market signal

indicator:"rsi", timeframe:"1h", op:"<", threshold:20

action

Execute a trade, set a stop, place order, etc.

action:"buy", size:100, symbol:ctx.currentTicker

scheduler

Pause or re-enter flow on schedule

interval:"5m"

loop

Iterate an array (e.g. tickers, historical dates)

varName:"historicalDates"

notification

Send email/Slack/Webhook

channel:"slack", msg:"Alert: low RSI"

custom

Hook your own connector (news, sentiment, ML)

module:"newsSentiment", params:{...}


4. How to Build Any Use-Case

  1. Define your nodes in the React Flow canvas; each plug-and-play node maps to one of the types above (or a new custom type you register).

  2. Wire them in the canvas: edges always flow β€œβ–Ά next step.”

  3. Configure node data in the side-panel: thresholds, symbols, cron expressions, API keys.

  4. On β€œRun”, Next.js fetches the JSON, hands it plus a fresh Context to runFlow().

  5. runFlow uses the protocol above to traverse, call your handlers, and ctx.logger() every step.

  6. LogsPanel subscribes (via simple React state or a WebSocket) to stream those messages in real time.


5. Example: Multi-Ticker Oversold Scan

[ Start ] 
   data: tickers="AAPL,MSFT,NVDA"
     β”‚
     β–Ό
[ Indicator (RSI<30) ]
     data: indicator="rsi", op="<", threshold=30
     β”‚ (passed only if RSI<30)
     β–Ό
[ Action (buy) ]
     data: action="buy", size=50
     β”‚
     β–Ό
[ Notification ]
     data: channel="slack", msg="Bought {{ctx.currentTicker}} oversold"

That single graph will loop through each ticker, check RSI, buy when condition’s met, and ping Slack. Swap or chain in any of the node types in section 3 to cover all your 15+ use-casesβ€”stop-loss, take-profit, scheduled rebalance, sentiment alerts, grid trading, backtests, you name it.


✏️ Next Steps:

  • Build/Flesh out any custom node handler (e.g. scheduler, notification).

  • Add a node registry in your flowEngine.ts that maps type β†’ handler.

  • Persist graphs in your DB so users can save/load flows.

  • Hook your real trading/data APIs inside each handler.

With this protocol in place, every automation you dreamed up becomes just β€œanother node” in the same simple engine.

PreviousImplementing BTC PointsNextWidget Integration

Last updated 9 days ago