# CheddarFlow Live Option Flow Integration Guide This guide explains how to use the CheddarFlow WebSocket service to receive live option flow data. ## Quick Start 1. **Get authentication tokens** from browser DevTools (see Authentication section below) 2. **Add to `.env` file:** ```env CHEDDARFLOW_SESSION=your_session_token CHEDDARFLOW_TOKEN=your_jwt_token ``` 3. **Find the GraphQL subscription query** from WebSocket messages (see GraphQL Subscription Query section) 4. **Set the query** in `.env`: ```env CHEDDARFLOW_SUBSCRIPTION_QUERY="subscription { ... }" ``` 5. **Start the server** - the service will automatically connect ## Overview The CheddarFlow WebSocket service connects to `wss://app.cheddarflow.com/api/ws` using the GraphQL Transport WebSocket protocol (`graphql-transport-ws`) to receive real-time option flow data. ## Setup ### 1. Enable the Service The service is enabled by default. To disable it, add to your `.env` file: ```env ENABLE_CHEDDARFLOW=false ``` ### 2. Database Storage By default, received data is automatically saved to the `OptionsFlow_monthly` table. To disable database storage: ```env CHEDDARFLOW_SAVE_TO_DB=false ``` ### 3. Authentication (Required) CheddarFlow requires authentication. You have two options: #### Option 1: Cookies (Recommended - Easiest) Get cookies from your browser after logging into CheddarFlow: 1. Open CheddarFlow dashboard in your browser 2. Open DevTools (F12) → Application tab → Cookies 3. Copy all cookies for `app.cheddarflow.com` or `dash.cheddarflow.com` 4. Format them as: `cookie1=value1; cookie2=value2; cookie3=value3` Add to `.env`: ```env CHEDDARFLOW_COOKIES=your_cookie_string_here ``` Example: ```env CHEDDARFLOW_COOKIES=auth0_session=xxx; auth0_csrf=yyy; other_cookie=zzz ``` #### Option 2: Session + Token If you prefer using session and token separately: ```env # Session token CHEDDARFLOW_SESSION=your_session_token_here # JWT token CHEDDARFLOW_TOKEN=your_jwt_token_here ``` **How to get your authentication:** ### Method 1: Cookies (Easiest - Recommended) 1. Open CheddarFlow dashboard in your browser (while logged in) 2. Open DevTools (F12) → Application tab → Cookies 3. Select `app.cheddarflow.com` or `dash.cheddarflow.com` 4. Copy all cookie name-value pairs 5. Format as: `name1=value1; name2=value2; name3=value3` 6. Add to `.env` as `CHEDDARFLOW_COOKIES` **Important**: Cookies may include session tokens that expire. Refresh them if connection fails. ### Method 2: From WebSocket Messages 1. Open CheddarFlow dashboard in your browser 2. Open DevTools (F12) → Network tab 3. Filter by "WS" (WebSocket) 4. Connect to the WebSocket (refresh page or navigate to a page that uses live data) 5. Look for the first message with `type: "connection_init"` 6. Copy the `session` and `token` values from the `payload` object Example payload structure: ```json { "type": "connection_init", "payload": { "session": "C7vnUHLdb9TORyCGmdOtb", "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImdLSEdIb1UxWTAxaE1JcmwzLUpSdiJ9..." } } ``` ### Method 2: From GraphQL API Response 1. Open CheddarFlow dashboard in your browser 2. Open DevTools (F12) → Network tab 3. Filter by "Fetch/XHR" 4. Look for a POST request to `https://app.cheddarflow.com/api` 5. Find the request with `operationName: "GetUserSessionAndMarketStatus"` 6. Copy the `token` from `data.session.token` in the response 7. For `session`, check cookies or use the WebSocket method above ### Method 3: Programmatic Fetch (Advanced) You can use the helper function to fetch tokens programmatically, but this requires authentication cookies: ```javascript import { fetchCheddarFlowSession } from './src/services/cheddarflowWebSocketService.js'; // Get cookies from browser DevTools → Application → Cookies const cookies = 'your_cookie_string_here'; const sessionData = await fetchCheddarFlowSession({ cookie: cookies }); console.log('Token:', sessionData.token); ``` **Note**: These tokens may expire. If the connection fails, refresh your tokens from the browser DevTools. ### 4. Configuration Options Add these optional settings to your `.env` file: ```env # Enable/disable CheddarFlow service (default: true) ENABLE_CHEDDARFLOW=true # Save received data to database (default: true) CHEDDARFLOW_SAVE_TO_DB=true # WebSocket URL (default: wss://app.cheddarflow.com/api/ws) CHEDDARFLOW_WS_URL=wss://app.cheddarflow.com/api/ws # Origin header (default: https://dash.cheddarflow.com) CHEDDARFLOW_ORIGIN=https://dash.cheddarflow.com # Feed ID and Topic for options feed subscription (required) CHEDDARFLOW_FEED_ID=1612407366 CHEDDARFLOW_FEED_TOPIC=1612407366 ``` ## How It Works 1. **Connection**: The service automatically connects to CheddarFlow's WebSocket on server startup 2. **GraphQL Protocol**: Uses the `graphql-transport-ws` protocol for GraphQL subscriptions 3. **Data Mapping**: Incoming data is automatically mapped to the `OptionsFlow_monthly` schema 4. **Database Storage**: Records are inserted into the database in real-time 5. **Auto-Reconnect**: Automatically reconnects if the connection is lost ## GraphQL Subscription Query The service uses the `OnOptionsFeedEvents` subscription which provides real-time option flow data. The subscription is already configured and ready to use. ### Feed ID Configuration The subscription requires a `feed ID` and `topic` (usually the same value). This appears to be a view/feed identifier in CheddarFlow. **To find your feed ID:** 1. Open CheddarFlow dashboard in browser DevTools 2. Go to Network tab → Filter by "WS" (WebSocket) 3. Look for a `subscribe` message with `operationName: "OnOptionsFeedEvents"` 4. Copy the `id` and `topic` values from `payload.variables` Example: ```json { "type": "subscribe", "payload": { "variables": { "id": "1612407366", "topic": "1612407366" } } } ``` **Add to `.env` file:** ```env CHEDDARFLOW_FEED_ID=1612407366 CHEDDARFLOW_FEED_TOPIC=1612407366 ``` If not set, the service defaults to `1612407366` (you may need to update this with your own feed ID). ## Data Format CheddarFlow sends option flow data in a tabular format within the `lastProcessedItems` field: ```json { "lastProcessedItems": "{\"ins\":[[\"headers\"],[[\"data\"]]]}" } ``` The service automatically: 1. Parses the JSON string from `lastProcessedItems` 2. Extracts the data rows (after the header row) 3. Maps each row to the database schema 4. Inserts records into `OptionsFlow_monthly` table ### Data Fields The subscription provides these fields (in order): - `idx`, `id`, `contract_id`, `timestamp`, `symbol`, `expiry`, `strike`, `put_call`, `side`, `buy_sell`, `spot`, `size`, `price`, `premium`, `sweep_block_split`, `volume`, `open_int`, `conds` These are automatically mapped to the `OptionsFlow_monthly` schema. ## Data Mapping The service automatically maps CheddarFlow data fields to the `OptionsFlow_monthly` schema: | Database Column | CheddarFlow Field Variations | |----------------|------------------------------| | `Symbol` | `symbol`, `Symbol`, `ticker`, `Ticker` | | `CallPut` | `callPut`, `CallPut`, `optionType`, `OptionType` | | `Strike` | `strike`, `Strike`, `strikePrice`, `StrikePrice` | | `Premium` | `premium`, `Premium`, `totalPremium`, `TotalPremium` | | `Volume` | `volume`, `Volume`, `vol`, `Vol`, `contracts` | | `Spot` | `spot`, `Spot`, `underlyingPrice`, `stockPrice` | | `Side` | `side`, `Side`, `tradeSide`, `direction` | | `ExpirationDate` | `expirationDate`, `ExpirationDate`, `expiry`, `expiration` | | ... and more | See `mapCheddarFlowToDatabase()` function | ## Monitoring ### Health Check Check service status via the health endpoint: ```bash curl http://localhost:3010/health ``` Response includes `cheddarFlow` status: ```json { "cheddarFlow": { "running": true, "connected": true, "subscriptionId": "sub_1234567890", "reconnectAttempts": 0, "status": "connected" } } ``` ### Logs The service logs connection status and data processing: ``` 📡 CheddarFlow: Connecting to wss://app.cheddarflow.com/api/ws... 📡 CheddarFlow: WebSocket opened 📡 CheddarFlow: Connection acknowledged 📡 CheddarFlow: Subscription started 📡 CheddarFlow: Inserted 10 records ``` ## Troubleshooting ### Service Not Connecting **Symptoms**: Logs show connection attempts but no connection **Solutions**: 1. Check your network connection 2. Verify the WebSocket URL is correct 3. Check if CheddarFlow requires authentication (may need to add auth headers) 4. Review firewall/proxy settings ### No Data Received **Symptoms**: Connected but no data flowing **Solutions**: 1. Verify the GraphQL subscription query is correct 2. Check if CheddarFlow requires authentication tokens 3. Inspect WebSocket messages to see what CheddarFlow is sending 4. Check if there's actual flow data available (market hours, etc.) ### Database Insert Errors **Symptoms**: Connection works but records aren't being saved **Solutions**: 1. Verify database connection is working 2. Check that `OptionsFlow_monthly` table exists 3. Review database logs for constraint violations 4. Ensure `CHEDDARFLOW_SAVE_TO_DB` is not set to `false` ### Authentication Required CheddarFlow requires `session` and `token` in the `connection_init` payload. The service automatically includes these if set in environment variables: ```env CHEDDARFLOW_SESSION=your_session_token CHEDDARFLOW_TOKEN=your_jwt_token ``` If these are missing, you'll see a warning in the logs and the connection will likely fail. **To get fresh tokens:** 1. Open CheddarFlow dashboard in browser 2. DevTools → Network → WS filter 3. Find `connection_init` message 4. Copy `session` and `token` from payload 5. Update your `.env` file **Token expiration:** JWT tokens typically expire after some time. If connection fails, refresh your tokens from the browser. ## Manual Testing You can test the service manually: ```javascript import { startCheddarFlowService, stopCheddarFlowService, getCheddarFlowStatus } from './src/services/cheddarflowWebSocketService.js'; // Start service const client = startCheddarFlowService({ enableDatabaseInsert: true, onData: (mappedRecord, rawData) => { console.log('Received flow:', mappedRecord); }, onError: (error) => { console.error('Error:', error); } }); // Check status setTimeout(() => { const status = getCheddarFlowStatus(); console.log('Status:', status); }, 5000); // Stop service (when done) // stopCheddarFlowService(); ``` ## Next Steps 1. **Determine GraphQL Query**: Find the actual subscription query from CheddarFlow 2. **Update Subscription**: Replace the placeholder query in `startSubscription()` 3. **Add Authentication**: If required, add authentication tokens 4. **Customize Mapping**: Adjust field mappings if CheddarFlow uses different field names 5. **Test**: Verify data is flowing and being saved correctly ## API Reference ### Functions - `startCheddarFlowService(options)` - Start the WebSocket service - `stopCheddarFlowService()` - Stop the service - `getCheddarFlowStatus()` - Get current service status - `mapCheddarFlowToDatabase(data)` - Map CheddarFlow data to database schema ### Options ```javascript { url: 'wss://app.cheddarflow.com/api/ws', // WebSocket URL origin: 'https://dash.cheddarflow.com', // Origin header enableDatabaseInsert: true, // Save to database autoReconnect: true, // Auto-reconnect on disconnect reconnectInterval: 5000, // Reconnect delay (ms) maxReconnectAttempts: 10, // Max reconnect attempts onData: (mappedRecord, rawData) => {}, // Data callback onError: (error) => {} // Error callback } ``` ## Support If you encounter issues: 1. Check the console logs for detailed error messages 2. Verify the WebSocket connection in browser DevTools 3. Test the GraphQL subscription query manually 4. Review the data mapping function for field name mismatches