-
Notifications
You must be signed in to change notification settings - Fork 786
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into yakir/feat/delete-orders
- Loading branch information
Showing
17 changed files
with
359 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from collections import namedtuple | ||
|
||
from .sma import sma | ||
from .ema import ema | ||
from .stddev import stddev | ||
|
||
import numpy as np | ||
|
||
from jesse.helpers import get_candle_source, slice_candles | ||
|
||
Stiffness = namedtuple('Stiffness', ['stiffness', 'threshold']) | ||
|
||
|
||
def stiffness(candles: np.ndarray, ma_length: int = 100, stiff_length: int = 60, stiff_smooth: int = 3, threshold: int = 90, source_type: str = "close") -> Stiffness: | ||
""" | ||
@author daviddtech | ||
credits: https://www.tradingview.com/script/MOw6mUQl-Stiffness-Indicator-DaviddTech | ||
STIFNESS - Stifness | ||
:param candles: np.ndarray | ||
:param ma_length: int - default: 100 | ||
:param stiff_length: int - default: 60 | ||
:param stiff_smooth: int - default: 3 | ||
:param threshold: int - default: 90 | ||
:param source_type: str - default: "close" | ||
:return: Stiffness(stiffness, threshold) | ||
""" | ||
if len(candles.shape) == 1: | ||
source = candles | ||
else: | ||
candles = slice_candles(candles, False) | ||
source = get_candle_source(candles, source_type=source_type) | ||
|
||
bound_stiffness = sma(source, ma_length, sequential=True) - 0.2 * \ | ||
stddev(source, ma_length, sequential=True) | ||
sum_above_stiffness = _count_price_exceed_series(source, bound_stiffness, stiff_length) | ||
stiffness = ema(np.array(sum_above_stiffness) * 100 / stiff_length, period=stiff_smooth) | ||
|
||
return Stiffness(stiffness, threshold) | ||
|
||
|
||
def _count_price_exceed_series(close_prices, art_series, length): | ||
ex_counts = [] | ||
|
||
for i in range(len(close_prices)): | ||
if i < length: | ||
ex_counts.append(0) | ||
continue | ||
count = 0 | ||
|
||
for j in range(i - length + 1, i + 1): | ||
if close_prices[j] > art_series[j]: | ||
count += 1 | ||
|
||
ex_counts.append(count) | ||
|
||
return ex_counts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from collections import namedtuple | ||
from .macd import macd | ||
from .sma import sma | ||
from .stddev import stddev | ||
import numpy as np | ||
from jesse.helpers import get_candle_source, slice_candles | ||
|
||
WaddahAttarExplosionTuple = namedtuple( | ||
'WaddahAttarExplosionTuple', ['explosion_line', 'trend_power', 'trend_direction'] | ||
) | ||
|
||
|
||
def waddah_attar_explosion(candles: np.ndarray, sensitivity: int = 150, fast_length: int = 20, slow_length: int = 40, channel_length: int = 20, mult: float = 2.0, source_type: str = "close") -> WaddahAttarExplosionTuple: | ||
""" | ||
@author LazyBear | ||
credits: https://www.tradingview.com/v/iu3kKWDI/ | ||
WADDAH_ATTAR_EXPLOSION - Waddah Attar Explosion | ||
:param candles: np.ndarray | ||
:param sensitivity: int - default: 150 | ||
:param fast_length: int - default: 20 | ||
:param slow_length: int - default: 40 | ||
:param channel_length: int - default: 20 | ||
:param mult: float - default: 2.0 | ||
:param source_type: str - default: "close" | ||
:return: WaddahAttarExplosionTuple(explosion_line, trend_power, trend_direction) | ||
""" | ||
if len(candles.shape) == 1: | ||
source = candles | ||
else: | ||
candles = slice_candles(candles, False) | ||
source = get_candle_source(candles, source_type=source_type) | ||
|
||
t1 = (macd(source, fast_period=fast_length, slow_period=slow_length)[0] - | ||
macd(source[:-1], fast_period=fast_length, slow_period=slow_length)[0])*sensitivity | ||
trend = 1 if t1 >= 0 else -1 | ||
e1 = _calc_bb_upper(source, channel_length, mult) - _calc_bb_lower(source, channel_length, mult) | ||
|
||
return WaddahAttarExplosionTuple(e1, t1, trend) | ||
|
||
|
||
def _calc_bb_upper(source, length, mult): | ||
basis = sma(source, length) | ||
dev = mult * stddev(source, length) | ||
return basis + dev | ||
|
||
|
||
def _calc_bb_lower(source, length, mult): | ||
basis = sma(source, length) | ||
dev = mult * stddev(source, length) | ||
return basis - dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
jesse/modes/import_candles_mode/drivers/Apex/ApexProMain.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import requests | ||
import jesse.helpers as jh | ||
from jesse.modes.import_candles_mode.drivers.interface import CandleExchange | ||
from typing import Union | ||
from jesse import exceptions | ||
from .apex_pro_utils import timeframe_to_interval | ||
|
||
|
||
class ApexProMain(CandleExchange): | ||
def __init__(self, name: str, rest_endpoint: str) -> None: | ||
from jesse.modes.import_candles_mode.drivers.Binance.BinanceSpot import BinanceSpot | ||
|
||
super().__init__(name=name, count=200, rate_limit_per_second=10, backup_exchange_class=BinanceSpot) | ||
self.name = name | ||
self.endpoint = rest_endpoint | ||
|
||
def get_starting_time(self, symbol: str) -> int: | ||
dashless_symbol = jh.dashless_symbol(symbol) | ||
payload = { | ||
'symbol': dashless_symbol, | ||
'interval': 'W', | ||
'limit': 200, | ||
'start': 1514811660 | ||
} | ||
|
||
response = requests.get(self.endpoint + '/v2/klines', params=payload) | ||
self.validate_response(response) | ||
|
||
if 'data' not in response.json(): | ||
raise exceptions.ExchangeInMaintenance(response.json()['msg']) | ||
elif response.json()['data'] == {}: | ||
raise exceptions.InvalidSymbol('Exchange does not support the entered symbol. Please enter a valid symbol.') | ||
|
||
data = response.json()['data'][dashless_symbol] | ||
# Reverse the data list | ||
data = data[::-1] | ||
|
||
return int(data[1]['t']) | ||
|
||
def fetch(self, symbol: str, start_timestamp: int, timeframe: str = '1m') -> Union[list, None]: | ||
dashless_symbol = jh.dashless_symbol(symbol) | ||
interval = timeframe_to_interval(timeframe) | ||
|
||
payload = { | ||
'symbol': dashless_symbol, | ||
'interval': interval, | ||
'start': int(start_timestamp / 1000), | ||
'limit': self.count | ||
} | ||
|
||
response = requests.get(self.endpoint + '/v2/klines', params=payload) | ||
# check data exist in response.json | ||
|
||
if 'data' not in response.json(): | ||
raise exceptions.ExchangeInMaintenance(response.json()['msg']) | ||
elif response.json()['data'] == {}: | ||
raise exceptions.InvalidSymbol('Exchange does not support the entered symbol. Please enter a valid symbol.') | ||
|
||
data = response.json()['data'][dashless_symbol] | ||
|
||
return [ | ||
{ | ||
'id': jh.generate_unique_id(), | ||
'exchange': self.name, | ||
'symbol': symbol, | ||
'timeframe': timeframe, | ||
'timestamp': int(d['t']), | ||
'open': float(d['o']), | ||
'close': float(d['c']), | ||
'high': float(d['h']), | ||
'low': float(d['l']), | ||
'volume': float(d['v']) | ||
} for d in data | ||
] |
10 changes: 10 additions & 0 deletions
10
jesse/modes/import_candles_mode/drivers/Apex/ApexProPerpetual.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from .ApexProMain import ApexProMain | ||
from jesse.enums import exchanges | ||
|
||
|
||
class ApexProPerpetual(ApexProMain): | ||
def __init__(self) -> None: | ||
super().__init__( | ||
name=exchanges.APEX_PRO_PERPETUAL, | ||
rest_endpoint='https://pro.apex.exchange/api' | ||
) |
10 changes: 10 additions & 0 deletions
10
jesse/modes/import_candles_mode/drivers/Apex/ApexProPerpetualTestnet.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from .ApexProMain import ApexProMain | ||
from jesse.enums import exchanges | ||
|
||
|
||
class ApexProPerpetualTestnet(ApexProMain): | ||
def __init__(self) -> None: | ||
super().__init__( | ||
name=exchanges.APEX_PRO_PERPETUAL_TESTNET, | ||
rest_endpoint='https://testnet.pro.apex.exchange/api' | ||
) |
Empty file.
65 changes: 65 additions & 0 deletions
65
jesse/modes/import_candles_mode/drivers/Apex/apex_pro_utils.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from jesse.enums import timeframes | ||
|
||
|
||
def timeframe_to_interval(timeframe: str) -> str: | ||
""" | ||
Convert a timeframe string to an interval in seconds. | ||
""" | ||
if timeframe == timeframes.MINUTE_1: | ||
return '1' | ||
elif timeframe == timeframes.MINUTE_3: | ||
return '3' | ||
elif timeframe == timeframes.MINUTE_5: | ||
return '5' | ||
elif timeframe == timeframes.MINUTE_15: | ||
return '15' | ||
elif timeframe == timeframes.MINUTE_30: | ||
return '30' | ||
elif timeframe == timeframes.HOUR_1: | ||
return '60' | ||
elif timeframe == timeframes.HOUR_2: | ||
return '120' | ||
elif timeframe == timeframes.HOUR_4: | ||
return '240' | ||
elif timeframe == timeframes.HOUR_6: | ||
return '360' | ||
elif timeframe == timeframes.HOUR_12: | ||
return '720' | ||
elif timeframe == timeframes.DAY_1: | ||
return 'D' | ||
elif timeframe == timeframes.WEEK_1: | ||
return 'W' | ||
else: | ||
raise ValueError('Invalid timeframe: {}'.format(timeframe)) | ||
|
||
|
||
def interval_to_timeframe(interval: str) -> str: | ||
""" | ||
Convert an interval in seconds to a timeframe string. | ||
""" | ||
if interval == '1': | ||
return timeframes.MINUTE_1 | ||
elif interval == '3': | ||
return timeframes.MINUTE_3 | ||
elif interval == '5': | ||
return timeframes.MINUTE_5 | ||
elif interval == '15': | ||
return timeframes.MINUTE_15 | ||
elif interval == '30': | ||
return timeframes.MINUTE_30 | ||
elif interval == '60': | ||
return timeframes.HOUR_1 | ||
elif interval == '120': | ||
return timeframes.HOUR_2 | ||
elif interval == '240': | ||
return timeframes.HOUR_4 | ||
elif interval == '360': | ||
return timeframes.HOUR_6 | ||
elif interval == '720': | ||
return timeframes.HOUR_12 | ||
elif interval == 'D': | ||
return timeframes.DAY_1 | ||
elif interval == 'W': | ||
return timeframes.WEEK_1 | ||
else: | ||
raise ValueError('Invalid interval: {}'.format(interval)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.