diff --git a/.travis.yml b/.travis.yml index 981eedcf8..f1192e80c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,15 @@ sudo: true os: - linux +dist: trusty language: python python: - 3.6 +services: + - docker +env: + global: + - IMAGE_NAME=freqtradeorg/freqtrade addons: apt: packages: @@ -11,24 +17,38 @@ addons: - libdw-dev - binutils-dev install: -- ./install_ta-lib.sh +- ./build_helpers/install_ta-lib.sh - export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH - pip install --upgrade flake8 coveralls pytest-random-order pytest-asyncio mypy - pip install -r requirements.txt - pip install -e . jobs: include: - - script: + - stage: tests + script: - pytest --cov=freqtrade --cov-config=.coveragerc freqtrade/tests/ - coveralls + name: pytest - script: - cp config.json.example config.json - python freqtrade/main.py --datadir freqtrade/tests/testdata backtesting + name: backtest - script: - cp config.json.example config.json - python freqtrade/main.py --datadir freqtrade/tests/testdata hyperopt -e 5 + name: hyperopt - script: flake8 freqtrade + name: flake8 - script: mypy freqtrade + name: mypy + + - stage: docker + if: branch in (master, develop, feat/improve_travis) AND (type in (push, cron)) + script: + - build_helpers/publish_docker.sh + name: "Build and test and push docker image" + + notifications: slack: secure: bKLXmOrx8e2aPZl7W8DA5BdPAXWGpI5UzST33oc1G/thegXcDVmHBTJrBs4sZak6bgAclQQrdZIsRd2eFYzHLalJEaw6pk7hoAw8SvLnZO0ZurWboz7qg2+aZZXfK4eKl/VUe4sM9M4e/qxjkK+yWG7Marg69c4v1ypF7ezUi1fPYILYw8u0paaiX0N5UX8XNlXy+PBlga2MxDjUY70MuajSZhPsY2pDUvYnMY1D/7XN3cFW0g+3O8zXjF0IF4q1Z/1ASQe+eYjKwPQacE+O8KDD+ZJYoTOFBAPllrtpO1jnOPFjNGf3JIbVMZw4bFjIL0mSQaiSUaUErbU3sFZ5Or79rF93XZ81V7uEZ55vD8KMfR2CB1cQJcZcj0v50BxLo0InkFqa0Y8Nra3sbpV4fV5Oe8pDmomPJrNFJnX6ULQhQ1gTCe0M5beKgVms5SITEpt4/Y0CmLUr6iHDT0CUiyMIRWAXdIgbGh1jfaWOMksybeRevlgDsIsNBjXmYI1Sw2ZZR2Eo2u4R6zyfyjOMLwYJ3vgq9IrACv2w5nmf0+oguMWHf6iWi2hiOqhlAN1W74+3HsYQcqnuM3LGOmuCnPprV1oGBqkPXjIFGpy21gNx4vHfO1noLUyJnMnlu2L7SSuN1CdLsnjJ1hVjpJjPfqB4nn8g12x87TqM1bOm+3Q= diff --git a/Dockerfile b/Dockerfile index 2506665ab..24cce0049 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,20 @@ FROM python:3.7.0-slim-stretch -# Install TA-lib -RUN apt-get update && apt-get -y install curl build-essential && apt-get clean -RUN curl -L http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz | \ - tar xzvf - && \ - cd ta-lib && \ - sed -i "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h && \ - ./configure && make && make install && \ - cd .. && rm -rf ta-lib -ENV LD_LIBRARY_PATH /usr/local/lib +RUN apt-get update \ + && apt-get -y install curl build-essential \ + && apt-get clean \ + && pip install --upgrade pip # Prepare environment RUN mkdir /freqtrade WORKDIR /freqtrade +# Install TA-lib +COPY build_helpers/* /tmp/ +RUN cd /tmp && /tmp/install_ta-lib.sh && rm -r /tmp/*ta-lib* + +ENV LD_LIBRARY_PATH /usr/local/lib + # Install dependencies COPY requirements.txt /freqtrade/ RUN pip install numpy --no-cache-dir \ diff --git a/Dockerfile.technical b/Dockerfile.technical new file mode 100644 index 000000000..5339eb232 --- /dev/null +++ b/Dockerfile.technical @@ -0,0 +1,6 @@ +FROM freqtradeorg/freqtrade:develop + +RUN apt-get update \ + && apt-get -y install git \ + && apt-get clean \ + && pip install git+https://github.com/berlinguyinca/technical diff --git a/build_helpers/install_ta-lib.sh b/build_helpers/install_ta-lib.sh new file mode 100755 index 000000000..4d4f37c17 --- /dev/null +++ b/build_helpers/install_ta-lib.sh @@ -0,0 +1,13 @@ +if [ ! -f "ta-lib/CHANGELOG.TXT" ]; then + tar zxvf ta-lib-0.4.0-src.tar.gz + cd ta-lib \ + && sed -i.bak "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h \ + && ./configure \ + && make \ + && which sudo && sudo make install || make install \ + && cd .. +else + echo "TA-lib already installed, skipping download and build." + cd ta-lib && sudo make install && cd .. + +fi diff --git a/build_helpers/publish_docker.sh b/build_helpers/publish_docker.sh new file mode 100755 index 000000000..c2b40ba81 --- /dev/null +++ b/build_helpers/publish_docker.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# - export TAG=`if [ "$TRAVIS_BRANCH" == "develop" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi` +# Replace / with _ to create a valid tag +TAG=$(echo "${TRAVIS_BRANCH}" | sed -e "s/\//_/") + + +if [ "${TRAVIS_EVENT_TYPE}" = "cron" ]; then + echo "event ${TRAVIS_EVENT_TYPE}: full rebuild - skipping cache" + docker build -t freqtrade:${TAG} . +else + echo "event ${TRAVIS_EVENT_TYPE}: building with cache" + # Pull last build to avoid rebuilding the whole image + docker pull ${REPO}:${TAG} + docker build --cache-from ${IMAGE_NAME}:${TAG} -t freqtrade:${TAG} . +fi + +if [ $? -ne 0 ]; then + echo "failed building image" + return 1 +fi + +# Run backtest +docker run --rm -it -v $(pwd)/config.json.example:/freqtrade/config.json:ro freqtrade:${TAG} --datadir freqtrade/tests/testdata backtesting + +if [ $? -ne 0 ]; then + echo "failed running backtest" + return 1 +fi + +# Tag image for upload +docker tag freqtrade:$TAG ${IMAGE_NAME}:$TAG +if [ $? -ne 0 ]; then + echo "failed tagging image" + return 1 +fi + +# Tag as latest for develop builds +if [ "${TRAVIS_BRANCH}" = "develop" ]; then + docker tag freqtrade:$TAG ${IMAGE_NAME}:latest +fi + +# Login +echo "$DOCKER_PASS" | docker login -u $DOCKER_USER --password-stdin + +if [ $? -ne 0 ]; then + echo "failed login" + return 1 +fi + +# Show all available images +docker images + +docker push ${IMAGE_NAME} +if [ $? -ne 0 ]; then + echo "failed pushing repo" + return 1 +fi diff --git a/ta-lib-0.4.0-src.tar.gz b/build_helpers/ta-lib-0.4.0-src.tar.gz similarity index 100% rename from ta-lib-0.4.0-src.tar.gz rename to build_helpers/ta-lib-0.4.0-src.tar.gz diff --git a/config_binance.json.example b/config_binance.json.example new file mode 100644 index 000000000..7773a8c39 --- /dev/null +++ b/config_binance.json.example @@ -0,0 +1,83 @@ +{ + "max_open_trades": 3, + "stake_currency": "BTC", + "stake_amount": 0.05, + "fiat_display_currency": "USD", + "ticker_interval" : "5m", + "dry_run": true, + "trailing_stop": false, + "unfilledtimeout": { + "buy": 10, + "sell": 30 + }, + "bid_strategy": { + "ask_last_balance": 0.0, + "use_order_book": false, + "order_book_top": 1, + "check_depth_of_market": { + "enabled": false, + "bids_to_ask_delta": 1 + } + }, + "ask_strategy":{ + "use_order_book": false, + "order_book_min": 1, + "order_book_max": 9 + }, + "exchange": { + "name": "binance", + "key": "your_exchange_key", + "secret": "your_exchange_secret", + "ccxt_config": {"enableRateLimit": true}, + "ccxt_async_config": { + "enableRateLimit": false + }, + "pair_whitelist": [ + "AST/BTC", + "ETC/BTC", + "ETH/BTC", + "EOS/BTC", + "IOTA/BTC", + "LTC/BTC", + "MTH/BTC", + "NCASH/BTC", + "TNT/BTC", + "XMR/BTC", + "XLM/BTC", + "XRP/BTC" + ], + "pair_blacklist": [ + "BNB/BTC" + ] + }, + "experimental": { + "use_sell_signal": false, + "sell_profit_only": false, + "ignore_roi_if_buy_signal": false + }, + "edge": { + "enabled": false, + "process_throttle_secs": 3600, + "calculate_since_number_of_days": 7, + "total_capital_in_stake_currency": 0.5, + "allowed_risk": 0.01, + "stoploss_range_min": -0.01, + "stoploss_range_max": -0.1, + "stoploss_range_step": -0.01, + "minimum_winrate": 0.60, + "minimum_expectancy": 0.20, + "min_trade_number": 10, + "max_trade_duration_minute": 1440, + "remove_pumps": false + }, + "telegram": { + "enabled": false, + "token": "your_telegram_token", + "chat_id": "your_telegram_chat_id" + }, + "initial_state": "running", + "forcebuy_enable": false, + "internals": { + "process_throttle_secs": 5 + } +} diff --git a/docs/installation.md b/docs/installation.md index d2002035e..18406e555 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -109,7 +109,25 @@ Dry-Run touch tradesv3.dryrun.sqlite ``` -### 2. Build the Docker image +### 2. Download or build the docker image + +Either use the prebuilt image from docker hub - or build the image yourself if you would like more control on which version is used. + +Branches / tags available can be checked out on [Dockerhub](https://hub.docker.com/r/freqtradeorg/freqtrade/tags/). + +#### 2.1. Download the docker image + +Pull the image from docker hub and (optionally) change the name of the image + +```bash +docker pull freqtradeorg/freqtrade:develop +# Optionally tag the repository so the run-commands remain shorter +docker tag freqtradeorg/freqtrade:develop freqtrade +``` + +To update the image, simply run the above commands again and restart your running container. + +#### 2.2. Build the Docker image ```bash cd freqtrade diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 74fabc409..4800691e8 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -181,7 +181,12 @@ class Edge(): return position_size def stoploss(self, pair: str) -> float: - return self._cached_pairs[pair].stoploss + if pair in self._cached_pairs: + return self._cached_pairs[pair].stoploss + else: + logger.warning('tried to access stoploss of a non-existing pair, ' + 'strategy stoploss is returned instead.') + return self.strategy.stoploss def adjust(self, pairs) -> list: """ diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 350c730a4..4573e461c 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -207,7 +207,8 @@ class Exchange(object): f'Pair {pair} not compatible with stake_currency: {stake_cur}') if self.markets and pair not in self.markets: raise OperationalException( - f'Pair {pair} is not available at {self.name}') + f'Pair {pair} is not available at {self.name}' + f'Please remove {pair} from your whitelist.') def validate_timeframes(self, timeframe: List[str]) -> None: """ diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 90f100eac..66e32ec4b 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -653,7 +653,7 @@ class FreqtradeBot(object): return True break else: - logger.info('checking sell') + logger.debug('checking sell') if self.check_sell(trade, sell_rate, buy, sell): return True diff --git a/freqtrade/tests/edge/test_edge.py b/freqtrade/tests/edge/test_edge.py index 40bb35209..d5457f342 100644 --- a/freqtrade/tests/edge/test_edge.py +++ b/freqtrade/tests/edge/test_edge.py @@ -152,6 +152,18 @@ def test_stoploss(mocker, edge_conf): assert edge.stoploss('E/F') == -0.01 +def test_nonexisting_stoploss(mocker, default_conf): + freqtrade = get_patched_freqtradebot(mocker, default_conf) + edge = Edge(default_conf, freqtrade.exchange, freqtrade.strategy) + mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock( + return_value={ + 'E/F': PairInfo(-0.01, 0.66, 3.71, 0.50, 1.71, 10, 60), + } + )) + + assert edge.stoploss('N/O') == -0.1 + + def _validate_ohlc(buy_ohlc_sell_matrice): for index, ohlc in enumerate(buy_ohlc_sell_matrice): # if not high < open < low or not high < close < low diff --git a/install_ta-lib.sh b/install_ta-lib.sh deleted file mode 100755 index d8ae2eeaa..000000000 --- a/install_ta-lib.sh +++ /dev/null @@ -1,7 +0,0 @@ -if [ ! -f "ta-lib/CHANGELOG.TXT" ]; then - tar zxvf ta-lib-0.4.0-src.tar.gz - cd ta-lib && sed -i.bak "s|0.00000001|0.000000000000000001 |g" src/ta_func/ta_utility.h && ./configure && make && sudo make install && cd .. -else - echo "TA-lib already installed, skipping download and build." - cd ta-lib && sudo make install && cd .. -fi diff --git a/requirements.txt b/requirements.txt index 6f969be06..f7db2ea09 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -ccxt==1.17.539 +ccxt==1.17.563 SQLAlchemy==1.2.14 python-telegram-bot==11.1.0 arrow==0.12.1