From 75d4a82c7067d4e90c6f792f59be03cfb4208811 Mon Sep 17 00:00:00 2001 From: David Brazda Date: Fri, 15 Sep 2023 15:09:09 +0200 Subject: [PATCH] bugfixy --- v2realbot/ENTRY_ClassicSL_v01.py | 100 ++++++++----------- v2realbot/__pycache__/config.cpython-310.pyc | Bin 3281 -> 3311 bytes v2realbot/config.py | 1 + v2realbot/controller/services.py | 6 ++ 4 files changed, 50 insertions(+), 57 deletions(-) diff --git a/v2realbot/ENTRY_ClassicSL_v01.py b/v2realbot/ENTRY_ClassicSL_v01.py index ca59cbd..3c2ee0a 100644 --- a/v2realbot/ENTRY_ClassicSL_v01.py +++ b/v2realbot/ENTRY_ClassicSL_v01.py @@ -890,67 +890,41 @@ def next(data, state: StrategyState): # endregion # region Subfunction - #toto upravit na take profit - #pripadne smazat - zatim nahrazeno by exit_conditions_met() - #TODO toto refactorovat - def sell_protection_enabled(): - options = safe_get(state.vars, 'sell_protection', None) - if options is None: - state.ilog(lvl=0,e="No options for sell protection in stratvars") - return False - - #docasne disabled, upravit pokud budu chtit pouzit - return False - disable_sell_proteciton_when = dict(AND=dict(), OR=dict()) + def dontexit_protection_met(direction: TradeDirection): + if direction == TradeDirection.LONG: + smer = "long" + else: + smer = "short" - #preconditions - disable_sell_proteciton_when['disabled_in_config'] = safe_get(options, 'enabled', False) is False - #too good to be true (maximum profit) - #disable_sell_proteciton_when['tgtbt_reached'] = safe_get(options, 'tgtbt', False) is False - disable_sell_proteciton_when['disable_if_positions_above'] = int(safe_get(options, 'disable_if_positions_above', 0)) < state.positions + mother_signal = state.vars.activeTrade.generated_by - #testing preconditions - result, conditions_met = eval_cond_dict(disable_sell_proteciton_when) - if result: - state.ilog(lvl=0,e=f"SELL_PROTECTION DISABLED by {conditions_met}", **conditions_met) - return False - - work_dict_dont_sell_if = get_work_dict_with_directive(starts_with="dont_sell_if") - state.ilog(lvl=0,e=f"SELL PROTECTION work_dict", message=work_dict_dont_sell_if) - - or_cond = evaluate_directive_conditions(work_dict_dont_sell_if, "OR") - result, conditions_met = eval_cond_dict(or_cond) - state.ilog(lvl=0,e=f"SELL PROTECTION =OR= {result}", **conditions_met) + if mother_signal is not None: + #TESTUJEME DONT_EXIT_ + cond_dict = state.vars.conditions[KW.dont_exit][mother_signal][smer] + #OR + result, conditions_met = evaluate_directive_conditions(cond_dict, "OR") + state.ilog(lvl=1,e=f"DONT_EXIT {mother_signal} {smer} =OR= {result}", **conditions_met, cond_dict=cond_dict) + if result: + return True + + #OR neprosly testujeme AND + result, conditions_met = evaluate_directive_conditions(cond_dict, "AND") + state.ilog(lvl=1,e=f"DONT_EXIT {mother_signal} {smer} =AND= {result}", **conditions_met, cond_dict=cond_dict) + if result: + return True + + cond_dict = state.vars.conditions[KW.dont_exit]["common"][smer] + #OR + result, conditions_met = evaluate_directive_conditions(cond_dict, "OR") + state.ilog(lvl=1,e=f"DONT_EXIT common {smer} =OR= {result}", **conditions_met, cond_dict=cond_dict) if result: return True #OR neprosly testujeme AND - and_cond = evaluate_directive_conditions(work_dict_dont_sell_if, "AND") - result, conditions_met = eval_cond_dict(and_cond) - state.ilog(lvl=0,e=f"SELL PROTECTION =AND= {result}", **conditions_met) - return result - - #PUVODNI NASTAVENI - IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později - - # #pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3) - - # #TODO zkusit pro pevny profit, jednoduse pozdrzet prodej - dokud tick_price roste nebo se drzi tak neprodavat, pokud klesne prodat - # #mozna mit dva mody - pri vetsi volatilite pouzivat momentum, pri mensi nebo kdyz potrebuju pryc, tak prodat hned - - #puvodni nastaveni - #slopeMA_rising = 2 - #rsi_not_falling = 3 - - # #toto docasne pryc dont_sell_when['slope_too_high'] = slope_too_high() and not isfalling(state.indicators.slopeMA,4) - # dont_sell_when['AND']['slopeMA_rising'] = isrising(state.indicators.slopeMA,safe_get(options, 'slopeMA_rising', 2)) - # dont_sell_when['AND']['rsi_not_falling'] = not isfalling(state.indicators.RSI14,safe_get(options, 'rsi_not_falling',3)) - # #dont_sell_when['rsi_dont_buy'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50) - - # result, conditions_met = eval_cond_dict(dont_sell_when) - # if result: - # state.ilog(lvl=0,e=f"SELL_PROTECTION {conditions_met} enabled") - # return result + result, conditions_met = evaluate_directive_conditions(cond_dict, "AND") + state.ilog(lvl=1,e=f"DONT_EXIT common {smer} =AND= {result}", **conditions_met, cond_dict=cond_dict) + return result def normalize_tick(tick: float, price: float = None, return_two_decimals: bool = False): """ @@ -1096,7 +1070,7 @@ def next(data, state: StrategyState): mother_signal = state.vars.activeTrade.generated_by if mother_signal is not None: - cond_dict = state.vars.conditions[keyword][state.vars.activeTrade.generated_by][smer] + cond_dict = state.vars.conditions[keyword][mother_signal][smer] result, conditions_met = evaluate_directive_conditions(cond_dict, "OR") state.ilog(lvl=1,e=f"{action} CONDITIONS of {mother_signal} =OR= {result}", **conditions_met, cond_dict=cond_dict) if result: @@ -1364,6 +1338,16 @@ def next(data, state: StrategyState): directive_name = 'SL_trailing_enabled_'+str(smer) sl_trailing_enabled = get_override_for_active_trade(directive_name=directive_name, default_value=safe_get(options, directive_name, False)) + + #SL_trailing_protection_window_short + directive_name = 'SL_trailing_protection_window_'+str(smer) + SL_trailing_protection_window = get_override_for_active_trade(directive_name=directive_name, default_value=safe_get(options, directive_name, 0)) + index_to_compare = int(state.vars.last_in_index)+int(SL_trailing_protection_window) + if index_to_compare > int(data["index"]): + state.ilog(lvl=1,e=f"SL trail PROTECTION WINDOW {SL_trailing_protection_window} - TOO SOON", currindex=data["index"], index_to_compare=index_to_compare, last_in_index=state.vars.last_in_index) + return + + if sl_trailing_enabled is True: directive_name = 'SL_trailing_stop_at_breakeven_'+str(smer) @@ -1481,7 +1465,7 @@ def next(data, state: StrategyState): #TODO pripadne pokud dosahne TGTBB prodat ihned max_price_signal = curr_price<=max_price #OPTIMALIZACE pri stoupajícím angle - if max_price_signal or sell_protection_enabled() is False: + if max_price_signal or dontexit_protection_met(direction=TradeDirection.SHORT) is False: close_position(direction=TradeDirection.SHORT, reason=f"PROFIT or MAXPROFIT REACHED {max_price_signal=}") return #mame long @@ -1529,7 +1513,7 @@ def next(data, state: StrategyState): #TODO pripadne pokud dosahne TGTBB prodat ihned max_price_signal = curr_price>=max_price #OPTIMALIZACE pri stoupajícím angle - if max_price_signal or sell_protection_enabled() is False: + if max_price_signal or dontexit_protection_met(direction=TradeDirection.LONG) is False: close_position(direction=TradeDirection.LONG, reason=f"PROFIT or MAXPROFIT REACHED {max_price_signal=}") return @@ -1958,6 +1942,7 @@ def init(state: StrategyState): # state.vars.conditions["exit"]["common"]["long"] = #sada podminek state.vars.conditions.setdefault(KW.dont_go,{}).setdefault(signalname,{})[smer] = get_conditions_from_configuration(action=KW.dont_go+"_" + smer +"_if", section=section) + state.vars.conditions.setdefault(KW.dont_exit,{}).setdefault(signalname,{})[smer] = get_conditions_from_configuration(action=KW.dont_exit+"_" + smer +"_if", section=section) state.vars.conditions.setdefault(KW.go,{}).setdefault(signalname,{})[smer] = get_conditions_from_configuration(action=KW.go+"_" + smer +"_if", section=section) state.vars.conditions.setdefault(KW.exit,{}).setdefault(signalname,{})[smer] = get_conditions_from_configuration(action=KW.exit+"_" + smer +"_if", section=section) state.vars.conditions.setdefault(KW.reverse,{}).setdefault(signalname,{})[smer] = get_conditions_from_configuration(action=KW.reverse+"_" + smer +"_if", section=section) @@ -1969,6 +1954,7 @@ def init(state: StrategyState): section = state.vars.exit["conditions"] for smer in TradeDirection: state.vars.conditions.setdefault(KW.exit,{}).setdefault("common",{})[smer] = get_conditions_from_configuration(action=KW.exit+"_" + smer +"_if", section=section) + state.vars.conditions.setdefault(KW.dont_exit,{}).setdefault("common",{})[smer] = get_conditions_from_configuration(action=KW.dont_exit+"_" + smer +"_if", section=section) state.vars.conditions.setdefault(KW.reverse,{}).setdefault("common",{})[smer] = get_conditions_from_configuration(action=KW.reverse+"_" + smer +"_if", section=section) state.vars.conditions.setdefault(KW.exitadd,{}).setdefault("common",{})[smer] = get_conditions_from_configuration(action=KW.exitadd+"_" + smer +"_if", section=section) #init klice v extData pro ulozeni historie SL diff --git a/v2realbot/__pycache__/config.cpython-310.pyc b/v2realbot/__pycache__/config.cpython-310.pyc index f7b5293aada67bcb14027f5050c1e1c747260cdf..754a4ef24b8220071dbb7ed42894eaaafda2c9a7 100644 GIT binary patch delta 1105 zcmZ9L&rcdb6vtUWe(XX;MJ<9q8fz_wCWx`NjcI`0fo@r0-CaPrtl(}8)_@r(sl7D4 z^inU)-1;B%*m!OF7xdD!r`M$Sp4!BJpfih#3Ykydy!U-?XXm~B9{U>$cfw)bMSrm2 zwKJc?@434m9NBHF)!uKuJnllEdDz)|K~3Nf?Edj#=e6DL!08umj^iTamphRdquF?z zVS*t_@yUf}m_0)#JbHYTnkl-vAqw6V;s*bS8;_E=o}a=%%Jgxv>rIKX)GQ^vc#^rM z7^WGP8HQTNiZfq=;t^e4FGaw0i^GZ2AKq#@?|ct3tOf*%_A$b^gOh%IpE_`odA(L^uZQQ@ex6~0;SR&_FmZC`OE0fe=bsS@ z7_l1tmIYC@SSX;HjCShf>Q-LTcGgo05XGOIhG@2!TYDz0rWIAHi;oSpQhROyIdNiY zF;(7rRxhMh)k=Lu7uO!9szAQ^MXpIAf!dq8V0-Nm%fI2W0=g?11b49pfyQ31)o=7{ z@LQdB&)n}o&@t>+tsc1P*6Ub)#)f5qAKQH!ckNO#bn~*a?ETUVF@_w2$RIge#F%F& zFbpqZ*p&}D8?t|uPG(jkjo`HAT&{tH)YxdgI}D4aj{$}8O{i?8c3&4BPaagC>v;J z>M-j#kgxnat^1pwPCzUxI$0}&5xY8dWK5W&vXn3x2ahhRFmXehN9>Th!c-h?UxpN! z-o};LB_D*@+?7-(J{afm>q${KgK8cbZC^g; RBE)Lq414{XEhn8&^FOt6BW3^q delta 1149 zcmZXSO-~a+7{|M%w58iZ%S#KifC-?f2~f(L8cl4s)3SEEyXf?SN@>fMVMqo?W@@Z`ZS;LH|Esk@n9o_XH(*_r>JiEk5udLZC)(C6$6 zSDE<~c+JfLe_W}RtF?o@r>70@?j6xmMOuO5Lbk)U@wsypJ|mNUQI@|ye2>WSH`v^?c{t%(on zbvkD{S7|3}Xzd3~LPQ3>ysW2)lmi>U@(la7b5!U2^CCoPKAJvsg@yFF?pV zIyU#s#j@En7c1n!z|uT;%;V#7)oNI7ngpYwq~x%kDj_VP5|VIMQwl)d4cr8nlohRz zl0-lmY=}Z0r&Bt@swN5uLaaEbSy#DZvCYj6?N5$)HG63aI`2E&3(63$59F6`W);FI!OmZ9%dDfpi5`EKBFPdzy-X!>y|As)K3!B{q$iX` z?C+lQ;V6uELXt=ix4Y{{ek$EnYRB76hp!je?Jnm|_RLKN{gWJ!xPLm^8SygbVnh+` TbiQ*LVm)nr{3j~%*1z`;-YFKk diff --git a/v2realbot/config.py b/v2realbot/config.py index 1a22f74..6b4439c 100644 --- a/v2realbot/config.py +++ b/v2realbot/config.py @@ -106,6 +106,7 @@ ACCOUNT2_PAPER_FEED = DataFeed.IEX class KW: activate: str = "activate" dont_go: str = "dont_go" + dont_exit: str = "dont_exit" go: str = "go" # wip addsize: str = "addsize" exit: str = "exit" diff --git a/v2realbot/controller/services.py b/v2realbot/controller/services.py index a3f88d3..89403e9 100644 --- a/v2realbot/controller/services.py +++ b/v2realbot/controller/services.py @@ -581,11 +581,14 @@ def populate_metrics_output_directory(strat: StrategyInstance, inter_batch_param short_wins = 0 max_profit = 0 max_profit_time = None + long_cnt = 0 + short_cnt = 0 for trade in strat.state.vars.prescribedTrades: if trade.profit_sum > max_profit: max_profit = trade.profit_sum max_profit_time = trade.last_update if trade.status == TradeStatus.ACTIVATED and trade.direction == TradeDirection.LONG: + long_cnt += 1 if trade.profit is not None: long_profit += trade.profit if trade.profit < 0: @@ -593,12 +596,15 @@ def populate_metrics_output_directory(strat: StrategyInstance, inter_batch_param if trade.profit > 0: long_wins += trade.profit if trade.status == TradeStatus.ACTIVATED and trade.direction == TradeDirection.SHORT: + short_cnt +=1 if trade.profit is not None: short_profit += trade.profit if trade.profit < 0: short_losses += trade.profit if trade.profit > 0: short_wins += trade.profit + res["long_cnt"] = long_cnt + res["short_cnt"] = short_cnt res["long_profit"] = round(long_profit,2) res["short_profit"] = round(short_profit,2) res["long_losses"] = round(long_losses,2)