agregace volume baru, SL optimizace + goalprice

This commit is contained in:
David Brazda
2023-11-07 17:57:08 +01:00
parent 0db88b194c
commit b7f148fadd
24 changed files with 797 additions and 101 deletions

View File

@ -43,3 +43,27 @@ def close_position(state, data, direction: TradeDirection, reason: str, followup
state.vars.last_exit_index = data["index"]
if followup is not None:
state.vars.requested_followup = followup
#close only partial position - no followup here, size multiplier must be between 0 and 1
def close_position_partial(state, data, direction: TradeDirection, reason: str, size: float):
if size <= 0 or size >=1:
raise Exception(f"size must be betweem 0 and 1")
size_abs = abs(int(int(state.positions)*size))
state.ilog(lvl=1,e=f"CLOSING TRADE PART: {size_abs} {size} {reason} {str(direction)}", curr_price=data["close"], trade=state.vars.activeTrade)
if direction == TradeDirection.SHORT:
res = state.buy(size=size_abs)
if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation STOPLOSS PARTIAL BUY {reason} {res}")
elif direction == TradeDirection.LONG:
res = state.sell(size=size_abs)
if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation STOPLOSS PARTIAL SELL {res}")
else:
raise Exception(f"unknow TradeDirection in close_position")
#pri uzavreni tradu zapisujeme SL history - lepsi zorbazeni v grafu
insert_SL_history(state)
state.vars.pending = state.vars.activeTrade.id
#state.vars.activeTrade = None
#state.vars.last_exit_index = data["index"]

View File

@ -1,4 +1,4 @@
from v2realbot.strategyblocks.activetrade.close.close_position import close_position
from v2realbot.strategyblocks.activetrade.close.close_position import close_position, close_position_partial
from v2realbot.strategy.base import StrategyState
from v2realbot.enums.enums import Followup
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus
@ -12,6 +12,7 @@ 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
from v2realbot.strategyblocks.activetrade.sl.optimsl import SLOptimizer
def eval_close_position(state: StrategyState, data):
curr_price = float(data['close'])
@ -25,11 +26,26 @@ def eval_close_position(state: StrategyState, data):
#mame short pozice - (IDEA: rozlisovat na zaklade aktivniho tradu - umozni mi spoustet i pri soucasne long pozicemi)
if int(state.positions) < 0:
#get TARGET PRICE pro dany smer a signal
goal_price = get_profit_target_price(state, data, TradeDirection.SHORT)
#pokud existujeme bereme z nastaveni tradu a nebo z defaultu
if state.vars.activeTrade.goal_price is not None:
goal_price = state.vars.activeTrade.goal_price
else:
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}")
state.ilog(lvl=1,e=f"Def Goal price {str(TradeDirection.SHORT)} {goal_price} max price {max_price}")
#SL - execution
#SL OPTIMALIZATION - PARTIAL EXIT
level_met, exit_adjustment = state.sl_optimizer_short.eval_position(state, data)
if level_met is not None and exit_adjustment is not None:
position = state.positions * exit_adjustment
state.ilog(lvl=1,e=f"SL OPTIMIZATION ENGAGED {str(TradeDirection.SHORT)} {position=} {level_met=} {exit_adjustment}", initial_levels=str(state.sl_optimizer_short.get_initial_abs_levels(state)), rem_levels=str(state.sl_optimizer_short.get_remaining_abs_levels(state)), exit_levels=str(state.sl_optimizer_short.exit_levels), exit_sizes=str(state.sl_optimizer_short.exit_sizes))
printanyway(f"SL OPTIMIZATION ENGAGED {str(TradeDirection.SHORT)} {position=} {level_met=} {exit_adjustment}")
close_position_partial(state=state, data=data, direction=TradeDirection.SHORT, reason=F"SL OPT LEVEL {level_met} REACHED", size=exit_adjustment)
return
#FULL SL reached - execution
if curr_price > state.vars.activeTrade.stoploss_value:
directive_name = 'reverse_for_SL_exit_short'
@ -90,13 +106,25 @@ def eval_close_position(state: StrategyState, data):
elif int(state.positions) > 0:
#get TARGET PRICE pro dany smer a signal
goal_price = get_profit_target_price(state, data, TradeDirection.LONG)
#pokud existujeme bereme z nastaveni tradu a nebo z defaultu
if state.vars.activeTrade.goal_price is not None:
goal_price = state.vars.activeTrade.goal_price
else:
goal_price = get_profit_target_price(state, data, TradeDirection.LONG)
max_price = get_max_profit_price(state, data, TradeDirection.LONG)
state.ilog(lvl=1,e=f"Goal price {str(TradeDirection.LONG)} {goal_price} max price {max_price}")
#EOD EXIT - TBD
#SL OPTIMALIZATION - PARTIAL EXIT
level_met, exit_adjustment = state.sl_optimizer_long.eval_position(state, data)
if level_met is not None and exit_adjustment is not None:
position = state.positions * exit_adjustment
state.ilog(lvl=1,e=f"SL OPTIMIZATION ENGAGED {str(TradeDirection.LONG)} {position=} {level_met=} {exit_adjustment}", initial_levels=str(state.sl_optimizer_long.get_initial_abs_levels(state)), rem_levels=str(state.sl_optimizer_long.get_remaining_abs_levels(state)), exit_levels=str(state.sl_optimizer_long.exit_levels), exit_sizes=str(state.sl_optimizer_long.exit_sizes))
printanyway(f"SL OPTIMIZATION ENGAGED {str(TradeDirection.LONG)} {position=} {level_met=} {exit_adjustment}")
close_position_partial(state=state, data=data, direction=TradeDirection.LONG, reason=f"SL OPT LEVEL {level_met} REACHED", size=exit_adjustment)
return
#SL - execution
#SL FULL execution
if curr_price < state.vars.activeTrade.stoploss_value:
directive_name = 'reverse_for_SL_exit_long'
reverse_for_SL_exit = get_override_for_active_trade(state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, "no"))

View File

@ -1,5 +1,3 @@
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
@ -161,12 +159,25 @@ def get_profit_target_price(state, data, direction: TradeDirection):
directive_name = 'profit_'+str(smer)
def_profit = get_override_for_active_trade(state, directive_name=directive_name, default_value=def_profit_both_directions)
normalized_def_profit = normalize_tick(state, data, float(def_profit))
#mame v direktivve ticky
if isinstance(def_profit, (float, int)):
normalized_def_profit = normalize_tick(state, data, float(def_profit))
state.ilog(lvl=0,e=f"PROFIT {def_profit=} {normalized_def_profit=}")
state.ilog(lvl=0,e=f"PROFIT {def_profit=} {normalized_def_profit=}")
base_price = state.avgp if state.avgp != 0 else data["close"]
to_return = price2dec(float(base_price)+normalized_def_profit,3) if direction == TradeDirection.LONG else price2dec(float(base_price)-normalized_def_profit,3)
#mame v direktive indikator
elif isinstance(def_profit, str):
to_return = float(value_or_indicator(state, def_profit))
if direction == TradeDirection.LONG and to_return < data['close'] or direction == TradeDirection.SHORT and to_return > data['close']:
state.ilog(lvl=1,e=f"SPATNA HODOTA DOTAZENEHO PROFITU z ind {def_profit} {to_return=} {smer} {data['close']}")
raise Exception(f"SPATNA HODOTA DOTAZENEHO PROFITU z ind{def_profit} {to_return=} {smer} {data['close']}")
state.ilog(lvl=1,e=f"DOTAZENY PROFIT z indikatoru {def_profit} {to_return=}")
return to_return
return price2dec(float(state.avgp)+normalized_def_profit,3) if int(state.positions) > 0 else price2dec(float(state.avgp)-normalized_def_profit,3)
def get_max_profit_price(state, data, direction: TradeDirection):
if direction == TradeDirection.LONG:
smer = "long"

View File

@ -0,0 +1,151 @@
import numpy as np
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus
from typing import Tuple
from copy import deepcopy
from v2realbot.strategyblocks.activetrade.helpers import get_override_for_active_trade
from v2realbot.utils.utils import safe_get
# FIBONACCI PRO PROFIT A SL
##most used fibonacci retracement levels
# 23.6% retracement level = (stop loss price - current price) * 0.236 + current price
# 38.2% retracement level = (stop loss price - current price) * 0.382 + current price
# 50.0% retracement level = (stop loss price - current price) * 0.500 + current price
# 61.8% retracement level = (stop loss price - current price) * 0.618 + current price
# 78.6% retracement level = (stop loss price - current price) * 0.786 + current price
#cil: moznost pouzit fibanocci scale pro castecny stoploss exit (percentage at each downlevel)
#a zároveň exit, případně add at each up level
#up retracements (profit retracement)
# exit part of position at certain -
# [0.236, 0.382, 0.618, 1.0] - 25% off at each level? a nebo 5% add? - TBD vymyslet jak pojmout v direktive?
#down retracement (stoploss retracement)
# exit part of position at certain levels - TBD jak zapsat v dsirektive?
# [0.236, 0.382, 0.618, 1.0] - 25% off at each level
# #tridu, kterou muze vyuzivat SL a Profit optimizer
class SLOptimizer:
""""
Class to handle SL positition optimization for active trade. It is assumed that two instances exists
one for LONG trade and one for SHORT. During evaluate call, settings is initialized from trade setting
and used for every call on that trade. When evaluate is called on different trade, it is again initialized
according to new trade settings.
-samostatna instance pro short a long
-zatim pri opakovem prekroceni targetu nic nedelame (target aplikovany jen jednouo)
exit_levels = aktuální levely, prekroceny je povazovan za vyuzitý a maze se
exit_sizes = aktualní size multipliers, prekroceny je povazovan za vyuzitý a maze se
init_exit_levels, init_exit_sizes - puvodni plne
"""
def __init__(self, direction: TradeDirection) -> None:
##init - make exit size same length:
self.direction = direction
self.last_trade = 0
# def reset_levels(self):
# self.exit_levels = self.init_exit_levels
# self.exit_sizes = self.init_exit_sizes
def get_trade_details(self, state):
trade: Trade = state.vars.activeTrade
#jde o novy trade - resetujeme levely
if trade.id != self.last_trade:
#inicializujeme a vymazeme pripadne puvodni
if self.initialize_levels(state) is False:
return None, None
self.last_trade = trade.id
#return cost_price, sl_price
return state.avgp, trade.stoploss_value
def initialize_levels(self, state):
directive_name = 'SL_opt_exit_levels_'+str(self.direction.value)
SL_opt_exit_levels = get_override_for_active_trade(state=state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, None))
directive_name = 'SL_opt_exit_sizes_'+str(self.direction.value)
SL_opt_exit_sizes = get_override_for_active_trade(state=state, directive_name=directive_name, default_value=safe_get(state.vars, directive_name, None))
if SL_opt_exit_levels is None or SL_opt_exit_sizes is None:
#print("no directives found: SL_opt_exit_levels/SL_opt_exit_sizes")
return False
if len(SL_opt_exit_sizes) == 1:
SL_opt_exit_sizes = SL_opt_exit_sizes * len(SL_opt_exit_levels)
if len(SL_opt_exit_sizes) != len(SL_opt_exit_levels):
raise Exception("exit_sizes doesnt fit exit_levels")
self.init_exit_levels = deepcopy(SL_opt_exit_levels)
self.init_exit_sizes = deepcopy(SL_opt_exit_sizes)
self.exit_levels = SL_opt_exit_levels
self.exit_sizes = SL_opt_exit_sizes
print(f"new levels initialized {self.exit_levels=} {self.exit_sizes=}")
return True
def get_initial_abs_levels(self, state):
"""
Returns price levels corresponding to initial setting of exit_levels
"""
cost_price, sl_price = self.get_trade_details(state)
if cost_price is None or sl_price is None:
return []
curr_sl_distance = np.abs(cost_price - sl_price)
if self.direction == TradeDirection.SHORT :
return [cost_price + exit_level * curr_sl_distance for exit_level in self.init_exit_levels]
else:
return [cost_price - exit_level * curr_sl_distance for exit_level in self.init_exit_levels]
def get_remaining_abs_levels(self, state):
"""
Returns price levels corresponding to remaing exit_levels for current trade
"""
cost_price, sl_price = self.get_trade_details(state)
if cost_price is None or sl_price is None:
return []
curr_sl_distance = np.abs(cost_price - sl_price)
if self.direction == TradeDirection.SHORT :
return [cost_price + exit_level * curr_sl_distance for exit_level in self.exit_levels]
else:
return [cost_price - exit_level * curr_sl_distance for exit_level in self.exit_levels]
def eval_position(self, state, data) -> Tuple[float, float]:
"""Evaluates optimalization for current position and returns if the given level was
met and how to adjust exit position.
"""
cost_price, sl_price = self.get_trade_details(state)
if cost_price is None or sl_price is None:
#print("no settings found")
return (None, None)
current_price = data["close"]
# Calculate the distance of the cost prcie from the stop-loss value
curr_sl_distance = np.abs(cost_price - sl_price)
level_met = None
exit_adjustment = None
if len(self.exit_levels) == 0 or len(self.exit_sizes) == 0:
#print("levels exhausted")
return (None, None)
#for short
if self.direction == TradeDirection.SHORT :
#first available exit point
level_price = cost_price + self.exit_levels[0] * curr_sl_distance
if current_price > level_price:
# Remove the first element from exit_levels.
level_met = self.exit_levels.pop(0)
# Remove the first element from exit_sizes.
exit_adjustment = self.exit_sizes.pop(0)
#for shorts
else:
#price of first available exit point
level_price = cost_price - self.exit_levels[0] * curr_sl_distance
if current_price < level_price:
# Remove the first element from exit_levels.
level_met = self.exit_levels.pop(0)
# Remove the first element from exit_sizes.
exit_adjustment = self.exit_sizes.pop(0)
return level_met, exit_adjustment

View File

@ -1,7 +1,3 @@
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

View File

@ -1,23 +1,57 @@
from v2realbot.strategy.base import StrategyState
from v2realbot.enums.enums import RecordType
def populate_cbar_tick_price_indicator(data, state: StrategyState):
try:
#pokud v potvrzovacím baru nebyly zmeny, nechavam puvodni hodnoty
# if tick_delta_volume == 0:
# state.indicators.tick_price[-1] = state.indicators.tick_price[-2]
# state.indicators.tick_volume[-1] = state.indicators.tick_volume[-2]
# else:
conf_bar = data['confirmed']
#tick_price = round2five(data['close'])
tick_price = data['close']
tick_delta_volume = data['volume'] - state.vars.last_tick_volume
#specifická sekce pro CBARVOLUME, kde vzdy máme nova data v confirmation baru (tzn. tickprice pocitame jak pri potvrzenem tak nepotvrzenem)
if state.rectype == RecordType.CBARVOLUME:
try:
tick_price = data['close']
tick_delta_volume = data['volume'] - state.vars.last_tick_volume
state.cbar_indicators.tick_price[-1] = tick_price
state.cbar_indicators.tick_volume[-1] = tick_delta_volume
except:
pass
state.cbar_indicators.tick_price[-1] = tick_price
state.cbar_indicators.tick_volume[-1] = tick_delta_volume
except:
pass
state.ilog(lvl=0,e=f"TICK PRICE {tick_price} VOLUME {tick_delta_volume} {data['confirmed']=}", prev_price=state.vars.last_tick_price, prev_volume=state.vars.last_tick_volume)
state.ilog(lvl=0,e=f"TICK PRICE CBARV {tick_price} VOLUME {tick_delta_volume} {data['confirmed']=}", prev_price=state.vars.last_tick_price, prev_volume=state.vars.last_tick_volume)
state.vars.last_tick_price = tick_price
state.vars.last_tick_volume = data['volume']
state.vars.last_tick_price = tick_price
state.vars.last_tick_volume = data['volume']
if conf_bar == 1:
#pri potvrzem CBARu nulujeme counter volume pro tick based indicator
state.vars.last_tick_volume = 0
state.vars.next_new = 1
#pro standardní CBARy
else:
if conf_bar == 1:
#pri potvrzem CBARu nulujeme counter volume pro tick based indicator
state.vars.last_tick_volume = 0
state.vars.next_new = 1
#naopak pri CBARu confirmation bar nema zadna nova data (tzn. tickprice pocitame jen pri potvrzenem)
else:
try:
#pokud v potvrzovacím baru nebyly zmeny, nechavam puvodni hodnoty
# if tick_delta_volume == 0:
# state.indicators.tick_price[-1] = state.indicators.tick_price[-2]
# state.indicators.tick_volume[-1] = state.indicators.tick_volume[-2]
# else:
#tick_price = round2five(data['close'])
tick_price = data['close']
tick_delta_volume = data['volume'] - state.vars.last_tick_volume
state.cbar_indicators.tick_price[-1] = tick_price
state.cbar_indicators.tick_volume[-1] = tick_delta_volume
except:
pass
state.ilog(lvl=0,e=f"TICK PRICE CBAR {tick_price} VOLUME {tick_delta_volume} {data['confirmed']=}", prev_price=state.vars.last_tick_price, prev_volume=state.vars.last_tick_volume)
state.vars.last_tick_price = tick_price
state.vars.last_tick_volume = data['volume']

View File

@ -1,5 +1,5 @@
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 v2realbot.strategy.base import StrategyState
from traceback import format_exc
#ZATIM tyto zkopirovany SEM DO HELPERS
@ -71,7 +71,7 @@ def get_source_or_MA(state, indicator):
except KeyError:
return state.bars[indicator]
def get_source_series(state: StrategyState, source: str):
def get_source_series(state, source: str):
"""
Podporujeme krome klice v bar a indikatoru a dalsi doplnujici, oddelene _ napr. dailyBars_close
vezme serii static.dailyBars[close]

View File

@ -55,20 +55,16 @@ def populate_all_indicators(data, state: StrategyState):
#TODO tento lof patri spis do nextu classic SL - je poplatny typu stratefie
#TODO na toto se podivam, nejak moc zajasonovani a zpatky -
#PERF PROBLEM
state.ilog(lvl=1,e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} SL:{state.vars.activeTrade.stoploss_value if state.vars.activeTrade is not None else None} profit:{round(float(state.profit),2)} profit_rel:{round(np.mean(state.rel_profit_cum),6) if len(state.rel_profit_cum)>0 else 0} Trades:{len(state.tradeList)} pend:{state.vars.pending}", rel_profit_cum=str(state.rel_profit_cum), activeTrade=json.loads(json.dumps(state.vars.activeTrade, default=json_serial)), prescribedTrades=json.loads(json.dumps(state.vars.prescribedTrades, default=json_serial)), pending=str(state.vars.pending))
state.ilog(lvl=1,e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} SL:{state.vars.activeTrade.stoploss_value if state.vars.activeTrade is not None else None} GP:{state.vars.activeTrade.goal_price if state.vars.activeTrade is not None else None} profit:{round(float(state.profit),2)} profit_rel:{round(np.mean(state.rel_profit_cum),6) if len(state.rel_profit_cum)>0 else 0} Trades:{len(state.tradeList)} pend:{state.vars.pending}", rel_profit_cum=str(state.rel_profit_cum), activeTrade=json.loads(json.dumps(state.vars.activeTrade, default=json_serial)), prescribedTrades=json.loads(json.dumps(state.vars.prescribedTrades, default=json_serial)), pending=str(state.vars.pending))
#kroky pro CONFIRMED BAR only
if conf_bar == 1:
#logika pouze pro potvrzeny bar
state.ilog(lvl=0,e="BAR potvrzeny")
#pri potvrzem CBARu nulujeme counter volume pro tick based indicator
state.vars.last_tick_volume = 0
state.vars.next_new = 1
#kroky pro CONTINOUS TICKS only
pass
else:
#CBAR INDICATOR pro tick price a deltu VOLUME
populate_cbar_tick_price_indicator(data, state)
pass
populate_cbar_tick_price_indicator(data, state)
#TBD nize predelat na typizovane RSI (a to jak na urovni CBAR tak confirmed)
#populate_cbar_rsi_indicator()

View File

@ -4,7 +4,8 @@ from v2realbot.utils.utils import zoneNY, json_serial
from datetime import datetime
#import random
import json
from v2realbot.strategyblocks.activetrade.helpers import insert_SL_history, get_default_sl_value, normalize_tick
from v2realbot.strategyblocks.activetrade.helpers import insert_SL_history, get_default_sl_value, normalize_tick, get_profit_target_price
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
#TODO nad prescribed trades postavit vstupni funkce
def execute_prescribed_trades(state: StrategyState, data):
@ -46,15 +47,28 @@ 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}")
#defaultni goal price pripadne nastavujeme az v notifikaci
#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)
#normalizuji dle aktualni ceny
sl_defvalue_normalized = normalize_tick(state, data,sl_defvalue)
state.vars.activeTrade.stoploss_value = float(data['close']) - sl_defvalue_normalized
if isinstance(sl_defvalue, (float, int)):
#normalizuji dle aktualni ceny
sl_defvalue_normalized = normalize_tick(state, data,sl_defvalue)
state.vars.activeTrade.stoploss_value = float(data['close']) - sl_defvalue_normalized
state.ilog(lvl=1,e=f"Nastaveno SL na {sl_defvalue}, priced normalized: {sl_defvalue_normalized} price: {state.vars.activeTrade.stoploss_value }")
elif isinstance(sl_defvalue, str):
#from indicator
ind = sl_defvalue_abs
sl_defvalue_abs = float(value_or_indicator(state, sl_defvalue))
if sl_defvalue_abs >= float(data['close']):
raise Exception(f"error in stoploss {sl_defvalue_abs} >= curr price")
state.vars.activeTrade.stoploss_value = sl_defvalue_abs
state.ilog(lvl=1,e=f"Nastaveno SL na {sl_defvalue_abs} dle indikatoru {ind}")
insert_SL_history(state)
state.ilog(lvl=1,e=f"Nastaveno SL na {sl_defvalue}, priced normalized: {sl_defvalue_normalized} price: {state.vars.activeTrade.stoploss_value }")
state.vars.pending = state.vars.activeTrade.id
elif state.vars.activeTrade.direction == TradeDirection.SHORT:
state.ilog(lvl=1,e="odesilame SHORT ORDER",trade=json.loads(json.dumps(state.vars.activeTrade, default=json_serial)))
@ -65,14 +79,26 @@ def execute_prescribed_trades(state: StrategyState, data):
res = state.sell(size=size)
if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation SHORT {res}")
#defaultní goalprice nastavujeme az v notifikaci
#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)
#normalizuji dle aktualni ceny
sl_defvalue_normalized = normalize_tick(state, data, sl_defvalue)
state.vars.activeTrade.stoploss_value = float(data['close']) + sl_defvalue_normalized
if isinstance(sl_defvalue, (float, int)):
#normalizuji dle aktualni ceny
sl_defvalue_normalized = normalize_tick(state, data,sl_defvalue)
state.vars.activeTrade.stoploss_value = float(data['close']) + sl_defvalue_normalized
state.ilog(lvl=1,e=f"Nastaveno SL na {sl_defvalue}, priced normalized: {sl_defvalue_normalized} price: {state.vars.activeTrade.stoploss_value }")
elif isinstance(sl_defvalue, str):
#from indicator
ind = sl_defvalue_abs
sl_defvalue_abs = float(value_or_indicator(state, sl_defvalue))
if sl_defvalue_abs <= float(data['close']):
raise Exception(f"error in stoploss {sl_defvalue_abs} <= curr price")
state.vars.activeTrade.stoploss_value = sl_defvalue_abs
state.ilog(lvl=1,e=f"Nastaveno SL na {sl_defvalue_abs} dle indikatoru {ind}")
insert_SL_history(state)
state.ilog(lvl=1,e=f"Nastaveno SL na {sl_defvalue}, priced normalized: {sl_defvalue_normalized} price: {state.vars.activeTrade.stoploss_value }")
state.vars.pending = state.vars.activeTrade.id
else:
state.ilog(lvl=1,e="unknow direction")