RISE Framework Specification
Spec ID: 30
Version: 1.0
Document ID: caishen-rise-api-v1.0
Last Updated: 2025-01-31
What the Express API Enables Users to Create:
Desired Outcomes:
http://localhost:3999
Currently no authentication required (internal use only).
Retrieve ChaosDataBuilder data for a POV.
Parameters: | Parameter | Type | Description | Default | |———–|——|————-|———| | pov | path | POV identifier (e.g., “EUR-USD_H4”) | required | | type | path | Data type to return | “bars” | | format | path | Output format | “csv” |
Type Options:
c or cdb - Single CDB summaryp or cdbs - Multi-timeframe perspectiveb or bars or bar - Price bars with indicatorsFormat Options:
csv - Comma-separated valuesjson - JSON objectExamples:
# Get bar data as CSV
GET /cdb/EUR-USD_H4/bars/csv
# Get CDB summary as JSON
GET /cdb/EUR-USD_H4/cdb/json
# Get multi-timeframe perspective as JSON
GET /cdb/EUR-USD_H4/p/json
Response (bars/csv):
Dt,Open,High,Low,Close,Volume,Lips,Teeth,Jaw,AO,SAO,AC,ACD,AOF,Zone,BDB,xBdb,MFI,Squat,FractalBuy,FractalSell,FractalDim
2025-01-31T10:00:00Z,1.0850,1.0860,1.0845,1.0855,1234,1.0823,1.0815,1.0810,0.0012,0.0011,0.0003,1,0.0015,1,0,0,2,0,,1.0860,1.5
Response (cdb/json):
{
"Instrument": "EUR/USD",
"Timeframe": "H4",
"TrendLastWave": "UP",
"MarketOverViewerNodeCurrentIsDiverging": false,
"PipSize": 0.0001,
"PriceHighestValue": 1.0920,
"PriceLowestValue": 1.0780,
"AOHighestValue": 0.0035,
"AOLowestValue": -0.0028,
"NbBarMouthIsOpen": 12,
"InstrumentProperty": {
"Symbol": "EUR/USD",
"mar": { "MMR": 0.02, "LMR": 0.01 },
"pips": 0.0001
}
}
Response (perspective/json):
{
"Instrument": "EUR/USD",
"InstrumentProperty": { ... },
"Perspective": {
"m5": { "Instrument": "EUR/USD", "Timeframe": "m5", ... },
"m15": { "Instrument": "EUR/USD", "Timeframe": "m15", ... },
"H1": { "Instrument": "EUR/USD", "Timeframe": "H1", ... },
"H4": { "Instrument": "EUR/USD", "Timeframe": "H4", ... },
"D1": { "Instrument": "EUR/USD", "Timeframe": "D1", ... },
"W1": { "Instrument": "EUR/USD", "Timeframe": "W1", ... },
"M1": { "Instrument": "EUR/USD", "Timeframe": "M1", ... }
}
}
Serve raw price data JSON files.
GET /pds/EUR-USD_H4.json
Serve indicator data JSON files.
GET /ids/EUR-USD_H4_indicators.json
Serve CDS DTO files.
GET /cds/EUR-USD_H4_cdb.json
Instrument,Timeframe,InstrumentPerspectiveDataDivergenceIndicatorSequence,
MarketOverViewerNodeCurrentIsDiverging,MarketOverViewerNodeCurrentBdb,
MarketOverViewerNodeCurrentDivA,MarketOverViewerNodeCurrentDivAPeakDt,
MarketOverViewerNodeCurrentDivB,MarketOverViewerNodeCurrentDivBPeakDt,
MarketOverViewerNodeCurrentTrendLastWave,MarketOverViewerNodeCurrentDivergenceIndicator,
MarketOverViewerNodeCurrentStrenghtOrder,TrendLastWave,TrendLastBar,
PovTlid,CorrelationId,GatorMouthMaxOpenessMaxDistGLRL,GatorMouthMaxOpenessMaxDistRLBL,
GatorMouthMaxOpenessMaxDistGLBL,AngleGatorDatadistGLRL,AngleGatorDatadistRLBL,
AngleGatorDatadistGLBL,AngleGatorDatadistGLPrice,AngleGatorDatadistRLPrice,
AngleGatorDatadistBLPrice,AngleGatorDatadistPriceMaxPrice,AngleDataRelativezeddistGLRL,
AngleDataRelativezeddistRLBL,AngleDataRelativezeddistGLBL,AngleDataRelativezeddistGLPrice,
AngleDataRelativezeddistRLPrice,AngleDataRelativezeddistBLPrice,
AngleDataRelativezeddistPriceMaxPrice,AngleDsDataMaxAngleGatorDataMaxLipsTeethDiff,
AngleDsDataMaxAngleGatorDataMaxTeethJawDiff,AngleDsDataMaxAngleGatorDataMaxLipsJawDiff,
AngleDsDataMaxAngleGatorDataMaxPriceDistFromLips,AngleDsDataMaxAngleGatorDataMaxPriceDistFromTeeth,
AngleDsDataMaxAngleGatorDataMaxPriceDistFromJaw,AngleDsDataNbBarMouthIsOpen,
PipSize,PriceHighestValue,PriceLowestValue,AOHighestValue,AOLowestValue,
ACHighestValue,ACLowestValue,NbBarMouthIsOpen,IPMMR,IPLMR,IPpre,IPpips,IPcm,
IPtsmi,IPtsmx,IPsubs,IPbu,IPqtmi,IPqtmx,IPcc
Dt,Open,High,Low,Close,Volume,Lips,Teeth,Jaw,AO,SAO,AC,ACD,AOF,Zone,BDB,xBdb,MFI,Squat,FractalBuy,FractalSell,FractalDim
Default: 3999
var cdbRootDir = path.join(__dirname, '/cdb-dto');
var ContextTimeframes = ['m5', 'm15', 'H1', 'H4', 'D1', 'W1', 'M1'];
Creative Advancement Scenario: Load Data in External Tool
Desired Outcome: TradingView or custom app displays Caishen data
Current Reality: User wants to analyze in preferred tool
Natural Progression Steps:
1. External app requests /cdb/EUR-USD_H4/bars/json
2. API reads CDB from file
3. JSON response returned
4. App parses and renders data
5. User sees chaos indicators in their tool
Achieved Outcome: Caishen data accessible anywhere
Supporting Features: JSON endpoint, CORS if needed
Creative Advancement Scenario: Build Trading Dashboard
Desired Outcome: Single view of all timeframes for instrument
Current Reality: Need to check each timeframe separately
Natural Progression Steps:
1. Dashboard requests /cdb/EUR-USD_H4/p/json
2. API loads all timeframe CDBs
3. Perspective object returned
4. Dashboard displays grid of timeframes
5. User sees complete picture
Achieved Outcome: Comprehensive instrument view
Supporting Features: Perspective endpoint
const express = require("express");
const fs = require("fs");
const path = require("path");
const app = express();
const port = 3999;
const cdbRootDir = path.join(__dirname, '/cdb-dto');
const ContextTimeframes = ['m5', 'm15', 'H1', 'H4', 'D1', 'W1', 'M1'];
app.get('/cdb/:pov/:t?/:outtype?', function(req, res) {
const pov = req.params.pov;
const t = req.params.t || "bars";
const outtype = req.params.outtype || "csv";
const cdb = readCDB(pov);
let output = "";
switch (outtype) {
case "csv":
if (t === "cdb" || t === "c") {
output = getCDBCsvHeader() + "\n" + getCDBCsvLine(cdb);
} else if (t === "bars" || t === "b") {
output = getChaosBarCsvHeader();
cdb.ChartBars.forEach(b => {
output += "\n" + getChaosBarCsvLine(b);
});
}
break;
case "json":
if (t === "cdb" || t === "c") {
output = JSON.stringify(cdb);
} else if (t === "cdbs" || t === "p") {
const perspective = {};
ContextTimeframes.forEach(tf => {
try {
const _pov = cdb.Instrument.replace("/", "-") + "_" + tf;
perspective[tf] = readCDB(_pov);
} catch (err) {
console.log(`Warning: Could not load ${tf} timeframe data`);
}
});
output = JSON.stringify({
Instrument: cdb.Instrument,
InstrumentProperty: cdb.InstrumentProperty,
Perspective: perspective
});
}
break;
}
res.send(output);
});
function readCDB(pov) {
const filePath = path.join(cdbRootDir, pov + '.json');
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
app.listen(port, () => {
console.log(`CaishenExpressAPI listening at http://localhost:${port}`);
});
from fastapi import FastAPI, HTTPException
from fastapi.responses import PlainTextResponse, JSONResponse
import json
from pathlib import Path
from typing import Optional
app = FastAPI(title="Caishen API", version="1.0")
CDB_ROOT_DIR = Path(__file__).parent / "cdb-dto"
CONTEXT_TIMEFRAMES = ['m5', 'm15', 'H1', 'H4', 'D1', 'W1', 'M1']
def read_cdb(pov: str) -> dict:
file_path = CDB_ROOT_DIR / f"{pov}.json"
if not file_path.exists():
raise HTTPException(status_code=404, detail=f"POV {pov} not found")
with open(file_path) as f:
return json.load(f)
@app.get("/cdb/{pov}")
@app.get("/cdb/{pov}/{data_type}")
@app.get("/cdb/{pov}/{data_type}/{output_format}")
async def get_cdb(
pov: str,
data_type: str = "bars",
output_format: str = "csv"
):
cdb = read_cdb(pov)
if output_format == "json":
if data_type in ("cdb", "c"):
return JSONResponse(cdb)
elif data_type in ("cdbs", "p"):
instrument = cdb.get("Instrument", "").replace("/", "-")
perspective = {}
for tf in CONTEXT_TIMEFRAMES:
try:
perspective[tf] = read_cdb(f"{instrument}_{tf}")
except FileNotFoundError:
# Timeframe data not available, skip it
pass
except Exception as e:
# Log other errors for debugging
print(f"Warning: Could not load {tf} data: {e}")
return JSONResponse({
"Instrument": cdb.get("Instrument"),
"InstrumentProperty": cdb.get("InstrumentProperty"),
"Perspective": perspective
})
elif output_format == "csv":
if data_type in ("bars", "b", "bar"):
header = "Dt,Open,High,Low,Close,Volume,Lips,Teeth,Jaw,AO,SAO,AC,Zone"
lines = [header]
for bar in cdb.get("ChartBars", []):
ask = bar.get("a", {})
bid = bar.get("b", {})
avg_o = (ask.get("o", 0) + bid.get("o", 0)) / 2
avg_h = (ask.get("h", 0) + bid.get("h", 0)) / 2
avg_l = (ask.get("l", 0) + bid.get("l", 0)) / 2
avg_c = (ask.get("c", 0) + bid.get("c", 0)) / 2
lines.append(
f"{bar.get('dt')},{avg_o},{avg_h},{avg_l},{avg_c},"
f"{bar.get('v',0)},{bar.get('l',0)},{bar.get('t',0)},"
f"{bar.get('j',0)},{bar.get('ao',0)},{bar.get('sa',0)},"
f"{bar.get('ac',0)},{bar.get('z',0)}"
)
return PlainTextResponse("\n".join(lines))
raise HTTPException(status_code=400, detail="Invalid parameters")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=3999)
import express, { Request, Response } from 'express';
import fs from 'fs';
import path from 'path';
const app = express();
const port = 3999;
const cdbRootDir = path.join(__dirname, 'cdb-dto');
const contextTimeframes = ['m5', 'm15', 'H1', 'H4', 'D1', 'W1', 'M1'];
interface ChaosDataBuilder {
Instrument: string;
Timeframe: string;
ChartBars: BarChaosItem[];
InstrumentProperty: any;
[key: string]: any;
}
interface BarChaosItem {
dt: string;
a: { o: number; h: number; l: number; c: number };
b: { o: number; h: number; l: number; c: number };
v: number;
l: number;
t: number;
j: number;
ao: number;
ac: number;
z: number;
[key: string]: any;
}
function readCDB(pov: string): ChaosDataBuilder {
const filePath = path.join(cdbRootDir, `${pov}.json`);
const data = fs.readFileSync(filePath, 'utf8');
return JSON.parse(data);
}
app.get('/cdb/:pov/:type?/:format?', (req: Request, res: Response) => {
const { pov, type = 'bars', format = 'csv' } = req.params;
try {
const cdb = readCDB(pov);
if (format === 'json') {
if (type === 'cdb' || type === 'c') {
return res.json(cdb);
}
if (type === 'cdbs' || type === 'p') {
const instrument = cdb.Instrument.replace('/', '-');
const perspective: Record<string, ChaosDataBuilder> = {};
for (const tf of contextTimeframes) {
try {
perspective[tf] = readCDB(`${instrument}_${tf}`);
} catch (error) {
// Timeframe data not available, continue with other timeframes
console.log(`Warning: Could not load ${tf} timeframe data for ${instrument}`);
}
}
return res.json({
Instrument: cdb.Instrument,
InstrumentProperty: cdb.InstrumentProperty,
Perspective: perspective
});
}
}
if (format === 'csv') {
if (type === 'bars' || type === 'b') {
const header = 'Dt,Open,High,Low,Close,Volume,Lips,Teeth,Jaw,AO,AC,Zone';
const lines = cdb.ChartBars.map(bar => {
const o = (bar.a.o + bar.b.o) / 2;
const h = (bar.a.h + bar.b.h) / 2;
const l = (bar.a.l + bar.b.l) / 2;
const c = (bar.a.c + bar.b.c) / 2;
return `${bar.dt},${o},${h},${l},${c},${bar.v},${bar.l},${bar.t},${bar.j},${bar.ao},${bar.ac},${bar.z}`;
});
return res.send([header, ...lines].join('\n'));
}
}
res.status(400).send('Invalid parameters');
} catch (error) {
res.status(404).send(`POV ${pov} not found`);
}
});
app.listen(port, () => {
console.log(`CaishenExpressAPI listening at http://localhost:${port}`);
});