removing whitespaces and long lines
This commit is contained in:
parent
75ba6578a3
commit
0594deafc6
@ -5,7 +5,6 @@ from typing import Any, Dict
|
|||||||
import arrow
|
import arrow
|
||||||
|
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
import freqtrade.optimize as optimize
|
import freqtrade.optimize as optimize
|
||||||
from freqtrade.optimize.backtesting import BacktestResult
|
from freqtrade.optimize.backtesting import BacktestResult
|
||||||
@ -40,7 +39,7 @@ class Edge():
|
|||||||
self.edge_config = self.config.get('edge', {})
|
self.edge_config = self.config.get('edge', {})
|
||||||
|
|
||||||
self._last_updated = None
|
self._last_updated = None
|
||||||
self._cached_pairs : list = []
|
self._cached_pairs: list = []
|
||||||
self._total_capital = self.edge_config['total_capital_in_stake_currency']
|
self._total_capital = self.edge_config['total_capital_in_stake_currency']
|
||||||
self._allowed_risk = self.edge_config['allowed_risk']
|
self._allowed_risk = self.edge_config['allowed_risk']
|
||||||
|
|
||||||
@ -62,14 +61,15 @@ class Edge():
|
|||||||
pairs = self.config['exchange']['pair_whitelist']
|
pairs = self.config['exchange']['pair_whitelist']
|
||||||
heartbeat = self.config['edge']['process_throttle_secs']
|
heartbeat = self.config['edge']['process_throttle_secs']
|
||||||
|
|
||||||
if ((self._last_updated is not None) and (self._last_updated + heartbeat > arrow.utcnow().timestamp)):
|
if (self._last_updated is not None) and \
|
||||||
|
(self._last_updated + heartbeat > arrow.utcnow().timestamp):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
data: Dict[str, Any] = {}
|
data: Dict[str, Any] = {}
|
||||||
logger.info('Using stake_currency: %s ...', self.config['stake_currency'])
|
logger.info('Using stake_currency: %s ...', self.config['stake_currency'])
|
||||||
logger.info('Using stake_amount: %s ...', self.config['stake_amount'])
|
logger.info('Using stake_amount: %s ...', self.config['stake_amount'])
|
||||||
logger.info('Using local backtesting data (using whitelist in given config) ...')
|
logger.info('Using local backtesting data (using whitelist in given config) ...')
|
||||||
#TODO: add "timerange" to Edge config
|
# TODO: add "timerange" to Edge config
|
||||||
timerange = Arguments.parse_timerange(None if self.config.get(
|
timerange = Arguments.parse_timerange(None if self.config.get(
|
||||||
'timerange') is None else str(self.config.get('timerange')))
|
'timerange') is None else str(self.config.get('timerange')))
|
||||||
|
|
||||||
@ -103,7 +103,6 @@ class Edge():
|
|||||||
stoploss_range_step = float(self.edge_config.get('stoploss_range_step', -0.001))
|
stoploss_range_step = float(self.edge_config.get('stoploss_range_step', -0.001))
|
||||||
stoploss_range = np.arange(stoploss_range_min, stoploss_range_max, stoploss_range_step)
|
stoploss_range = np.arange(stoploss_range_min, stoploss_range_max, stoploss_range_step)
|
||||||
|
|
||||||
########################### Call out BSlap Loop instead of Original BT code
|
|
||||||
trades: list = []
|
trades: list = []
|
||||||
for pair, pair_data in preprocessed.items():
|
for pair, pair_data in preprocessed.items():
|
||||||
# Sorting dataframe by date and reset index
|
# Sorting dataframe by date and reset index
|
||||||
@ -115,7 +114,6 @@ class Edge():
|
|||||||
|
|
||||||
trades += self._find_trades_for_stoploss_range(ticker_data, pair, stoploss_range)
|
trades += self._find_trades_for_stoploss_range(ticker_data, pair, stoploss_range)
|
||||||
|
|
||||||
|
|
||||||
# Switch List of Trade Dicts (trades) to Dataframe
|
# Switch List of Trade Dicts (trades) to Dataframe
|
||||||
# Fill missing, calculable columns, profit, duration , abs etc.
|
# Fill missing, calculable columns, profit, duration , abs etc.
|
||||||
trades_df = DataFrame(trades)
|
trades_df = DataFrame(trades)
|
||||||
@ -126,7 +124,6 @@ class Edge():
|
|||||||
trades_df = []
|
trades_df = []
|
||||||
trades_df = DataFrame.from_records(trades_df, columns=BacktestResult._fields)
|
trades_df = DataFrame.from_records(trades_df, columns=BacktestResult._fields)
|
||||||
|
|
||||||
|
|
||||||
self._cached_pairs = self._process_expectancy(trades_df)
|
self._cached_pairs = self._process_expectancy(trades_df)
|
||||||
self._last_updated = arrow.utcnow().timestamp
|
self._last_updated = arrow.utcnow().timestamp
|
||||||
return True
|
return True
|
||||||
@ -146,7 +143,7 @@ class Edge():
|
|||||||
if len(self._cached_pairs) == 0:
|
if len(self._cached_pairs) == 0:
|
||||||
self.calculate()
|
self.calculate()
|
||||||
edge_sorted_pairs = [x[0] for x in self._cached_pairs]
|
edge_sorted_pairs = [x[0] for x in self._cached_pairs]
|
||||||
return [x for _, x in sorted(zip(edge_sorted_pairs,pairs), key=lambda pair: pair[0])]
|
return [x for _, x in sorted(zip(edge_sorted_pairs, pairs), key=lambda pair: pair[0])]
|
||||||
|
|
||||||
def _fill_calculable_fields(self, result: DataFrame):
|
def _fill_calculable_fields(self, result: DataFrame):
|
||||||
"""
|
"""
|
||||||
@ -173,9 +170,11 @@ class Edge():
|
|||||||
close_fee = fee / 2
|
close_fee = fee / 2
|
||||||
|
|
||||||
result['trade_duration'] = result['close_time'] - result['open_time']
|
result['trade_duration'] = result['close_time'] - result['open_time']
|
||||||
result['trade_duration'] = result['trade_duration'].map(lambda x: int(x.total_seconds() / 60))
|
|
||||||
|
|
||||||
## Spends, Takes, Profit, Absolute Profit
|
result['trade_duration'] = \
|
||||||
|
result['trade_duration'].map(lambda x: int(x.total_seconds() / 60))
|
||||||
|
|
||||||
|
# Spends, Takes, Profit, Absolute Profit
|
||||||
|
|
||||||
# Buy Price
|
# Buy Price
|
||||||
result['buy_vol'] = stake / result['open_rate'] # How many target are we buying
|
result['buy_vol'] = stake / result['open_rate'] # How many target are we buying
|
||||||
@ -188,8 +187,9 @@ class Edge():
|
|||||||
result['sell_take'] = result['sell_sum'] - result['sell_fee']
|
result['sell_take'] = result['sell_sum'] - result['sell_fee']
|
||||||
|
|
||||||
# profit_percent
|
# profit_percent
|
||||||
result['profit_percent'] = (result['sell_take'] - result['buy_spend']) \
|
result['profit_percent'] = \
|
||||||
/ result['buy_spend']
|
(result['sell_take'] - result['buy_spend']) / result['buy_spend']
|
||||||
|
|
||||||
# Absolute profit
|
# Absolute profit
|
||||||
result['profit_abs'] = result['sell_take'] - result['buy_spend']
|
result['profit_abs'] = result['sell_take'] - result['buy_spend']
|
||||||
|
|
||||||
@ -198,8 +198,10 @@ class Edge():
|
|||||||
def _process_expectancy(self, results: DataFrame) -> list:
|
def _process_expectancy(self, results: DataFrame) -> list:
|
||||||
"""
|
"""
|
||||||
This is a temporary version of edge positioning calculation.
|
This is a temporary version of edge positioning calculation.
|
||||||
The function will be eventually moved to a plugin called Edge in order to calculate necessary WR, RRR and
|
The function will be eventually moved to a plugin called Edge in order
|
||||||
other indictaors related to money management periodically (each X minutes) and keep it in a storage.
|
to calculate necessary WR, RRR and
|
||||||
|
other indictaors related to money management periodically (each X minutes)
|
||||||
|
and keep it in a storage.
|
||||||
The calulation will be done per pair and per strategy.
|
The calulation will be done per pair and per strategy.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -238,21 +240,17 @@ class Edge():
|
|||||||
# Risk Reward Ratio
|
# Risk Reward Ratio
|
||||||
# 1 / ((loss money / losing trades) / (gained money / winning trades))
|
# 1 / ((loss money / losing trades) / (gained money / winning trades))
|
||||||
def risk_reward_ratio(x):
|
def risk_reward_ratio(x):
|
||||||
x = abs(1/ ((x[x<0].sum() / x[x < 0].count()) / (x[x > 0].sum() / x[x > 0].count())))
|
x = abs(1 / ((x[x < 0].sum() / x[x < 0].count()) / (x[x > 0].sum() / x[x > 0].count())))
|
||||||
return x
|
return x
|
||||||
##############################
|
##############################
|
||||||
|
|
||||||
# Required Risk Reward
|
# Required Risk Reward
|
||||||
# (1/(winrate - 1)
|
# (1/(winrate - 1)
|
||||||
def required_risk_reward(x):
|
def required_risk_reward(x):
|
||||||
x = (1/(x[x > 0].count()/x.count()) -1)
|
x = (1 / (x[x > 0].count() / x.count()) - 1)
|
||||||
return x
|
return x
|
||||||
##############################
|
##############################
|
||||||
|
|
||||||
def delta(x):
|
|
||||||
x = (abs(1/ ((x[x < 0].sum() / x[x < 0].count()) / (x[x > 0].sum() / x[x > 0].count())))) - (1/(x[x > 0].count()/x.count()) -1)
|
|
||||||
return x
|
|
||||||
|
|
||||||
# Expectancy
|
# Expectancy
|
||||||
# Tells you the interest percentage you should hope
|
# Tells you the interest percentage you should hope
|
||||||
# E.x. if expectancy is 0.35, on $1 trade you should expect a target of $1.35
|
# E.x. if expectancy is 0.35, on $1 trade you should expect a target of $1.35
|
||||||
@ -265,7 +263,7 @@ class Edge():
|
|||||||
##############################
|
##############################
|
||||||
|
|
||||||
final = results.groupby(['pair', 'stoploss'])['profit_abs'].\
|
final = results.groupby(['pair', 'stoploss'])['profit_abs'].\
|
||||||
agg([winrate, risk_reward_ratio, required_risk_reward, expectancy, delta]).\
|
agg([winrate, risk_reward_ratio, required_risk_reward, expectancy]).\
|
||||||
reset_index().sort_values(by=['expectancy', 'stoploss'], ascending=False)\
|
reset_index().sort_values(by=['expectancy', 'stoploss'], ascending=False)\
|
||||||
.groupby('pair').first().sort_values(by=['expectancy'], ascending=False)
|
.groupby('pair').first().sort_values(by=['expectancy'], ascending=False)
|
||||||
|
|
||||||
@ -280,14 +278,26 @@ class Edge():
|
|||||||
|
|
||||||
result: list = []
|
result: list = []
|
||||||
for stoploss in stoploss_range:
|
for stoploss in stoploss_range:
|
||||||
result += self._detect_stop_and_sell_points(buy_column, sell_column, date_column, ohlc_columns, round(stoploss, 6), pair)
|
result += self._detect_stop_and_sell_points(
|
||||||
|
buy_column, sell_column, date_column, ohlc_columns, round(stoploss, 6), pair
|
||||||
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _detect_stop_and_sell_points(self, buy_column, sell_column, date_column, ohlc_columns, stoploss, pair, start_point=0):
|
def _detect_stop_and_sell_points(
|
||||||
|
self,
|
||||||
|
buy_column,
|
||||||
|
sell_column,
|
||||||
|
date_column,
|
||||||
|
ohlc_columns,
|
||||||
|
stoploss,
|
||||||
|
pair,
|
||||||
|
start_point=0
|
||||||
|
):
|
||||||
|
|
||||||
result: list = []
|
result: list = []
|
||||||
open_trade_index = utf1st.find_1st(buy_column, 1, utf1st.cmp_equal)
|
open_trade_index = utf1st.find_1st(buy_column, 1, utf1st.cmp_equal)
|
||||||
#open_trade_index = np.argmax(buy_column == 1)
|
# open_trade_index = np.argmax(buy_column == 1)
|
||||||
|
|
||||||
# return empty if we don't find trade entry (i.e. buy==1)
|
# return empty if we don't find trade entry (i.e. buy==1)
|
||||||
if open_trade_index == -1:
|
if open_trade_index == -1:
|
||||||
@ -298,13 +308,14 @@ class Edge():
|
|||||||
stop_price = (open_price * stop_price_percentage)
|
stop_price = (open_price * stop_price_percentage)
|
||||||
|
|
||||||
# Searching for the index where stoploss is hit
|
# Searching for the index where stoploss is hit
|
||||||
stop_index = utf1st.find_1st(ohlc_columns[open_trade_index + 1:, 2], stop_price, utf1st.cmp_smaller)
|
stop_index = \
|
||||||
|
utf1st.find_1st(ohlc_columns[open_trade_index + 1:, 2], stop_price, utf1st.cmp_smaller)
|
||||||
|
|
||||||
# If we don't find it then we assume stop_index will be far in future (infinite number)
|
# If we don't find it then we assume stop_index will be far in future (infinite number)
|
||||||
if stop_index == -1:
|
if stop_index == -1:
|
||||||
stop_index = float('inf')
|
stop_index = float('inf')
|
||||||
|
|
||||||
#stop_index = np.argmax((ohlc_columns[open_trade_index + 1:, 2] < stop_price) == True)
|
# stop_index = np.argmax((ohlc_columns[open_trade_index + 1:, 2] < stop_price) == True)
|
||||||
|
|
||||||
# Searching for the index where sell is hit
|
# Searching for the index where sell is hit
|
||||||
sell_index = utf1st.find_1st(sell_column[open_trade_index + 1:], 1, utf1st.cmp_equal)
|
sell_index = utf1st.find_1st(sell_column[open_trade_index + 1:], 1, utf1st.cmp_equal)
|
||||||
@ -313,7 +324,7 @@ class Edge():
|
|||||||
if sell_index == -1:
|
if sell_index == -1:
|
||||||
sell_index = float('inf')
|
sell_index = float('inf')
|
||||||
|
|
||||||
#sell_index = np.argmax(sell_column[open_trade_index + 1:] == 1)
|
# sell_index = np.argmax(sell_column[open_trade_index + 1:] == 1)
|
||||||
|
|
||||||
# Check if we don't find any stop or sell point (in that case trade remains open)
|
# Check if we don't find any stop or sell point (in that case trade remains open)
|
||||||
# It is not interesting for Edge to consider it so we simply ignore the trade
|
# It is not interesting for Edge to consider it so we simply ignore the trade
|
||||||
|
Loading…
Reference in New Issue
Block a user