agregace volume baru, SL optimizace + goalprice
This commit is contained in:
@ -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"]
|
||||
@ -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"))
|
||||
|
||||
@ -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"
|
||||
|
||||
151
v2realbot/strategyblocks/activetrade/sl/optimsl.py
Normal file
151
v2realbot/strategyblocks/activetrade/sl/optimsl.py
Normal 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
|
||||
@ -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
|
||||
|
||||
@ -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']
|
||||
@ -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]
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
Reference in New Issue
Block a user