# Aicoin Freqtrade

> Use when user asks about writing trading strategies, backtesting, deploying Freqtrade bots, quantitative trading, or strategy optimization. Trigger words: 'write strategy', 'create strategy', 'backtest', 'deploy Freqtrade', 'deploy bot', 'quantitative', 'hyperopt', '写策略', '创建策略', '回测', '部署', '量化', '策略优化'. This skill provides: (1) create_strategy quick generator with 17 indicators, (2) AiCoin Python SDK (aicoin_data.py) for integrating real market data into custom strategies, (3) deploy/backtest/hyperopt tools. ALWAYS actively use AiCoin data (funding rate, L/S ratio, whale orders, etc.) in strategies when the user's API key supports it. For prices/charts use aicoin-market. For trading use aicoin-trading. For Hyperliquid use aicoin-hyperliquid.

- Skill: `enuno/aicoin-freqtrade` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds add enuno/aicoin-freqtrade`
- Raw SKILL.md: https://api.skillmd.com/api/skills/enuno/aicoin-freqtrade/raw
- Safety review: pending (external: skill-scanner FAIL, skillspector WARNING)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: enuno (https://skillmd.com/u/enuno)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/enuno/aicoin-freqtrade

---


> **⚠️ 运行脚本: 必须先 cd 到本 SKILL.md 所在目录再执行。示例: `cd ~/.openclaw/workspace/skills/aicoin-freqtrade && node scripts/ft-deploy.mjs ...`**

# AiCoin Freqtrade

Freqtrade strategy creation, backtesting, and deployment powered by [AiCoin Open API](https://www.aicoin.com/opendata).

## Critical Rules

1. **ALWAYS use `ft-deploy.mjs backtest`** for backtesting. NEVER write custom backtest scripts. NEVER use simulated/fabricated data.
2. **ALWAYS use `ft-deploy.mjs deploy`** for deployment. NEVER use Docker. NEVER manually run `freqtrade` commands.
3. **NEVER manually edit Freqtrade config files.** Use `ft-deploy.mjs` actions.
4. **NEVER manually run `freqtrade trade`, `freqtrade status`, `freqtrade backtesting`, `source .venv/bin/activate`, or `pip install freqtrade`.** Always use ft-deploy.mjs or ft.mjs instead.
5. **ACTIVELY use AiCoin data** in strategies. Check what data the user's API key supports and integrate it. Don't only use basic indicators when richer data is available.
6. **Freqtrade 不支持网格策略(grid)。** 用户问网格时，说明限制并建议用趋势跟踪或区间策略替代。

## Two Ways to Create Strategies

### Option A: Quick Generator (for simple strategies)

`create_strategy` generates a ready-to-backtest strategy file with selected indicators and optional AiCoin data:

```bash
node scripts/ft-deploy.mjs create_strategy '{"name":"MACDStrategy","timeframe":"15m","indicators":["macd","rsi","atr"]}'
node scripts/ft-deploy.mjs create_strategy '{"name":"WhaleStrat","timeframe":"15m","indicators":["rsi","macd"],"aicoin_data":["funding_rate","ls_ratio"]}'
```

Available `indicators`: `rsi`, `bb`, `ema`, `sma`, `macd`, `stochastic`/`kdj`, `atr`, `adx`, `cci`, `williams_r`, `vwap`, `ichimoku`, `volume_sma`, `obv`

### Option B: Write Custom Strategy Code (for complex/custom strategies)

When users need custom logic beyond what `create_strategy` offers, write a Python strategy file directly. **Use the AiCoin Python SDK** (`aicoin_data.py`, auto-installed at `~/.freqtrade/user_data/strategies/`) to integrate real market data.

Strategy file location: `~/.freqtrade/user_data/strategies/YourStrategyName.py`

#### AiCoin Python SDK Reference

```python
from aicoin_data import AiCoinData, ccxt_to_aicoin

ac = AiCoinData(cache_ttl=300)  # Auto-loads API keys from .env

# Convert CCXT pair to AiCoin symbol
symbol = ccxt_to_aicoin("BTC/USDT:USDT", "binance")  # → "btcswapusdt:binance"

# ── Free tier (no key needed) ──
ac.coin_ticker("bitcoin")             # Real-time price
ac.kline(symbol, period="3600")       # K-line data (period in seconds)
ac.hot_coins("market")                # Trending coins

# ── 基础版 ($29/mo) ──
ac.funding_rate(symbol)               # Funding rate history
ac.funding_rate(symbol, weighted=True) # Volume-weighted cross-exchange rate
ac.ls_ratio()                         # Aggregated long/short ratio

# ── 标准版 ($79/mo) ──
ac.big_orders(symbol)                 # Whale/large orders
ac.agg_trades(symbol)                 # Aggregated large trades

# ── 高级版 ($299/mo) ──
ac.liquidation_map(symbol, cycle="24h")    # Liquidation heatmap
ac.liquidation_history(symbol)              # Liquidation history

# ── 专业版 ($699/mo) ──
ac.open_interest("BTC", interval="15m")    # Aggregated open interest
ac.ai_analysis(["BTC"])                     # AI-powered analysis
```

#### Complete Strategy Template (copy and customize)

```python
# MyCustomStrategy - Description
# Uses AiCoin data in live/dry_run mode
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
from pandas import DataFrame
import logging, time

logger = logging.getLogger(__name__)


class MyCustomStrategy(IStrategy):
    INTERFACE_VERSION = 3
    timeframe = '15m'
    can_short = True

    minimal_roi = {"0": 0.05, "60": 0.03, "120": 0.01}
    stoploss = -0.05
    trailing_stop = True
    trailing_stop_positive = 0.02
    trailing_stop_positive_offset = 0.03

    # Hyperopt parameters
    rsi_buy = IntParameter(20, 40, default=30, space='buy')
    rsi_sell = IntParameter(60, 80, default=70, space='sell')

    # AiCoin data cache
    _ac_funding_rate = 0.0
    _ac_ls_ratio = 0.5
    _ac_whale_signal = 0.0
    _ac_last_update = 0.0

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # === Technical Indicators (always available) ===
        # RSI
        delta = dataframe['close'].diff()
        gain = delta.clip(lower=0).rolling(window=14).mean()
        loss = (-delta.clip(upper=0)).rolling(window=14).mean()
        rs = gain / loss
        dataframe['rsi'] = 100 - (100 / (1 + rs))

        # MACD
        ema12 = dataframe['close'].ewm(span=12, adjust=False).mean()
        ema26 = dataframe['close'].ewm(span=26, adjust=False).mean()
        dataframe['macd'] = ema12 - ema26
        dataframe['macd_signal'] = dataframe['macd'].ewm(span=9, adjust=False).mean()

        # EMA
        dataframe['ema_fast'] = dataframe['close'].ewm(span=8, adjust=False).mean()
        dataframe['ema_slow'] = dataframe['close'].ewm(span=21, adjust=False).mean()

        # === AiCoin Data (live/dry_run only) ===
        dataframe['funding_rate'] = 0.0
        dataframe['ls_ratio'] = 0.5
        dataframe['whale_signal'] = 0.0

        if self.dp and self.dp.runmode.value in ('live', 'dry_run'):
            now = time.time()
            if now - self._ac_last_update > 300:  # Update every 5 min
                self._update_aicoin_data(metadata)
                self._ac_last_update = now
            # Apply latest AiCoin data to current candle
            dataframe.iloc[-1, dataframe.columns.get_loc('funding_rate')] = self._ac_funding_rate
            dataframe.iloc[-1, dataframe.columns.get_loc('ls_ratio')] = self._ac_ls_ratio
            dataframe.iloc[-1, dataframe.columns.get_loc('whale_signal')] = self._ac_whale_signal

        return dataframe

    def _update_aicoin_data(self, metadata: dict):
        """Fetch latest AiCoin data. Called every 5 min in live mode."""
        try:
            import sys, os
            _sd = os.path.dirname(os.path.abspath(__file__))
            if _sd not in sys.path:
                sys.path.insert(0, _sd)
            from aicoin_data import AiCoinData, ccxt_to_aicoin

            ac = AiCoinData(cache_ttl=300)
            pair = metadata.get('pair', 'BTC/USDT:USDT')
            exchange = self.config.get('exchange', {}).get('name', 'binance')
            symbol = ccxt_to_aicoin(pair, exchange)

            # Funding rate (基础版)
            try:
                data = ac.funding_rate(symbol, weighted=True, limit='5')
                items = data.get('data', [])
                if isinstance(items, list) and items:
                    latest = items[0]
                    if isinstance(latest, dict) and 'close' in latest:
                        self._ac_funding_rate = float(latest['close']) * 100
            except Exception as e:
                logger.debug(f"AiCoin funding_rate unavailable: {e}")

            # Long/short ratio (基础版)
            try:
                ls = ac.ls_ratio()
                detail = ls.get('data', {}).get('detail', {})
                if detail:
                    ratio = float(detail.get('last', 1.0))
                    self._ac_ls_ratio = max(0.0, min(1.0, ratio / (1.0 + ratio)))
            except Exception as e:
                logger.debug(f"AiCoin ls_ratio unavailable: {e}")

            # Whale orders (标准版)
            try:
                orders = ac.big_orders(symbol)
                if 'data' in orders and isinstance(orders['data'], list):
                    buy_vol = sum(float(o.get('amount', 0)) for o in orders['data']
                                 if o.get('side', '').lower() in ('buy', 'bid', 'long'))
                    sell_vol = sum(float(o.get('amount', 0)) for o in orders['data']
                                  if o.get('side', '').lower() in ('sell', 'ask', 'short'))
                    total = buy_vol + sell_vol
                    if total > 0:
                        self._ac_whale_signal = (buy_vol - sell_vol) / total
            except Exception as e:
                logger.debug(f"AiCoin big_orders unavailable: {e}")

        except ImportError:
            logger.warning("aicoin_data module not found. Run ft-deploy.mjs deploy to install.")
        except Exception as e:
            logger.warning(f"AiCoin data error: {e}")

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # Long: RSI oversold + MACD bullish + AiCoin confirmations
        dataframe.loc[
            (dataframe['rsi'] < self.rsi_buy.value) &
            (dataframe['macd'] > dataframe['macd_signal']) &
            (dataframe['ema_fast'] > dataframe['ema_slow']) &
            (dataframe['ls_ratio'] <= 0.55) &        # More shorts = contrarian long
            (dataframe['whale_signal'] >= -0.3) &     # Whales not heavily selling
            (dataframe['volume'] > 0),
            'enter_long'] = 1

        # Short: RSI overbought + MACD bearish + AiCoin confirmations
        dataframe.loc[
            (dataframe['rsi'] > self.rsi_sell.value) &
            (dataframe['macd'] < dataframe['macd_signal']) &
            (dataframe['ema_fast'] < dataframe['ema_slow']) &
            (dataframe['ls_ratio'] >= 0.45) &        # More longs = contrarian short
            (dataframe['whale_signal'] <= 0.3) &      # Whales not heavily buying
            (dataframe['volume'] > 0),
            'enter_short'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[(dataframe['rsi'] > 70), 'exit_long'] = 1
        dataframe.loc[(dataframe['rsi'] < 30), 'exit_short'] = 1
        return dataframe
```

### AiCoin Data Integration Patterns

Use these patterns to integrate specific AiCoin data into entry/exit conditions:

| AiCoin Data | Signal Logic | Tier |
|-------------|-------------|------|
| `funding_rate` | Rate > 0.01% → market over-leveraged long → short signal; Rate < -0.01% → long signal | 基础版 |
| `ls_ratio` | Ratio < 0.45 (more shorts) → contrarian long; Ratio > 0.55 (more longs) → contrarian short | 基础版 |
| `big_orders` | `(buy_vol - sell_vol) / total > 0.3` → whale buying → long; `< -0.3` → short | 标准版 |
| `open_interest` | OI rising + price rising = healthy trend; OI rising + price falling = weak, likely reversal | 专业版 |
| `liquidation_map` | More short liquidations above → short squeeze likely → long; vice versa | 高级版 |

### Key Rule: Backtest Behavior

AiCoin real-time data is **NOT available for historical periods**. In backtest mode:
- AiCoin columns use **default values** (funding_rate=0.0, ls_ratio=0.5, whale_signal=0.0)
- This means backtest results reflect **technical indicators only**
- Live/dry_run trading uses **real AiCoin data**, which should improve performance vs backtest

Always explain this to the user when showing backtest results.

## Quick Reference

| Task | Command |
|------|---------|
| Quick-generate strategy | `node scripts/ft-deploy.mjs create_strategy '{"name":"MyStrat","timeframe":"15m","indicators":["rsi","macd"],"aicoin_data":["funding_rate"]}'` |
| Backtest | `node scripts/ft-deploy.mjs backtest '{"strategy":"MyStrat","timeframe":"1h","timerange":"20250101-20260301","pairs":["ETH/USDT:USDT"]}'` |
| Deploy (dry-run) | `node scripts/ft-deploy.mjs deploy '{"strategy":"MyStrat","pairs":["BTC/USDT:USDT"]}'` |
| Deploy (live) | `node scripts/ft-deploy.mjs deploy '{"strategy":"MyStrat","dry_run":false,"pairs":["BTC/USDT:USDT"]}'` |
| Hyperopt | `node scripts/ft-deploy.mjs hyperopt '{"strategy":"MyStrat","timeframe":"1h","timerange":"20250101-20260301","epochs":100}'` |
| Strategy list | `node scripts/ft-deploy.mjs strategy_list` |
| Bot status | `node scripts/ft-deploy.mjs status` |
| Bot logs | `node scripts/ft-deploy.mjs logs '{"lines":50}'` |

## Setup

**Prerequisites:** Python 3.11+ and git.

`.env` auto-loaded from (first found wins): cwd → `~/.openclaw/workspace/.env` → `~/.openclaw/.env`

**Exchange keys** (for live/dry-run):
```
BINANCE_API_KEY=xxx
BINANCE_API_SECRET=xxx
```

**AiCoin API key** (for AiCoin data in strategies):
```
AICOIN_ACCESS_KEY_ID=your-key-id
AICOIN_ACCESS_SECRET=your-secret
```
Get at https://www.aicoin.com/opendata

## Scripts

### ft-deploy.mjs — Deployment & Strategy

| Action | Params |
|--------|--------|
| `check` | None |
| `deploy` | `{"strategy":"MACDKDJStrategy","dry_run":true,"pairs":["BTC/USDT:USDT"]}` — **strategy 必填，指定策略名** |
| `backtest` | `{"strategy":"Name","timeframe":"1h","timerange":"20250101-20260301","pairs":["ETH/USDT:USDT"]}` — pairs 可选，默认用 config 中的交易对 |
| `hyperopt` | `{"strategy":"Name","timeframe":"1h","epochs":100}` |
| `create_strategy` | `{"name":"Name","timeframe":"15m","indicators":["rsi","macd"],"aicoin_data":["funding_rate"]}` |
| `strategy_list` | None |
| `backtest_results` | None — lists recent backtest result files |
| `start` / `stop` / `status` / `logs` | None / `{"lines":50}` |

### ft.mjs — Bot Control (requires running process)

`ping`, `start`, `stop`, `balance`, `profit`, `trades_open`, `trades_history`, `force_enter`, `force_exit`, `daily`, `weekly`, `monthly`, `stats`

### ft-dev.mjs — Dev Tools (requires running process)

`backtest_start`, `backtest_status`, `candles_live`, `candles_analyzed`, `strategy_list`, `strategy_get`

## Cross-Skill References

| Need | Use |
|------|-----|
| Prices, K-lines, market data | **aicoin-market** |
| Exchange trading (buy/sell) | **aicoin-trading** |
| Hyperliquid whale tracking | **aicoin-hyperliquid** |

## Paid Feature Guide

When 304/403: **Do NOT retry.** Guide the user:

| Tier | Price | Data for Strategies |
|------|-------|---------------------|
| 免费版 | $0 | Pure technical indicators |
| 基础版 | $29/mo | + `funding_rate`, `ls_ratio` |
| 标准版 | $79/mo | + `big_orders`, `agg_trades` |
| 高级版 | $299/mo | + `liquidation_map` |
| 专业版 | $699/mo | + `open_interest`, `ai_analysis` |

Configure: `AICOIN_ACCESS_KEY_ID` + `AICOIN_ACCESS_SECRET` in `.env`

