pridany metriky a bugfixy pro live run

This commit is contained in:
David Brazda
2023-08-28 20:22:37 +02:00
parent a94e2ed5e4
commit 4c861c59a1
9 changed files with 112 additions and 29 deletions

View File

@ -6,7 +6,7 @@ from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, Orde
from v2realbot.indicators.indicators import ema from v2realbot.indicators.indicators import ema
from v2realbot.indicators.oscillators import rsi from v2realbot.indicators.oscillators import rsi
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick, round2five, is_open_rush, is_close_rush, eval_cond_dict, Average, crossed_down, crossed_up, crossed, is_pivot, json_serial from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, round2five, is_open_rush, is_close_rush, eval_cond_dict, Average, crossed_down, crossed_up, crossed, is_pivot, json_serial
from datetime import datetime from datetime import datetime
from uuid import uuid4 from uuid import uuid4
import json import json
@ -173,13 +173,13 @@ def next(data, state: StrategyState):
#vrati true pokud dany indikator prekrocil threshold dolu #vrati true pokud dany indikator prekrocil threshold dolu
def buy_if_crossed_down(indicator, value): def buy_if_crossed_down(indicator, value):
res = crossed_down(threshold=value, list=get_source_or_MA(indicator)) res = crossed_down(threshold=value, list=get_source_or_MA(indicator))
state.ilog(e=f"buy_if_crossed_down {indicator} {value} {res}") state.ilog(e=f"signal_if_crossed_down {indicator} {value} {res}")
return res return res
#vrati true pokud dany indikator prekrocil threshold nahoru #vrati true pokud dany indikator prekrocil threshold nahoru
def buy_if_crossed_up(indicator, value): def buy_if_crossed_up(indicator, value):
res = crossed_up(threshold=value, list=get_source_or_MA(indicator)) res = crossed_up(threshold=value, list=get_source_or_MA(indicator))
state.ilog(e=f"buy_if_crossed_up {indicator} {value} {res}") state.ilog(e=f"signal_if_crossed_up {indicator} {value} {res}")
return res return res
def populate_cbar_tick_price_indicator(): def populate_cbar_tick_price_indicator():
@ -625,6 +625,36 @@ def next(data, state: StrategyState):
# state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled") # state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled")
# return result # return result
def normalize_tick(tick: float, price: float = None, return_two_decimals: bool = False):
"""
Pokud je nastaveno v direktive:
#zda normalizovat vsechyn ticky (tzn. profit, maxprofit, SL atp.)
Normalize_ticks= true
Normalized Tick base price = 30
prevede normalizovany tick na tick odpovidajici vstupni cene
vysledek je zaokoruhleny na 2 des.mista
u cen pod 30, vrací 0.01. U cen nad 30 vrací pomerne zvetsene,
"""
#nemusime dodavat cenu, bereme aktualni
if price is None:
price = data["close"]
normalize_ticks = safe_get(state.vars, "normalize_ticks",False)
normalized_base_price = safe_get(state.vars, "normalized_base_price",30)
if normalize_ticks:
if price<normalized_base_price:
return tick
else:
#ratio of price vs base price
ratio = price/normalized_base_price
normalized_tick = ratio*tick
return price2dec(normalized_tick) if return_two_decimals else normalized_tick
else:
return tick
def get_default_sl_value(direction: TradeDirection): def get_default_sl_value(direction: TradeDirection):
if direction == TradeDirection.LONG: if direction == TradeDirection.LONG:
smer = "long" smer = "long"
@ -641,12 +671,12 @@ def next(data, state: StrategyState):
def get_profit_target_price(): def get_profit_target_price():
def_profit = safe_get(state.vars, "def_profit",state.vars.profit) def_profit = safe_get(state.vars, "def_profit",state.vars.profit)
cena = float(state.avgp) cena = float(state.avgp)
return price2dec(cena+get_tick(cena,float(state.vars.profit)),3) if state.positions > 0 else price2dec(cena-get_tick(cena,float(state.vars.profit)),3) return price2dec(cena+normalize_tick(float(state.vars.profit)),3) if int(state.positions) > 0 else price2dec(cena-normalize_tick(float(state.vars.profit)),3)
def get_max_profit_price(): def get_max_profit_price():
max_profit = float(safe_get(state.vars, "max_profit",0.03)) max_profit = float(safe_get(state.vars, "max_profit",0.03))
cena = float(state.avgp) cena = float(state.avgp)
return price2dec(cena+get_tick(cena,max_profit),3) if state.positions > 0 else price2dec(cena-get_tick(cena,max_profit),3) return price2dec(cena+normalize_tick(max_profit),3) if int(state.positions) > 0 else price2dec(cena-normalize_tick(max_profit),3)
#TBD pripadne opet dat parsovani pole do INITu #TBD pripadne opet dat parsovani pole do INITu
@ -668,7 +698,7 @@ def next(data, state: StrategyState):
disable_exit_proteciton_when['disabled_in_config'] = safe_get(options, 'enabled', False) is False disable_exit_proteciton_when['disabled_in_config'] = safe_get(options, 'enabled', False) is False
#too good to be true (maximum profit) #too good to be true (maximum profit)
#disable_sell_proteciton_when['tgtbt_reached'] = safe_get(options, 'tgtbt', False) is False #disable_sell_proteciton_when['tgtbt_reached'] = safe_get(options, 'tgtbt', False) is False
disable_exit_proteciton_when['disable_if_positions_above'] = int(safe_get(options, 'disable_if_positions_above', 0)) < abs(state.positions) disable_exit_proteciton_when['disable_if_positions_above'] = int(safe_get(options, 'disable_if_positions_above', 0)) < abs(int(state.positions))
#testing preconditions #testing preconditions
result, conditions_met = eval_cond_dict(disable_exit_proteciton_when) result, conditions_met = eval_cond_dict(disable_exit_proteciton_when)
@ -747,20 +777,22 @@ def next(data, state: StrategyState):
#pokud je pozadovan trail jen do breakeven a uz prekroceno #pokud je pozadovan trail jen do breakeven a uz prekroceno
if (direction == TradeDirection.LONG and stop_breakeven and state.vars.activeTrade.stoploss_value >= float(state.avgp)) or (direction == TradeDirection.SHORT and stop_breakeven and state.vars.activeTrade.stoploss_value <= float(state.avgp)): if (direction == TradeDirection.LONG and stop_breakeven and state.vars.activeTrade.stoploss_value >= float(state.avgp)) or (direction == TradeDirection.SHORT and stop_breakeven and state.vars.activeTrade.stoploss_value <= float(state.avgp)):
state.ilog(e=f"SL trail stop at breakeven {str(smer)} SL {state.vars.activeTrade.stoploss_value} UNCHANGED", stop_breakeven=stop_breakeven) state.ilog(e=f"SL trail stop at breakeven {str(smer)} SL:{state.vars.activeTrade.stoploss_value} UNCHANGED", stop_breakeven=stop_breakeven)
return return
#IDEA: Nyni posouvame SL o offset, mozna ji posunout jen o direktivu step ? #IDEA: Nyni posouvame SL o offset, mozna ji posunout jen o direktivu step ?
offset_normalized = get_tick(data['close'],offset) #to ticks and from options offset_normalized = normalize_tick(offset) #to ticks and from options
def_SL_normalized = get_tick(data['close'],def_SL) def_SL_normalized = normalize_tick(def_SL)
if direction == TradeDirection.LONG: if direction == TradeDirection.LONG:
move_SL_threshold = state.vars.activeTrade.stoploss_value + offset_normalized + def_SL_normalized move_SL_threshold = state.vars.activeTrade.stoploss_value + offset_normalized + def_SL_normalized
state.ilog(e=f"SL trailing EVAL {smer} SL:{state.vars.activeTrade.stoploss_value} MOVETHRESHOLD:{move_SL_threshold}", def_SL=def_SL, offset=offset, offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
if (move_SL_threshold) < data['close']: if (move_SL_threshold) < data['close']:
state.vars.activeTrade.stoploss_value += offset_normalized state.vars.activeTrade.stoploss_value += offset_normalized
state.ilog(e=f"SL TRAIL TH {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized) state.ilog(e=f"SL TRAIL TH {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
elif direction == TradeDirection.SHORT: elif direction == TradeDirection.SHORT:
move_SL_threshold = state.vars.activeTrade.stoploss_value - offset_normalized - def_SL_normalized move_SL_threshold = state.vars.activeTrade.stoploss_value - offset_normalized - def_SL_normalized
state.ilog(e=f"SL trailing EVAL {smer} SL:{state.vars.activeTrade.stoploss_value} MOVETHRESHOLD:{move_SL_threshold}", def_SL=def_SL, offset=offset, offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
if (move_SL_threshold) > data['close']: if (move_SL_threshold) > data['close']:
state.vars.activeTrade.stoploss_value -= offset_normalized state.vars.activeTrade.stoploss_value -= offset_normalized
state.ilog(e=f"SL TRAIL TH {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized) state.ilog(e=f"SL TRAIL TH {smer} reached {move_SL_threshold} SL moved to {state.vars.activeTrade.stoploss_value}", offset_normalized=offset_normalized, def_SL_normalized=def_SL_normalized)
@ -788,7 +820,7 @@ def next(data, state: StrategyState):
#SL - execution #SL - execution
if curr_price > state.vars.activeTrade.stoploss_value: if curr_price > state.vars.activeTrade.stoploss_value:
state.ilog(e=f"STOPLOSS reached on SHORT", curr_price=curr_price, trade=state.vars.activeTrade) state.ilog(e=f"STOPLOSS reached on SHORT", curr_price=curr_price, trade=state.vars.activeTrade)
res = state.buy(size=abs(state.positions)) res = state.buy(size=abs(int(state.positions)))
if isinstance(res, int) and res < 0: if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation STOPLOSS BUY {res}") raise Exception(f"error in required operation STOPLOSS BUY {res}")
state.vars.pending = state.vars.activeTrade.id state.vars.pending = state.vars.activeTrade.id
@ -797,7 +829,7 @@ def next(data, state: StrategyState):
#CLOSING BASED ON EXIT CONDITIONS #CLOSING BASED ON EXIT CONDITIONS
if exit_conditions_met(TradeDirection.SHORT): if exit_conditions_met(TradeDirection.SHORT):
res = state.buy(size=abs(state.positions)) res = state.buy(size=abs(int(state.positions)))
if isinstance(res, int) and res < 0: if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation EXIT COND BUY {res}") raise Exception(f"error in required operation EXIT COND BUY {res}")
state.vars.pending = state.vars.activeTrade.id state.vars.pending = state.vars.activeTrade.id
@ -813,7 +845,7 @@ def next(data, state: StrategyState):
max_price_signal = curr_price<=max_price max_price_signal = curr_price<=max_price
#OPTIMALIZACE pri stoupajícím angle #OPTIMALIZACE pri stoupajícím angle
if max_price_signal or sell_protection_enabled() is False: if max_price_signal or sell_protection_enabled() is False:
res = state.buy(size=abs(state.positions)) res = state.buy(size=abs(int(state.positions)))
if isinstance(res, int) and res < 0: if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation PROFIT BUY {res}") raise Exception(f"error in required operation PROFIT BUY {res}")
state.vars.pending = state.vars.activeTrade.id state.vars.pending = state.vars.activeTrade.id
@ -838,7 +870,7 @@ def next(data, state: StrategyState):
return return
if exit_conditions_met(TradeDirection.LONG): if exit_conditions_met(TradeDirection.LONG):
res = state.sell(size=abs(state.positions)) res = state.sell(size=abs(int(state.positions)))
if isinstance(res, int) and res < 0: if isinstance(res, int) and res < 0:
raise Exception(f"error in required operation EXIT COND SELL {res}") raise Exception(f"error in required operation EXIT COND SELL {res}")
state.vars.pending = state.vars.activeTrade.id state.vars.pending = state.vars.activeTrade.id
@ -872,6 +904,7 @@ def next(data, state: StrategyState):
for trade in state.vars.prescribedTrades: for trade in state.vars.prescribedTrades:
if trade.status == TradeStatus.READY and trade.direction == TradeDirection.LONG and (trade.entry_price is None or trade.entry_price >= data['close']): if trade.status == TradeStatus.READY and trade.direction == TradeDirection.LONG and (trade.entry_price is None or trade.entry_price >= data['close']):
trade.status = TradeStatus.ACTIVATED trade.status = TradeStatus.ACTIVATED
trade.last_update = datetime.fromtimestamp(state.time).astimezone(zoneNY)
state.ilog(e=f"evaluated SHORT {str(trade)}", prescrTrades=json.loads(json.dumps(state.vars.prescribedTrades, default=json_serial))) state.ilog(e=f"evaluated SHORT {str(trade)}", prescrTrades=json.loads(json.dumps(state.vars.prescribedTrades, default=json_serial)))
state.vars.activeTrade = trade state.vars.activeTrade = trade
break break
@ -881,6 +914,7 @@ def next(data, state: StrategyState):
if trade.status == TradeStatus.READY and trade.direction == TradeDirection.SHORT and (trade.entry_price is None or trade.entry_price <= data['close']): if trade.status == TradeStatus.READY and trade.direction == TradeDirection.SHORT and (trade.entry_price is None or trade.entry_price <= data['close']):
state.ilog(e=f"evaluaed SHORT {str(trade)}", prescTrades=json.loads(json.dumps(state.vars.prescribedTrades, default=json_serial))) state.ilog(e=f"evaluaed SHORT {str(trade)}", prescTrades=json.loads(json.dumps(state.vars.prescribedTrades, default=json_serial)))
trade.status = TradeStatus.ACTIVATED trade.status = TradeStatus.ACTIVATED
trade.last_update = datetime.fromtimestamp(state.time).astimezone(zoneNY)
state.vars.activeTrade = trade state.vars.activeTrade = trade
break break
@ -895,7 +929,7 @@ def next(data, state: StrategyState):
if state.vars.activeTrade.stoploss_value is None: if state.vars.activeTrade.stoploss_value is None:
sl_defvalue = get_default_sl_value(direction=state.vars.activeTrade.direction) sl_defvalue = get_default_sl_value(direction=state.vars.activeTrade.direction)
#normalizuji dle aktualni ceny #normalizuji dle aktualni ceny
sl_defvalue_normalized = get_tick(data['close'],sl_defvalue) sl_defvalue_normalized = normalize_tick(sl_defvalue)
state.vars.activeTrade.stoploss_value = float(data['close']) - sl_defvalue_normalized state.vars.activeTrade.stoploss_value = float(data['close']) - sl_defvalue_normalized
state.ilog(e=f"Nastaveno SL na {sl_defvalue}, priced normalized: {sl_defvalue_normalized} price: {state.vars.activeTrade.stoploss_value }") state.ilog(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 state.vars.pending = state.vars.activeTrade.id
@ -908,7 +942,7 @@ def next(data, state: StrategyState):
if state.vars.activeTrade.stoploss_value is None: if state.vars.activeTrade.stoploss_value is None:
sl_defvalue = get_default_sl_value(direction=state.vars.activeTrade.direction) sl_defvalue = get_default_sl_value(direction=state.vars.activeTrade.direction)
#normalizuji dle aktualni ceny #normalizuji dle aktualni ceny
sl_defvalue_normalized = get_tick(data['close'],sl_defvalue) sl_defvalue_normalized = normalize_tick(sl_defvalue)
state.vars.activeTrade.stoploss_value = float(data['close']) + sl_defvalue_normalized state.vars.activeTrade.stoploss_value = float(data['close']) + sl_defvalue_normalized
state.ilog(e=f"Nastaveno SL na {sl_defvalue}, priced normalized: {sl_defvalue_normalized} price: {state.vars.activeTrade.stoploss_value }") state.ilog(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 state.vars.pending = state.vars.activeTrade.id
@ -1028,25 +1062,27 @@ def next(data, state: StrategyState):
recurring = safe_get(options, "reccurring", False) recurring = safe_get(options, "reccurring", False)
on_confirmed_only = safe_get(options, 'on_confirmed_only', False) on_confirmed_only = safe_get(options, 'on_confirmed_only', False)
plugin = safe_get(options, 'plugin', None) plugin = safe_get(options, 'plugin', None)
short_enabled = safe_get(state.vars, "short_enabled",True)
long_enabled = safe_get(state.vars, "long_enabled",True)
#pokud je plugin True, spusti se kod #pokud je plugin True, spusti se kod
if plugin: if plugin:
execute_signal_generator_plugin(name) execute_signal_generator_plugin(name)
else: else:
#common signals based on 1) configured signals in stratvars #common signals based on 1) configured signals in stratvars
#toto umoznuje jednoduchy prescribed trade bez ceny #toto umoznuje jednoduchy prescribed trade bez ceny
if conditions_met(signalname=name, direction=TradeDirection.LONG): if long_enabled and conditions_met(signalname=name, direction=TradeDirection.LONG):
state.vars.prescribedTrades.append(Trade( state.vars.prescribedTrades.append(Trade(
id=uuid4(), id=uuid4(),
validfrom=datetime.now(tz=zoneNY), last_update=datetime.fromtimestamp(state.time).astimezone(zoneNY),
status=TradeStatus.READY, status=TradeStatus.READY,
direction=TradeDirection.LONG, direction=TradeDirection.LONG,
entry_price=None, entry_price=None,
stoploss_value = None)) stoploss_value = None))
elif conditions_met(signalname=name, direction=TradeDirection.SHORT): elif short_enabled and conditions_met(signalname=name, direction=TradeDirection.SHORT):
state.vars.prescribedTrades.append(Trade( state.vars.prescribedTrades.append(Trade(
id=uuid4(), id=uuid4(),
validfrom=datetime.now(tz=zoneNY), last_update=datetime.fromtimestamp(state.time).astimezone(zoneNY),
status=TradeStatus.READY, status=TradeStatus.READY,
direction=TradeDirection.SHORT, direction=TradeDirection.SHORT,
entry_price=None, entry_price=None,

View File

@ -18,12 +18,12 @@ class TradeStoplossType(str, Enum):
class Trade(BaseModel): class Trade(BaseModel):
id: UUID id: UUID
validfrom: datetime last_update: datetime
status: TradeStatus status: TradeStatus
direction: TradeDirection direction: TradeDirection
entry_price: Optional[float] = None entry_price: Optional[float] = None
# stoploss_type: TradeStoplossType # stoploss_type: TradeStoplossType
stoploss_value: Optional[float] = None stoploss_value: Optional[float] = None
profit: Optional[float] = None profit: Optional[float] = 0
profit_sum: Optional[float] = None profit_sum: Optional[float] = 0

View File

@ -9,6 +9,7 @@ from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, Orde
from v2realbot.common.model import StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveDetail, RunArchiveChange, Bar, TradeEvent from v2realbot.common.model import StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveDetail, RunArchiveChange, Bar, TradeEvent
from v2realbot.utils.utils import AttributeDict, zoneNY, dict_replace_value, Store, parse_toml_string, json_serial, is_open_hours, send_to_telegram from v2realbot.utils.utils import AttributeDict, zoneNY, dict_replace_value, Store, parse_toml_string, json_serial, is_open_hours, send_to_telegram
from v2realbot.utils.ilog import delete_logs from v2realbot.utils.ilog import delete_logs
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType
from datetime import datetime from datetime import datetime
from threading import Thread, current_thread, Event, enumerate from threading import Thread, current_thread, Event, enumerate
from v2realbot.config import STRATVARS_UNCHANGEABLES, ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY, DATA_DIR,BT_FILL_CONS_TRADES_REQUIRED,BT_FILL_LOG_SURROUNDING_TRADES,BT_FILL_CONDITION_BUY_LIMIT,BT_FILL_CONDITION_SELL_LIMIT, GROUP_TRADES_WITH_TIMESTAMP_LESS_THAN from v2realbot.config import STRATVARS_UNCHANGEABLES, ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY, DATA_DIR,BT_FILL_CONS_TRADES_REQUIRED,BT_FILL_LOG_SURROUNDING_TRADES,BT_FILL_CONDITION_BUY_LIMIT,BT_FILL_CONDITION_SELL_LIMIT, GROUP_TRADES_WITH_TIMESTAMP_LESS_THAN
@ -466,9 +467,45 @@ def populate_metrics_output_directory(strat: StrategyInstance):
#filt = max_positions['side'] == 'OrderSide.BUY' #filt = max_positions['side'] == 'OrderSide.BUY'
res = dict(zip(max_positions['qty'], max_positions['count'])) res = dict(zip(max_positions['qty'], max_positions['count']))
#pridani klice obsahujici prescribed trades #metrikz z prescribedTrades, pokud existuji
try: try:
long_profit = 0
short_profit = 0
long_losses = 0
short_losses = 0
long_wins = 0
short_wins = 0
max_profit = 0
max_profit_time = None
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:
if trade.profit is not None:
long_profit += trade.profit
if trade.profit < 0:
long_losses += trade.profit
if trade.profit > 0:
long_wins += trade.profit
if trade.status == TradeStatus.ACTIVATED and trade.direction == TradeDirection.SHORT:
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_profit"] = round(long_profit,2)
res["short_profit"] = round(short_profit,2)
res["long_losses"] = round(long_losses,2)
res["short_losses"] = round(short_losses,2)
res["long_wins"] = round(long_wins,2)
res["short_wins"] = round(short_wins,2)
res["max_profit"] = round(max_profit,2)
res["max_profit_time"] = str(max_profit_time)
#vlozeni celeho listu
res["prescr_trades"]=json.loads(json.dumps(strat.state.vars.prescribedTrades, default=json_serial)) res["prescr_trades"]=json.loads(json.dumps(strat.state.vars.prescribedTrades, default=json_serial))
except NameError: except NameError:
pass pass

View File

@ -351,7 +351,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="note" class="form-label">note</label> <label for="note" class="form-label">note</label>
<textarea class="form-control" rows="2" id="note" name="note"></textarea> <textarea class="form-control" rows="7" id="note" name="note"></textarea>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="history" class="form-label">history</label> <label for="history" class="form-label">history</label>

View File

@ -2,10 +2,12 @@ from v2realbot.strategy.base import Strategy
from v2realbot.utils.utils import parse_alpaca_timestamp, ltp, AttributeDict,trunc,price2dec, zoneNY, print, json_serial, safe_get, get_tick from v2realbot.utils.utils import parse_alpaca_timestamp, ltp, AttributeDict,trunc,price2dec, zoneNY, print, json_serial, safe_get, get_tick
from v2realbot.utils.tlog import tlog, tlog_exception from v2realbot.utils.tlog import tlog, tlog_exception
from v2realbot.enums.enums import Mode, Order, Account, RecordType from v2realbot.enums.enums import Mode, Order, Account, RecordType
from alpaca.trading.models import TradeUpdate #from alpaca.trading.models import TradeUpdate
from v2realbot.common.model import TradeUpdate
from alpaca.trading.enums import TradeEvent, OrderStatus from alpaca.trading.enums import TradeEvent, OrderStatus
from v2realbot.indicators.indicators import ema from v2realbot.indicators.indicators import ema
import json import json
from datetime import datetime
#from rich import print #from rich import print
from random import randrange from random import randrange
from alpaca.common.exceptions import APIError from alpaca.common.exceptions import APIError
@ -49,7 +51,8 @@ class StrategyClassicSL(Strategy):
#zapsat profit do prescr.trades #zapsat profit do prescr.trades
for trade in self.state.vars.prescribedTrades: for trade in self.state.vars.prescribedTrades:
if trade.id == self.state.vars.pending: if trade.id == self.state.vars.pending:
trade.profit = trade_profit trade.last_update = datetime.fromtimestamp(self.state.time).astimezone(zoneNY)
trade.profit += trade_profit
trade.profit_sum = self.state.profit trade.profit_sum = self.state.profit
#zapsat update profitu do tradeList #zapsat update profitu do tradeList
@ -96,7 +99,8 @@ class StrategyClassicSL(Strategy):
#zapsat profit do prescr.trades #zapsat profit do prescr.trades
for trade in self.state.vars.prescribedTrades: for trade in self.state.vars.prescribedTrades:
if trade.id == self.state.vars.pending: if trade.id == self.state.vars.pending:
trade.profit = trade_profit trade.last_update = datetime.fromtimestamp(self.state.time).astimezone(zoneNY)
trade.profit += trade_profit
trade.profit_sum = self.state.profit trade.profit_sum = self.state.profit
#zapsat update profitu do tradeList #zapsat update profitu do tradeList

View File

@ -423,6 +423,8 @@ class Strategy:
async def order_updates(self, data: TradeUpdate): async def order_updates(self, data: TradeUpdate):
if self.mode == Mode.LIVE or self.mode == Mode.PAPER: if self.mode == Mode.LIVE or self.mode == Mode.PAPER:
now = datetime.now().timestamp() now = datetime.now().timestamp()
#z alpakýho TradeEvent si udelame svuj rozsireny TradeEvent (obsahujici navic profit atp.)
data = TradeUpdate(**data.dict())
else: else:
now = self.bt.time now = self.bt.time

View File

@ -80,7 +80,11 @@ def crossed(threshold, list):
def get_tick(price: float, normalized_ticks: float = 0.01): def get_tick(price: float, normalized_ticks: float = 0.01):
""" """
prevede normalizovany tick na tick odpovidajici vstupni cene Pozor existuje varianta "normalize_tick", ktera je lepsi a podporuje direktivy ve strategii:
Normalize_ticks= true
Normalized Tick base price = 30
Tahle verze pracuje s globalnim nastavenim.
Prevede normalizovany tick na tick odpovidajici vstupni cene
vysledek je zaokoruhleny na 2 des.mista vysledek je zaokoruhleny na 2 des.mista
u cen pod 30, vrací 0.01. U cen nad 30 vrací pomerne zvetsene, u cen pod 30, vrací 0.01. U cen nad 30 vrací pomerne zvetsene,