Merge branch 'master' of https://github.com/gcarq/freqtrade into develop

This commit is contained in:
gcarq 2017-09-08 16:27:00 +02:00
commit 1c5a811033
7 changed files with 44 additions and 22 deletions

1
.gitignore vendored
View File

@ -80,3 +80,4 @@ preprocessor.py
.env
.venv
.idea
.vscode

View File

@ -33,6 +33,9 @@ See the example below:
},
```
`stoploss` is loss in percentage that should trigger a sale.
For example value `-0.10` will cause immediate sell if the
profit dips below -10% for a given trade. This parameter is optional.
The other values should be self-explanatory,
if not feel free to raise a github issue.

View File

@ -8,6 +8,7 @@
"720": 0.01,
"0": 0.02
},
"stoploss": -0.10,
"poloniex": {
"enabled": false,
"key": "key",

44
main.py
View File

@ -118,6 +118,29 @@ def close_trade_if_fulfilled(trade: Trade) -> bool:
return False
def execute_sell(trade: Trade, current_rate: float) -> None:
"""
Executes a sell for the given trade and current rate
:param trade: Trade instance
:param current_rate: current rate
:return: None
"""
# Get available balance
currency = trade.pair.split('_')[1]
balance = exchange.get_balance(currency)
profit = trade.exec_sell_order(current_rate, balance)
message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format(
trade.exchange.name,
trade.pair.replace('_', '/'),
exchange.get_pair_detail_url(trade.pair),
trade.close_rate,
round(profit, 2)
)
logger.info(message)
telegram.send_msg(message)
def handle_trade(trade: Trade) -> None:
"""
Sells the current pair if the threshold is reached and updates the trade record.
@ -130,28 +153,19 @@ def handle_trade(trade: Trade) -> None:
logger.debug('Handling open trade %s ...', trade)
# Get current rate
current_rate = exchange.get_ticker(trade.pair)['bid']
current_profit = 100 * ((current_rate - trade.open_rate) / trade.open_rate)
current_profit = 100.0 * ((current_rate - trade.open_rate) / trade.open_rate)
# Get available balance
currency = trade.pair.split('_')[1]
balance = exchange.get_balance(currency)
if 'stoploss' in _conf and current_profit < float(_conf['stoploss']) * 100.0:
logger.debug('Stop loss hit.')
execute_sell(trade, current_rate)
return
for duration, threshold in sorted(_conf['minimal_roi'].items()):
duration, threshold = float(duration), float(threshold)
# Check if time matches and current rate is above threshold
time_diff = (datetime.utcnow() - trade.open_date).total_seconds() / 60
if time_diff > duration and current_rate > (1 + threshold) * trade.open_rate:
# Execute sell
profit = trade.exec_sell_order(current_rate, balance)
message = '*{}:* Selling [{}]({}) at rate `{:f} (profit: {}%)`'.format(
trade.exchange.name,
trade.pair.replace('_', '/'),
exchange.get_pair_detail_url(trade.pair),
trade.close_rate,
round(profit, 2)
)
logger.info(message)
telegram.send_msg(message)
execute_sell(trade, current_rate)
return
else:
logger.debug('Threshold not reached. (cur_profit: %1.2f%%)', current_profit)

View File

@ -3,9 +3,9 @@
conf_schema = {
'type': 'object',
'properties': {
'max_open_trades': {'type': 'integer'},
'stake_currency': {'type': 'string'},
'stake_amount': {'type': 'number'},
'max_open_trades': {'type': 'integer', 'minimum': 1},
'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT']},
'stake_amount': {'type': 'number', 'minimum': 0.0005},
'dry_run': {'type': 'boolean'},
'minimal_roi': {
'type': 'object',
@ -14,6 +14,7 @@ conf_schema = {
},
'minProperties': 1
},
'stoploss': {'type': 'number', 'maximum': 0, 'exclusiveMaximum': True},
'poloniex': {'$ref': '#/definitions/exchange'},
'bittrex': {'$ref': '#/definitions/exchange'},
'telegram': {

View File

@ -2,7 +2,9 @@ from datetime import datetime
from sqlalchemy import Boolean, Column, DateTime, Float, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.orm.scoping import scoped_session
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.types import Enum
import exchange
@ -33,7 +35,7 @@ def init(config: dict) -> None:
engine = create_engine(_db_handle, echo=False)
_session = scoped_session(sessionmaker(bind=engine, autoflush=True, autocommit=True))
Trade.session = _session
Trade.session = _session()
Trade.query = _session.query_property()
Base.metadata.create_all(engine)

View File

@ -151,7 +151,7 @@ def _profit(bot: Bot, update: Update) -> None:
profit_amounts.append((profit / 100) * trade.btc_amount)
profits.append(profit)
bp_pair, bp_rate = Trade.session.query(Trade.pair, func.sum(Trade.close_profit).label('profit_sum')) \
bp_pair, bp_rate = Trade.session().query(Trade.pair, func.sum(Trade.close_profit).label('profit_sum')) \
.filter(Trade.is_open.is_(False)) \
.group_by(Trade.pair) \
.order_by('profit_sum DESC') \
@ -272,7 +272,7 @@ def _performance(bot: Bot, update: Update) -> None:
send_msg('`trader is not running`', bot=bot)
return
pair_rates = Trade.session.query(Trade.pair, func.sum(Trade.close_profit).label('profit_sum')) \
pair_rates = Trade.session().query(Trade.pair, func.sum(Trade.close_profit).label('profit_sum')) \
.filter(Trade.is_open.is_(False)) \
.group_by(Trade.pair) \
.order_by('profit_sum DESC') \