Rules-Based
Visual condition builder with entry/exit rules. No coding required.
Best for: Simple indicator-based strategies
Create and manage trading strategies using either visual rule builders or Python code.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /strategies | Yes | List all strategies |
POST | /strategies | Yes | Create new strategy |
GET | /strategies/{id} | Yes | Get strategy details |
PUT | /strategies/{id} | Yes | Update strategy |
DELETE | /strategies/{id} | Yes | Delete strategy |
POST | /strategies/{id}/toggle | Yes | Toggle active status |
POST | /strategies/{id}/copy | Yes | Copy strategy |
Rules-Based
Visual condition builder with entry/exit rules. No coding required.
Best for: Simple indicator-based strategies
Code-Based
Python code for complex logic. Full flexibility.
Best for: Advanced strategies with custom logic
Get all strategies for the authenticated user, including base strategies.
GET /api/v1/strategies?active_only=false&limit=100&offset=0Authorization: Bearer <token>[ { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "RSI Mean Reversion", "description": "Buy oversold, sell overbought", "strategy_type": "rules", "rules": { "entry": { "conditions": [{"indicator": "rsi", "operator": "<", "value": 30}], "logic": "AND" }, "exit": { "conditions": [{"indicator": "rsi", "operator": ">", "value": 70}], "logic": "AND" } }, "parameters": {"rsi_period": 14}, "is_active": true, "is_base_strategy": false, "user_id": "c96ca3e5-94a1-49e3-b965-3e32ffb58b83", "created_at": "2025-01-15T10:30:00Z", "updated_at": "2025-01-15T10:30:00Z" }]| Parameter | Type | Default | Description |
|---|---|---|---|
active_only | boolean | false | Only return active strategies |
limit | integer | 100 | Max results |
offset | integer | 0 | Pagination offset |
POST /api/v1/strategiesAuthorization: Bearer <token>Content-Type: application/json
{ "name": "RSI Mean Reversion", "description": "Buy when RSI is oversold, sell when overbought", "strategy_type": "rules", "rules": { "entry": { "conditions": [ { "indicator": "rsi", "operator": "<", "value": 30 } ], "logic": "AND" }, "exit": { "conditions": [ { "indicator": "rsi", "operator": ">", "value": 70 } ], "logic": "AND" } }, "parameters": { "rsi_period": 14 }, "is_active": false}{ "id": "550e8400-e29b-41d4-a716-446655440000", "name": "RSI Mean Reversion", "description": "Buy when RSI is oversold, sell when overbought", "strategy_type": "rules", "rules": {...}, "parameters": {"rsi_period": 14}, "is_active": false, "is_base_strategy": false, "user_id": "c96ca3e5-94a1-49e3-b965-3e32ffb58b83", "created_at": "2025-12-17T10:30:00Z", "updated_at": "2025-12-17T10:30:00Z"}POST /api/v1/strategiesAuthorization: Bearer <token>Content-Type: application/json
{ "name": "Custom MACD Strategy", "description": "MACD crossover with RSI filter", "strategy_type": "code", "code": "def strategy(data):\n macd_cross = data['macd'] > data['macd_signal']\n rsi_filter = data['rsi'] < 70\n return macd_cross & rsi_filter", "parameters": { "macd_fast": 12, "macd_slow": 26, "macd_signal": 9, "rsi_period": 14 }, "is_active": false}{ "indicator": "rsi", "operator": "<", "value": 30}Or for indicator-to-indicator comparison:
{ "indicator": "ema_20", "operator": "cross_above", "compare_to": "ema_50"}| Indicator | Description | Parameters |
|---|---|---|
close | Close price | - |
open | Open price | - |
high | High price | - |
low | Low price | - |
volume | Trading volume | - |
sma_{period} | Simple Moving Average | sma_period |
ema_{period} | Exponential Moving Average | ema_period |
rsi | Relative Strength Index | rsi_period |
macd | MACD Line | macd_fast, macd_slow |
macd_signal | MACD Signal Line | macd_signal |
macd_histogram | MACD Histogram | - |
bb_upper | Bollinger Band Upper | bb_period, bb_std |
bb_middle | Bollinger Band Middle | bb_period |
bb_lower | Bollinger Band Lower | bb_period, bb_std |
momentum | Price Momentum | momentum_period |
| Operator | Description | Use With |
|---|---|---|
> | Greater than | value or indicator |
< | Less than | value or indicator |
>= | Greater than or equal | value or indicator |
<= | Less than or equal | value or indicator |
== | Equal to | value or indicator |
!= | Not equal to | value or indicator |
cross_above | Crosses above | indicator only |
cross_below | Crosses below | indicator only |
| Logic | Description |
|---|---|
AND | All conditions must be true |
OR | Any condition must be true |
{ "name": "Golden Cross", "strategy_type": "rules", "rules": { "entry": { "conditions": [ {"indicator": "sma_50", "operator": "cross_above", "compare_to": "sma_200"} ], "logic": "AND" }, "exit": { "conditions": [ {"indicator": "sma_50", "operator": "cross_below", "compare_to": "sma_200"} ], "logic": "AND" } }, "parameters": {"sma_short": 50, "sma_long": 200}}{ "name": "RSI MACD Combo", "strategy_type": "rules", "rules": { "entry": { "conditions": [ {"indicator": "rsi", "operator": "<", "value": 40}, {"indicator": "macd", "operator": ">", "compare_to": "macd_signal"} ], "logic": "AND" }, "exit": { "conditions": [ {"indicator": "rsi", "operator": ">", "value": 60}, {"indicator": "macd", "operator": "<", "compare_to": "macd_signal"} ], "logic": "OR" } }, "parameters": {"rsi_period": 14, "macd_fast": 12, "macd_slow": 26}}{ "name": "BB Squeeze", "strategy_type": "rules", "rules": { "entry": { "conditions": [ {"indicator": "close", "operator": "<", "compare_to": "bb_lower"} ], "logic": "AND" }, "exit": { "conditions": [ {"indicator": "close", "operator": ">", "compare_to": "bb_upper"} ], "logic": "AND" } }, "parameters": {"bb_period": 20, "bb_std": 2.0}}PUT /api/v1/strategies/550e8400-e29b-41d4-a716-446655440000Authorization: Bearer <token>Content-Type: application/json
{ "description": "Updated description", "parameters": { "rsi_period": 21 }, "is_active": true}{ "id": "550e8400-e29b-41d4-a716-446655440000", "name": "RSI Mean Reversion", "description": "Updated description", "parameters": {"rsi_period": 21}, "is_active": true, ...}Create a copy of any strategy (including base strategies).
POST /api/v1/strategies/550e8400-e29b-41d4-a716-446655440000/copyAuthorization: Bearer <token>Content-Type: application/json
{ "new_name": "My Custom RSI Strategy"}{ "id": "660e8400-e29b-41d4-a716-446655440001", "name": "My Custom RSI Strategy", "is_base_strategy": false, "user_id": "c96ca3e5-94a1-49e3-b965-3e32ffb58b83", ...}import axios from 'axios';
const api = axios.create({ baseURL: 'http://localhost:8501/api/v1', headers: { 'Authorization': `Bearer ${token}` }});
// Create a rules-based strategyasync function createRulesStrategy() { const { data } = await api.post('/strategies', { name: 'RSI Mean Reversion', description: 'Buy oversold, sell overbought', strategy_type: 'rules', rules: { entry: { conditions: [ { indicator: 'rsi', operator: '<', value: 30 } ], logic: 'AND' }, exit: { conditions: [ { indicator: 'rsi', operator: '>', value: 70 } ], logic: 'AND' } }, parameters: { rsi_period: 14 }, is_active: false });
console.log(`Created strategy: ${data.id}`); return data;}
// List and filter strategiesasync function getActiveStrategies() { const { data } = await api.get('/strategies', { params: { active_only: true } });
return data.filter(s => s.strategy_type === 'rules');}
// Copy a base strategyasync function copyBaseStrategy(strategyId, newName) { const { data } = await api.post(`/strategies/${strategyId}/copy`, { new_name: newName });
return data;}
// Toggle strategy active statusasync function toggleStrategy(strategyId) { const { data } = await api.post(`/strategies/${strategyId}/toggle`); console.log(`Strategy ${strategyId} is now ${data.is_active ? 'active' : 'inactive'}`); return data;}import requestsfrom typing import Dict, List, Optional
class StrategyManager: def __init__(self, base_url: str, token: str): self.base_url = base_url self.headers = {"Authorization": f"Bearer {token}"}
def create_strategy( self, name: str, strategy_type: str = "rules", rules: Optional[Dict] = None, code: Optional[str] = None, parameters: Optional[Dict] = None, description: str = "" ) -> Dict: """Create a new strategy.""" payload = { "name": name, "description": description, "strategy_type": strategy_type, "parameters": parameters or {}, "is_active": False }
if strategy_type == "rules": payload["rules"] = rules else: payload["code"] = code
response = requests.post( f"{self.base_url}/strategies", headers=self.headers, json=payload ) response.raise_for_status() return response.json()
def list_strategies(self, active_only: bool = False) -> List[Dict]: """List all strategies.""" response = requests.get( f"{self.base_url}/strategies", headers=self.headers, params={"active_only": active_only} ) response.raise_for_status() return response.json()
def copy_strategy(self, strategy_id: str, new_name: str) -> Dict: """Copy a strategy.""" response = requests.post( f"{self.base_url}/strategies/{strategy_id}/copy", headers=self.headers, json={"new_name": new_name} ) response.raise_for_status() return response.json()
def delete_strategy(self, strategy_id: str) -> None: """Delete a strategy.""" response = requests.delete( f"{self.base_url}/strategies/{strategy_id}", headers=self.headers ) response.raise_for_status()
# Usagemanager = StrategyManager("http://localhost:8501/api/v1", token)
# Create RSI strategyrsi_strategy = manager.create_strategy( name="My RSI Strategy", strategy_type="rules", rules={ "entry": { "conditions": [{"indicator": "rsi", "operator": "<", "value": 30}], "logic": "AND" }, "exit": { "conditions": [{"indicator": "rsi", "operator": ">", "value": 70}], "logic": "AND" } }, parameters={"rsi_period": 14}, description="Buy oversold, sell overbought")
print(f"Created strategy: {rsi_strategy['id']}")
# List active strategiesactive = manager.list_strategies(active_only=True)print(f"Active strategies: {len(active)}")Start Simple
Begin with simple rules-based strategies. Add complexity gradually after testing.
Document Logic
Use clear descriptions. Future you will thank you.
Test First
Always backtest before activating a strategy.
Version Control
Copy strategies before making major changes to preserve working versions.