# Kline Package

A Python package for fetching price data from Binance and Oanda with flexible caching capabilities.

## Features

- 🚀 **Fetch Price Data** from multiple sources:
  - Binance (cryptocurrency exchange) - direct API integration
  - Oanda (forex/CFD broker) - requires API key and account ID
  
- � **Real-time Streaming**:
  - Binance WebSocket (klines, trades, tickers, order book)
  - Oanda price streaming
  
- �💾 **Flexible Caching**:
  - Parquet format (efficient, compressed)
  - CSV format (human-readable)
  
- 🔧 **Universal Format**: Same symbol and timeframe format for all data sources
  - Symbols: `BTCUSDT`, `EURUSD`, `XAUUSD` (auto-converts for each API)
  - Timeframes: `1m`, `5m`, `1h`, `4h`, `1d` (auto-converts for each API)

## Installation

```bash
pip install kline-package
```

### Development Installation

```bash
git clone https://github.com/yourusername/kline-package.git
cd kline-package
pip install -e ".[dev]"
```

## Quick Start

### Fetching Binance Data

```python
from kline_package.fetchers import BinanceFetcher
from kline_package.cache import ParquetCache

# Initialize fetcher
fetcher = BinanceFetcher()

# Fetch data (universal format)
data = fetcher.fetch(symbol="BTCUSDT", interval="1h", limit=100)

# Cache to parquet
cache = ParquetCache(cache_dir="./data")
cache.save(data, filename="btc_prices")
```

### Fetching Oanda Data

```python
from kline_package.fetchers import OandaFetcher
from kline_package.cache import CSVCache

# Initialize with credentials
fetcher = OandaFetcher(
    api_key="your-api-key",
    account_id="your-account-id"
)

# Fetch data (universal format - auto-converts EURUSD to EUR_USD, 1h to H1)
data = fetcher.fetch(symbol="EURUSD", interval="1h", count=100)

# Cache to CSV
cache = CSVCache(cache_dir="./data")
cache.save(data, filename="eurusd_prices")
```

## Universal Format

Both fetchers use the same format for symbols and timeframes:

### Timeframes
| Universal | Binance | Oanda |
|-----------|---------|-------|
| `1m`      | 1m      | M1    |
| `5m`      | 5m      | M5    |
| `15m`     | 15m     | M15   |
| `1h`      | 1h      | H1    |
| `4h`      | 4h      | H4    |
| `1d`      | 1d      | D     |
| `1w`      | 1w      | W     |

### Symbols
| Universal | Binance   | Oanda   |
|-----------|-----------|---------|
| `BTCUSDT` | BTCUSDT   | -       |
| `EURUSD`  | -         | EUR_USD |
| `XAUUSD`  | -         | XAU_USD |

## Requirements

- Python >= 3.8
- pandas >= 1.3.0
- requests >= 2.26.0
- pyarrow >= 6.0.0 (for Parquet support)

## API Documentation

### Fetchers

#### BinanceFetcher
Fetches price data from Binance cryptocurrency exchange.

**Methods:**
- `fetch(symbol, interval, limit, start_time, end_time)` - Fetch kline/candlestick data

#### OandaFetcher
Fetches price data from Oanda forex/CFD broker.

**Methods:**
- `fetch(symbol, interval, count, from_time, to_time)` - Fetch candle data (uses universal format)

### Streamers

#### BinanceStreamer
Real-time WebSocket streaming from Binance.

**Methods:**
- `connect()` - Connect to WebSocket
- `disconnect()` - Close connection
- `subscribe_kline(symbol, interval, callback)` - Subscribe to kline stream
- `subscribe_trade(symbol, callback)` - Subscribe to trade stream
- `subscribe_ticker(symbol, callback)` - Subscribe to 24hr ticker
- `subscribe_depth(symbol, callback)` - Subscribe to order book

#### OandaStreamer
Real-time price streaming from Oanda.

**Methods:**
- `connect()` - Initialize connection
- `disconnect()` - Close connection
- `subscribe(symbol, callback)` - Subscribe to price stream

### Cache Handlers

#### ParquetCache
Saves and loads data in Parquet format (compressed, efficient).

**Methods:**
- `save(data, filename)` - Save DataFrame to Parquet
- `load(filename)` - Load DataFrame from Parquet

#### CSVCache
Saves and loads data in CSV format (human-readable).

**Methods:**
- `save(data, filename)` - Save DataFrame to CSV
- `load(filename)` - Load DataFrame from CSV

## Real-time Streaming

### Binance WebSocket Streaming

```python
import asyncio
from kline_package.streamers import BinanceStreamer

async def on_kline(data):
    print(f"Price: {data['close']}, Closed: {data['is_closed']}")

async def main():
    streamer = BinanceStreamer()
    await streamer.connect()
    await streamer.subscribe_kline("BTCUSDT", "1m", on_kline)
    await asyncio.sleep(60)  # Stream for 60 seconds
    await streamer.disconnect()

asyncio.run(main())
```

### Oanda Price Streaming

```python
import asyncio
from kline_package.streamers import OandaStreamer

async def on_price(data):
    print(f"Bid: {data['bid']}, Ask: {data['ask']}")

async def main():
    streamer = OandaStreamer(api_key="your-key", account_id="your-id")
    await streamer.connect()
    await streamer.subscribe("EURUSD", on_price)
    await asyncio.sleep(60)
    await streamer.disconnect()

asyncio.run(main())
```

## Installation Options

```bash
# Basic installation (fetchers + caching)
pip install kline-package

# With streaming support
pip install kline-package[streaming]

# All features
pip install kline-package[all]

# Development
pip install kline-package[dev]
```

## Examples

See the `examples/` directory for more usage examples:
- `basic_binance_usage.py` - Basic Binance data fetching
- `basic_oanda_usage.py` - Basic Oanda data fetching with authentication
- `advanced_caching.py` - Advanced caching strategies
- `streaming_binance.py` - Real-time Binance WebSocket streaming
- `streaming_oanda.py` - Real-time Oanda price streaming

## Development

### Running Tests

```bash
pytest
```

### Code Formatting

```bash
black src/
isort src/
```

### Type Checking

```bash
mypy src/
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Disclaimer

This package is for educational and informational purposes only. Always ensure you comply with the terms of service of the APIs you're using. Trading and financial data access may be subject to regulations in your jurisdiction.
