@devanshhq/indica 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pm/indica-research-report.md +390 -0
- package/ARCHITECTURE.md +470 -0
- package/Cargo.lock +1 -1
- package/Cargo.toml +2 -2
- package/README.md +98 -109
- package/package.json +2 -2
- package/src/batch/compute.rs +165 -0
- package/src/batch/mod.rs +2 -0
- package/src/batch/screen.rs +176 -0
- package/src/core/mod.rs +3 -0
- package/src/core/traits.rs +37 -0
- package/src/core/types.rs +22 -0
- package/src/core/utils.rs +43 -0
- package/src/indicators/india/circuit.rs +101 -0
- package/src/indicators/india/delivery.rs +116 -0
- package/src/indicators/india/mod.rs +2 -0
- package/src/indicators/mod.rs +6 -0
- package/src/indicators/momentum/macd.rs +123 -0
- package/src/indicators/momentum/mod.rs +3 -0
- package/src/indicators/momentum/rsi.rs +130 -0
- package/src/indicators/momentum/stochastic.rs +99 -0
- package/src/indicators/support_resistance/mod.rs +1 -0
- package/src/indicators/support_resistance/pivot.rs +40 -0
- package/src/indicators/trend/adx.rs +168 -0
- package/src/indicators/trend/ema.rs +110 -0
- package/src/indicators/trend/mod.rs +4 -0
- package/src/indicators/trend/sma.rs +75 -0
- package/src/indicators/trend/supertrend.rs +193 -0
- package/src/indicators/volatility/atr.rs +51 -0
- package/src/{bollinger.rs → indicators/volatility/bollinger.rs} +6 -22
- package/src/indicators/volatility/mod.rs +2 -0
- package/src/indicators/volume/mod.rs +3 -0
- package/src/indicators/volume/obv.rs +44 -0
- package/src/{volume.rs → indicators/volume/volume_trend.rs} +9 -27
- package/src/indicators/volume/vwap.rs +53 -0
- package/src/lib.rs +71 -21
- package/src/signals/engine.rs +139 -0
- package/src/signals/mod.rs +4 -0
- package/src/signals/presets.rs +109 -0
- package/src/signals/rules.rs +333 -0
- package/src/signals/types.rs +50 -0
- package/index.d.ts +0 -66
- package/indica.node +0 -0
- package/src/atr.rs +0 -66
- package/src/batch.rs +0 -139
- package/src/macd.rs +0 -132
- package/src/moving_avg.rs +0 -71
- package/src/napi_bindings.rs +0 -166
- package/src/pivot.rs +0 -58
- package/src/relative_strength.rs +0 -67
- package/src/rsi.rs +0 -74
- package/src/utils.rs +0 -17
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# indica — Architecture Design Document
|
|
2
|
+
|
|
3
|
+
## 1. Vision
|
|
4
|
+
|
|
5
|
+
indica is not "TA-Lib in Rust." It's a **trading intelligence library** built specifically for Indian stock markets. Three layers:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌──────────────────────────────────────────────────────────┐
|
|
9
|
+
│ SIGNALS LAYER │
|
|
10
|
+
│ Composite buy/sell signals with confidence + reasons │
|
|
11
|
+
├──────────────────────────────────────────────────────────┤
|
|
12
|
+
│ INDICATORS LAYER │
|
|
13
|
+
│ Standard TA (RSI, MACD, BB...) + India-specific │
|
|
14
|
+
│ (delivery %, circuit proximity, FII/DII momentum) │
|
|
15
|
+
├──────────────────────────────────────────────────────────┤
|
|
16
|
+
│ CORE LAYER │
|
|
17
|
+
│ Streaming trait, batch processing, math utils │
|
|
18
|
+
└──────────────────────────────────────────────────────────┘
|
|
19
|
+
│ │ │
|
|
20
|
+
Rust NAPI WASM
|
|
21
|
+
(crate) (Node.js) (Browser)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 2. Current State (v0.1)
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/
|
|
28
|
+
├── lib.rs ← flat re-exports
|
|
29
|
+
├── moving_avg.rs ← SMA, EMA, ema_series
|
|
30
|
+
├── rsi.rs ← RSI
|
|
31
|
+
├── macd.rs ← MACD
|
|
32
|
+
├── bollinger.rs ← Bollinger Bands
|
|
33
|
+
├── atr.rs ← ATR
|
|
34
|
+
├── pivot.rs ← Pivot Points
|
|
35
|
+
├── volume.rs ← Volume Trend
|
|
36
|
+
├── relative_strength.rs
|
|
37
|
+
├── batch.rs ← Rayon parallel batch
|
|
38
|
+
├── napi_bindings.rs ← Node.js FFI
|
|
39
|
+
└── utils.rs ← round, wilders_smooth
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Problems with current architecture:
|
|
43
|
+
- **Flat module structure** — everything in `src/`, will get messy at 20+ indicators
|
|
44
|
+
- **No shared trait** — each indicator is an independent function, no polymorphism
|
|
45
|
+
- **Batch is hardcoded** — `batch.rs` hardcodes which indicators to compute
|
|
46
|
+
- **NAPI bindings are manual** — every new indicator needs 20+ lines of boilerplate
|
|
47
|
+
- **No streaming** — must recompute from full array every time
|
|
48
|
+
|
|
49
|
+
## 3. Target Architecture (v1.0)
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
src/
|
|
53
|
+
├── lib.rs ← public API surface
|
|
54
|
+
│
|
|
55
|
+
├── core/ ← CORE LAYER
|
|
56
|
+
│ ├── mod.rs
|
|
57
|
+
│ ├── traits.rs ← Indicator trait (streaming + batch)
|
|
58
|
+
│ ├── types.rs ← Candle, Signal, shared types
|
|
59
|
+
│ └── utils.rs ← round, wilders_smooth, ema_step
|
|
60
|
+
│
|
|
61
|
+
├── indicators/ ← INDICATORS LAYER
|
|
62
|
+
│ ├── mod.rs ← re-exports all indicators
|
|
63
|
+
│ ├── trend/ ← Trend indicators
|
|
64
|
+
│ │ ├── mod.rs
|
|
65
|
+
│ │ ├── sma.rs
|
|
66
|
+
│ │ ├── ema.rs
|
|
67
|
+
│ │ ├── supertrend.rs
|
|
68
|
+
│ │ ├── adx.rs
|
|
69
|
+
│ │ └── ichimoku.rs (future)
|
|
70
|
+
│ ├── momentum/ ← Momentum indicators
|
|
71
|
+
│ │ ├── mod.rs
|
|
72
|
+
│ │ ├── rsi.rs
|
|
73
|
+
│ │ ├── macd.rs
|
|
74
|
+
│ │ ├── stochastic.rs
|
|
75
|
+
│ │ └── cci.rs (future)
|
|
76
|
+
│ ├── volatility/ ← Volatility indicators
|
|
77
|
+
│ │ ├── mod.rs
|
|
78
|
+
│ │ ├── bollinger.rs
|
|
79
|
+
│ │ └── atr.rs
|
|
80
|
+
│ ├── volume/ ← Volume indicators
|
|
81
|
+
│ │ ├── mod.rs
|
|
82
|
+
│ │ ├── obv.rs
|
|
83
|
+
│ │ ├── vwap.rs
|
|
84
|
+
│ │ └── volume_trend.rs
|
|
85
|
+
│ ├── support_resistance/ ← Levels
|
|
86
|
+
│ │ ├── mod.rs
|
|
87
|
+
│ │ ├── pivot.rs
|
|
88
|
+
│ │ └── fibonacci.rs (future)
|
|
89
|
+
│ └── india/ ← INDIA-SPECIFIC (the moat)
|
|
90
|
+
│ ├── mod.rs
|
|
91
|
+
│ ├── delivery.rs ← delivery %, delivery trend
|
|
92
|
+
│ ├── circuit.rs ← circuit proximity, hit count
|
|
93
|
+
│ └── fii_dii.rs ← institutional flow momentum
|
|
94
|
+
│
|
|
95
|
+
├── signals/ ← SIGNALS LAYER
|
|
96
|
+
│ ├── mod.rs
|
|
97
|
+
│ ├── types.rs ← Signal enum, Confidence, Reason
|
|
98
|
+
│ ├── engine.rs ← Composite signal generator
|
|
99
|
+
│ └── presets.rs ← Built-in strategies (swing, momentum, etc.)
|
|
100
|
+
│
|
|
101
|
+
├── batch/ ← Batch processing
|
|
102
|
+
│ ├── mod.rs
|
|
103
|
+
│ ├── compute.rs ← configurable batch compute
|
|
104
|
+
│ └── screen.rs ← stock screening with filters
|
|
105
|
+
│
|
|
106
|
+
└── bindings/ ← Platform bindings
|
|
107
|
+
├── mod.rs
|
|
108
|
+
├── napi.rs ← Node.js (feature-gated)
|
|
109
|
+
└── wasm.rs ← Browser (feature-gated)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 4. Key Architectural Decisions
|
|
113
|
+
|
|
114
|
+
### ADR-001: Streaming Indicator Trait
|
|
115
|
+
|
|
116
|
+
**Context:** Current indicators are pure functions that recompute from full arrays. Real-time trading needs O(1) updates.
|
|
117
|
+
|
|
118
|
+
**Decision:** Define an `Indicator` trait with two modes:
|
|
119
|
+
|
|
120
|
+
```rust
|
|
121
|
+
/// A candle of OHLCV data.
|
|
122
|
+
#[derive(Debug, Clone, Copy)]
|
|
123
|
+
pub struct Candle {
|
|
124
|
+
pub open: f64,
|
|
125
|
+
pub high: f64,
|
|
126
|
+
pub low: f64,
|
|
127
|
+
pub close: f64,
|
|
128
|
+
pub volume: f64,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// Core trait for all indicators.
|
|
132
|
+
/// Supports both streaming (one candle at a time) and batch (full array).
|
|
133
|
+
pub trait Indicator: Send + Sync {
|
|
134
|
+
/// The output type (f64, MacdResult, BollingerBandsResult, etc.)
|
|
135
|
+
type Output: Clone;
|
|
136
|
+
|
|
137
|
+
/// Feed one new candle. Returns None while building up, Some once ready.
|
|
138
|
+
fn update(&mut self, candle: &Candle) -> Option<Self::Output>;
|
|
139
|
+
|
|
140
|
+
/// Reset internal state.
|
|
141
|
+
fn reset(&mut self);
|
|
142
|
+
|
|
143
|
+
/// Compute from a full array (convenience wrapper around update).
|
|
144
|
+
fn compute(&mut self, candles: &[Candle]) -> Vec<Option<Self::Output>> {
|
|
145
|
+
self.reset();
|
|
146
|
+
candles.iter().map(|c| self.update(c)).collect()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// Compute the final value only (most common use case).
|
|
150
|
+
fn compute_last(&mut self, candles: &[Candle]) -> Option<Self::Output> {
|
|
151
|
+
self.reset();
|
|
152
|
+
let mut last = None;
|
|
153
|
+
for c in candles {
|
|
154
|
+
last = self.update(c);
|
|
155
|
+
}
|
|
156
|
+
last
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Trade-offs:**
|
|
162
|
+
- (+) O(1) streaming updates for real-time use
|
|
163
|
+
- (+) Batch mode built on top of streaming (DRY)
|
|
164
|
+
- (+) All indicators share the same interface → configurable batch
|
|
165
|
+
- (-) Slightly more complex than pure functions for simple use cases
|
|
166
|
+
- (-) Indicators need internal state (mutable)
|
|
167
|
+
|
|
168
|
+
**Backward compatibility:** Keep the existing pure functions (`sma()`, `rsi()`, etc.) as convenience wrappers that create an indicator, call `compute_last`, and return. Zero breaking changes.
|
|
169
|
+
|
|
170
|
+
```rust
|
|
171
|
+
// Convenience function (existing API, unchanged)
|
|
172
|
+
pub fn rsi(closes: &[f64], period: usize) -> Option<f64> {
|
|
173
|
+
let candles: Vec<Candle> = closes.iter()
|
|
174
|
+
.map(|&c| Candle { open: c, high: c, low: c, close: c, volume: 0.0 })
|
|
175
|
+
.collect();
|
|
176
|
+
let mut ind = Rsi::new(period);
|
|
177
|
+
ind.compute_last(&candles)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Streaming API (new)
|
|
181
|
+
let mut rsi = Rsi::new(14);
|
|
182
|
+
for candle in live_feed {
|
|
183
|
+
if let Some(value) = rsi.update(&candle) {
|
|
184
|
+
println!("RSI: {}", value);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### ADR-002: Candle as Universal Input
|
|
192
|
+
|
|
193
|
+
**Context:** Current functions take separate slices (`&[f64]` for closes, highs, lows, volumes). This leads to mismatched lengths and parameter explosion.
|
|
194
|
+
|
|
195
|
+
**Decision:** Introduce a `Candle` struct as the standard input type. Keep the `&[f64]` convenience functions for backward compatibility.
|
|
196
|
+
|
|
197
|
+
**Trade-offs:**
|
|
198
|
+
- (+) Type-safe: impossible to swap highs and lows
|
|
199
|
+
- (+) Simpler API: one `&[Candle]` instead of four `&[f64]` slices
|
|
200
|
+
- (+) Volume always available (needed for VWAP, OBV)
|
|
201
|
+
- (-) Slight overhead for indicators that only need close (e.g., SMA)
|
|
202
|
+
- (-) Users must construct Candle from their data format
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### ADR-003: Feature-Gated Bindings
|
|
207
|
+
|
|
208
|
+
**Context:** NAPI-RS and WASM have heavy dependencies. Pure Rust users shouldn't need them.
|
|
209
|
+
|
|
210
|
+
**Decision:** Feature-gate bindings:
|
|
211
|
+
|
|
212
|
+
```toml
|
|
213
|
+
[features]
|
|
214
|
+
default = []
|
|
215
|
+
napi = ["dep:napi", "dep:napi-derive"]
|
|
216
|
+
wasm = ["dep:wasm-bindgen"]
|
|
217
|
+
|
|
218
|
+
[dependencies]
|
|
219
|
+
napi = { version = "3", features = ["napi4"], optional = true }
|
|
220
|
+
napi-derive = { version = "3", optional = true }
|
|
221
|
+
wasm-bindgen = { version = "0.2", optional = true }
|
|
222
|
+
rayon = "1.11"
|
|
223
|
+
|
|
224
|
+
[lib]
|
|
225
|
+
crate-type = ["lib"] # default: pure Rust library
|
|
226
|
+
|
|
227
|
+
# NAPI users build with: cargo build --features napi
|
|
228
|
+
# WASM users build with: wasm-pack build --features wasm
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Trade-offs:**
|
|
232
|
+
- (+) Smaller dependency tree for pure Rust users
|
|
233
|
+
- (+) Clean separation of concerns
|
|
234
|
+
- (-) CI must test with and without features
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### ADR-004: India-Specific Module
|
|
239
|
+
|
|
240
|
+
**Context:** No other TA library has Indian market indicators. This is the differentiation.
|
|
241
|
+
|
|
242
|
+
**Decision:** Dedicated `indicators/india/` module for indicators that require India-specific data:
|
|
243
|
+
|
|
244
|
+
```rust
|
|
245
|
+
/// Delivery volume analysis (unique to NSE/BSE).
|
|
246
|
+
pub struct DeliveryAnalysis {
|
|
247
|
+
period: usize,
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
impl DeliveryAnalysis {
|
|
251
|
+
/// Compute delivery percentage.
|
|
252
|
+
/// delivery_pct = delivery_volume / total_volume * 100
|
|
253
|
+
pub fn delivery_pct(delivery_vol: f64, total_vol: f64) -> f64;
|
|
254
|
+
|
|
255
|
+
/// Delivery trend: compare recent avg delivery % to longer-term avg.
|
|
256
|
+
/// High delivery % on up days = genuine buying.
|
|
257
|
+
pub fn delivery_trend(
|
|
258
|
+
delivery_pcts: &[f64],
|
|
259
|
+
closes: &[f64],
|
|
260
|
+
short_period: usize,
|
|
261
|
+
long_period: usize,
|
|
262
|
+
) -> Option<DeliveryTrend>;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/// Circuit limit proximity detector.
|
|
266
|
+
pub fn circuit_proximity(
|
|
267
|
+
current_price: f64,
|
|
268
|
+
prev_close: f64,
|
|
269
|
+
circuit_limit: CircuitLimit, // Percent2, Percent5, Percent10, Percent20
|
|
270
|
+
) -> CircuitStatus; // { upper_distance_pct, lower_distance_pct, near_upper, near_lower }
|
|
271
|
+
|
|
272
|
+
/// FII/DII flow momentum.
|
|
273
|
+
pub fn fii_dii_momentum(
|
|
274
|
+
fii_flows: &[f64], // Daily net FII values
|
|
275
|
+
dii_flows: &[f64], // Daily net DII values
|
|
276
|
+
period: usize,
|
|
277
|
+
) -> Option<FlowMomentum>; // { fii_trend, dii_trend, divergence }
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**These indicators cannot exist in any US/global TA library** because the underlying data (delivery volume, circuit limits, FII/DII flows) is unique to Indian exchanges.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
### ADR-005: Signal Generation Engine
|
|
285
|
+
|
|
286
|
+
**Context:** Raw indicator values require interpretation. Traders need actionable signals.
|
|
287
|
+
|
|
288
|
+
**Decision:** A composable signal engine:
|
|
289
|
+
|
|
290
|
+
```rust
|
|
291
|
+
#[derive(Debug, Clone)]
|
|
292
|
+
pub enum SignalStrength {
|
|
293
|
+
StrongBuy,
|
|
294
|
+
Buy,
|
|
295
|
+
Neutral,
|
|
296
|
+
Sell,
|
|
297
|
+
StrongSell,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
#[derive(Debug, Clone)]
|
|
301
|
+
pub struct Signal {
|
|
302
|
+
pub strength: SignalStrength,
|
|
303
|
+
pub confidence: f64, // 0.0 to 1.0
|
|
304
|
+
pub reasons: Vec<String>, // ["RSI oversold (28.5)", "MACD bullish crossover"]
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/// Signal engine that combines multiple indicators.
|
|
308
|
+
pub struct SignalEngine {
|
|
309
|
+
rules: Vec<Box<dyn SignalRule>>,
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
pub trait SignalRule: Send + Sync {
|
|
313
|
+
fn evaluate(&self, snapshot: &IndicatorSnapshot) -> Option<SignalVote>;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Built-in rules:
|
|
317
|
+
// - RsiRule: oversold < 30 = Buy, overbought > 70 = Sell
|
|
318
|
+
// - MacdCrossoverRule: bullish crossover = Buy, bearish = Sell
|
|
319
|
+
// - SupertrendRule: price above = Buy, below = Sell
|
|
320
|
+
// - VolumeConfirmationRule: surging volume confirms signal
|
|
321
|
+
// - DeliveryRule (India-specific): high delivery % confirms Buy
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
The engine collects votes from all rules, weights them, and produces a composite signal. Users can add custom rules.
|
|
325
|
+
|
|
326
|
+
**Trade-offs:**
|
|
327
|
+
- (+) Actionable output (Buy/Sell, not 67.3)
|
|
328
|
+
- (+) Extensible via trait
|
|
329
|
+
- (+) Composable — users mix and match rules
|
|
330
|
+
- (-) Opinions baked in (what counts as "oversold"?)
|
|
331
|
+
- (-) More complex API surface
|
|
332
|
+
|
|
333
|
+
**Mitigation:** Built-in presets (conservative, aggressive, swing, momentum) plus full customization.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## 5. Implementation Phases
|
|
338
|
+
|
|
339
|
+
### Phase 1: Core Refactor (Foundation)
|
|
340
|
+
|
|
341
|
+
Restructure into the module layout. Introduce `Candle` type and `Indicator` trait. Migrate existing indicators to implement the trait while keeping convenience functions.
|
|
342
|
+
|
|
343
|
+
**Files:** `core/traits.rs`, `core/types.rs`, `core/utils.rs`
|
|
344
|
+
**Breaking changes:** None (existing API preserved)
|
|
345
|
+
|
|
346
|
+
### Phase 2: New Indicators
|
|
347
|
+
|
|
348
|
+
Add the 5 most-requested indicators:
|
|
349
|
+
|
|
350
|
+
| Indicator | Category | Depends on | Effort |
|
|
351
|
+
|-----------|----------|------------|--------|
|
|
352
|
+
| Supertrend | trend | ATR | 2 hrs |
|
|
353
|
+
| VWAP | volume | Volume data | 2 hrs |
|
|
354
|
+
| Stochastic | momentum | High/Low/Close | 2 hrs |
|
|
355
|
+
| ADX | trend | ATR | 3 hrs |
|
|
356
|
+
| OBV | volume | Close + Volume | 1 hr |
|
|
357
|
+
|
|
358
|
+
### Phase 3: India-Specific Indicators
|
|
359
|
+
|
|
360
|
+
| Indicator | What it does | Data needed |
|
|
361
|
+
|-----------|-------------|-------------|
|
|
362
|
+
| `delivery_pct` | Delivery volume / total volume | Delivery + total vol |
|
|
363
|
+
| `delivery_trend` | Delivery % trend with price context | Delivery pcts + closes |
|
|
364
|
+
| `circuit_proximity` | Distance from circuit limits | Price + prev close |
|
|
365
|
+
| `fii_dii_momentum` | Institutional flow trend | Daily FII/DII values |
|
|
366
|
+
|
|
367
|
+
### Phase 4: Signal Engine
|
|
368
|
+
|
|
369
|
+
Build the signal generation layer. Start with 5 built-in rules + 2 presets (swing trader, momentum trader).
|
|
370
|
+
|
|
371
|
+
### Phase 5: Bindings
|
|
372
|
+
|
|
373
|
+
- Feature-gate NAPI behind `features = ["napi"]`
|
|
374
|
+
- Add WASM bindings behind `features = ["wasm"]`
|
|
375
|
+
- Auto-generate NAPI bindings for new indicators using a macro
|
|
376
|
+
|
|
377
|
+
### Phase 6: Series Output
|
|
378
|
+
|
|
379
|
+
Add `_series()` variants to all indicators that return `Vec<f64>` (full history). Needed for charting and backtesting.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 6. Cargo.toml (Target State)
|
|
384
|
+
|
|
385
|
+
```toml
|
|
386
|
+
[package]
|
|
387
|
+
name = "indica"
|
|
388
|
+
version = "1.0.0"
|
|
389
|
+
edition = "2024"
|
|
390
|
+
description = "Fast technical analysis indicators for stock markets. Built for Indian markets."
|
|
391
|
+
license = "MIT"
|
|
392
|
+
repository = "https://github.com/Devansh-365/indica"
|
|
393
|
+
keywords = ["trading", "technical-analysis", "indicators", "nse", "stocks"]
|
|
394
|
+
categories = ["finance", "mathematics"]
|
|
395
|
+
|
|
396
|
+
[features]
|
|
397
|
+
default = []
|
|
398
|
+
napi = ["dep:napi", "dep:napi-derive"]
|
|
399
|
+
wasm = ["dep:wasm-bindgen"]
|
|
400
|
+
india = [] # India-specific indicators (delivery, circuit, FII/DII)
|
|
401
|
+
signals = [] # Signal generation engine
|
|
402
|
+
|
|
403
|
+
[dependencies]
|
|
404
|
+
rayon = "1.11"
|
|
405
|
+
napi = { version = "3", features = ["napi4"], optional = true }
|
|
406
|
+
napi-derive = { version = "3", optional = true }
|
|
407
|
+
wasm-bindgen = { version = "0.2", optional = true }
|
|
408
|
+
|
|
409
|
+
[lib]
|
|
410
|
+
crate-type = ["lib"]
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## 7. Public API Surface (Target)
|
|
414
|
+
|
|
415
|
+
```rust
|
|
416
|
+
// ── Convenience functions (existing, backward-compatible) ──
|
|
417
|
+
indica::sma(closes, period) -> Option<f64>
|
|
418
|
+
indica::ema(closes, period) -> Option<f64>
|
|
419
|
+
indica::rsi(closes, period) -> Option<f64>
|
|
420
|
+
indica::macd(closes, fast, slow, signal) -> Option<MacdResult>
|
|
421
|
+
indica::bollinger_bands(closes, period, mult) -> Option<BollingerBandsResult>
|
|
422
|
+
indica::atr(highs, lows, closes, period) -> Option<f64>
|
|
423
|
+
indica::pivot_points(high, low, close) -> PivotPointsResult
|
|
424
|
+
indica::volume_trend(volumes) -> &str
|
|
425
|
+
indica::relative_strength(stock, bench, period) -> Option<f64>
|
|
426
|
+
indica::supertrend(highs, lows, closes, period, mult) -> Option<SupertrendResult>
|
|
427
|
+
indica::vwap(candles) -> Option<f64>
|
|
428
|
+
indica::stochastic(highs, lows, closes, k_period, d_period) -> Option<StochasticResult>
|
|
429
|
+
indica::adx(highs, lows, closes, period) -> Option<f64>
|
|
430
|
+
indica::obv(closes, volumes) -> f64
|
|
431
|
+
|
|
432
|
+
// ── Streaming API (new) ──
|
|
433
|
+
let mut rsi = indica::Rsi::new(14);
|
|
434
|
+
rsi.update(&candle) -> Option<f64>
|
|
435
|
+
|
|
436
|
+
// ── Batch (existing, enhanced) ──
|
|
437
|
+
indica::batch::compute_parallel(stocks) -> Vec<IndicatorSnapshot>
|
|
438
|
+
indica::batch::screen(stocks, filter) -> Vec<ScreenResult>
|
|
439
|
+
|
|
440
|
+
// ── India-specific (new) ──
|
|
441
|
+
indica::india::delivery_pct(delivery_vol, total_vol) -> f64
|
|
442
|
+
indica::india::delivery_trend(pcts, closes, short, long) -> Option<DeliveryTrend>
|
|
443
|
+
indica::india::circuit_proximity(price, prev_close, limit) -> CircuitStatus
|
|
444
|
+
indica::india::fii_dii_momentum(fii, dii, period) -> Option<FlowMomentum>
|
|
445
|
+
|
|
446
|
+
// ── Signals (new) ──
|
|
447
|
+
let engine = indica::signals::Engine::preset_swing();
|
|
448
|
+
engine.evaluate(&snapshot) -> Signal { strength, confidence, reasons }
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## 8. Non-Functional Requirements
|
|
452
|
+
|
|
453
|
+
| Requirement | Target | How |
|
|
454
|
+
|-------------|--------|-----|
|
|
455
|
+
| Performance | 2,000 stocks in <10ms | Rayon parallelism, zero allocations in hot path |
|
|
456
|
+
| Correctness | Bit-exact with TA-Lib for standard indicators | Cross-reference tests against known values |
|
|
457
|
+
| Safety | Zero panics on any input | All unwrap() replaced with ?, fuzzing tests |
|
|
458
|
+
| Binary size | <500KB for WASM | Feature-gate heavy deps, LTO |
|
|
459
|
+
| Compatibility | Rust 1.85+ (edition 2024) | CI tests on MSRV |
|
|
460
|
+
| Platforms | macOS, Linux, Windows, WASM | CI matrix |
|
|
461
|
+
|
|
462
|
+
## 9. Risks
|
|
463
|
+
|
|
464
|
+
| Risk | Mitigation |
|
|
465
|
+
|------|------------|
|
|
466
|
+
| Streaming trait is too complex | Keep convenience functions as primary API |
|
|
467
|
+
| India indicators have no adoption | Ship them in Metis first, prove value |
|
|
468
|
+
| WASM + Rayon conflict | Rayon disabled in WASM, single-threaded batch |
|
|
469
|
+
| Signal engine is opinionated | Make rules configurable, presets optional |
|
|
470
|
+
| Breaking changes on refactor | Version bump to 0.2, deprecation warnings |
|
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "indica"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
edition = "2024"
|
|
5
|
-
description = "Fast technical analysis indicators for stock markets —
|
|
5
|
+
description = "Fast technical analysis indicators for Indian stock markets — 16 indicators, signal engine, batch screening, streaming API"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/Devansh-365/indica"
|
|
8
8
|
homepage = "https://github.com/Devansh-365/indica"
|