Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules/
dist/
.env
__pycache__/
*.pyc
.pytest_cache/
.coverage
coverage/
*.log
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Gekko API Client

A Python client for interacting with the Gekko trading platform API.

## Features

- Retrieve exchange information
- List available trading strategies
- Start and stop trading sessions
- Flexible configuration options

## Installation

1. Clone the repository
2. Install dependencies:
```
pip install -r requirements.txt
```

## Usage

```python
from src.gekko_api import GekkoAPI

# Initialize the API client
api = GekkoAPI(base_url='http://localhost:3000')

# Get exchange information
exchange_info = api.get_exchange_info('Binance')

# List available strategies
strategies = api.list_strategies()

# Start a trading session
config = {
'exchange': 'Binance',
'pair': 'BTC/USDT',
'strategy': 'MACD'
}
session_id = api.start_trading(config)

# Stop trading
api.stop_trading(session_id)
```

## Running Tests

```
pytest tests/
```

## Contributing

Please read the guidelines for contributing to this project.

## License

[Insert License Information]
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
requests==2.26.0
pytest==7.3.1
flask==2.1.0
python-dotenv==0.20.0
78 changes: 78 additions & 0 deletions src/gekko_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import requests
from typing import Dict, Any, Optional

class GekkoAPI:
"""
A client for interacting with the Gekko trading platform API.

Supports basic operations like fetching exchange info, trading strategies,
and managing trade configurations.
"""

def __init__(self, base_url: str = 'http://localhost:3000'):
"""
Initialize the Gekko API client.

:param base_url: Base URL of the Gekko API server
"""
self.base_url = base_url

def get_exchange_info(self, exchange: str) -> Dict[str, Any]:
"""
Retrieve information about a specific exchange.

:param exchange: Name of the exchange
:return: Exchange information dictionary
:raises ValueError: If exchange is not found or API request fails
"""
try:
response = requests.get(f'{self.base_url}/exchanges/{exchange}')
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise ValueError(f"Failed to retrieve exchange info: {str(e)}")

def list_strategies(self) -> Dict[str, Any]:
"""
List available trading strategies.

:return: Dictionary of available trading strategies
:raises RuntimeError: If API request fails
"""
try:
response = requests.get(f'{self.base_url}/strategies')
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise RuntimeError(f"Failed to list strategies: {str(e)}")

def start_trading(self, config: Dict[str, Any]) -> Optional[str]:
"""
Start a trading session with the given configuration.

:param config: Trading configuration dictionary
:return: Trading session ID or None
:raises ValueError: If configuration is invalid or start fails
"""
if not config:
raise ValueError("Trading configuration cannot be empty")

try:
response = requests.post(f'{self.base_url}/trade', json=config)
response.raise_for_status()
return response.json().get('sessionId')
except requests.RequestException as e:
raise ValueError(f"Failed to start trading: {str(e)}")

def stop_trading(self, session_id: str) -> bool:
"""
Stop a specific trading session.

:param session_id: ID of the trading session to stop
:return: True if trading stopped successfully, False otherwise
"""
try:
response = requests.delete(f'{self.base_url}/trade/{session_id}')
return response.status_code == 200
except requests.RequestException:
return False
82 changes: 82 additions & 0 deletions tests/test_gekko_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import pytest
import requests
from unittest.mock import patch
from src.gekko_api import GekkoAPI

class MockResponse:
def __init__(self, json_data, status_code=200):
self.json_data = json_data
self.status_code = status_code

def json(self):
return self.json_data

def raise_for_status(self):
if self.status_code >= 400:
raise requests.HTTPError(f"HTTP Error: {self.status_code}")

def test_gekko_api_initialization():
api = GekkoAPI()
assert api.base_url == 'http://localhost:3000'

@patch('requests.get')
def test_get_exchange_info(mock_get):
mock_get.return_value = MockResponse({
'name': 'Binance',
'supported': True,
'requiredPermissions': ['trade', 'balance']
})

api = GekkoAPI()
exchange_info = api.get_exchange_info('Binance')

assert exchange_info['name'] == 'Binance'
mock_get.assert_called_once_with('http://localhost:3000/exchanges/Binance')

@patch('requests.get')
def test_list_strategies(mock_get):
mock_get.return_value = MockResponse({
'strategies': ['MACD', 'RSI', 'EMA']
})

api = GekkoAPI()
strategies = api.list_strategies()

assert 'strategies' in strategies
assert len(strategies['strategies']) == 3
mock_get.assert_called_once_with('http://localhost:3000/strategies')

@patch('requests.post')
def test_start_trading(mock_post):
mock_post.return_value = MockResponse({
'sessionId': 'trade_123456'
})

api = GekkoAPI()
config = {
'exchange': 'Binance',
'pair': 'BTC/USDT',
'strategy': 'MACD'
}

session_id = api.start_trading(config)

assert session_id == 'trade_123456'
mock_post.assert_called_once_with('http://localhost:3000/trade', json=config)

@patch('requests.post')
def test_start_trading_empty_config(mock_post):
api = GekkoAPI()

with pytest.raises(ValueError, match="Trading configuration cannot be empty"):
api.start_trading({})

@patch('requests.delete')
def test_stop_trading(mock_delete):
mock_delete.return_value = MockResponse({}, status_code=200)

api = GekkoAPI()
result = api.stop_trading('trade_123456')

assert result is True
mock_delete.assert_called_once_with('http://localhost:3000/trade/trade_123456')