balik zmen uff
This commit is contained in:
96
v2realbot/strategyblocks/activetrade/close/eod_exit.py
Normal file
96
v2realbot/strategyblocks/activetrade/close/eod_exit.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, Followup
|
||||
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus
|
||||
from v2realbot.utils.utils import isrising, isfalling,zoneNY, price2dec, print, safe_get, is_still, is_window_open, eval_cond_dict, crossed_down, crossed_up, crossed, is_pivot, json_serial, pct_diff, create_new_bars, slice_dict_lists
|
||||
from v2realbot.utils.directive_utils import get_conditions_from_configuration
|
||||
from v2realbot.ml.mlutils import load_model
|
||||
from v2realbot.common.model import SLHistory
|
||||
from v2realbot.config import KW
|
||||
from uuid import uuid4
|
||||
from datetime import datetime
|
||||
#import random
|
||||
import json
|
||||
import numpy as np
|
||||
#from icecream import install, ic
|
||||
from rich import print as printanyway
|
||||
from threading import Event
|
||||
import os
|
||||
from traceback import format_exc
|
||||
from v2realbot.strategyblocks.activetrade.helpers import insert_SL_history
|
||||
from v2realbot.strategyblocks.activetrade.close.conditions import dontexit_protection_met, exit_conditions_met
|
||||
from v2realbot.strategyblocks.activetrade.helpers import get_max_profit_price, get_profit_target_price, get_override_for_active_trade, keyword_conditions_met
|
||||
|
||||
|
||||
def eod_exit_activated(state: StrategyState, data, direction: TradeDirection):
|
||||
"""
|
||||
Function responsible for end of day management
|
||||
|
||||
V budoucnu bude obsahovat optimalizace pro uzaviraci okno
|
||||
(obsahuje subokna - nejprve ceka na snizený profit, pak na minimálně breakeven a naposledy až forced exit)
|
||||
|
||||
1) zatim pouze - na breakeven(cele okno) + forced exit(posledni minuta)
|
||||
|
||||
|
||||
do budoucna udelat interpolacni krivku s ubývajícím časem na snížování profit
|
||||
tzn. mam např. 60minut, tak rozdělím 4:2 +poslední minuta
|
||||
- 40 snižující profit (aktuální profit je např. 0.20ticků - tzn. 40 je 0.20, 0 je 0) - print(np.interp(atr10, [1, 10,11,12], [0, 1,100,1]))
|
||||
- 19 waiting for breakeven
|
||||
- 1 min forced immediate
|
||||
"""
|
||||
|
||||
directive_name = "forced_exit_window_start"
|
||||
forced_exit_window_start = get_override_for_active_trade(state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, None))
|
||||
|
||||
if forced_exit_window_start is None:
|
||||
state.ilog(lvl=0,e="Forced exit not required.")
|
||||
return False
|
||||
|
||||
|
||||
directive_name = "forced_exit_window_end"
|
||||
forced_exit_window_end = get_override_for_active_trade(state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, 389))
|
||||
|
||||
if forced_exit_window_start>389:
|
||||
state.ilog(lvl=0,e="Forced exit window end max is 389")
|
||||
return False
|
||||
|
||||
#TBD - mozna brat skutecny cas (state.time) - nez cas tradu? mozna do budoucna
|
||||
if is_window_open(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), forced_exit_window_start, forced_exit_window_end) is False:
|
||||
state.ilog(lvl=1,e=f"Forced Exit Window CLOSED", msg=f"{forced_exit_window_start=} {forced_exit_window_end=} ", time=str(datetime.fromtimestamp(data['updated']).astimezone(zoneNY)))
|
||||
return False
|
||||
|
||||
# #dokdy konci okno snizujiciho se profitu (zbytek je breakeven a posledni minuta forced) - default pulka okna
|
||||
# directive_name = "forced_exit_decreasing_profit_window_end"
|
||||
# forced_exit_decreasing_profit_window_end = get_override_for_active_trade(state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, (forced_exit_window_end-forced_exit_window_end)/2))
|
||||
|
||||
# if forced_exit_decreasing_profit_window_end > forced_exit_window_end-1:
|
||||
# state.ilog(lvl=0,e="Decreasing profit window must be less than window end -1.")
|
||||
# return False
|
||||
|
||||
#TODO v rámci profit optimalizace, udelat decreasing profit window direktivu jez kontroluje interpolovaný snizujici zisk až do 0 a pak až jede breakeven
|
||||
#TODO v rámci tech optimalizace nevolat is_window_open dvakrat - volá se per tick
|
||||
if is_window_open(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), forced_exit_window_start, forced_exit_window_end-1) is True:
|
||||
state.ilog(lvl=1,e=f"Forced Exit Window OPEN - breakeven check", msg=f"{forced_exit_window_start=} {forced_exit_window_end=} ", time=str(datetime.fromtimestamp(data['updated']).astimezone(zoneNY)))
|
||||
|
||||
directive_name = "forced_exit_breakeven_period"
|
||||
forced_exit_breakeven_period = get_override_for_active_trade(state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, True))
|
||||
|
||||
if forced_exit_breakeven_period is False:
|
||||
return False
|
||||
|
||||
#zatim krom posledni minuty cekame alespon na breakeven
|
||||
curr_price = float(data['close'])
|
||||
#short smer
|
||||
if direction == TradeDirection.SHORT and curr_price<=float(state.avgp):
|
||||
state.ilog(lvl=1,e=f"Forced Exit - price better than avgp, dir SHORT")
|
||||
return True
|
||||
|
||||
if direction == TradeDirection.LONG and curr_price>=float(state.avgp):
|
||||
state.ilog(lvl=1,e=f"Forced Exit - price better than avgp, dir LONG")
|
||||
return True
|
||||
|
||||
return False
|
||||
else:
|
||||
state.ilog(lvl=1,e=f"Forced Exit - last minute - EXIT IMMEDIATE")
|
||||
return True
|
||||
|
||||
@@ -9,6 +9,7 @@ from rich import print as printanyway
|
||||
from threading import Event
|
||||
import os
|
||||
from traceback import format_exc
|
||||
from v2realbot.strategyblocks.activetrade.close.eod_exit import eod_exit_activated
|
||||
from v2realbot.strategyblocks.activetrade.close.conditions import dontexit_protection_met, exit_conditions_met
|
||||
from v2realbot.strategyblocks.activetrade.helpers import get_max_profit_price, get_profit_target_price, get_override_for_active_trade, keyword_conditions_met
|
||||
|
||||
@@ -26,12 +27,8 @@ def eval_close_position(state: StrategyState, data):
|
||||
#get TARGET PRICE pro dany smer a signal
|
||||
goal_price = get_profit_target_price(state, data, TradeDirection.SHORT)
|
||||
max_price = get_max_profit_price(state, data, TradeDirection.SHORT)
|
||||
state.ilog(lvl=1,e=f"Goal price {str(TradeDirection.SHORT)} {goal_price} max price {max_price}")
|
||||
|
||||
|
||||
#EOD EXIT - TBD
|
||||
#FORCED EXIT PRI KONCI DNE
|
||||
|
||||
state.ilog(lvl=1,e=f"Goal price {str(TradeDirection.SHORT)} {goal_price} max price {max_price}")
|
||||
|
||||
#SL - execution
|
||||
if curr_price > state.vars.activeTrade.stoploss_value:
|
||||
|
||||
@@ -46,6 +43,7 @@ def eval_close_position(state: StrategyState, data):
|
||||
followup_action = None
|
||||
close_position(state=state, data=data, direction=TradeDirection.SHORT, reason="SL REACHED", followup=followup_action)
|
||||
return
|
||||
|
||||
|
||||
#REVERSE BASED ON REVERSE CONDITIONS
|
||||
if keyword_conditions_met(state, data, direction=TradeDirection.SHORT, keyword=KW.reverse):
|
||||
@@ -82,6 +80,12 @@ def eval_close_position(state: StrategyState, data):
|
||||
if max_price_signal or dontexit_protection_met(state=state, data=data,direction=TradeDirection.SHORT) is False:
|
||||
close_position(state=state, data=data, direction=TradeDirection.SHORT, reason=f"PROFIT or MAXPROFIT REACHED {max_price_signal=}")
|
||||
return
|
||||
|
||||
#FORCED EXIT PRI KONCI DNE
|
||||
if eod_exit_activated(state, data, TradeDirection.SHORT):
|
||||
close_position(state=state, data=data, direction=TradeDirection.SHORT, reason="EOD EXIT ACTIVATED")
|
||||
return
|
||||
|
||||
#mame long
|
||||
elif int(state.positions) > 0:
|
||||
|
||||
@@ -145,3 +149,8 @@ def eval_close_position(state: StrategyState, data):
|
||||
if max_price_signal or dontexit_protection_met(state, data, direction=TradeDirection.LONG) is False:
|
||||
close_position(state=state, data=data, direction=TradeDirection.LONG, reason=f"PROFIT or MAXPROFIT REACHED {max_price_signal=}")
|
||||
return
|
||||
|
||||
#FORCED EXIT PRI KONCI DNE
|
||||
if eod_exit_activated(state, data, TradeDirection.LONG):
|
||||
close_position(state=state, data=data, direction=TradeDirection.LONG, reason="EOD EXIT ACTIVATED")
|
||||
return
|
||||
@@ -9,6 +9,7 @@ from v2realbot.common.model import SLHistory
|
||||
from v2realbot.config import KW
|
||||
from uuid import uuid4
|
||||
from datetime import datetime
|
||||
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
|
||||
#import random
|
||||
import json
|
||||
import numpy as np
|
||||
|
||||
@@ -3,7 +3,7 @@ from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from traceback import format_exc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series, value_or_indicator
|
||||
|
||||
#RSI INDICATOR
|
||||
# type = RSI, source = [close, vwap, hlcc4], rsi_length = [14], MA_length = int (optional), on_confirmed_only = [true, false]
|
||||
@@ -22,10 +22,11 @@ def populate_dynamic_RSI_indicator(data, state: StrategyState, name):
|
||||
#poustet kazdy tick nebo jenom na confirmed baru (on_confirmed_only = true)
|
||||
on_confirmed_only = safe_get(options, 'on_confirmed_only', False)
|
||||
req_source = safe_get(options, 'source', 'vwap')
|
||||
rsi_length = int(safe_get(options, "length",14))
|
||||
rsi_length = safe_get(options, "length",14)
|
||||
rsi_MA_length = safe_get(options, "MA_length", None)
|
||||
start = safe_get(options, "start","linear") #linear/sharp
|
||||
|
||||
rsi_length = int(value_or_indicator(state, rsi_length))
|
||||
|
||||
if on_confirmed_only is False or (on_confirmed_only is True and data['confirmed']==1):
|
||||
try:
|
||||
|
||||
@@ -4,7 +4,6 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
@@ -5,19 +5,20 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
#indicator allowing to be based on any bar parameter (index, high,open,close,trades,volume, etc.)
|
||||
def barparams(state, params):
|
||||
def barparams(state, params, name):
|
||||
funcName = "barparams"
|
||||
if params is None:
|
||||
return -2, "params required"
|
||||
source = safe_get(params, "source", None)
|
||||
lookback = safe_get(params, "lookback", 1)
|
||||
if source is None:
|
||||
return -2, "source required"
|
||||
try:
|
||||
return 0, state.bars[source][-1]
|
||||
return 0, get_source_series(state, source)[-lookback]
|
||||
#return 0, state.bars[source][-1]
|
||||
except Exception as e:
|
||||
return -2, str(e)+format_exc()
|
||||
|
||||
@@ -4,29 +4,36 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
from scipy.stats import linregress
|
||||
from scipy.fft import fft
|
||||
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
|
||||
|
||||
#vstupem je bud indicator nebo bar parametr
|
||||
#na tomto vstupu dokaze provest zakladni statisticke funkce pro subpole X hodnot zpatky
|
||||
#podporovane functions: min, max, mean
|
||||
def basestats(state, params):
|
||||
def basestats(state, params, name):
|
||||
funcName = "basestats"
|
||||
#name of indicator or
|
||||
source = safe_get(params, "source", None)
|
||||
lookback = safe_get(params, "lookback", None)
|
||||
func = safe_get(params, "function", None)
|
||||
returns = safe_get(params, "returns", None)
|
||||
|
||||
source_dict = defaultdict(list)
|
||||
source_dict[source] = get_source_series(state, source)
|
||||
|
||||
self = state.indicators[name]
|
||||
if lookback is None:
|
||||
source_array = source_dict[source]
|
||||
|
||||
else:
|
||||
lookback = int(value_or_indicator(state, lookback))
|
||||
|
||||
try:
|
||||
source_array = source_dict[source][-lookback-1:]
|
||||
self = self[-lookback-1:]
|
||||
except IndexError:
|
||||
source_array = source_dict[source]
|
||||
|
||||
@@ -69,7 +76,7 @@ def basestats(state, params):
|
||||
try:
|
||||
np.seterr(all="raise")
|
||||
val, _, _, _, _ = linregress(np.arange(len(source_array)), source_array)
|
||||
val = round(val, 4)
|
||||
val = val*1000
|
||||
except FloatingPointError:
|
||||
return -2, "FloatingPointError"
|
||||
#zatim takto, dokud nebudou podporovany indikatory s vice vystupnimi
|
||||
@@ -82,6 +89,60 @@ def basestats(state, params):
|
||||
val = round(val, 4)
|
||||
except FloatingPointError:
|
||||
return -2, "FloatingPointError"
|
||||
elif func == "fourier":
|
||||
time_series = np.array(source_array)
|
||||
n = len(time_series)
|
||||
|
||||
# Compute the Fourier transform
|
||||
yf = fft(time_series)
|
||||
xf = np.linspace(0.0, 1.0/(2.0), n//2)
|
||||
|
||||
dominant_frequencies = xf[np.argsort(np.abs(yf[:n//2]))[-3:]]
|
||||
state.ilog(lvl=1,e=f"IND {name}:{funcName} 3 dominant freq are {str(dominant_frequencies)}", **params)
|
||||
|
||||
if returns is not None:
|
||||
#vracime druhou
|
||||
if returns == "second":
|
||||
if len(dominant_frequencies) > 1:
|
||||
val = dominant_frequencies[-2]
|
||||
else:
|
||||
val = 0
|
||||
else:
|
||||
#vracime most dominant
|
||||
val = float(np.max(dominant_frequencies))
|
||||
return 0, val
|
||||
|
||||
elif func == "maxima":
|
||||
if len(source_array) < 3:
|
||||
return 0, state.bars["high"]
|
||||
|
||||
if len(self) == 0:
|
||||
self_max = 0
|
||||
else:
|
||||
#nejvyssi dosavadni maxima za lookback
|
||||
#self_max = float(np.max(self))
|
||||
#zkusim zatim takto, a dalsi indikator z toho pak bude delat lajny?
|
||||
self_max = self[-2]
|
||||
|
||||
state.ilog(lvl=1,e=f"IND {name}:{funcName} {str(self_max)}", **params)
|
||||
|
||||
# 3 .. 2 nahoru
|
||||
if source_array[-2] > source_array[-3]:
|
||||
# 2 .. 1 dolu - mame pivot
|
||||
if source_array[-2] > source_array[-1]:
|
||||
##jsme max za obdobi
|
||||
if source_array[-2] > self_max:
|
||||
return 0, source_array[-2]
|
||||
else:
|
||||
return 0, self_max
|
||||
# 2 .. 1 nahoru - drzime puvodni -do otocky
|
||||
else:
|
||||
return 0, self_max
|
||||
|
||||
# 3 ..2 dolu drzime max
|
||||
else:
|
||||
return 0, self_max
|
||||
|
||||
else:
|
||||
return -2, "wrong function"
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series, evaluate_directive_conditions
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
@@ -24,7 +23,7 @@ from collections import defaultdict
|
||||
#novy podminkovy indikator, muze obsahovat az N podminek ve stejne syntaxy jako u signalu
|
||||
#u kazde podminky je hodnota, ktera se vraci pokud je true
|
||||
#hodi se pro vytvareni binarnich targetu pro ML
|
||||
def conditional(state, params):
|
||||
def conditional(state, params, name):
|
||||
funcName = "conditional"
|
||||
if params is None:
|
||||
return -2, "params required"
|
||||
@@ -42,13 +41,13 @@ def conditional(state, params):
|
||||
#zde je pripavena podminka, kterou jen evaluujeme
|
||||
cond_dict = condsettings["cond_dict"]
|
||||
result, conditions_met = evaluate_directive_conditions(state, cond_dict, "OR")
|
||||
state.ilog(lvl=1,e=f"IND PODMINKA {condname} =OR= {result}", **conditions_met, cond_dict=cond_dict)
|
||||
state.ilog(lvl=1,e=f"IND PODMINKA {name}:{condname} =OR= {result}", **conditions_met, cond_dict=cond_dict)
|
||||
if result:
|
||||
return 0, true_val
|
||||
|
||||
#OR neprosly testujeme AND
|
||||
result, conditions_met = evaluate_directive_conditions(state, cond_dict, "AND")
|
||||
state.ilog(lvl=1,e=f"IND PODMINKA {condname} =AND= {result}", **conditions_met, cond_dict=cond_dict)
|
||||
state.ilog(lvl=1,e=f"IND PODMINKA {name}:{condname} =AND= {result}", **conditions_met, cond_dict=cond_dict)
|
||||
if result:
|
||||
return 0, true_val
|
||||
|
||||
|
||||
@@ -4,13 +4,12 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
#strength, absolute change of parameter between current value and lookback value (n-past)
|
||||
#used for example to measure unusual peaks
|
||||
def delta(state, params):
|
||||
def delta(state, params, name):
|
||||
funcName = "delta"
|
||||
source = safe_get(params, "source", None)
|
||||
lookback = safe_get(params, "lookback",1)
|
||||
@@ -20,5 +19,5 @@ def delta(state, params):
|
||||
currval = source_series[-1]
|
||||
delta = currval - lookbackval
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {delta} {source=} {lookback=}", currval=currval, lookbackval=lookbackval, **params)
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {delta} {source=} {lookback=}", currval=currval, lookbackval=lookbackval, **params)
|
||||
return 0, delta
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
from v2realbot.utils.utils import isrising, isfalling,zoneNY, price2dec, print, safe_get, is_still, is_window_open, eval_cond_dict, crossed_down, crossed_up, crossed, is_pivot, json_serial, pct_diff, create_new_bars, slice_dict_lists
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
#abs/rel divergence of two indicators
|
||||
def divergence(state, params):
|
||||
funcName = "indicatorDivergence"
|
||||
source1 = safe_get(params, "source1", None)
|
||||
source1_series = get_source_series(state, source1)
|
||||
source2 = safe_get(params, "source2", None)
|
||||
source2_series = get_source_series(state, source2)
|
||||
mode = safe_get(params, "type")
|
||||
state.ilog(lvl=0,e=f"INSIDE {funcName} {source1=} {source2=} {mode=}", **params)
|
||||
val = 0
|
||||
if mode == "abs":
|
||||
val = round(abs(float(source1_series[-1]) - float(source2_series[-1])),4)
|
||||
elif mode == "absn":
|
||||
val = round((abs(float(source1_series[-1]) - float(source2_series[-1])))/float(source1_series[-1]),4)
|
||||
elif mode == "rel":
|
||||
val = round(float(source1_series[-1]) - float(source2_series[-1]),4)
|
||||
elif mode == "reln":
|
||||
val = round((float(source1_series[-1]) - float(source2_series[-1]))/float(source1_series[-1]),4)
|
||||
elif mode == "pctabs":
|
||||
val = pct_diff(num1=float(source1_series[-1]),num2=float(source2_series[-1]), absolute=True)
|
||||
elif mode == "pct":
|
||||
val = pct_diff(num1=float(source1_series[-1]),num2=float(source2_series[-1]))
|
||||
return 0, val
|
||||
|
||||
#model - naloadovana instance modelu
|
||||
#seq - sekvence pro vstup
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,13 +4,12 @@ from v2realbot.indicators.indicators import ema as ext_ema
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
|
||||
#strength, absolute change of parameter between current value and lookback value (n-past)
|
||||
#used for example to measure unusual peaks
|
||||
def ema(state, params):
|
||||
def ema(state, params, name):
|
||||
funcName = "ema"
|
||||
source = safe_get(params, "source", None)
|
||||
lookback = safe_get(params, "lookback",14)
|
||||
@@ -22,5 +21,5 @@ def ema(state, params):
|
||||
ema_value = ext_ema(source_series, lookback)
|
||||
val = round(ema_value[-1],4)
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {val} {source=} {lookback=}", **params)
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {val} {source=} {lookback=}", **params)
|
||||
return 0, val
|
||||
@@ -1,6 +1,10 @@
|
||||
from v2realbot.utils.utils import isrising, isfalling,zoneNY, price2dec, print, safe_get, is_still, is_window_open, eval_cond_dict, crossed_down, crossed_up, crossed, is_pivot, json_serial, pct_diff, create_new_bars, slice_dict_lists
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
import numpy as np
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
import v2realbot.utils.utils as utls
|
||||
# from v2realbot.utils.utils import isrising, isfalling,zoneNY, price2dec, print, safe_get, is_still, is_window_open, eval_cond_dict, crossed_down, crossed_up, crossed, is_pivot, json_serial, pct_diff, create_new_bars, slice_dict_lists
|
||||
|
||||
|
||||
#allows executing a expression - pozor neni sanitized a zatim se spousti i v globalni scopu
|
||||
#v pripade jineho nez soukromeho uziti zabezpecit
|
||||
@@ -9,24 +13,30 @@ import numpy as np
|
||||
#eval nyni umi i user-defined function, string operation and control statements
|
||||
|
||||
#teroeticky se dá pouzit i SYMPY - kde se daji vytvorit jednotlive symboly s urcitou funkcni
|
||||
def expression(state: StrategyState, params):
|
||||
funcName = "expression"
|
||||
#indicator name
|
||||
operation = safe_get(params, "expression", None)
|
||||
def expression(state: StrategyState, params, name):
|
||||
try:
|
||||
funcName = "expression"
|
||||
#indicator name
|
||||
operation = utls.safe_get(params, "expression", None)
|
||||
|
||||
if operation is None :
|
||||
return -2, "required param missing"
|
||||
|
||||
state.ilog(lvl=0,e=f"BEFORE {funcName} {operation=}", **params)
|
||||
|
||||
#pro zacatek eval
|
||||
val = eval(operation, {'state': state, 'np': np}, state.ind_mapping)
|
||||
if operation is None :
|
||||
return -2, "required param missing"
|
||||
|
||||
state.ilog(lvl=0,e=f"BEFORE {name}:{funcName} {operation=}", **params)
|
||||
|
||||
#pro zacatek eval
|
||||
val = eval(operation, {'state': state, 'np': np, 'utls': utls}, state.ind_mapping)
|
||||
|
||||
if not np.isfinite(val):
|
||||
val = 0
|
||||
#val = ne.evaluate(operation, state.ind_mapping)
|
||||
#printanyway(val)
|
||||
|
||||
state.ilog(lvl=1,e=f"IND {funcName} {operation=} res:{val}", **params)
|
||||
if not np.isfinite(val):
|
||||
val = 0
|
||||
#val = ne.evaluate(operation, state.ind_mapping)
|
||||
|
||||
state.ilog(lvl=1,e=f"IND {name}:{funcName} {operation=} res:{val}", **params)
|
||||
except Exception as e:
|
||||
printanyway(name + str(e) + format_exc())
|
||||
raise e
|
||||
return 0, val
|
||||
|
||||
|
||||
|
||||
@@ -4,22 +4,23 @@ import v2realbot.indicators.moving_averages as mi
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
|
||||
# from talib import BBANDS, MACD, RSI, MA_Type
|
||||
|
||||
|
||||
#IMPLEMENTS different types of moving averages in package v2realbot.indicators.moving_averages
|
||||
def ma(state, params):
|
||||
def ma(state, params, name):
|
||||
funcName = "ma"
|
||||
type = safe_get(params, "type", "ema")
|
||||
source = safe_get(params, "source", None)
|
||||
lookback = safe_get(params, "lookback",14)
|
||||
start = safe_get(params, "start","linear") #linear/sharp
|
||||
|
||||
defval = safe_get(params, "defval",0)
|
||||
#lookback muze byt odkaz na indikator, pak berem jeho hodnotu
|
||||
lookback = int(value_or_indicator(state, lookback))
|
||||
defval = int(value_or_indicator(state, defval))
|
||||
|
||||
source_series = get_source_series(state, source)
|
||||
|
||||
@@ -34,7 +35,14 @@ def ma(state, params):
|
||||
ma_function = eval(type)
|
||||
|
||||
ma_value = ma_function(source_series, lookback)
|
||||
val = round(ma_value[-1],4)
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {val} {type=} {source=} {lookback=}", **params)
|
||||
if not np.isfinite(ma_value[-1]):
|
||||
val = defval
|
||||
else:
|
||||
val = round(ma_value[-1],4)
|
||||
|
||||
if val == 0:
|
||||
val = defval
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {val} {type=} {source=} {lookback=}", **params)
|
||||
return 0, val
|
||||
@@ -3,7 +3,8 @@ from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series, value_or_indicator
|
||||
|
||||
#allows basic mathematical operators to one or more indicators (add two indicator, add value to a indicator etc.)
|
||||
def mathop(state, params):
|
||||
#REPLACED by EXPRESSION
|
||||
def mathop(state, params, name):
|
||||
funcName = "mathop"
|
||||
#indicator name
|
||||
source1 = safe_get(params, "source1", None)
|
||||
@@ -24,7 +25,7 @@ def mathop(state, params):
|
||||
val = round(float(source1_series[-1] * druhy),4)
|
||||
else:
|
||||
return -2, "unknow operator"
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {source1=} {source2=} {val} {druhy=}", **params)
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {source1=} {source2=} {val} {druhy=}", **params)
|
||||
return 0, val
|
||||
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
def model(state, params):
|
||||
def model(state, params, ind_name):
|
||||
funcName = "model"
|
||||
if params is None:
|
||||
return -2, "params required"
|
||||
|
||||
@@ -4,17 +4,16 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
#WIP -
|
||||
#testing custom indicator CODE
|
||||
def opengap(state, params):
|
||||
def opengap(state, params, name):
|
||||
funcName = "opengap"
|
||||
param1 = safe_get(params, "param1")
|
||||
param2 = safe_get(params, "param2")
|
||||
state.ilog(lvl=0,e=f"INSIDE {funcName} {param1=} {param2=}", **params)
|
||||
state.ilog(lvl=0,e=f"INSIDE {name}:{funcName} {param1=} {param2=}", **params)
|
||||
last_close = 28.45
|
||||
today_open = 29.45
|
||||
val = pct_diff(last_close, today_open)
|
||||
|
||||
@@ -4,14 +4,13 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
import bisect
|
||||
|
||||
#strength, absolute change of parameter between current value and lookback value (n-past)
|
||||
#used for example to measure unusual peaks
|
||||
def sameprice(state, params):
|
||||
def sameprice(state, params, name):
|
||||
funcName = "sameprice"
|
||||
typ = safe_get(params, "type", None)
|
||||
|
||||
@@ -40,13 +39,13 @@ def sameprice(state, params):
|
||||
|
||||
#jde o daily high
|
||||
if pozice_prvniho_vetsiho == -1:
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {typ} {pozice_prvniho_vetsiho=} vracime 1")
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {typ} {pozice_prvniho_vetsiho=} vracime 1")
|
||||
return 0, celkova_delka
|
||||
|
||||
delka_k_predchozmu = celkova_delka - pozice_prvniho_vetsiho
|
||||
normalizovano = delka_k_predchozmu/celkova_delka
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {typ} {pozice_prvniho_vetsiho=} {celkova_delka=} {delka_k_predchozmu=} {normalizovano=}", pozice_prvniho_vetsiho=pozice_prvniho_vetsiho, celkova_delka=celkova_delka, delka_k_predchozmu=delka_k_predchozmu, **params)
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {typ} {pozice_prvniho_vetsiho=} {celkova_delka=} {delka_k_predchozmu=} {normalizovano=}", pozice_prvniho_vetsiho=pozice_prvniho_vetsiho, celkova_delka=celkova_delka, delka_k_predchozmu=delka_k_predchozmu, **params)
|
||||
|
||||
return 0, delka_k_predchozmu
|
||||
|
||||
|
||||
@@ -4,12 +4,11 @@ from v2realbot.indicators.indicators import ema, natr, roc
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
|
||||
#rate of change - last value of source indicator vs lookback value of lookback_priceline indicator
|
||||
def slope(state, params):
|
||||
def slope(state, params, name):
|
||||
funcName = "slope"
|
||||
source = safe_get(params, "source", None)
|
||||
source_series = get_source_series(state, source)
|
||||
@@ -31,5 +30,5 @@ def slope(state, params):
|
||||
slope = ((currval - lookbackprice)/abs(lookbackprice))*100
|
||||
#slope = round(slope, 4)
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {slope} {source=} {lookback=}", currval_source=currval, lookbackprice=lookbackprice, lookbacktime=lookbacktime, **params)
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {slope} {source=} {lookback=}", currval_source=currval, lookbackprice=lookbackprice, lookbacktime=lookbacktime, **params)
|
||||
return 0, slope
|
||||
|
||||
@@ -5,13 +5,12 @@ from v2realbot.indicators.moving_averages import vwma as ext_vwma
|
||||
from v2realbot.strategyblocks.indicators.helpers import get_source_series
|
||||
from rich import print as printanyway
|
||||
from traceback import format_exc
|
||||
from v2realbot.ml.ml import ModelML
|
||||
import numpy as np
|
||||
from collections import defaultdict
|
||||
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
|
||||
|
||||
# Volume(or reference_source) Weighted moving Average
|
||||
def vwma(state, params):
|
||||
def vwma(state, params, name):
|
||||
funcName = "vwma"
|
||||
source = safe_get(params, "source", None)
|
||||
ref_source = safe_get(params, "ref_source", "volume")
|
||||
@@ -34,5 +33,5 @@ def vwma(state, params):
|
||||
vwma_value = ext_vwma(source_series, ref_source_series, lookback)
|
||||
val = round(vwma_value[-1],4)
|
||||
|
||||
state.ilog(lvl=1,e=f"INSIDE {funcName} {val} {source=} {ref_source=} {lookback=}", **params)
|
||||
state.ilog(lvl=1,e=f"INSIDE {name}:{funcName} {val} {source=} {ref_source=} {lookback=}", **params)
|
||||
return 0, val
|
||||
@@ -133,7 +133,7 @@ def populate_dynamic_custom_indicator(data, state: StrategyState, name):
|
||||
|
||||
subtype = "ci."+subtype+"."+subtype
|
||||
custom_function = eval(subtype)
|
||||
res_code, new_val = custom_function(state, custom_params)
|
||||
res_code, new_val = custom_function(state, custom_params, name)
|
||||
if res_code == 0:
|
||||
state.indicators[name][-1-save_to_past]=new_val
|
||||
state.ilog(lvl=1,e=f"IND {name} {subtype} VAL FROM FUNCTION: {new_val}", lastruntime=state.vars.indicators[name]["last_run_time"], lastrunindex=state.vars.indicators[name]["last_run_index"], save_to_past=save_to_past)
|
||||
@@ -159,7 +159,7 @@ def populate_dynamic_custom_indicator(data, state: StrategyState, name):
|
||||
else:
|
||||
state.ilog(lvl=0,e=f"IND {name} {subtype} COND NOT READY: {msg}")
|
||||
|
||||
#not time to run
|
||||
#not time to run - copy last value
|
||||
if len(state.indicators[name]) >= 2:
|
||||
state.indicators[name][-1]=state.indicators[name][-2]
|
||||
|
||||
|
||||
@@ -71,11 +71,22 @@ def get_source_or_MA(state, indicator):
|
||||
except KeyError:
|
||||
return state.bars[indicator]
|
||||
|
||||
def get_source_series(state, source):
|
||||
try:
|
||||
return state.bars[source]
|
||||
except KeyError:
|
||||
return state.indicators[source]
|
||||
def get_source_series(state: StrategyState, source: str):
|
||||
"""
|
||||
Podporujeme krome klice v bar a indikatoru a dalsi doplnujici, oddelene _ napr. dailyBars_close
|
||||
vezme serii static.dailyBars[close]
|
||||
"""
|
||||
|
||||
split_index = source.find("|")
|
||||
if split_index == -1:
|
||||
try:
|
||||
return state.bars[source]
|
||||
except KeyError:
|
||||
return state.indicators[source]
|
||||
else:
|
||||
dict_name = source[:split_index]
|
||||
key = source[split_index + 1:]
|
||||
return getattr(state, dict_name)[key]
|
||||
|
||||
#TYTO NEJSPIS DAT do util
|
||||
#vrati true pokud dany indikator prekrocil threshold dolu
|
||||
|
||||
@@ -4,7 +4,6 @@ from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, Foll
|
||||
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus
|
||||
from v2realbot.utils.utils import isrising, isfalling,zoneNY, price2dec, print, safe_get, is_still, is_window_open, eval_cond_dict, crossed_down, crossed_up, crossed, is_pivot, json_serial, pct_diff, create_new_bars, slice_dict_lists
|
||||
from v2realbot.utils.directive_utils import get_conditions_from_configuration
|
||||
from v2realbot.ml.mlutils import load_model
|
||||
from v2realbot.common.model import SLHistory
|
||||
from v2realbot.config import KW
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -9,6 +9,7 @@ from v2realbot.common.model import SLHistory
|
||||
from v2realbot.config import KW
|
||||
from uuid import uuid4
|
||||
from datetime import datetime
|
||||
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
|
||||
#import random
|
||||
import json
|
||||
import numpy as np
|
||||
@@ -106,6 +107,8 @@ def common_go_preconditions_check(state, data, signalname: str, options: dict):
|
||||
return False
|
||||
|
||||
next_signal_offset = safe_get(options, "next_signal_offset_from_last_exit",safe_get(state.vars, "next_signal_offset_from_last_exit",0))
|
||||
#muze byt i indikator
|
||||
next_signal_offset = int(value_or_indicator(state, next_signal_offset))
|
||||
|
||||
if state.vars.last_exit_index is not None:
|
||||
index_to_compare = int(state.vars.last_exit_index)+int(next_signal_offset)
|
||||
|
||||
Reference in New Issue
Block a user