Merge branch 'develop' into fix_dry_run_stop_price

This commit is contained in:
misagh 2018-11-30 10:37:58 +01:00
commit 8ff82e3dac
19 changed files with 277 additions and 160 deletions

View File

@ -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=

View File

@ -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 \

6
Dockerfile.technical Normal file
View File

@ -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

13
build_helpers/install_ta-lib.sh Executable file
View File

@ -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

57
build_helpers/publish_docker.sh Executable file
View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -157,7 +157,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:
"""

View File

@ -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:
"""
@ -478,7 +479,9 @@ class Exchange(object):
# Because some exchange sort Tickers ASC and other DESC.
# Ex: Bittrex returns a list of tickers ASC (oldest first, newest last)
# when GDAX returns a list of tickers DESC (newest first, oldest last)
data = sorted(data, key=lambda x: x[0])
# Only sort if necessary to save computing time
if data and data[0][0] > data[-1][0]:
data = sorted(data, key=lambda x: x[0])
# keeping last candle time as last refreshed time of the pair
if data:
@ -500,51 +503,6 @@ class Exchange(object):
except ccxt.BaseError as e:
raise OperationalException(f'Could not fetch ticker data. Msg: {e}')
@retrier
def get_candle_history(self, pair: str, tick_interval: str,
since_ms: Optional[int] = None) -> List[Dict]:
try:
# last item should be in the time interval [now - tick_interval, now]
till_time_ms = arrow.utcnow().shift(
minutes=-constants.TICKER_INTERVAL_MINUTES[tick_interval]
).timestamp * 1000
# it looks as if some exchanges return cached data
# and they update it one in several minute, so 10 mins interval
# is necessary to skeep downloading of an empty array when all
# chached data was already downloaded
till_time_ms = min(till_time_ms, arrow.utcnow().shift(minutes=-10).timestamp * 1000)
data: List[Dict[Any, Any]] = []
while not since_ms or since_ms < till_time_ms:
data_part = self._api.fetch_ohlcv(pair, timeframe=tick_interval, since=since_ms)
# Because some exchange sort Tickers ASC and other DESC.
# Ex: Bittrex returns a list of tickers ASC (oldest first, newest last)
# when GDAX returns a list of tickers DESC (newest first, oldest last)
data_part = sorted(data_part, key=lambda x: x[0])
if not data_part:
break
logger.debug('Downloaded data for %s time range [%s, %s]',
pair,
arrow.get(data_part[0][0] / 1000).format(),
arrow.get(data_part[-1][0] / 1000).format())
data.extend(data_part)
since_ms = data[-1][0] + 1
return data
except ccxt.NotSupported as e:
raise OperationalException(
f'Exchange {self._api.name} does not support fetching historical candlestick data.'
f'Message: {e}')
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
raise TemporaryError(
f'Could not load ticker history due to {e.__class__.__name__}. Message: {e}')
except ccxt.BaseError as e:
raise OperationalException(f'Could not fetch ticker data. Msg: {e}')
@retrier
def cancel_order(self, order_id: str, pair: str) -> None:
if self._conf['dry_run']:

View File

@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
def parse_ticker_dataframe(ticker: list) -> DataFrame:
"""
Analyses the trend for the given ticker history
:param ticker: See exchange.get_candle_history
:param ticker: ticker list, as returned by exchange.async_get_candle_history
:return: DataFrame
"""
cols = ['date', 'open', 'high', 'low', 'close', 'volume']

View File

@ -4,7 +4,6 @@ import logging
from datetime import datetime
from functools import reduce
from typing import Dict, Optional
from collections import namedtuple
from unittest.mock import MagicMock, PropertyMock
import arrow
@ -13,7 +12,7 @@ from telegram import Chat, Message, Update
from freqtrade.exchange.exchange_helpers import parse_ticker_dataframe
from freqtrade.exchange import Exchange
from freqtrade.edge import Edge
from freqtrade.edge import Edge, PairInfo
from freqtrade.freqtradebot import FreqtradeBot
logging.getLogger('').setLevel(logging.INFO)
@ -56,13 +55,11 @@ def patch_edge(mocker) -> None:
# "LTC/BTC",
# "XRP/BTC",
# "NEO/BTC"
pair_info = namedtuple(
'pair_info',
'stoploss, winrate, risk_reward_ratio, required_risk_reward, expectancy')
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
return_value={
'NEO/BTC': pair_info(-0.20, 0.66, 3.71, 0.50, 1.71),
'LTC/BTC': pair_info(-0.21, 0.66, 3.71, 0.50, 1.71),
'NEO/BTC': PairInfo(-0.20, 0.66, 3.71, 0.50, 1.71, 10, 25),
'LTC/BTC': PairInfo(-0.21, 0.66, 3.71, 0.50, 1.71, 11, 20),
}
))
mocker.patch('freqtrade.edge.Edge.stoploss', MagicMock(return_value=-0.20))

View File

@ -152,6 +152,18 @@ def test_stoploss(mocker, default_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

View File

@ -875,65 +875,10 @@ def make_fetch_ohlcv_mock(data):
return fetch_ohlcv_mock
def test_get_candle_history(default_conf, mocker):
api_mock = MagicMock()
tick = [
[
1511686200000, # unix timestamp ms
1, # open
2, # high
3, # low
4, # close
5, # volume (in quote currency)
]
]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# retrieve original ticker
ticks = exchange.get_candle_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1511686200000
assert ticks[0][1] == 1
assert ticks[0][2] == 2
assert ticks[0][3] == 3
assert ticks[0][4] == 4
assert ticks[0][5] == 5
# change ticker and ensure tick changes
new_tick = [
[
1511686210000, # unix timestamp ms
6, # open
7, # high
8, # low
9, # close
10, # volume (in quote currency)
]
]
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(new_tick))
exchange = get_patched_exchange(mocker, default_conf, api_mock)
ticks = exchange.get_candle_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1511686210000
assert ticks[0][1] == 6
assert ticks[0][2] == 7
assert ticks[0][3] == 8
assert ticks[0][4] == 9
assert ticks[0][5] == 10
ccxt_exceptionhandlers(mocker, default_conf, api_mock,
"get_candle_history", "fetch_ohlcv",
pair='ABCD/BTC', tick_interval=default_conf['ticker_interval'])
with pytest.raises(OperationalException, match=r'Exchange .* does not support.*'):
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NotSupported)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_candle_history(pair='ABCD/BTC', tick_interval=default_conf['ticker_interval'])
def test_get_candle_history_sort(default_conf, mocker):
api_mock = MagicMock()
@pytest.mark.asyncio
async def test___async_get_candle_history_sort(default_conf, mocker):
def sort_data(data, key):
return sorted(data, key=key)
# GDAX use-case (real data from GDAX)
# This ticker history is ordered DESC (newest first, oldest last)
@ -949,13 +894,15 @@ def test_get_candle_history_sort(default_conf, mocker):
[1527830700000, 0.07652, 0.07652, 0.07651, 0.07652, 10.04822687],
[1527830400000, 0.07649, 0.07651, 0.07649, 0.07651, 2.5734867]
]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange = get_patched_exchange(mocker, default_conf)
exchange._api_async.fetch_ohlcv = get_mock_coro(tick)
sort_mock = mocker.patch('freqtrade.exchange.sorted', MagicMock(side_effect=sort_data))
# Test the ticker history sort
ticks = exchange.get_candle_history('ETH/BTC', default_conf['ticker_interval'])
res = await exchange._async_get_candle_history('ETH/BTC', default_conf['ticker_interval'])
assert res[0] == 'ETH/BTC'
ticks = res[1]
assert sort_mock.call_count == 1
assert ticks[0][0] == 1527830400000
assert ticks[0][1] == 0.07649
assert ticks[0][2] == 0.07651
@ -984,11 +931,15 @@ def test_get_candle_history_sort(default_conf, mocker):
[1527830100000, 0.076695, 0.07671, 0.07624171, 0.07671, 1.80689244],
[1527830400000, 0.07671, 0.07674399, 0.07629216, 0.07655213, 2.31452783]
]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange._api_async.fetch_ohlcv = get_mock_coro(tick)
# Reset sort mock
sort_mock = mocker.patch('freqtrade.exchange.sorted', MagicMock(side_effect=sort_data))
# Test the ticker history sort
ticks = exchange.get_candle_history('ETH/BTC', default_conf['ticker_interval'])
res = await exchange._async_get_candle_history('ETH/BTC', default_conf['ticker_interval'])
assert res[0] == 'ETH/BTC'
ticks = res[1]
# Sorted not called again - data is already in order
assert sort_mock.call_count == 0
assert ticks[0][0] == 1527827700000
assert ticks[0][1] == 0.07659999
assert ticks[0][2] == 0.0766

View File

@ -292,7 +292,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, markets, caplog, mocker,
freqtrade = FreqtradeBot(edge_conf)
freqtrade.active_pair_whitelist = ['NEO/BTC']
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
trade = Trade.query.first()
trade.update(limit_buy_order)
@ -332,7 +332,7 @@ def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, markets,
freqtrade = FreqtradeBot(edge_conf)
freqtrade.active_pair_whitelist = ['NEO/BTC']
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
trade = Trade.query.first()
trade.update(limit_buy_order)
@ -1010,7 +1010,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade, value=(True, True))
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
@ -1066,7 +1066,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade, value=(True, False))
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: True
freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
freqtrade.create_trade()
@ -1099,7 +1099,7 @@ def test_handle_trade_experimental(
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
trade = Trade.query.first()
@ -1633,7 +1633,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order,
}
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
@ -1665,7 +1665,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order,
}
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
trade = Trade.query.first()
@ -1727,7 +1727,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, marke
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
@ -1757,7 +1757,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, markets, m
}
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: True
freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
freqtrade.create_trade()
@ -1789,7 +1789,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, markets, caplog,
default_conf['trailing_stop'] = True
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
@ -1824,7 +1824,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets
default_conf['trailing_stop_positive'] = 0.01
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
trade = Trade.query.first()
@ -1884,7 +1884,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
default_conf['trailing_stop_positive_offset'] = 0.011
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
freqtrade.create_trade()
trade = Trade.query.first()
@ -1943,7 +1943,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order,
}
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: True
freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
freqtrade.create_trade()

View File

@ -30,6 +30,7 @@ def test_sync_wallet_at_boot(mocker, default_conf):
assert freqtrade.wallets.wallets['GAS'].free == 0.260739
assert freqtrade.wallets.wallets['GAS'].used == 0.0
assert freqtrade.wallets.wallets['GAS'].total == 0.260739
assert freqtrade.wallets.get_free('BNT') == 1.0
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
@ -56,6 +57,7 @@ def test_sync_wallet_at_boot(mocker, default_conf):
assert freqtrade.wallets.wallets['GAS'].free == 0.270739
assert freqtrade.wallets.wallets['GAS'].used == 0.1
assert freqtrade.wallets.wallets['GAS'].total == 0.260439
assert freqtrade.wallets.get_free('GAS') == 0.270739
def test_sync_wallet_missing_data(mocker, default_conf):
@ -84,3 +86,4 @@ def test_sync_wallet_missing_data(mocker, default_conf):
assert freqtrade.wallets.wallets['GAS'].free == 0.260739
assert freqtrade.wallets.wallets['GAS'].used is None
assert freqtrade.wallets.wallets['GAS'].total == 0.260739
assert freqtrade.wallets.get_free('GAS') == 0.260739

View File

@ -35,8 +35,8 @@ class Wallets(object):
return 999.9
balance = self.wallets.get(currency)
if balance and balance['free']:
return balance['free']
if balance and balance.free:
return balance.free
else:
return 0

View File

@ -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

View File

@ -1,4 +1,4 @@
ccxt==1.17.536
ccxt==1.17.556
SQLAlchemy==1.2.14
python-telegram-bot==11.1.0
arrow==0.12.1