Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jkbrzt committed Mar 20, 2015
0 parents commit 525f2c2
Show file tree
Hide file tree
Showing 57 changed files with 3,662 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.sqlite3
*.rdb
*.db
*.pyc
*.egg-info
tmp/
node_modules/
public/
bower_components/
settings_local.py
21 changes: 21 additions & 0 deletions LICENCE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License

Copyright (c) 2015 Jakub Roztocil <[email protected]>

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.
176 changes: 176 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Cointrol

Cointrol is a Bitcoin trading bot and real-time dashboard for [Bitstamp](https://bitstamp.net).

![browser](_/browser.png "Dashboard")

Cointrol was created to automate Bitcoin speculation. Besides automated trading based on price change triggers and various trading strategies, it also provides a dashboard for your Bitstamp account where you can see all your orders and transactions real-time updated (something Bitstamp lacks).

Even though the original idea was to perhaps provide a fully-fledged hosted service, the system remained quite basic as it has only been used by its creator for a period of time in the winter of '13/'14 (when BTC price fluctuations were pretty insane). Some of the obvious limitations—all of which could easily be addressed—are:

* Only basic trading strategies are implemented
* Single user/Bitstamp account is supported
* Only one active trading session at a time
* The whole account value is used when trading
* Django admin is used for auth and trading strategy/session manipulations

Even though Cointrol has been used for real transactions, no guarantees are provided in terms of security, correctness, etc. (see `LICENCE`).


## Architecture

The system consists of the following components:

![](_/architecture.png)


####`cointrol-trader`

* Polls various Bitstamp API endpoints
* Writes changes to DB
* Publishes changes to Redis pub/sub
* Opens orders, when suitable


###`cointrol-server`

* Serves Webapp static files
* Exposes DB for Webapp via a REST API
* Forwards Redis pub/sub messages from Trader to Webapp via WebSocket
* Exposes Django administration that is currently used for managing trading sessions


### `webapp`

* REST/WebSocket API-powered Single Page App
* Real-time updated overview on orders, transactions, and trading sessions


## Technology

**The server-side parts** (`cointrol-server` + `cointrol-trader`) are written in **Python 3** (3.3+ is required) and use a mixture of **Django** (models, admin) and **Tornado** (WebSockets, async IO). Other libraries that are used include sockjs-tornado, Django REST framework.

**The single-page webapp** is written in CoffeeScript, Sass, Handlebars and uses Backbone.js, Brunch, socksjs-client, Bootstrap.



## Installation


### Prerequisites

* Python 3.3+
* Redis


### Install Cointrol

#### Server
```bash
mkdir Cointrol && cd Cointrol

# Create an isolated virtual environment
pip install virtualenv
virtualenv ./virtualenv --python=$(which python3)

# Activate the virtualenv
# IMPORTANT: it needs to be activated everytime before you run
# a manage.py or cointrol-* command.
. virtualenv/bin/activate

git clone [email protected]:jakubroztocil/cointrol.git

echo 'from .settings_dev import *' > cointrol/cointrol/conf/settings_local.py

pip install -r cointrol/cointrol/conf/requirements.txt
pip install -e ./cointrol

cointrol/manage.py syncdb --noinput
```

#### Web client

Development setup — only needed if you plan on making changes to the single-page webapp.

```bash
# Install dependencies
sudo npm -g install bower
cd cointrol/webapp
npm install
bower install

# Watch source files
brunch watch
```

### Create user

```bash
. virtualenv/bin/activate
cointrol/manage.py createsuperuser
```


### Configure Bitstamp API access

1. Go to [https://www.bitstamp.net/account/security/api](https://www.bitstamp.net/account/security/api) to get you API key/secret
2. Activate the virtualenv and run `cointrol-server`
3. Go to [http://localhost:8000/admin/core/account/1/](http://localhost:8000/admin/core/account/1/) and enter your Bitstamp account details

## Usage

### Start the sever


```bash
. virtualenv/bin/activate
cointrol-server
```


By default, it will run on [http://localhost:8000](localhost:8000). You can change the port with `--port=<port>`.

The Django administration interface is used for log-in — just go back to `/` after you've done that.

### Start the updater/trader

```bash
. virtualenv/bin/activate
cointrol-trader
```


### Trading

1. Through the admin ([http://localhost:8000/admin/](http://localhost:8000/admin/)) you can create a trading strategy profile. It can be for the *fixed* (fixed price points in USD are used as buy/sell triggers) or the *relative* (percentage of the initial BTC price are used) strategy.
2. Create a trading session (also in the admin interface).
3. To perform actual transactions, you'll have to enable them in the settings (we used the `settings_dev` module which disables them). Add `COINTROL_DO_TRADE = True` to your `cointrol/cointrol/conf/settings_local.py`.


## Settings

The settings is resolved in this order:

1. `settings_local.py`
2. `settings_(prod|dev).py`
3. `settings_defaults.py`
4. Django defaults

During the installation process, you've created `cointrol/cointrol/conf/settings_local.py` which imports settings from the `settings_dev.py` file. All the settings are [Django settings](https://docs.djangoproject.com/en/1.7/ref/settings/). The only non-Django settings is `COINTROL_DO_TRADE` (`False` in `dev`, `True` in `prod`). You can override any of the default settings in the `settings_local.py` file.

Besides `settings_dev.py`, the `conf` directory also has `settings_prod.py`, which is more suitable for production use. It defines logging configuration which makes messages of a level `>=` `WARNING` logged by the trader to be sent to you via email (e.g. when the trader places an order or there is an error). If you decide to use this settings file (by changing the import in `settings_local.py` to `from .settings_prod import *`, you'll have to configure at least [`DATABASES`](https://docs.djangoproject.com/en/1.7/ref/settings/#databases), [`ADMINS`](https://docs.djangoproject.com/en/1.7/ref/settings/#admins) and [`SECRET_KEY`](https://docs.djangoproject.com/en/1.7/ref/settings/#secret-key) as well in your in `settings_local.py`.


## Contact

Jakub Roztocil

* [https://github.com/jakubroztocil](https://github.com/jakubroztocil)
* [https://twitter.com/jakubroztocil](https://twitter.com/jakubroztocil)
* `3NVcdcoXrBV7jKv7T3st6kQz7XdsPNUn34`

## Licence

MIT. See [LICENCE](./LICENCE).


Binary file added _/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _/browser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions cointrol/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import logging
import os


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cointrol.conf')

import django
django.setup()


log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
log.propagate = False
console = logging.StreamHandler()
console.setFormatter(
logging.Formatter('[%(asctime)s %(levelname)1.1s] %(name)s: %(message)s'))
log.addHandler(console)



14 changes: 14 additions & 0 deletions cointrol/conf/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import sys


try:
from .settings_local import *
except ImportError as e:
sys.stderr.write("""
ERROR: It looks like settings_local.py is missing:
{}
""".format(str(e)))

sys.exit(1)
9 changes: 9 additions & 0 deletions cointrol/conf/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Django==1.7.6
django-extensions==1.2.5
djangorestframework==3.1.0
hiredis==0.1.4
pytz==2014.7
redis==2.10.3
sockjs-tornado==1.0.1
tornado==4.1
tornado-redis==2.4.18
46 changes: 46 additions & 0 deletions cointrol/conf/settings_defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Cointrol default settings.
"""
import os


BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
AUTH_USER_MODEL = 'core.User'
ROOT_URLCONF = 'cointrol.server.urls'
INSTALLED_APPS = [
'django_extensions',
'rest_framework',
'cointrol.core',
'cointrol.server',
'cointrol.trader',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.staticfiles',

]
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Copenhagen'
USE_I18N = False
USE_L10N = True
USE_TZ = True
WEBAPP_DIR = os.path.join(BASE_DIR, 'webapp')
WEBAPP_STATIC_DIR = os.path.join(WEBAPP_DIR, 'public')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
WEBAPP_STATIC_DIR
]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':
'cointrol.server.api.pagination.CointrolPagination',
}
21 changes: 21 additions & 0 deletions cointrol/conf/settings_dev.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Cointrol development settings that extend the defaults ones.
"""
import os

from .settings_defaults import *


DEBUG = True
TEMPLATE_DEBUG = True
SECRET_KEY = 'asdf*&*hifdasfHKhljdsaf778'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'cointrol.sqlite3'),
}
}


COINTROL_DO_TRADE = False
42 changes: 42 additions & 0 deletions cointrol/conf/settings_prod.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
Cointrol production settings that extend the defaults ones.
"""
from .settings_defaults import *


DEBUG = False
TEMPLATE_DEBUG = False
LOGGING = {
'version': 1,
'disable_existing_loggers': False,

# Taken from django/utils/log.py:31
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
},
'handlers': {
'mail_admins': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},
'stdout': {
'class': 'logging.StreamHandler',
'level': 'DEBUG'
}
},

'loggers': {
'cointrol.trader': {
'handlers': ['stdout', 'mail_admins'],
'level': 'INFO',
'propagate': True,
}
}
}


COINTROL_DO_TRADE = True
4 changes: 4 additions & 0 deletions cointrol/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
Core modules used by both the server and the trader services.
"""
Loading

0 comments on commit 525f2c2

Please sign in to comment.