Update order_types to use entry/exit definition
This commit is contained in:
parent
1ce55e88b4
commit
e492bf3159
@ -51,11 +51,11 @@
|
|||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
"order_types": {
|
"order_types": {
|
||||||
"buy": "limit",
|
"entry": "limit",
|
||||||
"sell": "limit",
|
"exit": "limit",
|
||||||
"emergencysell": "market",
|
"emergencyexit": "market",
|
||||||
"forcesell": "market",
|
"forceexit": "market",
|
||||||
"forcebuy": "market",
|
"forceentry": "market",
|
||||||
"stoploss": "market",
|
"stoploss": "market",
|
||||||
"stoploss_on_exchange": false,
|
"stoploss_on_exchange": false,
|
||||||
"stoploss_on_exchange_interval": 60
|
"stoploss_on_exchange_interval": 60
|
||||||
|
@ -392,11 +392,11 @@ Syntax for Strategy:
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
order_types = {
|
order_types = {
|
||||||
"buy": "limit",
|
"entry": "limit",
|
||||||
"sell": "limit",
|
"exit": "limit",
|
||||||
"emergencysell": "market",
|
"emergencyexit": "market",
|
||||||
"forcebuy": "market",
|
"forceentry": "market",
|
||||||
"forcesell": "market",
|
"forceexit": "market",
|
||||||
"stoploss": "market",
|
"stoploss": "market",
|
||||||
"stoploss_on_exchange": False,
|
"stoploss_on_exchange": False,
|
||||||
"stoploss_on_exchange_interval": 60,
|
"stoploss_on_exchange_interval": 60,
|
||||||
|
@ -20,7 +20,7 @@ DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite'
|
|||||||
UNLIMITED_STAKE_AMOUNT = 'unlimited'
|
UNLIMITED_STAKE_AMOUNT = 'unlimited'
|
||||||
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
|
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
|
||||||
REQUIRED_ORDERTIF = ['entry', 'exit']
|
REQUIRED_ORDERTIF = ['entry', 'exit']
|
||||||
REQUIRED_ORDERTYPES = ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']
|
REQUIRED_ORDERTYPES = ['entry', 'exit', 'stoploss', 'stoploss_on_exchange']
|
||||||
ORDERBOOK_SIDES = ['ask', 'bid']
|
ORDERBOOK_SIDES = ['ask', 'bid']
|
||||||
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
|
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
|
||||||
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
|
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
|
||||||
@ -214,11 +214,11 @@ CONF_SCHEMA = {
|
|||||||
'order_types': {
|
'order_types': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'buy': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
'entry': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
||||||
'sell': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
'exit': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
||||||
'forcesell': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
'forceexit': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
||||||
'forcebuy': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
'forceentry': {'type': 'string', 'enum': ORDERTYPE_POSSIBILITIES},
|
||||||
'emergencysell': {
|
'emergencyexit': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
'enum': ORDERTYPE_POSSIBILITIES,
|
'enum': ORDERTYPE_POSSIBILITIES,
|
||||||
'default': 'market'},
|
'default': 'market'},
|
||||||
@ -228,7 +228,7 @@ CONF_SCHEMA = {
|
|||||||
'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0,
|
'stoploss_on_exchange_limit_ratio': {'type': 'number', 'minimum': 0.0,
|
||||||
'maximum': 1.0}
|
'maximum': 1.0}
|
||||||
},
|
},
|
||||||
'required': ['buy', 'sell', 'stoploss', 'stoploss_on_exchange']
|
'required': ['entry', 'exit', 'stoploss', 'stoploss_on_exchange']
|
||||||
},
|
},
|
||||||
'order_time_in_force': {
|
'order_time_in_force': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
|
@ -630,7 +630,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
f"{stake_amount} ...")
|
f"{stake_amount} ...")
|
||||||
|
|
||||||
amount = (stake_amount / enter_limit_requested) * leverage
|
amount = (stake_amount / enter_limit_requested) * leverage
|
||||||
order_type = ordertype or self.strategy.order_types['buy']
|
order_type = ordertype or self.strategy.order_types['entry']
|
||||||
|
|
||||||
if not pos_adjust and not strategy_safe_wrapper(
|
if not pos_adjust and not strategy_safe_wrapper(
|
||||||
self.strategy.confirm_trade_entry, default_retval=True)(
|
self.strategy.confirm_trade_entry, default_retval=True)(
|
||||||
@ -1247,11 +1247,11 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
self.update_trade_state(trade, trade.open_order_id, corder)
|
self.update_trade_state(trade, trade.open_order_id, corder)
|
||||||
|
|
||||||
trade.open_order_id = None
|
trade.open_order_id = None
|
||||||
logger.info('Partial %s order timeout for %s.', trade.enter_side, trade)
|
logger.info(f'Partial {trade.enter_side} order timeout for {trade}.')
|
||||||
reason += f", {constants.CANCEL_REASON['PARTIALLY_FILLED']}"
|
reason += f", {constants.CANCEL_REASON['PARTIALLY_FILLED']}"
|
||||||
|
|
||||||
self.wallets.update()
|
self.wallets.update()
|
||||||
self._notify_enter_cancel(trade, order_type=self.strategy.order_types[trade.enter_side],
|
self._notify_enter_cancel(trade, order_type=self.strategy.order_types['entry'],
|
||||||
reason=reason)
|
reason=reason)
|
||||||
return was_trade_fully_canceled
|
return was_trade_fully_canceled
|
||||||
|
|
||||||
@ -1296,7 +1296,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
self.wallets.update()
|
self.wallets.update()
|
||||||
self._notify_exit_cancel(
|
self._notify_exit_cancel(
|
||||||
trade,
|
trade,
|
||||||
order_type=self.strategy.order_types[trade.exit_side],
|
order_type=self.strategy.order_types['exit'],
|
||||||
reason=reason
|
reason=reason
|
||||||
)
|
)
|
||||||
return cancelled
|
return cancelled
|
||||||
@ -1376,10 +1376,10 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
# First cancelling stoploss on exchange ...
|
# First cancelling stoploss on exchange ...
|
||||||
trade = self.cancel_stoploss_on_exchange(trade)
|
trade = self.cancel_stoploss_on_exchange(trade)
|
||||||
|
|
||||||
order_type = ordertype or self.strategy.order_types[exit_type]
|
order_type = ordertype or self.strategy.order_types['exit']
|
||||||
if sell_reason.sell_type == SellType.EMERGENCY_SELL:
|
if sell_reason.sell_type == SellType.EMERGENCY_SELL:
|
||||||
# Emergency sells (default to market!)
|
# Emergency sells (default to market!)
|
||||||
order_type = self.strategy.order_types.get("emergencysell", "market")
|
order_type = self.strategy.order_types.get("emergencyexit", "market")
|
||||||
|
|
||||||
amount = self._safe_exit_amount(trade.pair, trade.amount)
|
amount = self._safe_exit_amount(trade.pair, trade.amount)
|
||||||
time_in_force = self.strategy.order_time_in_force['exit']
|
time_in_force = self.strategy.order_time_in_force['exit']
|
||||||
|
@ -491,7 +491,7 @@ class Backtesting:
|
|||||||
return None
|
return None
|
||||||
# call the custom exit price,with default value as previous closerate
|
# call the custom exit price,with default value as previous closerate
|
||||||
current_profit = trade.calc_profit_ratio(closerate)
|
current_profit = trade.calc_profit_ratio(closerate)
|
||||||
order_type = self.strategy.order_types['sell']
|
order_type = self.strategy.order_types['exit']
|
||||||
if sell.sell_type in (SellType.SELL_SIGNAL, SellType.CUSTOM_SELL):
|
if sell.sell_type in (SellType.SELL_SIGNAL, SellType.CUSTOM_SELL):
|
||||||
# Custom exit pricing only for sell-signals
|
# Custom exit pricing only for sell-signals
|
||||||
if order_type == 'limit':
|
if order_type == 'limit':
|
||||||
@ -599,7 +599,7 @@ class Backtesting:
|
|||||||
current_time = row[DATE_IDX].to_pydatetime()
|
current_time = row[DATE_IDX].to_pydatetime()
|
||||||
entry_tag = row[ENTER_TAG_IDX] if len(row) >= ENTER_TAG_IDX + 1 else None
|
entry_tag = row[ENTER_TAG_IDX] if len(row) >= ENTER_TAG_IDX + 1 else None
|
||||||
# let's call the custom entry price, using the open price as default price
|
# let's call the custom entry price, using the open price as default price
|
||||||
order_type = self.strategy.order_types['buy']
|
order_type = self.strategy.order_types['entry']
|
||||||
propose_rate = row[OPEN_IDX]
|
propose_rate = row[OPEN_IDX]
|
||||||
if order_type == 'limit':
|
if order_type == 'limit':
|
||||||
propose_rate = strategy_safe_wrapper(self.strategy.custom_entry_price,
|
propose_rate = strategy_safe_wrapper(self.strategy.custom_entry_price,
|
||||||
@ -639,7 +639,7 @@ class Backtesting:
|
|||||||
# In case of pos adjust, still return the original trade
|
# In case of pos adjust, still return the original trade
|
||||||
# If not pos adjust, trade is None
|
# If not pos adjust, trade is None
|
||||||
return trade
|
return trade
|
||||||
order_type = self.strategy.order_types['buy']
|
order_type = self.strategy.order_types['entry']
|
||||||
time_in_force = self.strategy.order_time_in_force['entry']
|
time_in_force = self.strategy.order_time_in_force['entry']
|
||||||
|
|
||||||
if not pos_adjust:
|
if not pos_adjust:
|
||||||
|
@ -138,11 +138,11 @@ class UnfilledTimeout(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class OrderTypes(BaseModel):
|
class OrderTypes(BaseModel):
|
||||||
buy: OrderTypeValues
|
entry: OrderTypeValues
|
||||||
sell: OrderTypeValues
|
exit: OrderTypeValues
|
||||||
emergencysell: Optional[OrderTypeValues]
|
emergencyexit: Optional[OrderTypeValues]
|
||||||
forcesell: Optional[OrderTypeValues]
|
forceexit: Optional[OrderTypeValues]
|
||||||
forcebuy: Optional[OrderTypeValues]
|
forceentry: Optional[OrderTypeValues]
|
||||||
stoploss: OrderTypeValues
|
stoploss: OrderTypeValues
|
||||||
stoploss_on_exchange: bool
|
stoploss_on_exchange: bool
|
||||||
stoploss_on_exchange_interval: Optional[int]
|
stoploss_on_exchange_interval: Optional[int]
|
||||||
|
@ -708,7 +708,7 @@ class RPC:
|
|||||||
trade.pair, refresh=False, side=trade.exit_side)
|
trade.pair, refresh=False, side=trade.exit_side)
|
||||||
sell_reason = SellCheckTuple(sell_type=SellType.FORCE_SELL)
|
sell_reason = SellCheckTuple(sell_type=SellType.FORCE_SELL)
|
||||||
order_type = ordertype or self._freqtrade.strategy.order_types.get(
|
order_type = ordertype or self._freqtrade.strategy.order_types.get(
|
||||||
"forcesell", self._freqtrade.strategy.order_types["sell"])
|
"forceexit", self._freqtrade.strategy.order_types["exit"])
|
||||||
|
|
||||||
self._freqtrade.execute_trade_exit(
|
self._freqtrade.execute_trade_exit(
|
||||||
trade, current_rate, sell_reason, ordertype=order_type)
|
trade, current_rate, sell_reason, ordertype=order_type)
|
||||||
@ -731,7 +731,7 @@ class RPC:
|
|||||||
trade_filter=[Trade.id == trade_id, Trade.is_open.is_(True), ]
|
trade_filter=[Trade.id == trade_id, Trade.is_open.is_(True), ]
|
||||||
).first()
|
).first()
|
||||||
if not trade:
|
if not trade:
|
||||||
logger.warning('forcesell: Invalid argument received')
|
logger.warning('forceexit: Invalid argument received')
|
||||||
raise RPCException('invalid argument')
|
raise RPCException('invalid argument')
|
||||||
|
|
||||||
_exec_forcesell(trade)
|
_exec_forcesell(trade)
|
||||||
@ -780,7 +780,7 @@ class RPC:
|
|||||||
# execute buy
|
# execute buy
|
||||||
if not order_type:
|
if not order_type:
|
||||||
order_type = self._freqtrade.strategy.order_types.get(
|
order_type = self._freqtrade.strategy.order_types.get(
|
||||||
'forcebuy', self._freqtrade.strategy.order_types['buy'])
|
'forceentry', self._freqtrade.strategy.order_types['entry'])
|
||||||
if self._freqtrade.execute_entry(pair, stake_amount, price,
|
if self._freqtrade.execute_entry(pair, stake_amount, price,
|
||||||
ordertype=order_type, trade=trade,
|
ordertype=order_type, trade=trade,
|
||||||
is_short=is_short,
|
is_short=is_short,
|
||||||
|
@ -944,7 +944,7 @@ class Telegram(RPCHandler):
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
msg = self._rpc._rpc_forceexit(trade_id)
|
msg = self._rpc._rpc_forceexit(trade_id)
|
||||||
self._send_msg('Forcesell Result: `{result}`'.format(**msg))
|
self._send_msg('Forceexit Result: `{result}`'.format(**msg))
|
||||||
|
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
self._send_msg(str(e))
|
self._send_msg(str(e))
|
||||||
|
@ -87,8 +87,8 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
|
|
||||||
# Optional order types
|
# Optional order types
|
||||||
order_types: Dict = {
|
order_types: Dict = {
|
||||||
'buy': 'limit',
|
'entry': 'limit',
|
||||||
'sell': 'limit',
|
'exit': 'limit',
|
||||||
'stoploss': 'limit',
|
'stoploss': 'limit',
|
||||||
'stoploss_on_exchange': False,
|
'stoploss_on_exchange': False,
|
||||||
'stoploss_on_exchange_interval': 60,
|
'stoploss_on_exchange_interval': 60,
|
||||||
|
@ -76,8 +76,8 @@ class SampleShortStrategy(IStrategy):
|
|||||||
|
|
||||||
# Optional order type mapping.
|
# Optional order type mapping.
|
||||||
order_types = {
|
order_types = {
|
||||||
'buy': 'limit',
|
'entry': 'limit',
|
||||||
'sell': 'limit',
|
'exit': 'limit',
|
||||||
'stoploss': 'market',
|
'stoploss': 'market',
|
||||||
'stoploss_on_exchange': False
|
'stoploss_on_exchange': False
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,8 @@ class SampleStrategy(IStrategy):
|
|||||||
|
|
||||||
# Optional order type mapping.
|
# Optional order type mapping.
|
||||||
order_types = {
|
order_types = {
|
||||||
'buy': 'limit',
|
'entry': 'limit',
|
||||||
'sell': 'limit',
|
'exit': 'limit',
|
||||||
'stoploss': 'market',
|
'stoploss': 'market',
|
||||||
'stoploss_on_exchange': False
|
'stoploss_on_exchange': False
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user