Merge branch 'freqtrade:develop' into strategy_utils
This commit is contained in:
@@ -20,8 +20,8 @@ from freqtrade.persistence import LocalTrade, Trade, init_db
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Newest format
|
||||
BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date',
|
||||
'open_rate', 'close_rate',
|
||||
BT_DATA_COLUMNS = ['pair', 'stake_amount', 'max_stake_amount', 'amount',
|
||||
'open_date', 'close_date', 'open_rate', 'close_rate',
|
||||
'fee_open', 'fee_close', 'trade_duration',
|
||||
'profit_ratio', 'profit_abs', 'exit_reason',
|
||||
'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs',
|
||||
@@ -241,6 +241,33 @@ def find_existing_backtest_stats(dirname: Union[Path, str], run_ids: Dict[str, s
|
||||
return results
|
||||
|
||||
|
||||
def _load_backtest_data_df_compatibility(df: pd.DataFrame) -> pd.DataFrame:
|
||||
"""
|
||||
Compatibility support for older backtest data.
|
||||
"""
|
||||
df['open_date'] = pd.to_datetime(df['open_date'],
|
||||
utc=True,
|
||||
infer_datetime_format=True
|
||||
)
|
||||
df['close_date'] = pd.to_datetime(df['close_date'],
|
||||
utc=True,
|
||||
infer_datetime_format=True
|
||||
)
|
||||
# Compatibility support for pre short Columns
|
||||
if 'is_short' not in df.columns:
|
||||
df['is_short'] = False
|
||||
if 'leverage' not in df.columns:
|
||||
df['leverage'] = 1.0
|
||||
if 'enter_tag' not in df.columns:
|
||||
df['enter_tag'] = df['buy_tag']
|
||||
df = df.drop(['buy_tag'], axis=1)
|
||||
if 'max_stake_amount' not in df.columns:
|
||||
df['max_stake_amount'] = df['stake_amount']
|
||||
if 'orders' not in df.columns:
|
||||
df['orders'] = None
|
||||
return df
|
||||
|
||||
|
||||
def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = None) -> pd.DataFrame:
|
||||
"""
|
||||
Load backtest data file.
|
||||
@@ -269,24 +296,7 @@ def load_backtest_data(filename: Union[Path, str], strategy: Optional[str] = Non
|
||||
data = data['strategy'][strategy]['trades']
|
||||
df = pd.DataFrame(data)
|
||||
if not df.empty:
|
||||
df['open_date'] = pd.to_datetime(df['open_date'],
|
||||
utc=True,
|
||||
infer_datetime_format=True
|
||||
)
|
||||
df['close_date'] = pd.to_datetime(df['close_date'],
|
||||
utc=True,
|
||||
infer_datetime_format=True
|
||||
)
|
||||
# Compatibility support for pre short Columns
|
||||
if 'is_short' not in df.columns:
|
||||
df['is_short'] = 0
|
||||
if 'leverage' not in df.columns:
|
||||
df['leverage'] = 1.0
|
||||
if 'enter_tag' not in df.columns:
|
||||
df['enter_tag'] = df['buy_tag']
|
||||
df = df.drop(['buy_tag'], axis=1)
|
||||
if 'orders' not in df.columns:
|
||||
df['orders'] = None
|
||||
df = _load_backtest_data_df_compatibility(df)
|
||||
|
||||
else:
|
||||
# old format - only with lists.
|
||||
|
@@ -31,7 +31,7 @@ class Binance(Exchange):
|
||||
"ccxt_futures_name": "future"
|
||||
}
|
||||
_ft_has_futures: Dict = {
|
||||
"stoploss_order_types": {"limit": "limit", "market": "market"},
|
||||
"stoploss_order_types": {"limit": "stop", "market": "stop_market"},
|
||||
"tickers_have_price": False,
|
||||
}
|
||||
|
||||
|
@@ -109,11 +109,10 @@ def migrate_trades_and_orders_table(
|
||||
else:
|
||||
is_short = get_column_def(cols, 'is_short', '0')
|
||||
|
||||
# Margin Properties
|
||||
# Futures Properties
|
||||
interest_rate = get_column_def(cols, 'interest_rate', '0.0')
|
||||
|
||||
# Futures properties
|
||||
funding_fees = get_column_def(cols, 'funding_fees', '0.0')
|
||||
max_stake_amount = get_column_def(cols, 'max_stake_amount', 'stake_amount')
|
||||
|
||||
# If ticker-interval existed use that, else null.
|
||||
if has_column(cols, 'ticker_interval'):
|
||||
@@ -162,7 +161,8 @@ def migrate_trades_and_orders_table(
|
||||
timeframe, open_trade_value, close_profit_abs,
|
||||
trading_mode, leverage, liquidation_price, is_short,
|
||||
interest_rate, funding_fees, realized_profit,
|
||||
amount_precision, price_precision, precision_mode, contract_size
|
||||
amount_precision, price_precision, precision_mode, contract_size,
|
||||
max_stake_amount
|
||||
)
|
||||
select id, lower(exchange), pair, {base_currency} base_currency,
|
||||
{stake_currency} stake_currency,
|
||||
@@ -190,7 +190,8 @@ def migrate_trades_and_orders_table(
|
||||
{is_short} is_short, {interest_rate} interest_rate,
|
||||
{funding_fees} funding_fees, {realized_profit} realized_profit,
|
||||
{amount_precision} amount_precision, {price_precision} price_precision,
|
||||
{precision_mode} precision_mode, {contract_size} contract_size
|
||||
{precision_mode} precision_mode, {contract_size} contract_size,
|
||||
{max_stake_amount} max_stake_amount
|
||||
from {trade_back_name}
|
||||
"""))
|
||||
|
||||
@@ -310,8 +311,8 @@ def check_migrate(engine, decl_base, previous_tables) -> None:
|
||||
# if ('orders' not in previous_tables
|
||||
# or not has_column(cols_orders, 'funding_fee')):
|
||||
migrating = False
|
||||
# if not has_column(cols_trades, 'contract_size'):
|
||||
if not has_column(cols_orders, 'funding_fee'):
|
||||
# if not has_column(cols_orders, 'funding_fee'):
|
||||
if not has_column(cols_trades, 'max_stake_amount'):
|
||||
migrating = True
|
||||
logger.info(f"Running database migration for trades - "
|
||||
f"backup: {table_back_name}, {order_table_bak_name}")
|
||||
|
@@ -293,6 +293,7 @@ class LocalTrade():
|
||||
close_profit: Optional[float] = None
|
||||
close_profit_abs: Optional[float] = None
|
||||
stake_amount: float = 0.0
|
||||
max_stake_amount: float = 0.0
|
||||
amount: float = 0.0
|
||||
amount_requested: Optional[float] = None
|
||||
open_date: datetime
|
||||
@@ -469,8 +470,8 @@ class LocalTrade():
|
||||
'amount': round(self.amount, 8),
|
||||
'amount_requested': round(self.amount_requested, 8) if self.amount_requested else None,
|
||||
'stake_amount': round(self.stake_amount, 8),
|
||||
'max_stake_amount': round(self.max_stake_amount, 8) if self.max_stake_amount else None,
|
||||
'strategy': self.strategy,
|
||||
'buy_tag': self.enter_tag,
|
||||
'enter_tag': self.enter_tag,
|
||||
'timeframe': self.timeframe,
|
||||
|
||||
@@ -507,7 +508,6 @@ class LocalTrade():
|
||||
'profit_pct': round(self.close_profit * 100, 2) if self.close_profit else None,
|
||||
'profit_abs': self.close_profit_abs,
|
||||
|
||||
'sell_reason': self.exit_reason, # Deprecated
|
||||
'exit_reason': self.exit_reason,
|
||||
'exit_order_status': self.exit_order_status,
|
||||
'stop_loss_abs': self.stop_loss,
|
||||
@@ -876,6 +876,7 @@ class LocalTrade():
|
||||
ZERO = FtPrecise(0.0)
|
||||
current_amount = FtPrecise(0.0)
|
||||
current_stake = FtPrecise(0.0)
|
||||
max_stake_amount = FtPrecise(0.0)
|
||||
total_stake = 0.0 # Total stake after all buy orders (does not subtract!)
|
||||
avg_price = FtPrecise(0.0)
|
||||
close_profit = 0.0
|
||||
@@ -917,7 +918,9 @@ class LocalTrade():
|
||||
exit_rate, amount=exit_amount, open_rate=avg_price)
|
||||
else:
|
||||
total_stake = total_stake + self._calc_open_trade_value(tmp_amount, price)
|
||||
max_stake_amount += (tmp_amount * price)
|
||||
self.funding_fees = funding_fees
|
||||
self.max_stake_amount = float(max_stake_amount)
|
||||
|
||||
if close_profit:
|
||||
self.close_profit = close_profit
|
||||
@@ -1169,6 +1172,7 @@ class Trade(_DECL_BASE, LocalTrade):
|
||||
close_profit = Column(Float)
|
||||
close_profit_abs = Column(Float)
|
||||
stake_amount = Column(Float, nullable=False)
|
||||
max_stake_amount = Column(Float)
|
||||
amount = Column(Float)
|
||||
amount_requested = Column(Float)
|
||||
open_date = Column(DateTime, nullable=False, default=datetime.utcnow)
|
||||
|
@@ -217,8 +217,8 @@ class TradeSchema(BaseModel):
|
||||
amount: float
|
||||
amount_requested: float
|
||||
stake_amount: float
|
||||
max_stake_amount: Optional[float]
|
||||
strategy: str
|
||||
buy_tag: Optional[str] # Deprecated
|
||||
enter_tag: Optional[str]
|
||||
timeframe: int
|
||||
fee_open: Optional[float]
|
||||
@@ -243,7 +243,6 @@ class TradeSchema(BaseModel):
|
||||
profit_pct: Optional[float]
|
||||
profit_abs: Optional[float]
|
||||
profit_fiat: Optional[float]
|
||||
sell_reason: Optional[str] # Deprecated
|
||||
exit_reason: Optional[str]
|
||||
exit_order_status: Optional[str]
|
||||
stop_loss_abs: Optional[float]
|
||||
|
Reference in New Issue
Block a user