pridano indikator natr + vychytavky na frontendu
This commit is contained in:
@ -3,7 +3,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.indicators import ema, natr
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, round2five, is_open_rush, is_close_rush, is_still, is_window_open, eval_cond_dict, Average, crossed_down, crossed_up, crossed, is_pivot, json_serial
|
||||
@ -248,6 +248,8 @@ def next(data, state: StrategyState):
|
||||
populate_dynamic_RSI_indicator(name = name)
|
||||
elif type == "EMA":
|
||||
populate_dynamic_ema_indicator(name = name)
|
||||
elif type == "NATR":
|
||||
populate_dynamic_natr_indicator(name = name)
|
||||
else:
|
||||
return
|
||||
|
||||
@ -285,6 +287,34 @@ def next(data, state: StrategyState):
|
||||
except Exception as e:
|
||||
state.ilog(e=f"IND ERROR {name} EMA necháváme 0", message=str(e)+format_exc())
|
||||
|
||||
#NATR INDICATOR
|
||||
# type = NATR, ĺength = [14], on_confirmed_only = [true, false]
|
||||
def populate_dynamic_natr_indicator(name):
|
||||
ind_type = "NATR"
|
||||
options = safe_get(state.vars.indicators, name, None)
|
||||
if options is None:
|
||||
state.ilog(e=f"No options for {name} in stratvars")
|
||||
return
|
||||
|
||||
#poustet kazdy tick nebo jenom na confirmed baru (on_confirmed_only = true)
|
||||
on_confirmed_only = safe_get(options, 'on_confirmed_only', False)
|
||||
natr_length = int(safe_get(options, "length",5))
|
||||
if on_confirmed_only is False or (on_confirmed_only is True and data['confirmed']==1):
|
||||
try:
|
||||
source_high = state.bars["high"][-natr_length:]
|
||||
source_low = state.bars["low"][-natr_length:]
|
||||
source_close = state.bars["close"][-natr_length:]
|
||||
#if len(source) > ema_length:
|
||||
natr_value = natr(source_high, source_low, source_close, natr_length)
|
||||
val = round(natr_value[-1],4)
|
||||
state.indicators[name][-1]= val
|
||||
#state.indicators[name][-1]= round2five(val)
|
||||
state.ilog(e=f"IND {name} NATR {val} {natr_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} NATR necháváme 0", message=str(e)+format_exc())
|
||||
|
||||
#RSI INDICATOR
|
||||
# type = RSI, source = [close, vwap, hlcc4], rsi_length = [14], MA_length = int (optional), on_confirmed_only = [true, false]
|
||||
# pokud existuje MA, vytvarime i stejnojnojmenny MAcko
|
||||
@ -742,18 +772,32 @@ def next(data, state: StrategyState):
|
||||
else:
|
||||
smer = "short"
|
||||
|
||||
#get name of strategy
|
||||
signal_originator = state.vars.activeTrade.generated_by
|
||||
|
||||
if signal_originator is not None:
|
||||
exit_cond_only_on_confirmed = safe_get(state.vars.signals[signal_originator], "exit_cond_only_on_confirmed", safe_get(state.vars, "exit_cond_only_on_confirmed", False))
|
||||
else:
|
||||
exit_cond_only_on_confirmed = safe_get(state.vars, "exit_cond_only_on_confirmed", False)
|
||||
directive_name = "exit_cond_only_on_confirmed"
|
||||
exit_cond_only_on_confirmed = get_override_for_active_trade(directive_name=directive_name, default_value=safe_get(state.vars, directive_name, False))
|
||||
|
||||
if exit_cond_only_on_confirmed and data['confirmed'] == 0:
|
||||
state.ilog("EXIT COND ONLY ON CONFIRMED BAR")
|
||||
return False
|
||||
|
||||
#POKUD je nastaven MIN PROFIT, zkontrolujeme ho a az pripadne pustime CONDITIONY
|
||||
directive_name = "exit_cond_min_profit"
|
||||
exit_cond_min_profit = get_override_for_active_trade(directive_name=directive_name, default_value=safe_get(state.vars, directive_name, None))
|
||||
|
||||
#máme nastavený exit_cond_min_profit
|
||||
# zjistíme, zda jsme v daném profit a případně nepustíme dál
|
||||
# , zjistíme aktuální cenu a přičteme k avgp tento profit a podle toho pustime dal
|
||||
|
||||
if exit_cond_min_profit is not None:
|
||||
exit_cond_min_profit_normalized = normalize_tick(float(exit_cond_min_profit))
|
||||
exit_cond_goal_price = price2dec(float(state.avgp)+exit_cond_min_profit_normalized,3) if int(state.positions) > 0 else price2dec(float(state.avgp)-exit_cond_min_profit_normalized,3)
|
||||
curr_price = float(data["close"])
|
||||
state.ilog(e=f"EXIT COND min profit {exit_cond_goal_price=} {exit_cond_min_profit=} {exit_cond_min_profit_normalized=} {curr_price=}")
|
||||
if (int(state.positions) < 0 and curr_price<=exit_cond_goal_price) or (int(state.positions) > 0 and curr_price>=exit_cond_goal_price):
|
||||
state.ilog(e=f"EXIT COND min profit PASS - POKRACUJEME")
|
||||
else:
|
||||
state.ilog(e=f"EXIT COND min profit NOT PASS")
|
||||
return False
|
||||
|
||||
#TOTO ZATIM NEMA VYZNAM
|
||||
# options = safe_get(state.vars, 'exit_conditions', None)
|
||||
# if options is None:
|
||||
@ -919,7 +963,8 @@ def next(data, state: StrategyState):
|
||||
#pri uzavreni tradu zapisujeme SL history - lepsi zorbazeni v grafu
|
||||
insert_SL_history()
|
||||
state.vars.pending = state.vars.activeTrade.id
|
||||
state.vars.activeTrade = None
|
||||
state.vars.activeTrade = None
|
||||
state.vars.last_exit_index = data["index"]
|
||||
|
||||
def eval_close_position():
|
||||
curr_price = float(data['close'])
|
||||
@ -1125,14 +1170,6 @@ def next(data, state: StrategyState):
|
||||
#ZAKLADNI KONTROLY ATRIBUTU s fallbackem na obecné
|
||||
#check working windows (open - close, in minutes from the start of marker)
|
||||
|
||||
next_signal_offset = safe_get(options, "next_signal_offset_from_last",safe_get(state.vars, "next_signal_offset_from_last",0))
|
||||
|
||||
if state.vars.last_buy_index is not None:
|
||||
index_to_compare = int(state.vars.last_buy_index)+int(next_signal_offset)
|
||||
if index_to_compare > int(data["index"]):
|
||||
state.ilog(e=f"NEXT SIGNAL OFFSET {next_signal_offset} waiting - TOO SOON", currindex=data["index"], index_to_compare=index_to_compare)
|
||||
return False
|
||||
|
||||
window_open = safe_get(options, "window_open",safe_get(state.vars, "window_open",0))
|
||||
window_close = safe_get(options, "window_close",safe_get(state.vars, "window_close",390))
|
||||
|
||||
@ -1140,6 +1177,14 @@ def next(data, state: StrategyState):
|
||||
state.ilog(e=f"SIGNAL {signalname} - WINDOW CLOSED", msg=f"{window_open=} {window_close=} ")
|
||||
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))
|
||||
|
||||
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(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)
|
||||
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):
|
||||
# state.ilog(e=f"SIGNAL {signalname} - WINDOW CLOSED", msg=f"{open_rush=} {close_rush=} ")
|
||||
# return False
|
||||
@ -1415,6 +1460,7 @@ def init(state: StrategyState):
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 0
|
||||
state.vars.last_buy_index = None
|
||||
state.vars.last_exit_index = None
|
||||
state.vars.last_update_time = 0
|
||||
state.vars.reverse_position_waiting_amount = 0
|
||||
#INIT promenne, ktere byly zbytecne ve stratvars
|
||||
|
||||
Binary file not shown.
@ -121,6 +121,7 @@ class Runner(BaseModel):
|
||||
run_instance: Optional[object] = None
|
||||
run_pause_ev: Optional[object] = None
|
||||
run_stop_ev: Optional[object] = None
|
||||
run_stratvars_toml: Optional[str] = None
|
||||
|
||||
|
||||
class Bar(BaseModel):
|
||||
@ -207,6 +208,7 @@ class RunArchive(BaseModel):
|
||||
end_positions: int = 0
|
||||
end_positions_avgp: float = 0
|
||||
open_orders: Union[dict, int] = None
|
||||
stratvars_toml: Optional[str] = None
|
||||
|
||||
#trida pro ukladani historie stoplossy do ext_data
|
||||
class SLHistory(BaseModel):
|
||||
|
||||
@ -490,7 +490,8 @@ def run_stratin(id: UUID, runReq: RunRequest, synchronous: bool = False, inter_b
|
||||
run_account = runReq.account,
|
||||
run_ilog_save = runReq.ilog_save,
|
||||
run_mode = runReq.mode,
|
||||
run_instance = instance)
|
||||
run_instance = instance,
|
||||
run_stratvars_toml=i.stratvars_conf)
|
||||
db.runners.append(runner)
|
||||
print(db.runners)
|
||||
print(i)
|
||||
@ -666,7 +667,8 @@ def archive_runner(runner: Runner, strat: StrategyInstance, inter_batch_params:
|
||||
trade_count=len(strat.state.tradeList),
|
||||
end_positions=strat.state.positions,
|
||||
end_positions_avgp=round(float(strat.state.avgp),3),
|
||||
open_orders=results_metrics
|
||||
open_orders=results_metrics,
|
||||
stratvars_toml=runner.run_stratvars_toml
|
||||
)
|
||||
|
||||
#flatten indicators from numpy array
|
||||
|
||||
Binary file not shown.
@ -5,6 +5,14 @@ from collections import deque
|
||||
import typing
|
||||
from v2realbot.utils.utils import check_series, convert_to_numpy
|
||||
|
||||
|
||||
def natr(data_high, data_low, data_close, period: int = 5):
|
||||
data_high = convert_to_numpy(data_high)
|
||||
data_low = convert_to_numpy(data_low)
|
||||
data_close = convert_to_numpy(data_close)
|
||||
natr = ti.natr(data_high, data_low, data_close, period=period)
|
||||
return natr
|
||||
|
||||
def ema(data, period: int = 50, use_series=False):
|
||||
if check_series(data):
|
||||
use_series = True
|
||||
|
||||
@ -100,7 +100,15 @@ $(document).ready(function () {
|
||||
$('#editidarchive').val(row.id);
|
||||
$('#editnote').val(row.note);
|
||||
$('#metrics').val(JSON.stringify(row.open_orders,null,2));
|
||||
$('#editstratvars').val(JSON.stringify(row.stratvars,null,2));
|
||||
//$('#metrics').val(TOML.parse(row.open_orders));
|
||||
if (row.stratvars_toml) {
|
||||
$('#editstratvars').val(row.stratvars_toml);
|
||||
}
|
||||
else{
|
||||
$('#editstratvars').val(JSON.stringify(row.stratvars,null,2));
|
||||
}
|
||||
|
||||
|
||||
$('#editstratjson').val(row.strat_json);
|
||||
});
|
||||
|
||||
@ -237,7 +245,8 @@ var archiveRecords =
|
||||
{data: 'end_positions', visible: true},
|
||||
{data: 'end_positions_avgp', visible: true},
|
||||
{data: 'strat_json', visible: false},
|
||||
{data: 'open_orders', visible: true}
|
||||
{data: 'open_orders', visible: true},
|
||||
{data: 'stratvars_toml', visible: false},
|
||||
],
|
||||
paging: false,
|
||||
processing: false,
|
||||
|
||||
Reference in New Issue
Block a user