enables day by day bt run, bt market premium+inds

This commit is contained in:
David Brazda
2023-10-15 20:14:44 +02:00
parent 793c776d45
commit 7c1bba028b
25 changed files with 500 additions and 83 deletions

View File

@ -63,27 +63,30 @@ def trail_SL_management(state: StrategyState, data):
def_SL = get_override_for_active_trade(state=state, directive_name=directive_name, default_value=safe_get(options, directive_name, 0.01))
directive_name = "SL_trailing_offset_"+str(smer)
offset = get_override_for_active_trade(state=state, directive_name=directive_name, default_value=safe_get(options, directive_name, 0.01))
directive_name = "SL_trailing_step_"+str(smer)
step = get_override_for_active_trade(state=state, directive_name=directive_name, default_value=safe_get(options, directive_name, offset))
#pokud je pozadovan trail jen do breakeven a uz prekroceno
if (direction == TradeDirection.LONG and stop_breakeven and state.vars.activeTrade.stoploss_value >= float(state.avgp)) or (direction == TradeDirection.SHORT and stop_breakeven and state.vars.activeTrade.stoploss_value <= float(state.avgp)):
state.ilog(lvl=1,e=f"SL trail STOP at breakeven {str(smer)} SL:{state.vars.activeTrade.stoploss_value} UNCHANGED", stop_breakeven=stop_breakeven)
return
#IDEA: Nyni posouvame SL o offset, mozna ji posunout jen o direktivu step ?
#Aktivace SL pokud vystoupa na "offset", a nasledne posunuti o "step"
offset_normalized = normalize_tick(state, data, offset) #to ticks and from options
step_normalized = normalize_tick(state, data, step)
def_SL_normalized = normalize_tick(state, data, def_SL)
if direction == TradeDirection.LONG:
move_SL_threshold = state.vars.activeTrade.stoploss_value + offset_normalized + def_SL_normalized
state.ilog(lvl=1,e=f"SL TRAIL EVAL {smer} SL:{round(state.vars.activeTrade.stoploss_value,3)} TRAILGOAL:{move_SL_threshold}", def_SL=def_SL, offset=offset, offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
state.ilog(lvl=1,e=f"SL TRAIL EVAL {smer} SL:{round(state.vars.activeTrade.stoploss_value,3)} TRAILGOAL:{move_SL_threshold}", def_SL=def_SL, offset=offset, offset_normalized=offset_normalized, step_normalized=step_normalized, def_SL_normalized=def_SL_normalized)
if (move_SL_threshold) < data['close']:
state.vars.activeTrade.stoploss_value += offset_normalized
state.vars.activeTrade.stoploss_value += step_normalized
insert_SL_history(state)
state.ilog(lvl=1,e=f"SL TRAIL TH {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
state.ilog(lvl=1,e=f"SL TRAIL TH {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, step_normalized=step_normalized, def_SL_normalized=def_SL_normalized)
elif direction == TradeDirection.SHORT:
move_SL_threshold = state.vars.activeTrade.stoploss_value - offset_normalized - def_SL_normalized
state.ilog(lvl=0,e=f"SL TRAIL EVAL {smer} SL:{round(state.vars.activeTrade.stoploss_value,3)} TRAILGOAL:{move_SL_threshold}", def_SL=def_SL, offset=offset, offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
state.ilog(lvl=0,e=f"SL TRAIL EVAL {smer} SL:{round(state.vars.activeTrade.stoploss_value,3)} TRAILGOAL:{move_SL_threshold}", def_SL=def_SL, offset=offset, offset_normalized=offset_normalized, step_normalized=step_normalized, def_SL_normalized=def_SL_normalized)
if (move_SL_threshold) > data['close']:
state.vars.activeTrade.stoploss_value -= offset_normalized
state.vars.activeTrade.stoploss_value -= step_normalized
insert_SL_history(state)
state.ilog(lvl=1,e=f"SL TRAIL GOAL {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
state.ilog(lvl=1,e=f"SL TRAIL GOAL {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, step_normalized=step_normalized, def_SL_normalized=def_SL_normalized)

View File

@ -1 +1,10 @@
from . import *
import os
# import importlib
# from v2realbot.strategyblocks.indicators.custom.opengap import opengap
for filename in os.listdir("v2realbot/strategyblocks/indicators/custom"):
if filename.endswith(".py") and filename != "__init__.py":
# __import__(filename[:-3])
__import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}")
#importlib.import_module()

View File

@ -35,6 +35,32 @@ def basestats(state, params):
val = np.amax(source_array)
elif func == "mean":
val = np.mean(source_array)
elif func == "var":
data = np.array(source_array)
mean_value = np.mean(data)
# Calculate the variance of the data
val = np.mean((data - mean_value) ** 2)
elif func == "angle":
delka_pole = len(source_array)
if delka_pole < 2:
return 0,0
x = np.arange(delka_pole)
y = np.array(source_array)
# Fit a linear polynomial to the data
coeffs = np.polyfit(x, y, 1)
# Calculate the angle in radians angle_rad
val = np.arctan(coeffs[0]) * 1000
# Convert the angle to degrees angle_deg
#angle_deg = np.degrees(angle_rad)
# Normalize the degrees between -1 and 1
#val = 2 * (angle_deg / 180) - 1
elif func =="stdev":
val = np.std(source_array)
else:
return -2, "wrong function"

View File

@ -0,0 +1,26 @@
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 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):
funcName = "ema"
source = safe_get(params, "source", None)
lookback = safe_get(params, "lookback",14)
#lookback muze byt odkaz na indikator, pak berem jeho hodnotu
lookback = int(value_or_indicator(state, lookback))
source_series = get_source_series(state, source)[-lookback:]
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)
return 0, val

View File

@ -15,13 +15,16 @@ def mathop(state, params):
if source1 is None or source2 is None or operator is None:
return -2, "required source1 source2 operator"
druhy = float(value_or_indicator(state, source2))
if operator == "+":
val = round(float(source1_series[-1] + value_or_indicator(state, source2)),4)
val = round(float(source1_series[-1] + druhy),4)
elif operator == "-":
val = round(float(source1_series[-1] - value_or_indicator(state, source2)),4)
val = round(float(source1_series[-1] - druhy),4)
elif operator == "*":
val = round(float(source1_series[-1] * druhy),4)
else:
return -2, "unknow operator"
#state.ilog(lvl=0,e=f"INSIDE {funcName} {source1=} {source2=} {val}", **params)
state.ilog(lvl=1,e=f"INSIDE {funcName} {source1=} {source2=} {val} {druhy=}", **params)
return 0, val

View File

@ -0,0 +1,52 @@
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
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):
funcName = "sameprice"
typ = safe_get(params, "type", None)
def find_first_bigger_than_lastitem_backwards(list1):
last_item = list1[-1]
for i in range(len(list1) - 2, -1, -1):
if list1[i] > last_item:
return i
return -1
def find_first_smaller_than_lastitem_backwards(list1):
last_item = list1[-1]
for i in range(len(list1) - 2, -1, -1):
if list1[i] < last_item:
return i
return -1
if typ == "up":
pozice_prvniho_vetsiho = find_first_bigger_than_lastitem_backwards(state.bars["vwap"])
elif typ == "down":
pozice_prvniho_vetsiho = find_first_smaller_than_lastitem_backwards(state.bars["vwap"])
else:
return -2, "unknow type"
celkova_delka = len(state.bars["vwap"])
#jde o daily high
if pozice_prvniho_vetsiho == -1:
state.ilog(lvl=1,e=f"INSIDE {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)
return 0, delka_k_predchozmu

View File

@ -8,15 +8,16 @@ import importlib
#TODO TENTO IMPORT VYMYSLET, abych naloadoval package custom a nemusel nic pridat (vymyslet dynamicke volani z cele package ci)
#from v2realbot.strategyblocks.indicators.custom._upscaled_rsi_wip import upscaledrsi
from v2realbot.strategyblocks.indicators.custom.barparams import barparams
from v2realbot.strategyblocks.indicators.custom.basestats import basestats
from v2realbot.strategyblocks.indicators.custom.delta import delta
from v2realbot.strategyblocks.indicators.custom.divergence import divergence
from v2realbot.strategyblocks.indicators.custom.model import model
from v2realbot.strategyblocks.indicators.custom.opengap import opengap
from v2realbot.strategyblocks.indicators.custom.slope import slope
from v2realbot.strategyblocks.indicators.custom.conditional import conditional
from v2realbot.strategyblocks.indicators.custom.mathop import mathop
import v2realbot.strategyblocks.indicators.custom as ci
# from v2realbot.strategyblocks.indicators.custom.barparams import barparams
# from v2realbot.strategyblocks.indicators.custom.basestats import basestats
# from v2realbot.strategyblocks.indicators.custom.delta import delta
# from v2realbot.strategyblocks.indicators.custom.divergence import divergence
# from v2realbot.strategyblocks.indicators.custom.model import model
# from v2realbot.strategyblocks.indicators.custom.opengap import opengap
# from v2realbot.strategyblocks.indicators.custom.slope import slope
# from v2realbot.strategyblocks.indicators.custom.conditional import conditional
# from v2realbot.strategyblocks.indicators.custom.mathop import mathop
# import v2realbot.strategyblocks.indicators.custom as ci
@ -143,7 +144,7 @@ def populate_dynamic_custom_indicator(data, state: StrategyState, name):
#pozor jako defaultní hodnotu dává engine 0 - je to ok?
try:
#subtype = "ci."+subtype
subtype = "ci."+subtype+"."+subtype
custom_function = eval(subtype)
res_code, new_val = custom_function(state, custom_params)
if res_code == 0:

View File

@ -1,4 +1,4 @@
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.utils import isrising, isfalling,isfallingc, isrisingc, 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 traceback import format_exc
@ -9,13 +9,16 @@ from traceback import format_exc
def value_or_indicator(state,value):
#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
if isinstance(value, (int, float)):
if isinstance(value, (float, int)):
return value
elif isinstance(value, str):
try:
#pokud existuje v indikatoru MA bereme MA jinak indikator, pokud neexistuje bereme bar
ret = get_source_or_MA(state, indicator=value)[-1]
state.ilog(lvl=0,e=f"Pro porovnani bereme posledni hodnotu {ret} z indikatoru {value}")
lvl = 0
if ret == 0:
lvl = 1
state.ilog(lvl=lvl,e=f"Pro porovnani bereme posledni hodnotu {ret} z indikatoru {value}")
except Exception as e :
ret = 0
state.ilog(lvl=1,e=f"Neexistuje indikator s nazvem {value} vracime 0" + str(e) + format_exc())
@ -38,6 +41,8 @@ def evaluate_directive_conditions(state, work_dict, cond_type):
"above": lambda ind, val: get_source_or_MA(state, ind)[-1] > value_or_indicator(state,val),
"equals": lambda ind, val: get_source_or_MA(state, ind)[-1] == value_or_indicator(state,val),
"below": lambda ind, val: get_source_or_MA(state, ind)[-1] < value_or_indicator(state,val),
"fallingc": lambda ind, val: isfallingc(get_source_or_MA(state, ind), val),
"risingc": lambda ind, val: isrisingc(get_source_or_MA(state, ind), val),
"falling": lambda ind, val: isfalling(get_source_or_MA(state, ind), val),
"rising": lambda ind, val: isrising(get_source_or_MA(state, ind), val),
"crossed_down": lambda ind, val: buy_if_crossed_down(state, ind, value_or_indicator(state,val)),

View File

@ -1,7 +1,7 @@
from v2realbot.strategy.base import StrategyState
from v2realbot.strategyblocks.indicators.cbar_price import populate_cbar_tick_price_indicator
from v2realbot.strategyblocks.indicators.custom.custom_hub import populate_dynamic_custom_indicator
from v2realbot.strategyblocks.indicators.custom_hub import populate_dynamic_custom_indicator
from v2realbot.strategyblocks.indicators.slope import populate_dynamic_slope_indicator
from v2realbot.strategyblocks.indicators.slopeLP import populate_dynamic_slopeLP_indicator
from v2realbot.strategyblocks.indicators.ema import populate_dynamic_ema_indicator

View File

@ -33,18 +33,18 @@ def go_conditions_met(state, data, signalname: str, direction: TradeDirection):
#dont_buy_above = value nebo hazev indikatoru
#TESTUJEME SPECIFICKY DONT_GO -
#u techto ma smysl pouze OR
#jak OR tak i AND
cond_dict = state.vars.conditions[KW.dont_go][signalname][smer]
result, conditions_met = evaluate_directive_conditions(state, cond_dict, "OR")
state.ilog(lvl=1,e=f"SPECIFIC PRECOND {smer} {result}", **conditions_met, cond_dict=cond_dict)
state.ilog(lvl=1,e=f"SPECIFIC PRECOND =OR= {smer} {result}", **conditions_met, cond_dict=cond_dict)
if result:
return False
#OR neprosly testujeme AND
result, conditions_met = evaluate_directive_conditions(state, cond_dict, "AND")
state.ilog(lvl=1,e=f"SPECIFIC PRECOND =AND={smer} {result}", **conditions_met, cond_dict=cond_dict)
if result:
return False
# #OR neprosly testujeme AND
# result, conditions_met = evaluate_directive_conditions(cond_dict, "AND")
# state.ilog(lvl=0,e=f"EXIT CONDITIONS of activeTrade {smer} =AND= {result}", **conditions_met, cond_dict=cond_dict)
# if result:
# return True
#tyto timto nahrazeny - dat do konfigurace (dont_short_when, dont_long_when)
#dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
@ -110,7 +110,7 @@ def common_go_preconditions_check(state, data, signalname: str, options: dict):
if state.vars.last_exit_index is not None:
index_to_compare = int(state.vars.last_exit_index)+int(next_signal_offset)
if index_to_compare > int(data["index"]):
state.ilog(lvl=1,e=f"NEXT SIGNAL OFFSET from EXIT {next_signal_offset} waiting - TOO SOON", currindex=data["index"], index_to_compare=index_to_compare, last_exit_index=state.vars.last_exit_index)
state.ilog(lvl=1,e=f"NEXT SIGNAL OFFSET from EXIT {next_signal_offset} waiting - TOO SOON {signalname}", currindex=data["index"], index_to_compare=index_to_compare, last_exit_index=state.vars.last_exit_index)
return False
# if is_open_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), open_rush) or is_close_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), close_rush):

View File

@ -45,7 +45,7 @@ def execute_prescribed_trades(state: StrategyState, data):
res = state.buy(size=size)
if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation LONG {res}")
#nastaveni SL az do notifikace, kdy je známá
#TODO nastaveni SL az do notifikace, kdy je známá
#pokud neni nastaveno SL v prescribe, tak nastavuji default dle stratvars
if state.vars.activeTrade.stoploss_value is None:
sl_defvalue = get_default_sl_value(state, direction=state.vars.activeTrade.direction)

View File

@ -38,7 +38,7 @@ def signal_search(state: StrategyState, data):
# to vse za predpokladu, ze neni aktivni trade
def execute_signal_generator(state, data, name):
state.ilog(lvl=0,e=f"SIGNAL SEARCH for {name}", cond_go=state.vars.conditions[KW.go][name], cond_dontgo=state.vars.conditions[KW.dont_go][name], cond_activate=state.vars.conditions[KW.activate][name] )
state.ilog(lvl=1,e=f"SIGNAL SEARCH for {name}", cond_go=state.vars.conditions[KW.go][name], cond_dontgo=state.vars.conditions[KW.dont_go][name], cond_activate=state.vars.conditions[KW.activate][name] )
options = safe_get(state.vars.signals, name, None)
if options is None:
@ -60,7 +60,7 @@ def execute_signal_generator(state, data, name):
custom_function = eval(signal_plugin)
custom_function()
except NameError:
state.ilog(lvl=1,e="Custom plugin {signal_plugin} not found")
state.ilog(lvl=1,e=f"Custom plugin {signal_plugin} not found")
else:
short_enabled = safe_get(options, "short_enabled",safe_get(state.vars, "short_enabled",True))
long_enabled = safe_get(options, "long_enabled",safe_get(state.vars, "long_enabled",True))