Metadata-Version: 2.4
Name: cnlib
Version: 0.1.4
Summary: Algorithmic trading competition library — leveraged long/short backtest engine
License: MIT License
        
        Copyright (c) 2026 Iztech Software Society
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/IYTE-Yazilim-Toplulugu/code-night-lib
Project-URL: Issues, https://github.com/IYTE-Yazilim-Toplulugu/code-night-lib/issues
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=2.0
Requires-Dist: pyarrow>=12.0
Requires-Dist: numpy>=1.24
Dynamic: license-file

# cnlib — Code Night Algorithmic Trading Library

Leveraged long/short backtest engine for the Code Night trading competition.  
Participants write a strategy, the platform runs it, results are ranked.

---

## How It Works

Three synthetic crypto assets — **kapcoin-usd_train**, **metucoin-usd_train**, **tamcoin-usd_train** — modeled after BTC, SOL, and XRP volatility profiles.

- Starting capital: **$3,000**
- Available leverage: **1x, 2x, 3x, 5x, 10x**
- Positions: **Long** (profit when price rises) or **Short** (profit when price falls)
- `predict()` is called on every candle close — you decide what to do next

---

## Installation

```bash
pip install cnlib
```

Or from source:

```bash
git clone https://github.com/IYTE-Yazilim-Toplulugu/code-night-lib.git
cd code-night-lib
pip install -e .
```

---

## Quickstart

Create a `strategy.py` file anywhere:

```python
from cnlib.base_strategy import BaseStrategy

class MyStrategy(BaseStrategy):
    def predict(self, data):
        closes = data["kapcoin-usd_train"]["Close"]

        if closes.iloc[-1] > closes.iloc[-2]:
            signal = 1   # price went up → go long
        else:
            signal = -1  # price went down → go short

        return [
            {"coin": "kapcoin-usd_train",  "signal": signal, "allocation": 0.5, "leverage": 2},
            {"coin": "metucoin-usd_train", "signal": 0,      "allocation": 0.0, "leverage": 1},
            {"coin": "tamcoin-usd_train",  "signal": 0,      "allocation": 0.0, "leverage": 1},
        ]
```

Run the backtest:

```python
from cnlib import backtest
from strategy import MyStrategy

result = backtest.run(MyStrategy(), initial_capital=3000.0)
result.print_summary()
```

Output:

```
=======================================================
  BACKTEST RESULTS
=======================================================
  Initial Capital     : $    3,000.00
  Final Portfolio     : $    3,220.35
  Net P&L             : $     +220.35
  Return              :      +7.3450%
-------------------------------------------------------
  Total Candles       :         1,000
  Total Trades        :            54
  Liquidations        :             0
  Liquidation Loss    : $        0.00
  Validation Errors   :             0
=======================================================
```

---

## The `predict()` Contract

Called on **every candle close**. Receives all historical OHLCV data up to the current candle.

### Input

```python
data = {
    "kapcoin-usd_train":  pd.DataFrame,  # columns: Date, Open, High, Low, Close, Volume
    "metucoin-usd_train": pd.DataFrame,
    "tamcoin-usd_train":  pd.DataFrame,
}
```

> Each DataFrame only contains candles up to **now** — no future data leakage.

### Output

A list with **exactly one entry per coin, every candle**:

```python
return [
    {"coin": "kapcoin-usd_train",  "signal": 1,  "allocation": 0.5, "leverage": 10},
    {"coin": "metucoin-usd_train", "signal": -1, "allocation": 0.3, "leverage": 2},
    {"coin": "tamcoin-usd_train",  "signal": 0,  "allocation": 0.0, "leverage": 1},
]
```

| Field | Type | Description |
|---|---|---|
| `coin` | `str` | One of `kapcoin-usd_train`, `metucoin-usd_train`, `tamcoin-usd_train` |
| `signal` | `int` | `1` = long, `-1` = short, `0` = close any open position |
| `allocation` | `float` | Fraction of portfolio to allocate `[0.0 – 1.0]` |
| `leverage` | `int` | `1`, `2`, `3`, `5`, or `10` |

### Rules

- All three coins must appear in every list — no omissions
- To **hold** an open position, re-state the same `signal`
- To stay **flat**, use `signal=0, allocation=0.0`
- `signal=0` → `allocation` must be `0.0`
- Sum of active allocations cannot exceed `1.0`
- Leverage must be one of `{1, 2, 3, 5, 10}` (ignored when `signal=0`)
- Violations raise `ValidationError` — that candle is skipped, positions are held

---

## Liquidation

Positions are force-closed when the candle's intrabar extreme hits the liquidation threshold — longs on the candle **Low**, shorts on the candle **High**. Capital is **fully lost** on liquidation — no cash is returned.

```
Long  → liquidated when Low  ≤ entry × (1 - 1/leverage)
Short → liquidated when High ≥ entry × (1 + 1/leverage)

Example: long at $100 with 10x leverage
  Liquidation price = 100 × (1 - 1/10) = $90
  If the candle Low touches $90 or below → position wiped out
```

---

## Position Sizing

`allocation` is a fraction of your **current total portfolio value**, not just cash:

```python
# Portfolio value: $3,000, allocation=0.4, leverage=5
allocated_capital = 3000 × 0.4 = $1,200
effective_exposure = $1,200 × 5 = $6,000

# If price rises 2%:
pnl = $1,200 × 5 × 0.02 = +$120  (+10% on allocated capital)
```

---

## Strategy State

`self` persists between candles — use it to store state:

```python
class MyStrategy(BaseStrategy):
    def __init__(self):
        super().__init__()
        self.prev_signal = {
            "kapcoin-usd_train":  0,
            "metucoin-usd_train": 0,
            "tamcoin-usd_train":  0,
        }
        self.entry_prices = {}

    def predict(self, data):
        # self.candle_index → current candle number (0-based)
        # self.coin_data    → full OHLCV history dict
        ...
```

---

## Result Object

```python
result = backtest.run(strategy)

result.print_summary()              # formatted console output
result.portfolio_dataframe()        # time-series DataFrame: candle_index, portfolio_value, cash, *_price
result.trade_history                # list of dicts for candles where trades occurred
result.final_portfolio_value        # float
result.net_pnl                      # float
result.return_pct                   # float
result.total_liquidations           # int
result.validation_errors            # int
```

---

## Project Structure

```
code-night-lib/
├── pyproject.toml
├── cnlib/
│   ├── base_strategy.py      # BaseStrategy — inherit this
│   ├── backtest.py           # backtest.run()
│   ├── portfolio.py          # position & liquidation logic
│   ├── validator.py          # predict() output validation
│   └── data/
│       ├── kapcoin-usd_train.parquet
│       ├── metucoin-usd_train.parquet
│       └── tamcoin-usd_train.parquet
└── docs/
    └── README.md             # participant guide (Turkish)
```
