Merge branch 'develop' into feat/short
This commit is contained in:
@@ -33,6 +33,9 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac
|
||||
if settings[setting] is not None:
|
||||
btconfig[setting] = settings[setting]
|
||||
|
||||
# Force dry-run for backtesting
|
||||
btconfig['dry_run'] = True
|
||||
|
||||
# Start backtesting
|
||||
# Initialize backtesting object
|
||||
def run_backtest():
|
||||
|
@@ -162,7 +162,7 @@ class ShowConfig(BaseModel):
|
||||
trailing_stop_positive_offset: Optional[float]
|
||||
trailing_only_offset_is_reached: Optional[bool]
|
||||
unfilledtimeout: UnfilledTimeout
|
||||
order_types: OrderTypes
|
||||
order_types: Optional[OrderTypes]
|
||||
use_custom_stoploss: Optional[bool]
|
||||
timeframe: Optional[str]
|
||||
timeframe_ms: int
|
||||
|
@@ -3,7 +3,7 @@ from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from fastapi.exceptions import HTTPException
|
||||
|
||||
from freqtrade import __version__
|
||||
@@ -31,7 +31,8 @@ logger = logging.getLogger(__name__)
|
||||
# Pre-1.1, no version was provided
|
||||
# Version increments should happen in "small" steps (1.1, 1.12, ...) unless big changes happen.
|
||||
# 1.11: forcebuy and forcesell accept ordertype
|
||||
API_VERSION = 1.11
|
||||
# 1.12: add blacklist delete endpoint
|
||||
API_VERSION = 1.12
|
||||
|
||||
# Public API, requires no auth.
|
||||
router_public = APIRouter()
|
||||
@@ -158,6 +159,13 @@ def blacklist_post(payload: BlacklistPayload, rpc: RPC = Depends(get_rpc)):
|
||||
return rpc._rpc_blacklist(payload.blacklist)
|
||||
|
||||
|
||||
@router.delete('/blacklist', response_model=BlacklistResponse, tags=['info', 'pairlist'])
|
||||
def blacklist_delete(pairs_to_delete: List[str] = Query([]), rpc: RPC = Depends(get_rpc)):
|
||||
"""Provide a list of pairs to delete from the blacklist"""
|
||||
|
||||
return rpc._rpc_blacklist_delete(pairs_to_delete)
|
||||
|
||||
|
||||
@router.get('/whitelist', response_model=WhitelistResponse, tags=['info', 'pairlist'])
|
||||
def whitelist(rpc: RPC = Depends(get_rpc)):
|
||||
return rpc._rpc_whitelist()
|
||||
|
@@ -47,7 +47,7 @@ class UvicornServer(uvicorn.Server):
|
||||
else:
|
||||
asyncio.set_event_loop(uvloop.new_event_loop())
|
||||
try:
|
||||
loop = asyncio.get_event_loop()
|
||||
loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
# When running in a thread, we'll not have an eventloop yet.
|
||||
loop = asyncio.new_event_loop()
|
||||
|
@@ -7,7 +7,7 @@ import datetime
|
||||
import logging
|
||||
from typing import Dict, List
|
||||
|
||||
from cachetools.ttl import TTLCache
|
||||
from cachetools import TTLCache
|
||||
from pycoingecko import CoinGeckoAPI
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
|
@@ -863,6 +863,20 @@ class RPC:
|
||||
}
|
||||
return res
|
||||
|
||||
def _rpc_blacklist_delete(self, delete: List[str]) -> Dict:
|
||||
""" Removes pairs from currently active blacklist """
|
||||
errors = {}
|
||||
for pair in delete:
|
||||
if pair in self._freqtrade.pairlists.blacklist:
|
||||
self._freqtrade.pairlists.blacklist.remove(pair)
|
||||
else:
|
||||
errors[pair] = {
|
||||
'error_msg': f"Pair {pair} is not in the current blacklist."
|
||||
}
|
||||
resp = self._rpc_blacklist()
|
||||
resp['errors'] = errors
|
||||
return resp
|
||||
|
||||
def _rpc_blacklist(self, add: List[str] = None) -> Dict:
|
||||
""" Returns the currently active blacklist"""
|
||||
errors = {}
|
||||
|
@@ -60,6 +60,10 @@ class RPCManager:
|
||||
}
|
||||
"""
|
||||
logger.info('Sending rpc message: %s', msg)
|
||||
if 'pair' in msg:
|
||||
msg.update({
|
||||
'base_currency': self._rpc._freqtrade.exchange.get_pair_base_currency(msg['pair'])
|
||||
})
|
||||
for mod in self.registered_modules:
|
||||
logger.debug('Forwarding message to rpc.%s', mod.name)
|
||||
try:
|
||||
|
@@ -111,9 +111,9 @@ class Telegram(RPCHandler):
|
||||
r'/daily$', r'/daily \d+$', r'/profit$', r'/profit \d+',
|
||||
r'/stats$', r'/count$', r'/locks$', r'/balance$',
|
||||
r'/stopbuy$', r'/reload_config$', r'/show_config$',
|
||||
r'/logs$', r'/whitelist$', r'/blacklist$', r'/edge$',
|
||||
r'/logs$', r'/whitelist$', r'/blacklist$', r'/bl_delete$',
|
||||
r'/weekly$', r'/weekly \d+$', r'/monthly$', r'/monthly \d+$',
|
||||
r'/forcebuy$', r'/help$', r'/version$']
|
||||
r'/forcebuy$', r'/edge$', r'/help$', r'/version$']
|
||||
# Create keys for generation
|
||||
valid_keys_print = [k.replace('$', '') for k in valid_keys]
|
||||
|
||||
@@ -170,6 +170,7 @@ class Telegram(RPCHandler):
|
||||
CommandHandler('stopbuy', self._stopbuy),
|
||||
CommandHandler('whitelist', self._whitelist),
|
||||
CommandHandler('blacklist', self._blacklist),
|
||||
CommandHandler(['blacklist_delete', 'bl_delete'], self._blacklist_delete),
|
||||
CommandHandler('logs', self._logs),
|
||||
CommandHandler('edge', self._edge),
|
||||
CommandHandler('help', self._help),
|
||||
@@ -199,8 +200,8 @@ class Telegram(RPCHandler):
|
||||
|
||||
self._updater.start_polling(
|
||||
bootstrap_retries=-1,
|
||||
timeout=30,
|
||||
read_latency=60,
|
||||
timeout=20,
|
||||
read_latency=60, # Assumed transmission latency
|
||||
drop_pending_updates=True,
|
||||
)
|
||||
logger.info(
|
||||
@@ -213,6 +214,7 @@ class Telegram(RPCHandler):
|
||||
Stops all running telegram threads.
|
||||
:return: None
|
||||
"""
|
||||
# This can take up to `timeout` from the call to `start_polling`.
|
||||
self._updater.stop()
|
||||
|
||||
def _format_buy_msg(self, msg: Dict[str, Any]) -> str:
|
||||
@@ -1178,22 +1180,28 @@ class Telegram(RPCHandler):
|
||||
Handler for /blacklist
|
||||
Shows the currently active blacklist
|
||||
"""
|
||||
try:
|
||||
self.send_blacklist_msg(self._rpc._rpc_blacklist(context.args))
|
||||
|
||||
blacklist = self._rpc._rpc_blacklist(context.args)
|
||||
errmsgs = []
|
||||
for pair, error in blacklist['errors'].items():
|
||||
errmsgs.append(f"Error adding `{pair}` to blacklist: `{error['error_msg']}`")
|
||||
if errmsgs:
|
||||
self._send_msg('\n'.join(errmsgs))
|
||||
def send_blacklist_msg(self, blacklist: Dict):
|
||||
errmsgs = []
|
||||
for pair, error in blacklist['errors'].items():
|
||||
errmsgs.append(f"Error adding `{pair}` to blacklist: `{error['error_msg']}`")
|
||||
if errmsgs:
|
||||
self._send_msg('\n'.join(errmsgs))
|
||||
|
||||
message = f"Blacklist contains {blacklist['length']} pairs\n"
|
||||
message += f"`{', '.join(blacklist['blacklist'])}`"
|
||||
message = f"Blacklist contains {blacklist['length']} pairs\n"
|
||||
message += f"`{', '.join(blacklist['blacklist'])}`"
|
||||
|
||||
logger.debug(message)
|
||||
self._send_msg(message)
|
||||
except RPCException as e:
|
||||
self._send_msg(str(e))
|
||||
logger.debug(message)
|
||||
self._send_msg(message)
|
||||
|
||||
@authorized_only
|
||||
def _blacklist_delete(self, update: Update, context: CallbackContext) -> None:
|
||||
"""
|
||||
Handler for /bl_delete
|
||||
Deletes pair(s) from current blacklist
|
||||
"""
|
||||
self.send_blacklist_msg(self._rpc._rpc_blacklist_delete(context.args or []))
|
||||
|
||||
@authorized_only
|
||||
def _logs(self, update: Update, context: CallbackContext) -> None:
|
||||
@@ -1274,6 +1282,8 @@ class Telegram(RPCHandler):
|
||||
"*/whitelist:* `Show current whitelist` \n"
|
||||
"*/blacklist [pair]:* `Show current blacklist, or adds one or more pairs "
|
||||
"to the blacklist.` \n"
|
||||
"*/blacklist_delete [pairs]| /bl_delete [pairs]:* "
|
||||
"`Delete pair / pattern from blacklist. Will reset on reload_conf.` \n"
|
||||
"*/reload_config:* `Reload configuration file` \n"
|
||||
"*/unlock <pair|id>:* `Unlock this Pair (or this lock id if it's numeric)`\n"
|
||||
|
||||
|
Reference in New Issue
Block a user