Compare commits
2 Commits
feature/so
...
bug/attach
| Author | SHA1 | Date | |
|---|---|---|---|
| 50ad60fa12 | |||
| adc7c3c1b6 |
@ -524,7 +524,7 @@ class Backtester:
|
|||||||
if actual_minus_reserved <= 0:
|
if actual_minus_reserved <= 0:
|
||||||
cena = price if price else self.get_last_price(time, self.symbol)
|
cena = price if price else self.get_last_price(time, self.symbol)
|
||||||
if (self.cash - reserved_price - float(int(size)*float(cena))) < 0:
|
if (self.cash - reserved_price - float(int(size)*float(cena))) < 0:
|
||||||
printanyway("not enough cash for shorting. cash",self.cash,"reserved",reserved,"available",self.cash-reserved,"needed",float(int(size)*float(cena)))
|
printanyway("ERROR: not enough cash for shorting. cash",self.cash,"reserved",reserved,"available",self.cash-reserved,"needed",float(int(size)*float(cena)))
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
#check for available cash
|
#check for available cash
|
||||||
@ -550,7 +550,7 @@ class Backtester:
|
|||||||
if actual_plus_reserved_qty >= 0:
|
if actual_plus_reserved_qty >= 0:
|
||||||
cena = price if price else self.get_last_price(time, self.symbol)
|
cena = price if price else self.get_last_price(time, self.symbol)
|
||||||
if (self.cash - reserved_price - float(int(size)*float(cena))) < 0:
|
if (self.cash - reserved_price - float(int(size)*float(cena))) < 0:
|
||||||
printanyway("not enough cash to buy long. cash",self.cash,"reserved_qty",reserved_qty,"reserved_price",reserved_price, "available",self.cash-reserved_price,"needed",float(int(size)*float(cena)))
|
printanyway("ERROR: not enough cash to buy long. cash",self.cash,"reserved_qty",reserved_qty,"reserved_price",reserved_price, "available",self.cash-reserved_price,"needed",float(int(size)*float(cena)))
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
id = str(uuid4())
|
id = str(uuid4())
|
||||||
|
|||||||
@ -495,6 +495,12 @@ function refresh_logfile() {
|
|||||||
readOnly: true
|
readOnly: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// Focus at the end of the file:
|
||||||
|
const model = editorLog.getModel();
|
||||||
|
const lastLineNumber = model.getLineCount();
|
||||||
|
const lastLineColumn = model.getLineMaxColumn(lastLineNumber);
|
||||||
|
editorLog.setPosition({ lineNumber: lastLineNumber, column: lastLineColumn });
|
||||||
|
editorLog.revealPosition({ lineNumber: lastLineNumber, column: lastLineColumn });
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
var err = eval("(" + xhr.responseText + ")");
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
|
|||||||
@ -35,40 +35,62 @@ class StrategyClassicSL(Strategy):
|
|||||||
|
|
||||||
max_sum_profit_to_quit_rel = safe_get(self.state.vars, "max_sum_profit_to_quit_rel", None)
|
max_sum_profit_to_quit_rel = safe_get(self.state.vars, "max_sum_profit_to_quit_rel", None)
|
||||||
max_sum_loss_to_quit_rel = safe_get(self.state.vars, "max_sum_loss_to_quit_rel", None)
|
max_sum_loss_to_quit_rel = safe_get(self.state.vars, "max_sum_loss_to_quit_rel", None)
|
||||||
|
#load typ direktivy hard/soft cutoff
|
||||||
|
hard_cutoff = safe_get(self.state.vars, "hard_cutoff", False)
|
||||||
|
|
||||||
rel_profit = round(float(np.sum(self.state.rel_profit_cum)),5)
|
rel_profit = round(float(np.sum(self.state.rel_profit_cum)),5)
|
||||||
if max_sum_profit_to_quit_rel is not None:
|
if max_sum_profit_to_quit_rel is not None:
|
||||||
if rel_profit >= float(max_sum_profit_to_quit_rel):
|
if rel_profit >= float(max_sum_profit_to_quit_rel):
|
||||||
self.state.ilog(e=f"QUITTING MAX SUM REL PROFIT REACHED {max_sum_profit_to_quit_rel=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
msg = f"QUITTING {hard_cutoff=} MAX SUM REL PROFIT REACHED {max_sum_profit_to_quit_rel=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}"
|
||||||
|
printanyway(msg)
|
||||||
|
self.state.ilog(e=msg)
|
||||||
self.state.vars.pending = "max_sum_profit_to_quit_rel"
|
self.state.vars.pending = "max_sum_profit_to_quit_rel"
|
||||||
if self.mode not in [Mode.BT, Mode.PREP]:
|
if self.mode not in [Mode.BT, Mode.PREP]:
|
||||||
send_to_telegram(f"QUITTING MAX SUM REL PROFIT REACHED {max_sum_profit_to_quit_rel=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
send_to_telegram(msg)
|
||||||
self.signal_stop = True
|
if hard_cutoff:
|
||||||
|
self.hard_stop = True
|
||||||
|
else:
|
||||||
|
self.soft_stop = True
|
||||||
return True
|
return True
|
||||||
if max_sum_loss_to_quit_rel is not None:
|
if max_sum_loss_to_quit_rel is not None:
|
||||||
if rel_profit < 0 and rel_profit <= float(max_sum_loss_to_quit_rel):
|
if rel_profit < 0 and rel_profit <= float(max_sum_loss_to_quit_rel):
|
||||||
self.state.ilog(e=f"QUITTING MAX SUM REL LOSS REACHED {max_sum_loss_to_quit_rel=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
msg=f"QUITTING {hard_cutoff=} MAX SUM REL LOSS REACHED {max_sum_loss_to_quit_rel=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}"
|
||||||
|
printanyway(msg)
|
||||||
|
self.state.ilog(e=msg)
|
||||||
self.state.vars.pending = "max_sum_loss_to_quit_rel"
|
self.state.vars.pending = "max_sum_loss_to_quit_rel"
|
||||||
if self.mode not in [Mode.BT, Mode.PREP]:
|
if self.mode not in [Mode.BT, Mode.PREP]:
|
||||||
send_to_telegram(f"QUITTING MAX SUM REL LOSS REACHED {max_sum_loss_to_quit_rel=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
send_to_telegram(msg)
|
||||||
self.signal_stop = True
|
if hard_cutoff:
|
||||||
|
self.hard_stop = True
|
||||||
|
else:
|
||||||
|
self.soft_stop = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if max_sum_profit_to_quit is not None:
|
if max_sum_profit_to_quit is not None:
|
||||||
if float(self.state.profit) >= float(max_sum_profit_to_quit):
|
if float(self.state.profit) >= float(max_sum_profit_to_quit):
|
||||||
self.state.ilog(e=f"QUITTING MAX SUM ABS PROFIT REACHED {max_sum_profit_to_quit=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
msg = f"QUITTING {hard_cutoff=} MAX SUM ABS PROFIT REACHED {max_sum_profit_to_quit=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}"
|
||||||
|
printanyway(msg)
|
||||||
|
self.state.ilog(e=msg)
|
||||||
self.state.vars.pending = "max_sum_profit_to_quit"
|
self.state.vars.pending = "max_sum_profit_to_quit"
|
||||||
if self.mode not in [Mode.BT, Mode.PREP]:
|
if self.mode not in [Mode.BT, Mode.PREP]:
|
||||||
send_to_telegram(f"QUITTING MAX SUM ABS PROFIT REACHED {max_sum_profit_to_quit=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
send_to_telegram(msg)
|
||||||
self.signal_stop = True
|
if hard_cutoff:
|
||||||
|
self.hard_stop = True
|
||||||
|
else:
|
||||||
|
self.soft_stop = True
|
||||||
return True
|
return True
|
||||||
if max_sum_loss_to_quit is not None:
|
if max_sum_loss_to_quit is not None:
|
||||||
if float(self.state.profit) < 0 and float(self.state.profit) <= float(max_sum_loss_to_quit):
|
if float(self.state.profit) < 0 and float(self.state.profit) <= float(max_sum_loss_to_quit):
|
||||||
self.state.ilog(e=f"QUITTING MAX SUM ABS LOSS REACHED {max_sum_loss_to_quit=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
msg = f"QUITTING {hard_cutoff=} MAX SUM ABS LOSS REACHED {max_sum_loss_to_quit=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}"
|
||||||
|
printanyway(msg)
|
||||||
|
self.state.ilog(e=msg)
|
||||||
self.state.vars.pending = "max_sum_loss_to_quit"
|
self.state.vars.pending = "max_sum_loss_to_quit"
|
||||||
if self.mode not in [Mode.BT, Mode.PREP]:
|
if self.mode not in [Mode.BT, Mode.PREP]:
|
||||||
send_to_telegram(f"QUITTING MAX SUM ABS LOSS REACHED {max_sum_loss_to_quit=} {self.state.profit=} {rel_profit=} relprofits:{str(self.state.rel_profit_cum)}")
|
send_to_telegram(msg)
|
||||||
self.signal_stop = True
|
if hard_cutoff:
|
||||||
|
self.hard_stop = True
|
||||||
|
else:
|
||||||
|
self.soft_stop = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@ -414,7 +436,7 @@ class StrategyClassicSL(Strategy):
|
|||||||
populate_all_indicators(item, self.state)
|
populate_all_indicators(item, self.state)
|
||||||
|
|
||||||
#pro přípravu dat next nevoláme
|
#pro přípravu dat next nevoláme
|
||||||
if self.mode == Mode.PREP:
|
if self.mode == Mode.PREP or self.soft_stop:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.next(item, self.state)
|
self.next(item, self.state)
|
||||||
|
|||||||
@ -80,7 +80,8 @@ class Strategy:
|
|||||||
self.pe = pe
|
self.pe = pe
|
||||||
self.se = se
|
self.se = se
|
||||||
#signal stop - internal
|
#signal stop - internal
|
||||||
self.signal_stop = False
|
self.hard_stop = False #indikuje hard stop, tedy vypnuti strategie
|
||||||
|
self.soft_stop = False #indikuje soft stop (napr. při dosažení max zisku/ztráty), tedy pokracovani strategie, vytvareni dat, jen bez obchodu
|
||||||
|
|
||||||
#prdelat queue na dynamic - podle toho jak bud uchtit pracovat s multiresolutions
|
#prdelat queue na dynamic - podle toho jak bud uchtit pracovat s multiresolutions
|
||||||
#zatim jen jedna q1
|
#zatim jen jedna q1
|
||||||
@ -433,7 +434,7 @@ class Strategy:
|
|||||||
#printnow(current_thread().name, "Items waiting in queue:", self.q1.qsize())
|
#printnow(current_thread().name, "Items waiting in queue:", self.q1.qsize())
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
#check internal signals - for profit/loss optim etc - valid for runner
|
#check internal signals - for profit/loss optim etc - valid for runner
|
||||||
if self.signal_stop:
|
if self.hard_stop:
|
||||||
print(current_thread().name, "Stopping signal - internal")
|
print(current_thread().name, "Stopping signal - internal")
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -454,7 +455,7 @@ class Strategy:
|
|||||||
if item == "last" or self.se.is_set():
|
if item == "last" or self.se.is_set():
|
||||||
print(current_thread().name, "stopping")
|
print(current_thread().name, "stopping")
|
||||||
break
|
break
|
||||||
elif self.signal_stop:
|
elif self.hard_stop:
|
||||||
print(current_thread().name, "Stopping signal - internal")
|
print(current_thread().name, "Stopping signal - internal")
|
||||||
break
|
break
|
||||||
elif self.pe.is_set():
|
elif self.pe.is_set():
|
||||||
|
|||||||
@ -5,12 +5,14 @@ from v2realbot.utils.utils import slice_dict_lists,zoneUTC,safe_get, AttributeDi
|
|||||||
#id = "b11c66d9-a9b6-475a-9ac1-28b11e1b4edf"
|
#id = "b11c66d9-a9b6-475a-9ac1-28b11e1b4edf"
|
||||||
#state = AttributeDict(vars={})
|
#state = AttributeDict(vars={})
|
||||||
from rich import print
|
from rich import print
|
||||||
|
from traceback import format_exc
|
||||||
|
|
||||||
def attach_previous_data(state):
|
def attach_previous_data(state):
|
||||||
"""""
|
"""""
|
||||||
Attaches data from previous runner of the same batch.
|
Attaches data from previous runner of the same batch.
|
||||||
"""""
|
"""""
|
||||||
print("ATTACHING PREVIOUS DATA")
|
print("ATTACHING PREVIOUS DATA")
|
||||||
|
try:
|
||||||
runner : Runner
|
runner : Runner
|
||||||
#get batch_id of current runer
|
#get batch_id of current runer
|
||||||
res, runner = cs.get_runner(state.runner_id)
|
res, runner = cs.get_runner(state.runner_id)
|
||||||
@ -57,6 +59,10 @@ def attach_previous_data(state):
|
|||||||
detail = RunArchiveDetail(**val)
|
detail = RunArchiveDetail(**val)
|
||||||
#print("toto jsme si dotahnuli", detail.bars)
|
#print("toto jsme si dotahnuli", detail.bars)
|
||||||
|
|
||||||
|
if len(detail.bars["time"]) == 0:
|
||||||
|
print(f"no bars for runner {last_runner}")
|
||||||
|
return None
|
||||||
|
|
||||||
# from stratvars directives
|
# from stratvars directives
|
||||||
attach_previous_bar_data = safe_get(state.vars, "attach_previous_bar_data", 50)
|
attach_previous_bar_data = safe_get(state.vars, "attach_previous_bar_data", 50)
|
||||||
attach_previous_tick_data = safe_get(state.vars, "attach_previous_tick_data", None)
|
attach_previous_tick_data = safe_get(state.vars, "attach_previous_tick_data", None)
|
||||||
@ -67,6 +73,7 @@ def attach_previous_data(state):
|
|||||||
#time -datetime utc, updated - timestamp float
|
#time -datetime utc, updated - timestamp float
|
||||||
bars = slice_dict_lists(d=detail.bars, last_item=attach_previous_bar_data, time_to_datetime=True)
|
bars = slice_dict_lists(d=detail.bars, last_item=attach_previous_bar_data, time_to_datetime=True)
|
||||||
|
|
||||||
|
cbar_ids = {}
|
||||||
#zarovname tick spolu s bar daty
|
#zarovname tick spolu s bar daty
|
||||||
if attach_previous_tick_data is None:
|
if attach_previous_tick_data is None:
|
||||||
oldest_timestamp = bars["updated"][0]
|
oldest_timestamp = bars["updated"][0]
|
||||||
@ -98,6 +105,8 @@ def attach_previous_data(state):
|
|||||||
# if hasattr(detail, "ext_data") and "dailyBars" in detail.ext_data:
|
# if hasattr(detail, "ext_data") and "dailyBars" in detail.ext_data:
|
||||||
# state.dailyBars = detail.ext_data["dailyBars"]
|
# state.dailyBars = detail.ext_data["dailyBars"]
|
||||||
return
|
return
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e)+format_exc())
|
||||||
|
return None
|
||||||
# if __name__ == "__main__":
|
# if __name__ == "__main__":
|
||||||
# attach_previous_data(state)
|
# attach_previous_data(state)
|
||||||
@ -78,7 +78,7 @@ def execute_signal_generator(state, data, name):
|
|||||||
last_update=datetime.fromtimestamp(state.time).astimezone(zoneNY),
|
last_update=datetime.fromtimestamp(state.time).astimezone(zoneNY),
|
||||||
status=TradeStatus.READY,
|
status=TradeStatus.READY,
|
||||||
generated_by=name,
|
generated_by=name,
|
||||||
size=multiplier*state.vars.chunk,
|
size=int(multiplier*state.vars.chunk),
|
||||||
size_multiplier = multiplier,
|
size_multiplier = multiplier,
|
||||||
direction=TradeDirection.LONG,
|
direction=TradeDirection.LONG,
|
||||||
entry_price=None,
|
entry_price=None,
|
||||||
@ -90,7 +90,7 @@ def execute_signal_generator(state, data, name):
|
|||||||
last_update=datetime.fromtimestamp(state.time).astimezone(zoneNY),
|
last_update=datetime.fromtimestamp(state.time).astimezone(zoneNY),
|
||||||
status=TradeStatus.READY,
|
status=TradeStatus.READY,
|
||||||
generated_by=name,
|
generated_by=name,
|
||||||
size=multiplier*state.vars.chunk,
|
size=int(multiplier*state.vars.chunk),
|
||||||
size_multiplier = multiplier,
|
size_multiplier = multiplier,
|
||||||
direction=TradeDirection.SHORT,
|
direction=TradeDirection.SHORT,
|
||||||
entry_price=None,
|
entry_price=None,
|
||||||
|
|||||||
@ -151,11 +151,15 @@ def get_multiplier(state: StrategyState, data, signaloptions: dict, direction: T
|
|||||||
|
|
||||||
#pocet ztrátových obchodů v řadě mi udává multiplikátor (0 - 1, 1 ztráta 2x, 3 v řadě - 4x atp.)
|
#pocet ztrátových obchodů v řadě mi udává multiplikátor (0 - 1, 1 ztráta 2x, 3 v řadě - 4x atp.)
|
||||||
if martingale_enabled:
|
if martingale_enabled:
|
||||||
|
|
||||||
|
#martingale base - základ umocňování - klasicky 2
|
||||||
|
base = float(utls.safe_get(options, "martingale_base", 2))
|
||||||
|
#pocet aktuálních konsekutivních ztrát
|
||||||
cont_loss_series_cnt = state.vars["transferables"]["martingale"]["cont_loss_series_cnt"]
|
cont_loss_series_cnt = state.vars["transferables"]["martingale"]["cont_loss_series_cnt"]
|
||||||
if cont_loss_series_cnt == 0:
|
if cont_loss_series_cnt == 0:
|
||||||
multiplier = 1
|
multiplier = 1
|
||||||
else:
|
else:
|
||||||
multiplier = 2 ** cont_loss_series_cnt
|
multiplier = base ** cont_loss_series_cnt
|
||||||
state.ilog(lvl=1,e=f"SIZER - MARTINGALE {multiplier}", options=options, time=state.time, cont_loss_series_cnt=cont_loss_series_cnt)
|
state.ilog(lvl=1,e=f"SIZER - MARTINGALE {multiplier}", options=options, time=state.time, cont_loss_series_cnt=cont_loss_series_cnt)
|
||||||
|
|
||||||
if (martingale_enabled is False and multiplier > 1) or multiplier <= 0:
|
if (martingale_enabled is False and multiplier > 1) or multiplier <= 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user