agregace volume baru, SL optimizace + goalprice
This commit is contained in:
6
testy/ascending.py
Normal file
6
testy/ascending.py
Normal file
File diff suppressed because one or more lines are too long
179
testy/fibonaccistoploss.py
Normal file
179
testy/fibonaccistoploss.py
Normal file
@ -0,0 +1,179 @@
|
||||
import numpy as np
|
||||
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus
|
||||
from typing import Tuple
|
||||
from copy import deepcopy
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategyblocks.activetrade.helpers import get_max_profit_price, get_profit_target_price, get_override_for_active_trade, keyword_conditions_met
|
||||
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: StrategyState):
|
||||
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)
|
||||
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)
|
||||
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 not 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
|
||||
|
||||
#0.236, 0.382, 0.5, 0.618, 0.786, 1
|
||||
exit_levels_input = [0.236, 0.382, 0.618, 1]
|
||||
exit_sizes_input = [0.5] #or [0.25, 0.25, 0.25]
|
||||
|
||||
long_sl_optimizer = SLOptimizer(exit_levels_input, exit_sizes_input, TradeDirection.SHORT)
|
||||
#short_sl_optimizer = SLOptimizer(exit_levels, exit_sizes, TradeDirection.SHORT)
|
||||
|
||||
print(long_sl_optimizer.get_remaining_abs_levels(90,100))
|
||||
|
||||
#new LONG trade
|
||||
level_met, exit_adjustment = long_sl_optimizer.eval_position(current_price=95,cost_price=90,sl_price=100)
|
||||
print(long_sl_optimizer.get_remaining_abs_levels(90,100))
|
||||
print(level_met, exit_adjustment)
|
||||
print(long_sl_optimizer.__dict__)
|
||||
|
||||
level_met, exit_adjustment = long_sl_optimizer.eval_position(current_price=95,cost_price=90,sl_price=100)
|
||||
print(long_sl_optimizer.get_remaining_abs_levels(90,100))
|
||||
print(level_met, exit_adjustment)
|
||||
print(long_sl_optimizer.__dict__)
|
||||
|
||||
level_met, exit_adjustment = long_sl_optimizer.eval_position(current_price=95,cost_price=90,sl_price=100)
|
||||
print(long_sl_optimizer.get_remaining_abs_levels(90,100))
|
||||
print(level_met, exit_adjustment)
|
||||
print(long_sl_optimizer.__dict__)
|
||||
|
||||
#long_sl_optimizer.eval_position(100,120)
|
||||
Reference in New Issue
Block a user