refactor direktiv - skoro hotovo
This commit is contained in:
46
testy/getdirective.py
Normal file
46
testy/getdirective.py
Normal file
@ -0,0 +1,46 @@
|
||||
#ROZPRACOVANE pri vytvareni OR/AND dynamickych buysignalu
|
||||
# indicator.ema
|
||||
# length = 3
|
||||
# buy_if_below = 15
|
||||
# OR.buy_if_below = 15 #totozne s predchozim, staci kdyz jedna podminka plati
|
||||
# AND.buy_if_below = 15 #musi platiti vsechny podminky u vsech indikatoru
|
||||
|
||||
|
||||
|
||||
|
||||
#TOTO dodelat
|
||||
|
||||
#nejspis v INITU nahrat vsechny buysignal directivy do jednoho dictu
|
||||
#a ten pouzivat v celem lifecyclu
|
||||
|
||||
#tato funkce by je mohla vytvorit
|
||||
# vysledek: {'AND': [('ema', 'ema20')], 'OR': []}
|
||||
|
||||
#tato funkce vytvori dictionary typu podminek (OR/AND) a indikatoru s direktivami buy_if
|
||||
# do OR jsou dane i bez prefixu
|
||||
# {'AND': [('nazev indikatoru', 'nazev direktivy', 'hodnotadirektivy')], 'OR': []}
|
||||
def get_indicators_with_buy_directive():
|
||||
starts_with = "buy_if"
|
||||
reslist = dict(AND=[], OR=[])
|
||||
|
||||
for indname, indsettings in vars["indicators"].items():
|
||||
for option,value in indsettings.items():
|
||||
if option.startswith(starts_with):
|
||||
reslist["OR"].append((indname, option, value))
|
||||
if option == "AND":
|
||||
#vsechny buy direktivy, ktere jsou pod AND
|
||||
for key, val in value.items():
|
||||
if key.startswith(starts_with):
|
||||
reslist["AND"].append((indname, key, val))
|
||||
if option == "OR" :
|
||||
#vsechny buy direktivy, ktere jsou pod OR
|
||||
for key, val in value.items():
|
||||
if key.startswith(starts_with):
|
||||
reslist["OR"].append((indname, key, val))
|
||||
return reslist
|
||||
|
||||
|
||||
vars = {'maxpozic': 2000, 'def_mode_from': 2000, 'chunk': 100, 'profit': 0.014, 'def_profit': 0.01, 'max_profit': 0.03, 'vykladka': 1, 'curve': [0.03, 0.01, 0.01, 0.0, 0.02, 0.02, 0.01, 0.01, 0.01, 0.03, 0.01, 0.01, 0.01, 0.04, 0.01, 0.01, 0.01, 0.05, 0.01, 0.01, 0.01, 0.01, 0.06, 0.01, 0.01, 0.01, 0.01], 'curve_def': [0.02, 0.03, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02], 'ticks2reset': 0.06, 'consolidation_bar_count': 5, 'first_buy_market': True, 'first_buy_market_def_mode': False, 'market_buy_multiplier': 1, 'rsi_dont_buy_above': 70, 'bigwave_slope_above': 0.12, 'minimum_slope': -0.1, 'open_rush': 30, 'close_rush': 30, 'lastbuy_offset': 5, 'last_buy_offset_reset_after_sell': False, 'buy_only_on_confirmed': False, 'indicators': {'ema': {'type': 'EMA', 'source': 'close', 'length': 5, 'on_confirmed_only': False, 'AND': {'buy_if_crossed_down': 'ema20'}}, 'ema20': {'type': 'EMA', 'source': 'close', 'length': 20, 'on_confirmed_only': False}, 'RSI14': {'type': 'RSI', 'RSI_length': 14, 'source': 'vwap', 'MA_length': 5}, 'slope': {'type': 'slope', 'on_confirmed_only': False, 'MA_length': 5, 'slope_lookback': 10, 'lookback_offset': 3, 'minimum_slope': -0.1, 'maximum_slope': 0.2}, 'slopeLP': {'type': 'slopeLP', 'on_confirmed_only': False, 'leftpoint': 'baropen', 'slope_lookback': 8, 'lookback_offset': 4, 'minimum_slope': -0.09, 'maximum_slope': 0.2}, 'slope10': {'type': 'slope', 'on_confirmed_only': False, 'MA_length': 5, 'slope_lookback': 60, 'lookback_offset': 20, 'minimum_slope': -0.1, 'maximum_slope': 0.45}, 'slope20': {'type': 'slope', 'on_confirmed_only': False, 'MA_length': 5, 'slope_lookback': 120, 'lookback_offset': 25, 'minimum_slope': -0.1, 'dont_buy_above': 0.3, 'maximum_slope': 0.45}}, 'sell_protection': {'enabled': False, 'slopeMA_rising': 2, 'rsi_not_falling': 3}, 'sell_in_progress': False, 'mode': None, 'last_tick_price': 48.41, 'last_50_deltas': [0.027251, 2.050578, 0.205957, 2.226359, 0.00071, 4.034629, 0.0, 0.387769, 2.779256, 1.735168, 1.208257, 0.729469, 1.215035, 2.510941, 4.126465, 0.0, 0.89464, 0.863604, 0.363522, 0.808834, 3.007671, 1.450134, 5.292132, 2.532213, 0.0, 2.185073, 3.185483, 1.664617, 1.972669, 1.552979, 0.45697, 1.370411, 1.125679, 0.0, 0.390609, 0.770417, 0.050253, 1.652531, 0.729488, 0.788619, 0.873404, 1.013351, 0.045697, 2.992692, 4.046475, 0.165393, 0.0, 5.635894, 0.0, 3.558663], 'last_tick_volume': 200, 'next_new': 1, 'lastbuyindex': 103, 'last_update_time': 1689001643.057809, 'reverse_position_waiting_amount': 0, 'pendingbuys': {}, 'limitka': None, 'limitka_price': None, 'jevylozeno': 0, 'blockbuy': 0, 'ticks2reset_backup': 0.06}
|
||||
|
||||
a = get_indicators_with_buy_directive()
|
||||
print(a)
|
||||
@ -1,4 +1,4 @@
|
||||
|
||||
from v2realbot.utils.utils import isfalling, isrising
|
||||
|
||||
test1_threshold = 28.905
|
||||
bacma = []
|
||||
@ -10,54 +10,32 @@ bacma.append([28.91,28.90,28.89,28.88,28.87])
|
||||
bacma.append([28.91,28.90,28.89,28.88,28.87,28.86])
|
||||
|
||||
|
||||
#is_pivot function to check if there is A shaped pivot in the list, each leg consists of N points
|
||||
def is_pivot(list, leg):
|
||||
"""check if there is A shaped pivot in the list, each leg consists of N points"""
|
||||
try:
|
||||
if len(list) < leg*2+1:
|
||||
pole = [1,2,3,2,1,2,3,4,5,6,2,1]
|
||||
|
||||
#is_pivot function to check if there is A(V) shaped pivot in the list, each leg consists of N points
|
||||
#middle point is the shared one [1,2,3,2,1] - one leg is [1,2,3] second leg is [3,2,1]
|
||||
def is_pivot(stock_prices_list, leg_number, type: str = "A"):
|
||||
if len(stock_prices_list) < (2 * leg_number)-1:
|
||||
print("Not enough values in the list")
|
||||
return False
|
||||
else:
|
||||
if list[-leg-1] < list[-leg] and list[-leg] > list[-leg+1] and list[-leg-1] > list[-leg-2] and list[-leg] > list[-leg+2]:
|
||||
|
||||
left_leg = stock_prices_list[-2*leg_number+1:-leg_number+1]
|
||||
print(left_leg)
|
||||
right_leg = stock_prices_list[-leg_number:]
|
||||
print(right_leg)
|
||||
|
||||
if type == "A":
|
||||
if isrising(left_leg) and isfalling(right_leg):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except IndexError:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def crossed_up(threshold, list):
|
||||
"""check if threshold has crossed up last thresholdue in list"""
|
||||
try:
|
||||
if threshold < list[-1] and threshold >= list[-2]:
|
||||
elif type == "V":
|
||||
if isfalling(left_leg) and isrising(right_leg):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except IndexError:
|
||||
return False
|
||||
|
||||
def crossed_down(threshold, list):
|
||||
"""check if threshold has crossed down last thresholdue in list"""
|
||||
try:
|
||||
if threshold > list[-1] and threshold <= list[-2]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except IndexError:
|
||||
print("Unknown type")
|
||||
return False
|
||||
|
||||
def crossed(threshold, list):
|
||||
"""check if threshold has crossed last thresholdue in list"""
|
||||
if crossed_down(threshold, list) or crossed_up(threshold, list):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
for i in bacma:
|
||||
print(i)
|
||||
print(f"threshold crossed down {i}", threshold_crossed_down(test1_threshold, i))
|
||||
print(f"threshold crossed up {i}", threshold_crossed_up(test1_threshold, i))
|
||||
|
||||
|
||||
|
||||
|
||||
print(is_pivot(pole, 3))
|
||||
10
testy/testcrosseddown.py
Normal file
10
testy/testcrosseddown.py
Normal file
@ -0,0 +1,10 @@
|
||||
from v2realbot.utils.utils import crossed_down
|
||||
|
||||
pole = [48.495432098765434, 48.48296296296296, 48.480617283950615, 48.47475308641976, 48.467543209876546]
|
||||
thr = 48.4778923123465
|
||||
|
||||
|
||||
|
||||
res = crossed_down(threshold=thr, list=pole)
|
||||
|
||||
print(res)
|
||||
@ -5,7 +5,7 @@ from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import Strat
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick, round2five, is_open_rush, is_close_rush, eval_cond_dict, Average, crossed_down, crossed_up
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick, round2five, is_open_rush, is_close_rush, eval_cond_dict, Average, crossed_down, crossed_up, is_pivot
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
@ -217,7 +217,7 @@ def next(data, state: StrategyState):
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
@ -352,154 +352,6 @@ def next(data, state: StrategyState):
|
||||
modded_section = section
|
||||
return safe_get(modded_section, name, safe_get(section, name, default))
|
||||
|
||||
def populate_ema_indicator():
|
||||
#BAR EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
|
||||
##pokus MACKO zakrouhlit na tri desetina a petku
|
||||
state.indicators.ema[-1]=round2five(ema_value[-1])
|
||||
##state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
#state.ilog(e=f"EMA {state.indicators.ema[-1]}", ema_last=state.indicators.ema[-6:])
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA nechavame 0", message=str(e)+format_exc())
|
||||
#state.indicators.ema[-1]=(0)
|
||||
#evaluate buy signal
|
||||
#consolidation
|
||||
|
||||
# [stratvars.indicators.slope]
|
||||
# lookback
|
||||
# lookback_offset
|
||||
|
||||
def populate_slow_slope_indicator():
|
||||
options = safe_get(state.vars.indicators, 'slow_slope', None)
|
||||
if options is None:
|
||||
state.ilog(e="No options for slow slope in stratvars")
|
||||
return
|
||||
|
||||
|
||||
#SLOW SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slow_slope = 99
|
||||
slope_lookback = safe_get(options, 'slope_lookback', 100)
|
||||
minimum_slope = safe_get(options, 'minimum_slope', 25)
|
||||
maximum_slope = safe_get(options, "maximum_slope",0.9)
|
||||
lookback_offset = safe_get(options, 'lookback_offset', 25)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
lookbacktime = state.bars.time[-slope_lookback]
|
||||
else:
|
||||
#kdyz neni dostatek hodnot, pouzivame jako levy bod open hodnotu close[0]
|
||||
lookbackprice = state.bars.close[0]
|
||||
lookbacktime = state.bars.time[0]
|
||||
state.ilog(e="Slow Slope - not enough data bereme left bod open", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
|
||||
#výpočet úhlu - a jeho normalizace
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slow_slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle_slow = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=lookbacktime, lookbackprice=lookbackprice, minimum_slope=minimum_slope, maximum_slope=maximum_slope)
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = safe_get(options, 'MA_length', 5)
|
||||
source = state.indicators.slow_slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slow_slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"SLOW {slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
#slope = slopeMA
|
||||
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slow Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slow Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
def populate_slope_indicator():
|
||||
#populuje indikator typu SLOPE
|
||||
|
||||
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu - a jeho normalizace
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope, maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
#TODO predelat na dynamicky type=RSI, source = ["close", "vwap","hlcc4"]
|
||||
|
||||
def populate_rsi_indicator():
|
||||
#RSI14 INDICATOR
|
||||
try:
|
||||
rsi_length = int(safe_get(state.vars, "rsi_length",14))
|
||||
source = state.bars.vwap #[-rsi_length:] #state.bars.vwap
|
||||
|
||||
#cekame na dostatek dat
|
||||
if len(source) > rsi_length:
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14[-1]=rsi_value
|
||||
else:
|
||||
state.ilog(e=f"RSI {rsi_length=} necháváme 0", message="not enough source data")
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
def populate_cbar_rsi_indicator():
|
||||
#CBAR RSI indicator
|
||||
options = safe_get(state.vars.indicators, 'crsi', None)
|
||||
@ -520,108 +372,24 @@ def next(data, state: StrategyState):
|
||||
state.ilog(e=f"CRSI {crsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
# def populate_secondary_rsi_indicator():
|
||||
# #SBAR RSI indicator
|
||||
# try:
|
||||
# srsi_length = int(safe_get(state.vars, "srsi_length",14))
|
||||
# source = state.secondary_indicators.sec_price #[-rsi_length:] #state.bars.vwap
|
||||
# srsi_res = rsi(source, srsi_length)
|
||||
# srsi_value = trunc(srsi_res[-1],3)
|
||||
# state.secondary_indicators.SRSI[-1]=srsi_value
|
||||
# #state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
# except Exception as e:
|
||||
# state.ilog(e=f"SRSI {srsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
# #state.indicators.RSI14[-1]=0
|
||||
|
||||
#TODO predelat na dynamicky - tzn. vstup je nazev slopu a i z nej se dotahne minimum slope
|
||||
|
||||
|
||||
#gets all indicators of type slow and check which they have dont_buy_below_minimum
|
||||
# [stratvars.indicators.slope]
|
||||
# type = "slope"
|
||||
# dont_buy_below = -0.10
|
||||
#get all indicators of type slow and check whether they have dont_buy_below_minimum
|
||||
# if so, it evaluates if it is below current value
|
||||
def slope_too_low():
|
||||
retboolList = []
|
||||
desc = ""
|
||||
for indname, indsettings in state.vars.indicators.items():
|
||||
for option,value in indsettings.items():
|
||||
if (option == "type" and value == "slope") or (option == "type" and value == "slopeLP"):
|
||||
#pokud zde mame dont_buy_below
|
||||
minimum_val = safe_get(indsettings, "dont_buy_below", None)
|
||||
if minimum_val is not None:
|
||||
#minimum_val = float(safe_get(indsettings, "minimum_slope", 1))
|
||||
|
||||
#pokud exisuje MA, měříme na MA, jinak na standardu
|
||||
try:
|
||||
curr_val = state.indicators[indname+"MA"][-1]
|
||||
except KeyError:
|
||||
curr_val = state.indicators[indname][-1]
|
||||
|
||||
ret = (curr_val < minimum_val)
|
||||
if ret:
|
||||
desc += f"ID:{indname}/{curr_val} below {minimum_val=} /"
|
||||
else:
|
||||
desc += f"ID:{indname}{curr_val} OK above {minimum_val=} /"
|
||||
retboolList.append(ret)
|
||||
else:
|
||||
desc += f"ID:{indname} - no min set /"
|
||||
retboolList.append(False)
|
||||
#pokud obsahuje aspon jedno true
|
||||
slopelow = any(retboolList)
|
||||
|
||||
#DEBUG - poté zapsat jen když je True
|
||||
if slopelow:
|
||||
state.ilog(e=f"SLOPELOW {slopelow}", msg=desc)
|
||||
|
||||
return slopelow
|
||||
|
||||
#gets all indicators of type slow and check which they have dont_buy_above
|
||||
# [stratvars.indicators.slope]
|
||||
# type = "slope"
|
||||
# dont_buy_above = 0.20
|
||||
#get all indicators of type slow and check whether they have dont_buy_above
|
||||
# if so, it evaluates if it is above current value
|
||||
def slope_too_high():
|
||||
retboolList = []
|
||||
desc = ""
|
||||
for indname, indsettings in state.vars.indicators.items():
|
||||
for option,value in indsettings.items():
|
||||
if (option == "type" and value == "slope") or (option == "type" and value == "slopeLP"):
|
||||
#pokud zde mame dont_buy_above
|
||||
maximum_val = safe_get(indsettings, "dont_buy_above", None)
|
||||
if maximum_val is not None:
|
||||
#pokud exisuje MA, měříme na MA, jinak na standardu
|
||||
try:
|
||||
curr_val = state.indicators[indname+"MA"][-1]
|
||||
except KeyError:
|
||||
curr_val = state.indicators[indname][-1]
|
||||
|
||||
ret = (curr_val > maximum_val)
|
||||
if ret:
|
||||
desc += f"ID:{indname}/{curr_val} above {maximum_val=} /"
|
||||
else:
|
||||
desc += f"ID:{indname}{curr_val} OK below {maximum_val=} /"
|
||||
retboolList.append(ret)
|
||||
else:
|
||||
desc += f"ID:{indname} - no max set /"
|
||||
retboolList.append(False)
|
||||
#pokud obsahuje aspon jedno true
|
||||
slopehigh = any(retboolList)
|
||||
|
||||
#DEBUG - poté zapsat jen když je True
|
||||
if slopehigh:
|
||||
state.ilog(e=f"SLOPEHIGH {slopehigh}", msg=desc)
|
||||
|
||||
return slopehigh
|
||||
|
||||
#resetujeme, kdyz 1) je aktivni buy protection 2) kdyz to ujede
|
||||
#TODO mozna tick2reset spoustet jednou za X opakovani
|
||||
def pendingbuys_optimalization():
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
if buy_protection_enabled():
|
||||
#state.ilog(e="PENDINGBUYS reset", message=inspect.currentframe().f_code.co_name)
|
||||
#misto volani buy_protection vytvarime direktivu cancel_pendingbuys
|
||||
|
||||
#pouze jako OR
|
||||
#cancel_pendingbuys_above
|
||||
#cancel_pendingbuys_below
|
||||
|
||||
pb_dict= get_work_dict_with_directive(starts_with="cancel_pendingbuys_if")
|
||||
|
||||
state.ilog(e=f"CANCEL PB work_dict", message=pb_dict)
|
||||
#u techto ma smysl pouze OR
|
||||
cond = create_conditions_from_directives(pb_dict, "OR")
|
||||
result, conditions_met = eval_cond_dict(cond)
|
||||
state.ilog(e=f"CANCEL PB =OR= {result}", **conditions_met)
|
||||
if result:
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e="CANCEL pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
else:
|
||||
@ -645,18 +413,6 @@ def next(data, state: StrategyState):
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB prazdne nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
##kdy nesmí být žádné nákupní objednávky - zruší se
|
||||
def buy_protection_enabled():
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY_PROTECTION {cond_met}", message=cond_met)
|
||||
return result
|
||||
|
||||
def sell_protection_enabled():
|
||||
options = safe_get(state.vars, 'sell_protection', None)
|
||||
if options is None:
|
||||
@ -669,147 +425,222 @@ def next(data, state: StrategyState):
|
||||
disable_sell_proteciton_when['disabled_in_config'] = safe_get(options, 'enabled', False) is False
|
||||
#too good to be true (maximum profit)
|
||||
#disable_sell_proteciton_when['tgtbt_reached'] = safe_get(options, 'tgtbt', False) is False
|
||||
|
||||
disable_sell_proteciton_when['disable_if_positions_above'] = int(safe_get(options, 'disable_if_positions_above', 0)) < state.positions
|
||||
|
||||
#testing preconditions
|
||||
result, conditions_met = eval_cond_dict(disable_sell_proteciton_when)
|
||||
if result:
|
||||
state.ilog(e=f"SELL_PROTECTION DISABLED by precondition {conditions_met}")
|
||||
state.ilog(e=f"SELL_PROTECTION DISABLED by {conditions_met}", **conditions_met)
|
||||
return False
|
||||
|
||||
dont_sell_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
work_dict_dont_sell_if = get_work_dict_with_directive(starts_with="dont_sell_if")
|
||||
state.ilog(e=f"SELL PROTECTION work_dict", message=work_dict_dont_sell_if)
|
||||
|
||||
#IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později
|
||||
|
||||
#pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3)
|
||||
|
||||
#TODO zkusit pro pevny profit, jednoduse pozdrzet prodej - dokud tick_price roste nebo se drzi tak neprodavat, pokud klesne prodat
|
||||
#mozna mit dva mody - pri vetsi volatilite pouzivat momentum, pri mensi nebo kdyz potrebuju pryc, tak prodat hned
|
||||
|
||||
|
||||
#toto docasne pryc dont_sell_when['slope_too_high'] = slope_too_high() and not isfalling(state.indicators.slopeMA,4)
|
||||
dont_sell_when['AND']['slopeMA_rising'] = isrising(state.indicators.slopeMA,safe_get(options, 'slopeMA_rising', 2))
|
||||
dont_sell_when['AND']['rsi_not_falling'] = not isfalling(state.indicators.RSI14,safe_get(options, 'rsi_not_falling',3))
|
||||
#dont_sell_when['rsi_dont_buy'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
|
||||
result, conditions_met = eval_cond_dict(dont_sell_when)
|
||||
or_cond = create_conditions_from_directives(work_dict_dont_sell_if, "OR")
|
||||
result, conditions_met = eval_cond_dict(or_cond)
|
||||
state.ilog(e=f"SELL PROTECTION =OR= {result}", **conditions_met)
|
||||
if result:
|
||||
state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled")
|
||||
return True
|
||||
|
||||
#OR neprosly testujeme AND
|
||||
and_cond = create_conditions_from_directives(work_dict_dont_sell_if, "AND")
|
||||
result, conditions_met = eval_cond_dict(and_cond)
|
||||
state.ilog(e=f"SELL PROTECTION =AND= {result}", **conditions_met)
|
||||
return result
|
||||
|
||||
#preconditions and conditions of BUY SIGNAL
|
||||
def buy_conditions_met():
|
||||
#preconditions
|
||||
# #IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později
|
||||
|
||||
# #pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3)
|
||||
|
||||
# #TODO zkusit pro pevny profit, jednoduse pozdrzet prodej - dokud tick_price roste nebo se drzi tak neprodavat, pokud klesne prodat
|
||||
# #mozna mit dva mody - pri vetsi volatilite pouzivat momentum, pri mensi nebo kdyz potrebuju pryc, tak prodat hned
|
||||
|
||||
#puvodni nastaveni
|
||||
# slopeMA_rising = 2
|
||||
# rsi_not_falling = 3
|
||||
|
||||
|
||||
# #testing preconditions
|
||||
# result, conditions_met = eval_cond_dict(disable_sell_proteciton_when)
|
||||
# if result:
|
||||
# state.ilog(e=f"SELL_PROTECTION DISABLED by precondition {conditions_met}")
|
||||
# return False
|
||||
|
||||
# dont_sell_when = dict(AND=dict(), OR=dict())
|
||||
# ##add conditions here
|
||||
|
||||
# #IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později
|
||||
|
||||
# #pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3)
|
||||
|
||||
# #TODO zkusit pro pevny profit, jednoduse pozdrzet prodej - dokud tick_price roste nebo se drzi tak neprodavat, pokud klesne prodat
|
||||
# #mozna mit dva mody - pri vetsi volatilite pouzivat momentum, pri mensi nebo kdyz potrebuju pryc, tak prodat hned
|
||||
|
||||
# #TOTO do budoucna zdynamictit
|
||||
|
||||
# #toto docasne pryc dont_sell_when['slope_too_high'] = slope_too_high() and not isfalling(state.indicators.slopeMA,4)
|
||||
# dont_sell_when['AND']['slopeMA_rising'] = isrising(state.indicators.slopeMA,safe_get(options, 'slopeMA_rising', 2))
|
||||
# dont_sell_when['AND']['rsi_not_falling'] = not isfalling(state.indicators.RSI14,safe_get(options, 'rsi_not_falling',3))
|
||||
# #dont_sell_when['rsi_dont_buy'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
|
||||
# result, conditions_met = eval_cond_dict(dont_sell_when)
|
||||
# if result:
|
||||
# state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled")
|
||||
# return result
|
||||
|
||||
#preconditions and conditions of BUY SIGNAL
|
||||
def conditions_met():
|
||||
#preconditions - TODO zdynamictit
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
|
||||
#OBECNE DONT BUYS
|
||||
if safe_get(state.vars, "buy_only_on_confirmed",True):
|
||||
dont_buy_when['bar_not_confirmed'] = (data['confirmed'] == 0)
|
||||
#od posledniho vylozeni musi ubehnout N baru
|
||||
dont_buy_when['last_buy_offset_too_soon'] = data['index'] < (int(state.vars.lastbuyindex) + int(safe_get(state.vars, "lastbuy_offset",3)))
|
||||
dont_buy_when['blockbuy_active'] = (state.vars.blockbuy == 1)
|
||||
dont_buy_when['jevylozeno_active'] = (state.vars.jevylozeno == 1)
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
dont_buy_when['slope_too_high'] = slope_too_high()
|
||||
dont_buy_when['open_rush'] = is_open_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "open_rush",0))
|
||||
dont_buy_when['close_rush'] = is_close_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "close_rush",0))
|
||||
dont_buy_when['rsi_is_zero'] = (state.indicators.RSI14[-1] == 0)
|
||||
dont_buy_when['reverse_position_waiting_amount_not_0'] = (state.vars.reverse_position_waiting_amount != 0)
|
||||
|
||||
#testing preconditions
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY precondition not met {cond_met}", message=cond_met)
|
||||
state.ilog(e=f"BUY PRECOND GENERAL not met {cond_met}", message=cond_met)
|
||||
return False
|
||||
|
||||
#conditions - bud samostatne nebo v groupe - ty musi platit dohromady
|
||||
buy_cond = dict(AND=dict(), OR=dict())
|
||||
##add buy conditions here
|
||||
#cond groups ["AND"]
|
||||
#cond groups ["OR"]
|
||||
#no cond group - takes first
|
||||
#TEST BUY SIGNALu z cbartick_price - 3klesave za sebou
|
||||
#buy_cond['tick_price_falling_trend'] = isfalling(state.cbar_indicators.tick_price,state.vars.Trend)
|
||||
#SPECIFICKE DONT BUYS - direktivy zacinajici dont_buy
|
||||
#dont_buy_below = value nebo nazev indikatoru
|
||||
#dont_buy_above = value nebo hazev indikatoru
|
||||
|
||||
#slopeMA jde dolu, rsi jde nahoru
|
||||
#buy mame kazdy potvrzeny, tzn. rsi falling muze byt jen 2
|
||||
#do INITU
|
||||
work_dict_dont_buy = get_work_dict_with_directive(starts_with="dont_buy_if")
|
||||
|
||||
#buy_cond['AND']['slopeMA_falling'] = isfalling(state.indicators.slopeMA,3)
|
||||
#buy_cond['AND']['rsi_is_rising'] = isrising(state.indicators.RSI14,2)
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
state.ilog(e=f"BUY PRECOND DONTBUY work_dict", message=work_dict_dont_buy)
|
||||
#u techto ma smysl pouze OR
|
||||
precond = create_conditions_from_directives(work_dict_dont_buy, "OR")
|
||||
result, conditions_met = eval_cond_dict(precond)
|
||||
state.ilog(e=f"BUY PRECOND DONTBUY =OR= {result}", **conditions_met)
|
||||
if result:
|
||||
return False
|
||||
|
||||
#puvodni buy conditiony RSI pod + EMA klesajici
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
#buy_cond["AND"]["ema_trend_is_falling"] = isfalling(state.indicators.ema,state.vars.Trend)
|
||||
#tyto timto nahrazeny - dat do konfigurace
|
||||
#dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
#dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
#dont_buy_when['slope_too_high'] = slope_too_high()
|
||||
#dont_buy_when['rsi_is_zero'] = (state.indicators.RSI14[-1] == 0)
|
||||
#dont_buy_when['reverse_position_waiting_amount_not_0'] = (state.vars.reverse_position_waiting_amount != 0)
|
||||
|
||||
|
||||
#cela tato sekce prepracovana do dynamickych podminek
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
#buy_cond["AND"]["rsi_is_falling"] = isfalling(state.indicators.RSI14,state.vars.Trend)
|
||||
#buy_cond["AND"]['crsi_below_crsi_buy_limit'] = state.cbar_indicators.CRSI[-1] < safe_get(state.vars, "crsi_buy_signal_below",25)
|
||||
#buy_cond["AND"]['slopeMA_is_below_limit'] = state.indicators.slopeMA[-1] < safe_get(state.vars, "slopeMA_buy_signal_below",1)
|
||||
|
||||
#TBD nize prepracovat do funkce a pouzit obecne
|
||||
# do pole podminek pridame podminky z indikatoru, ktere maji nastavenou direktivu buy_if_cross_down(up)
|
||||
#buy_cond["AND"].update(get_conditions_from_indicators_with_directive("buy_if_cross_down"))
|
||||
|
||||
#u indikatoru muzoun byt tyto directivy pro generovani buysignalu
|
||||
# buy_if_crossed_down - kdyz prekrocil dolu
|
||||
# buy_if_crossed_up - kdyz prekrocil nahoru
|
||||
# buy_if_is_falling - kdyz je klesajici po N
|
||||
# buy_if_is_rising - kdyz je rostouci po N
|
||||
# buy_if_is_below - kdyz je pod prahem
|
||||
# buy_if_is_above - kdyz je nad prahem
|
||||
# buy_if_crossed_down - kdyz prekrocil dolu, VALUE: hodnota nebo nazev indikatoru
|
||||
# buy_if_crossed_up - kdyz prekrocil nahoru, VALUE: hodnota nebo nazev indikatoru
|
||||
# buy_if_falling - kdyz je klesajici po N, VALUE: hodnota
|
||||
# buy_if_rising - kdyz je rostouci po N, VALUE: hodnota
|
||||
# buy_if_below - kdyz je pod prahem, VALUE: hodnota nebo nazev indikatoru
|
||||
# buy_if_above - kdyz je nad prahem, VALUE: hodnota nebo nazev indikatoru
|
||||
# buy_if_pivot_a - kdyz je pivot A. VALUE: delka nohou
|
||||
# buy_if_pivot_v - kdyz je pivot V. VALUE: delka nohou
|
||||
|
||||
#sekce pro dynamicke vytvareni podminek - pokud indikatory maji nastavenou buysignal direktivu
|
||||
#dotahneme si jejich value a vytvorime podminku (plati AND)
|
||||
# direktivy se mohou nachazet v podsekci AND nebo OR - daneho indikatoru (nebo na volno, pak = OR)
|
||||
# OR - staci kdyz plati jedna takova podminka a buysignal je aktivni
|
||||
# AND - musi platit vsechny podminky ze vsech indikatoru, aby byl buysignal aktivni
|
||||
|
||||
indicators_with_is_above = get_indicators_with_directive("buy_if_is_above")
|
||||
for indicator, value in indicators_with_is_above:
|
||||
buy_cond["AND"]["buy_if_is_above_"+indicator] = get_source_or_MA(indicator)[-1] > value
|
||||
#populate work dict - muze byt i jen jednou v INIT nebo 1x za cas
|
||||
#dict oindexovane podminkou (OR/AND) obsahuje vsechny buy_if direktivy v tuplu (nazevind,direktiva,hodnota
|
||||
# {'AND': [('nazev indikatoru', 'nazev direktivy', 'hodnotadirektivy')], 'OR': []}
|
||||
work_dict_buy_if = get_work_dict_with_directive(starts_with="buy_if")
|
||||
state.ilog(e=f"BUY SIGNAL work_dict", message=work_dict_buy_if)
|
||||
|
||||
indicators_with_is_below = get_indicators_with_directive("buy_if_is_below")
|
||||
for indicator, value in indicators_with_is_below:
|
||||
buy_cond["AND"]["buy_if_is_below_"+indicator] = get_source_or_MA(indicator)[-1] < value
|
||||
buy_or_cond = create_conditions_from_directives(work_dict_buy_if, "OR")
|
||||
result, conditions_met = eval_cond_dict(buy_or_cond)
|
||||
state.ilog(e=f"BUY SIGNAL =OR= {result}", **conditions_met)
|
||||
if result:
|
||||
return True
|
||||
|
||||
indicators_with_is_falling = get_indicators_with_directive("buy_if_is_falling")
|
||||
for indicator, value in indicators_with_is_falling:
|
||||
buy_cond["AND"]["buy_if_is_falling_"+indicator] = isfalling(get_source_or_MA(indicator),value)
|
||||
|
||||
|
||||
indicators_with_is_rising = get_indicators_with_directive("buy_if_is_rising")
|
||||
for indicator, value in indicators_with_is_rising:
|
||||
buy_cond["AND"]["buy_if_is_rising_"+indicator] = isrising(get_source_or_MA(indicator),value)
|
||||
|
||||
indicators_with_cross_down = get_indicators_with_directive("buy_if_crossed_down")
|
||||
for indicator, value in indicators_with_cross_down:
|
||||
buy_cond["AND"]["buy_if_crossed_down_"+indicator] = buy_if_crossed_down(indicator, value)
|
||||
|
||||
indicators_with_cross_up = get_indicators_with_directive("buy_if_crossed_up")
|
||||
for indicator, value in indicators_with_cross_up:
|
||||
buy_cond["AND"]["buy_if_crossed_up_"+indicator] = buy_if_crossed_up(indicator, value)
|
||||
|
||||
|
||||
#slopME klesa a RSI začalo stoupat
|
||||
# buy_cond["AND"]["rsi_is_rising2"] = isrising(state.indicators.RSI14,2)
|
||||
# buy_cond['AND']['slopeMA_falling_Trend'] = isfalling(state.indicators.slopeMA,state.vars.Trend)
|
||||
# buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
#zkusit jako doplnkovy BUY SIGNAL 3 klesavy cbar RSI pripadne TICK PRICE
|
||||
result, conditions_met = eval_cond_dict(buy_cond)
|
||||
#if result:
|
||||
state.ilog(e=f"BUY SIGNAL {result} {conditions_met}")
|
||||
#OR neprosly testujeme AND
|
||||
buy_and_cond = create_conditions_from_directives(work_dict_buy_if, "AND")
|
||||
result, conditions_met = eval_cond_dict(buy_and_cond)
|
||||
state.ilog(e=f"BUY SIGNAL =AND= {result}", **conditions_met)
|
||||
return result
|
||||
|
||||
#vrati vsechny indikatory, ktere obsahuji danou directivu a vrati v listu tuple (nazev, hodnota)
|
||||
def get_indicators_with_directive(directive):
|
||||
reslist = []
|
||||
#preklad direktivy podle typu, pokud je int anebo float - je to primo hodnota
|
||||
#pokud je str, jde o indikator a dotahujeme posledni hodnotu z nej
|
||||
def value_or_indicator(value):
|
||||
if isinstance(value, (int, float)):
|
||||
return value
|
||||
elif isinstance(value, str):
|
||||
try:
|
||||
#pokud existuje MA bereme MA jinak standard
|
||||
ret = get_source_or_MA(indicator=value)[-1]
|
||||
state.ilog(e=f"Pro porovnani bereme posledni hodnotu {ret} z indikatoru {value}")
|
||||
except Exception as e :
|
||||
ret = 0
|
||||
state.ilog(e=f"Neexistuje indikator s nazvem {value} vracime 0" + str(e) + format_exc())
|
||||
return ret
|
||||
|
||||
#funkce vytvori podminky (bud pro AND/OR) z pracovniho dict
|
||||
def create_conditions_from_directives(work_dict, cond_type):
|
||||
cond = {}
|
||||
cond[cond_type] = {}
|
||||
for indname, directive, value in work_dict[cond_type]:
|
||||
#direktivy zobecnime ve tvaru prefix_ACTION
|
||||
# ACTIONS = is_above, is_below, is_falling, is_rising, crossed_up, crossed_down, is_pivot_a, is_pivot_v
|
||||
|
||||
#OBECNE DIREKTIVY - REUSOVATELNE
|
||||
if directive.endswith("above"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = get_source_or_MA(indname)[-1] > value_or_indicator(value)
|
||||
elif directive.endswith("below"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = get_source_or_MA(indname)[-1] < value_or_indicator(value)
|
||||
elif directive.endswith("falling"):
|
||||
if directive.endswith("not_falling"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = not isfalling(get_source_or_MA(indname),value)
|
||||
else:
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = isfalling(get_source_or_MA(indname),value)
|
||||
elif directive.endswith("rising"):
|
||||
if directive.endswith("not_rising"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = not isrising(get_source_or_MA(indname),value)
|
||||
else:
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = isrising(get_source_or_MA(indname),value)
|
||||
elif directive.endswith("crossed_down"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = buy_if_crossed_down(indname, value_or_indicator(value))
|
||||
elif directive.endswith("crossed_up"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = buy_if_crossed_up(indname, value_or_indicator(value))
|
||||
elif directive.endswith("pivot_a"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = is_pivot(source=get_source_or_MA(indname), leg_number=value, type="A")
|
||||
elif directive.endswith("pivot_v"):
|
||||
cond[cond_type][directive+"_"+indname+"_"+str(value)] = is_pivot(source=get_source_or_MA(indname), leg_number=value, type="V")
|
||||
|
||||
#PRIPADNE DALSI SPECIFICKE ZDE
|
||||
# elif directive == "buy_if_necospecifckeho":
|
||||
# pass
|
||||
|
||||
return cond
|
||||
|
||||
|
||||
#tato funkce vytvori dictionary typu podminek (OR/AND)
|
||||
# z indikatoru, ktere obsahuji direktivami daneho typu(buy_if, dont_buy_when)
|
||||
# v tuplu (nazevind,direktiva,hodnota)
|
||||
# do OR jsou dane i bez prefixu
|
||||
# {'AND': [('nazev indikatoru', 'nazev direktivy', 'hodnotadirektivy')], 'OR': []}
|
||||
def get_work_dict_with_directive(starts_with: str):
|
||||
reslist = dict(AND=[], OR=[])
|
||||
|
||||
for indname, indsettings in state.vars.indicators.items():
|
||||
for option,value in indsettings.items():
|
||||
if option == directive:
|
||||
reslist.append((indname, value))
|
||||
if option.startswith(starts_with):
|
||||
reslist["OR"].append((indname, option, value))
|
||||
if option == "AND":
|
||||
#vsechny buy direktivy, ktere jsou pod AND
|
||||
for key, val in value.items():
|
||||
if key.startswith(starts_with):
|
||||
reslist["AND"].append((indname, key, val))
|
||||
if option == "OR" :
|
||||
#vsechny buy direktivy, ktere jsou pod OR
|
||||
for key, val in value.items():
|
||||
if key.startswith(starts_with):
|
||||
reslist["OR"].append((indname, key, val))
|
||||
return reslist
|
||||
|
||||
def get_source_or_MA(indicator):
|
||||
@ -832,7 +663,7 @@ def next(data, state: StrategyState):
|
||||
return res
|
||||
|
||||
def eval_buy():
|
||||
if buy_conditions_met():
|
||||
if conditions_met():
|
||||
vyloz()
|
||||
|
||||
def populate_cbar_tick_price_indicator():
|
||||
@ -863,11 +694,11 @@ def next(data, state: StrategyState):
|
||||
#print(state.indicators.items())
|
||||
for key in state.indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.indicators[key][-5:]
|
||||
last_ind_vals[key] = state.indicators[key][-6:]
|
||||
|
||||
for key in state.cbar_indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.cbar_indicators[key][-5:]
|
||||
last_ind_vals[key] = state.cbar_indicators[key][-6:]
|
||||
|
||||
# for key in state.secondary_indicators:
|
||||
# if key != 'time':
|
||||
@ -918,14 +749,14 @@ def next(data, state: StrategyState):
|
||||
if on_confirmed_only is False or (on_confirmed_only is True and data['confirmed']==1):
|
||||
try:
|
||||
source = state.bars[req_source][-ema_length:]
|
||||
if len(source) > ema_length:
|
||||
#if len(source) > ema_length:
|
||||
ema_value = ema(source, ema_length)
|
||||
val = ema_value[-1]
|
||||
val = round(ema_value[-1],4)
|
||||
state.indicators[name][-1]= val
|
||||
#state.indicators[name][-1]= round2five(val)
|
||||
state.ilog(e=f"IND {name} EMA {val} {ema_length=}")
|
||||
else:
|
||||
state.ilog(e=f"IND {name} EMA necháváme 0", message="not enough source data", source=source, ema_length=ema_length)
|
||||
#else:
|
||||
# state.ilog(e=f"IND {name} EMA necháváme 0", message="not enough source data", source=source, ema_length=ema_length)
|
||||
except Exception as e:
|
||||
state.ilog(e=f"IND ERROR {name} EMA necháváme 0", message=str(e)+format_exc())
|
||||
|
||||
@ -958,14 +789,14 @@ def next(data, state: StrategyState):
|
||||
#cekame na dostatek dat
|
||||
if len(source) > rsi_length:
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],4)
|
||||
rsi_value = round(rsi_res[-1],4)
|
||||
state.indicators[name][-1]=rsi_value
|
||||
state.ilog(e=f"IND {name} RSI {rsi_value}")
|
||||
|
||||
if rsi_MA_length is not None:
|
||||
src = state.indicators[name][-rsi_MA_length:]
|
||||
rsi_MA_res = ema(src, rsi_MA_length)
|
||||
rsi_MA_value = rsi_MA_res[-1]
|
||||
rsi_MA_value = round(rsi_MA_res[-1],4)
|
||||
state.indicators[name+"MA"][-1]=rsi_MA_value
|
||||
state.ilog(e=f"IND {name} RSIMA {rsi_MA_value}")
|
||||
|
||||
@ -1077,7 +908,7 @@ def next(data, state: StrategyState):
|
||||
if slope_MA_length is not None:
|
||||
source = state.indicators[name][-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
slopeMA = round(slopeMAseries[-1],5)
|
||||
state.indicators[name+"MA"][-1]=slopeMA
|
||||
last_slopesMA = state.indicators[name+"MA"][-10:]
|
||||
|
||||
@ -1089,7 +920,6 @@ def next(data, state: StrategyState):
|
||||
print(f"Exception in {name} slope Indicator section", str(e))
|
||||
state.ilog(e=f"EXCEPTION in {name}", msg="Exception in slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
|
||||
def populate_dynamic_slope_indicator(name):
|
||||
options = safe_get(state.vars.indicators, name, None)
|
||||
if options is None:
|
||||
@ -1167,7 +997,7 @@ def next(data, state: StrategyState):
|
||||
if slope_MA_length is not None:
|
||||
source = state.indicators[name][-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
slopeMA = round(slopeMAseries[-1],4)
|
||||
state.indicators[name+"MA"][-1]=slopeMA
|
||||
last_slopesMA = state.indicators[name+"MA"][-10:]
|
||||
|
||||
@ -1231,7 +1061,8 @@ def next(data, state: StrategyState):
|
||||
#lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
lp = data['close']
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", pb=str(state.vars.pendingbuys), last_price=lp, data=data, stratvars=str(state.vars))
|
||||
state.ilog(e="Indikatory", msg=str(get_last_ind_vals()))
|
||||
inds = get_last_ind_vals()
|
||||
state.ilog(e="Indikatory", **inds)
|
||||
|
||||
eval_buy()
|
||||
pendingbuys_optimalization()
|
||||
@ -1244,7 +1075,8 @@ def init(state: StrategyState):
|
||||
#pro vsechny indikatory, ktere maji ve svych stratvars TYPE inicializujeme
|
||||
for indname, indsettings in state.vars.indicators.items():
|
||||
for option,value in indsettings.items():
|
||||
if option == "type":
|
||||
#inicializujeme nejenom typizovane
|
||||
#if option == "type":
|
||||
state.indicators[indname] = []
|
||||
#pokud ma MA_length incializujeme i MA variantu
|
||||
if safe_get(indsettings, 'MA_length', False):
|
||||
@ -1254,6 +1086,9 @@ def init(state: StrategyState):
|
||||
#inicializujeme statinds (pro uhel na FE)
|
||||
state.statinds[indname] = dict(minimum_slope=safe_get(indsettings, 'minimum_slope', -1), maximum_slope=safe_get(indsettings, 'maximum_slope', 1))
|
||||
|
||||
|
||||
#TODO presunout inicializaci work_dict u podminek - sice hodnoty nepujdou zmenit, ale zlepsi se performance
|
||||
#pripadne udelat refresh kazdych x-iterací
|
||||
state.vars['sell_in_progress'] = False
|
||||
state.vars.mode = None
|
||||
state.vars.last_tick_price = 0
|
||||
@ -1263,14 +1098,21 @@ def init(state: StrategyState):
|
||||
state.vars.lastbuyindex = 0
|
||||
state.vars.last_update_time = 0
|
||||
state.vars.reverse_position_waiting_amount = 0
|
||||
#INIT promenne, ktere byly zbytecne ve stratvars
|
||||
state.vars.pendingbuys={}
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price=0
|
||||
state.vars.jevylozeno=0
|
||||
state.vars.blockbuy = 0
|
||||
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
#state.cbar_indicators['ivwap'] = []
|
||||
state.cbar_indicators['tick_price'] = []
|
||||
state.cbar_indicators['tick_volume'] = []
|
||||
state.cbar_indicators['CRSI'] = []
|
||||
#state.secondary_indicators['SRSI'] = []
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
#state.indicators['ema'] = []
|
||||
#state.indicators['RSI14'] = []
|
||||
|
||||
initialize_dynamic_indicators()
|
||||
|
||||
|
||||
7
v2realbot/slicingtest.py
Normal file
7
v2realbot/slicingtest.py
Normal file
@ -0,0 +1,7 @@
|
||||
word = "buy_if_not_something"
|
||||
|
||||
|
||||
if word.endswith("something") and word[:-len] == "not_":
|
||||
print("Word meets the condition.")
|
||||
else:
|
||||
print("Word does not meet the condition.")
|
||||
@ -22,6 +22,7 @@ settings = {}
|
||||
settings
|
||||
//ostatni indicatory nez vwap, volume a bary
|
||||
indConfig = [ {name: "ema", titlevisible: false, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
|
||||
{name: "ema20", titlevisible: false, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
|
||||
{name: "tick_volume", histogram: true, titlevisible: true, embed: true, display: true, priceScaleId: '', lastValueVisible: false},
|
||||
{name: "tick_price", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
|
||||
{name: "ivwap", titlevisible: true, embed: true, display: false, priceScaleId: "right", lastValueVisible: false},
|
||||
@ -38,6 +39,7 @@ indConfig = [ {name: "ema", titlevisible: false, embed: true, display: true, pri
|
||||
{name: "emaSlow", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
|
||||
{name: "emaFast", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},
|
||||
{name: "RSI14", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
|
||||
{name: "RSI14MA", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
|
||||
{name: "CRSI", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
|
||||
{name: "aroon", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
|
||||
{name: "apo", titlevisible: true, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false},
|
||||
|
||||
Binary file not shown.
@ -23,10 +23,36 @@ import numpy as np
|
||||
import pandas as pd
|
||||
from collections import deque
|
||||
|
||||
|
||||
#is_pivot function to check if there is A(V) shaped pivot in the list, each leg consists of N points
|
||||
#middle point is the shared one [1,2,3,2,1] - one leg is [1,2,3] second leg is [3,2,1]
|
||||
def is_pivot(source: list, leg_number: int, type: str = "A"):
|
||||
if len(source) < (2 * leg_number)-1:
|
||||
print("Not enough values in the list")
|
||||
return False
|
||||
|
||||
left_leg = source[-2*leg_number+1:-leg_number+1]
|
||||
right_leg = source[-leg_number:]
|
||||
|
||||
if type == "A":
|
||||
if isrising(left_leg) and isfalling(right_leg):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif type == "V":
|
||||
if isfalling(left_leg) and isrising(right_leg):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
print("Unknown type")
|
||||
return False
|
||||
|
||||
def crossed_up(threshold, list):
|
||||
"""check if threshold has crossed up last thresholdue in list"""
|
||||
try:
|
||||
if threshold < list[-1] and threshold >= list[-2]:
|
||||
#upraveno, ze threshold muze byt vetsi nez predpredposledni
|
||||
if threshold < list[-1] and threshold >= list[-2] or threshold < list[-1] and threshold >= list[-3]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@ -36,7 +62,8 @@ def crossed_up(threshold, list):
|
||||
def crossed_down(threshold, list):
|
||||
"""check if threshold has crossed down last thresholdue in list"""
|
||||
try:
|
||||
if threshold > list[-1] and threshold <= list[-2]:
|
||||
#upraveno, ze threshold muze byt mensi nez predpredposledni
|
||||
if threshold > list[-1] and threshold <= list[-2] or threshold > list[-1] and threshold <= list[-3]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@ -281,13 +308,17 @@ def is_open_hours(dt, business_hours: dict = None):
|
||||
and dt.date() not in holidays \
|
||||
and business_hours["from"] <= dt.time() < business_hours["to"]
|
||||
|
||||
def isfalling(pole: list, pocet: int):
|
||||
#vraci zda dane pole je klesajici (bud cele a nebo jen pocet poslednich)
|
||||
def isfalling(pole: list, pocet: int = None):
|
||||
if pocet is None: pocet = len(pole)
|
||||
if len(pole)<pocet: return False
|
||||
pole = pole[-pocet:]
|
||||
res = all(i > j for i, j in zip(pole, pole[1:]))
|
||||
return res
|
||||
|
||||
def isrising(pole: list, pocet: int):
|
||||
#vraci zda dane pole je roustouci (bud cele a nebo jen pocet poslednich)
|
||||
def isrising(pole: list, pocet: int = None):
|
||||
if pocet is None: pocet = len(pole)
|
||||
if len(pole)<pocet: return False
|
||||
pole = pole[-pocet:]
|
||||
res = all(i < j for i, j in zip(pole, pole[1:]))
|
||||
|
||||
Reference in New Issue
Block a user