drafting first order refactoring phase
This commit is contained in:
parent
d71f631886
commit
52aefa8c34
67
freqtrade/execution/default_execution.py
Normal file
67
freqtrade/execution/default_execution.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from freqtrade.execution.interface import IExecution
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultExecution(IExecution):
|
||||||
|
|
||||||
|
def _get_target_bid(self, pair: str, ticker: Dict[str, float]) -> float:
|
||||||
|
"""
|
||||||
|
Calculates bid target between current ask price and last price
|
||||||
|
:param ticker: Ticker to use for getting Ask and Last Price
|
||||||
|
:return: float: Price
|
||||||
|
"""
|
||||||
|
if ticker['ask'] < ticker['last']:
|
||||||
|
ticker_rate = ticker['ask']
|
||||||
|
else:
|
||||||
|
balance = self.config['bid_strategy']['ask_last_balance']
|
||||||
|
ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
|
||||||
|
|
||||||
|
used_rate = ticker_rate
|
||||||
|
config_bid_strategy = self.config.get('bid_strategy', {})
|
||||||
|
if 'use_order_book' in config_bid_strategy and\
|
||||||
|
config_bid_strategy.get('use_order_book', False):
|
||||||
|
logger.info('Getting price from order book')
|
||||||
|
order_book_top = config_bid_strategy.get('order_book_top', 1)
|
||||||
|
order_book = self.exchange.get_order_book(pair, order_book_top)
|
||||||
|
logger.debug('order_book %s', order_book)
|
||||||
|
# top 1 = index 0
|
||||||
|
order_book_rate = order_book['bids'][order_book_top - 1][0]
|
||||||
|
# if ticker has lower rate, then use ticker ( usefull if down trending )
|
||||||
|
logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate)
|
||||||
|
if ticker_rate < order_book_rate:
|
||||||
|
logger.info('...using ticker rate instead %0.8f', ticker_rate)
|
||||||
|
used_rate = ticker_rate
|
||||||
|
else:
|
||||||
|
used_rate = order_book_rate
|
||||||
|
else:
|
||||||
|
logger.info('Using Last Ask / Last Price')
|
||||||
|
used_rate = ticker_rate
|
||||||
|
|
||||||
|
return used_rate
|
||||||
|
|
||||||
|
def execute_buy(self, pair: str, stake_amount: float, price: float) -> str:
|
||||||
|
pair_s = pair.replace('_', '/')
|
||||||
|
|
||||||
|
if price:
|
||||||
|
buy_limit = price
|
||||||
|
else:
|
||||||
|
# Calculate amount
|
||||||
|
buy_limit = self._get_target_bid(pair, self.exchange.get_ticker(pair))
|
||||||
|
|
||||||
|
min_stake_amount = self._get_min_pair_stake_amount(pair_s, buy_limit)
|
||||||
|
if min_stake_amount is not None and min_stake_amount > stake_amount:
|
||||||
|
logger.warning(
|
||||||
|
f'Can\'t open a new trade for {pair_s}: stake amount'
|
||||||
|
f' is too small ({stake_amount} < {min_stake_amount})'
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
amount = stake_amount / buy_limit
|
||||||
|
|
||||||
|
order_id = self.exchange.buy(pair, buy_limit, amount)['id']
|
||||||
|
return order_id or None
|
89
freqtrade/execution/interface.py
Normal file
89
freqtrade/execution/interface.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
"""
|
||||||
|
IExecute interface
|
||||||
|
This module defines the execution strategy
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from freqtrade.exchange import Exchange
|
||||||
|
|
||||||
|
|
||||||
|
class MarketOrder():
|
||||||
|
"""
|
||||||
|
Class encapsulating an order to be placed at the current market price.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, exchange=None):
|
||||||
|
self._exchange = exchange
|
||||||
|
|
||||||
|
def get_limit_price(self, _is_buy):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_stop_price(self, _is_buy):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class LimitOrder():
|
||||||
|
"""
|
||||||
|
Execution style representing an order to be executed at a price equal to or
|
||||||
|
better than a specified limit price.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, limit_price, asset=None, exchange=None):
|
||||||
|
"""
|
||||||
|
Store the given price.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.limit_price = limit_price
|
||||||
|
self._exchange = exchange
|
||||||
|
self.asset = asset
|
||||||
|
|
||||||
|
|
||||||
|
class StopOrder():
|
||||||
|
"""
|
||||||
|
Execution style representing an order to be placed once the market price
|
||||||
|
reaches a specified stop price.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, stop_price, asset=None, exchange=None):
|
||||||
|
"""
|
||||||
|
Store the given price.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.stop_price = stop_price
|
||||||
|
self._exchange = exchange
|
||||||
|
self.asset = asset
|
||||||
|
|
||||||
|
|
||||||
|
class StopLimitOrder():
|
||||||
|
"""
|
||||||
|
Execution style representing a limit order to be placed with a specified
|
||||||
|
limit price once the market reaches a specified stop price.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, limit_price, stop_price, asset=None, exchange=None):
|
||||||
|
"""
|
||||||
|
Store the given prices
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.limit_price = limit_price
|
||||||
|
self.stop_price = stop_price
|
||||||
|
self._exchange = exchange
|
||||||
|
self.asset = asset
|
||||||
|
|
||||||
|
|
||||||
|
class IExecution(ABC):
|
||||||
|
|
||||||
|
def __init__(self, config: dict, exchange: Exchange) -> None:
|
||||||
|
self.config = config
|
||||||
|
self.exchange = exchange
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def execute_buy(self, pair: str, stake_amount: float = None, price: float = None) -> str:
|
||||||
|
"""
|
||||||
|
Populate indicators that will be used in the Buy and Sell strategy
|
||||||
|
:param pair: pair to buy
|
||||||
|
:param stake_amount: Amount to buy (Optional)
|
||||||
|
:param price: Price at which the asset should be bought (Optional)
|
||||||
|
:return: Order id if execution was successful, otherwise None
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
Loading…
Reference in New Issue
Block a user