weekday filter na run gui, delete batch
This commit is contained in:
@ -88,6 +88,9 @@ class RunRequest(BaseModel):
|
|||||||
ilog_save: bool = False
|
ilog_save: bool = False
|
||||||
bt_from: datetime = None
|
bt_from: datetime = None
|
||||||
bt_to: datetime = None
|
bt_to: datetime = None
|
||||||
|
#weekdays filter
|
||||||
|
#pokud je uvedeny filtrujeme tyto dny
|
||||||
|
weekdays_filter: Optional[list] = None
|
||||||
#id testovaciho intervalu TODO prejmenovat
|
#id testovaciho intervalu TODO prejmenovat
|
||||||
test_batch_id: Optional[str] = None
|
test_batch_id: Optional[str] = None
|
||||||
#GENERATED ID v ramci runu, vaze vsechny runnery v batchovem behu
|
#GENERATED ID v ramci runu, vaze vsechny runnery v batchovem behu
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from alpaca.data.timeframe import TimeFrame
|
|||||||
from v2realbot.strategy.base import StrategyState
|
from v2realbot.strategy.base import StrategyState
|
||||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide
|
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide
|
||||||
from v2realbot.common.model import RunDay, StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveView, RunArchiveDetail, RunArchiveChange, Bar, TradeEvent, TestList, Intervals, ConfigItem, InstantIndicator
|
from v2realbot.common.model import RunDay, StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveView, RunArchiveDetail, RunArchiveChange, Bar, TradeEvent, TestList, Intervals, ConfigItem, InstantIndicator
|
||||||
from v2realbot.utils.utils import AttributeDict, zoneNY, zonePRG, safe_get, dict_replace_value, Store, parse_toml_string, json_serial, is_open_hours, send_to_telegram
|
from v2realbot.utils.utils import AttributeDict, zoneNY, zonePRG, safe_get, dict_replace_value, Store, parse_toml_string, json_serial, is_open_hours, send_to_telegram, concatenate_weekdays
|
||||||
from v2realbot.utils.ilog import delete_logs
|
from v2realbot.utils.ilog import delete_logs
|
||||||
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType
|
from v2realbot.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -410,7 +410,8 @@ def run_batch_stratin(id: UUID, runReq: RunRequest):
|
|||||||
end_time = dateto
|
end_time = dateto
|
||||||
cal_list.append(RunDay(start = start_time, end = end_time, note = note, id = id))
|
cal_list.append(RunDay(start = start_time, end = end_time, note = note, id = id))
|
||||||
|
|
||||||
print(f"Getting interval dates from - to - RESULT ({len(cal_list)}): {cal_list}")
|
print(f"Getting interval dates from - to - RESULT ({len(cal_list)}):")
|
||||||
|
print(cal_list)
|
||||||
return cal_list
|
return cal_list
|
||||||
|
|
||||||
#getting days to run into RunDays format
|
#getting days to run into RunDays format
|
||||||
@ -474,19 +475,34 @@ def batch_run_manager(id: UUID, runReq: RunRequest, rundays: list[RunDay]):
|
|||||||
rundays.sort(key=lambda x: x.start)
|
rundays.sort(key=lambda x: x.start)
|
||||||
#print("RUNDAYS after sort:", rundays)
|
#print("RUNDAYS after sort:", rundays)
|
||||||
|
|
||||||
|
#APPLY WEEKDAYS filter - necháváme pouze ty, ktere jsou uvedene
|
||||||
|
if runReq.weekdays_filter is not None:
|
||||||
|
rundays = [run_day for run_day in rundays if run_day.start.weekday() in runReq.weekdays_filter]
|
||||||
|
|
||||||
|
if len(rundays) == 0:
|
||||||
|
print("No eligible DAYS")
|
||||||
|
return
|
||||||
|
|
||||||
cnt_max = len(rundays)
|
cnt_max = len(rundays)
|
||||||
cnt = 0
|
cnt = 0
|
||||||
#promenna pro sdileni mezi runy jednotlivych batchů (např. daily profit)
|
#promenna pro sdileni mezi runy jednotlivych batchů (např. daily profit)
|
||||||
inter_batch_params = dict(batch_profit=0, batch_rel_profit=0)
|
inter_batch_params = dict(batch_profit=0, batch_rel_profit=0)
|
||||||
note_from_run_request = runReq.note
|
note_from_run_request = runReq.note
|
||||||
first = None
|
first = None
|
||||||
|
first_frm = None
|
||||||
last = None
|
last = None
|
||||||
|
last_frm = None
|
||||||
|
|
||||||
# Find the minimum start date and maximum end date to add to Note
|
# Find the minimum start date and maximum end date to add to Note
|
||||||
first = min(runday.start for runday in rundays)
|
first = min(runday.start for runday in rundays)
|
||||||
last = max(runday.end for runday in rundays)
|
last = max(runday.end for runday in rundays)
|
||||||
first_frm = first.strftime("%d.%m.")
|
first_frm = first.strftime("%d.%m.")
|
||||||
last_frm = last.strftime("%d.%m.")
|
last_frm = last.strftime("%d.%m.")
|
||||||
|
|
||||||
|
weekdayfilter_string = ""
|
||||||
|
if runReq.weekdays_filter is not None:
|
||||||
|
weekdayfilter_string = concatenate_weekdays(runReq.weekdays_filter)
|
||||||
|
weekdayfilter_string = "DAYS:" + weekdayfilter_string.upper() if weekdayfilter_string != '' else ''
|
||||||
|
|
||||||
for day in rundays:
|
for day in rundays:
|
||||||
cnt += 1
|
cnt += 1
|
||||||
@ -494,7 +510,7 @@ def batch_run_manager(id: UUID, runReq: RunRequest, rundays: list[RunDay]):
|
|||||||
print("Datum do", day.end)
|
print("Datum do", day.end)
|
||||||
runReq.bt_from = day.start
|
runReq.bt_from = day.start
|
||||||
runReq.bt_to = day.end
|
runReq.bt_to = day.end
|
||||||
runReq.note = f"{first_frm}-{last_frm} Batch {batch_id} #{cnt}/{cnt_max} {day.name} N:{day.note} {note_from_run_request}"
|
runReq.note = f"{first_frm}-{last_frm} Batch {batch_id} #{cnt}/{cnt_max} {weekdayfilter_string} {day.name} N:{day.note} {note_from_run_request}"
|
||||||
|
|
||||||
#protoze jsme v ridicim vlaknu, poustime za sebou jednotlive stratiny v synchronnim modu
|
#protoze jsme v ridicim vlaknu, poustime za sebou jednotlive stratiny v synchronnim modu
|
||||||
res, id_val = run_stratin(id=id, runReq=runReq, synchronous=True, inter_batch_params=inter_batch_params)
|
res, id_val = run_stratin(id=id, runReq=runReq, synchronous=True, inter_batch_params=inter_batch_params)
|
||||||
|
|||||||
@ -247,6 +247,8 @@ def _run_stratin(stratin_id: UUID, runReq: RunRequest):
|
|||||||
if runReq.mode != Mode.LIVE and runReq.test_batch_id is not None or (runReq.bt_from.date() != runReq.bt_to.date()):
|
if runReq.mode != Mode.LIVE and runReq.test_batch_id is not None or (runReq.bt_from.date() != runReq.bt_to.date()):
|
||||||
res, id = cs.run_batch_stratin(id=stratin_id, runReq=runReq)
|
res, id = cs.run_batch_stratin(id=stratin_id, runReq=runReq)
|
||||||
else:
|
else:
|
||||||
|
if runReq.weekdays_filter is not None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Weekday only for backtest mode with batch (not single day)")
|
||||||
res, id = cs.run_stratin(id=stratin_id, runReq=runReq)
|
res, id = cs.run_stratin(id=stratin_id, runReq=runReq)
|
||||||
if res == 0: return id
|
if res == 0: return id
|
||||||
elif res < 0:
|
elif res < 0:
|
||||||
|
|||||||
@ -703,6 +703,40 @@
|
|||||||
<label for="bt_to" class="form-label">bt_to</label>
|
<label for="bt_to" class="form-label">bt_to</label>
|
||||||
<input type="datetime-local" class="form-control" id="bt_to" name="bt_to" placeholder="2023-04-06T09:00:00Z" step="1">
|
<input type="datetime-local" class="form-control" id="bt_to" name="bt_to" placeholder="2023-04-06T09:00:00Z" step="1">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Initial Checkbox for Enabling Weekday Selection -->
|
||||||
|
<div class="form-group">
|
||||||
|
<div style="display:inline-flex">
|
||||||
|
<label for="enable_weekdays" class="form-label">Limit BT to Weekdays</label>
|
||||||
|
<input type="checkbox" class="form-check" id="enable_weekdays" name="enable_weekdays" aria-label="Enable Weekday Selection">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Weekday Checkboxes -->
|
||||||
|
<div class="form-group weekday-checkboxes" style="display:none;">
|
||||||
|
<!-- <label class="form-label">Select Weekdays:</label> -->
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="monday" name="weekdays" value="monday">
|
||||||
|
<label for="monday">Monday</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="tuesday" name="weekdays" value="tuesday">
|
||||||
|
<label for="tuesday">Tuesday</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="wednesday" name="weekdays" value="wednesday">
|
||||||
|
<label for="wednesday">Wednesday</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="thursday" name="weekdays" value="thursday">
|
||||||
|
<label for="thursday">Thursday</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="friday" name="weekdays" value="friday">
|
||||||
|
<label for="friday">Friday</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="test_batch_id" class="form-label">Test Batch ID</label>
|
<label for="test_batch_id" class="form-label">Test Batch ID</label>
|
||||||
<input type="text" class="form-control" id="test_batch_id" name="test_batch_id" placeholder="test intervals ID">
|
<input type="text" class="form-control" id="test_batch_id" name="test_batch_id" placeholder="test intervals ID">
|
||||||
|
|||||||
@ -558,6 +558,7 @@ $(document).ready(function () {
|
|||||||
if (row == undefined || row.batch_id == undefined) {
|
if (row == undefined || row.batch_id == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
$('#deletebatch').attr('disabled', 'disabled');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url:"/archived_runners/batch/"+row.batch_id,
|
url:"/archived_runners/batch/"+row.batch_id,
|
||||||
beforeSend: function (xhr) {
|
beforeSend: function (xhr) {
|
||||||
@ -569,7 +570,8 @@ $(document).ready(function () {
|
|||||||
data: JSON.stringify(row.batch_id),
|
data: JSON.stringify(row.batch_id),
|
||||||
success:function(data){
|
success:function(data){
|
||||||
$('#delFormBatch')[0].reset();
|
$('#delFormBatch')[0].reset();
|
||||||
window.$('#delModalBatch').modal('hide');
|
window.$('#delModalBatch').modal('hide');
|
||||||
|
$('#deletebatch').attr('disabled', false);
|
||||||
$('#button_delete_batch').attr('disabled', false);
|
$('#button_delete_batch').attr('disabled', false);
|
||||||
//console.log(data)
|
//console.log(data)
|
||||||
archiveRecords.ajax.reload();
|
archiveRecords.ajax.reload();
|
||||||
@ -578,6 +580,7 @@ $(document).ready(function () {
|
|||||||
var err = eval("(" + xhr.responseText + ")");
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
window.alert(JSON.stringify(xhr));
|
window.alert(JSON.stringify(xhr));
|
||||||
console.log(JSON.stringify(xhr));
|
console.log(JSON.stringify(xhr));
|
||||||
|
$('#deletebatch').attr('disabled', false);
|
||||||
$('#button_delete_batch').attr('disabled', false);
|
$('#button_delete_batch').attr('disabled', false);
|
||||||
archiveRecords.ajax.reload();
|
archiveRecords.ajax.reload();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -625,6 +625,8 @@ $(document).ready(function () {
|
|||||||
if (row == undefined) {
|
if (row == undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
$('#enable_weekdays').prop('checked', false);
|
||||||
|
$('.weekday-checkboxes').hide();
|
||||||
window.$('#runModal').modal('show');
|
window.$('#runModal').modal('show');
|
||||||
$('#bt_from').val(localStorage.getItem("bt_from"));
|
$('#bt_from').val(localStorage.getItem("bt_from"));
|
||||||
//console.log(localStorage.getItem("bt_from"))
|
//console.log(localStorage.getItem("bt_from"))
|
||||||
@ -654,7 +656,14 @@ $(document).ready(function () {
|
|||||||
$("#bt_from, #bt_to").prop("disabled", false);
|
$("#bt_from, #bt_to").prop("disabled", false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//listen for changes on weekday enabling button
|
||||||
|
$('#enable_weekdays').change(function() {
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
$('.weekday-checkboxes').show();
|
||||||
|
} else {
|
||||||
|
$('.weekday-checkboxes').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -865,10 +874,33 @@ $("#runModal").on('submit','#runForm', function(event){
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#run').attr('disabled','disabled');
|
$('#run').attr('disabled','disabled');
|
||||||
|
|
||||||
|
// Handle weekdays functionality
|
||||||
|
var weekdays = [];
|
||||||
|
if ($('#enable_weekdays').is(':checked')) {
|
||||||
|
$('#runForm input[name="weekdays"]:checked').each(function() {
|
||||||
|
var weekday = $(this).val();
|
||||||
|
switch(weekday) {
|
||||||
|
case 'monday': weekdays.push(0); break;
|
||||||
|
case 'tuesday': weekdays.push(1); break;
|
||||||
|
case 'wednesday': weekdays.push(2); break;
|
||||||
|
case 'thursday': weekdays.push(3); break;
|
||||||
|
case 'friday': weekdays.push(4); break;
|
||||||
|
// Add cases for Saturday and Sunday if needed
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var formData = $(this).serializeJSON();
|
var formData = $(this).serializeJSON();
|
||||||
//rename runid to id
|
//rename runid to id
|
||||||
Object.defineProperty(formData, "id", Object.getOwnPropertyDescriptor(formData, "runid"));
|
Object.defineProperty(formData, "id", Object.getOwnPropertyDescriptor(formData, "runid"));
|
||||||
delete formData["runid"];
|
delete formData["runid"];
|
||||||
|
delete formData["enable_weekdays"]
|
||||||
|
delete formData["weekdays"]
|
||||||
|
|
||||||
|
//pokud je zatrzeno tak aplikujeme filter, jinak nevyplnujeme
|
||||||
|
if (weekdays.length > 0) {
|
||||||
|
formData.weekdays_filter = weekdays
|
||||||
|
}
|
||||||
console.log(formData)
|
console.log(formData)
|
||||||
if ($('#ilog_save').prop('checked')) {
|
if ($('#ilog_save').prop('checked')) {
|
||||||
formData.ilog_save = true;
|
formData.ilog_save = true;
|
||||||
|
|||||||
@ -27,6 +27,16 @@ from collections import deque
|
|||||||
import socket
|
import socket
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
def concatenate_weekdays(weekday_filter):
|
||||||
|
# Mapping of weekdays where 0 is Monday and 6 is Sunday
|
||||||
|
weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||||||
|
|
||||||
|
# Convert the integers in weekday_filter to their corresponding weekday strings
|
||||||
|
weekday_strings = [weekdays[day] for day in weekday_filter]
|
||||||
|
|
||||||
|
# Concatenate the weekday strings
|
||||||
|
return '-'.join(weekday_strings)
|
||||||
|
|
||||||
def slice_dict_lists(d, last_item, to_tmstp = False):
|
def slice_dict_lists(d, last_item, to_tmstp = False):
|
||||||
"""Slices every list in the dictionary to the last last_item items.
|
"""Slices every list in the dictionary to the last last_item items.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user