1 Commits

Author SHA1 Message Date
1e5e6a311f toml validation to frontend 2024-03-14 17:36:48 +01:00
11 changed files with 124 additions and 233 deletions

View File

@ -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("ERROR: not enough cash for shorting. cash",self.cash,"reserved",reserved,"available",self.cash-reserved,"needed",float(int(size)*float(cena))) printanyway("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("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))) 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)))
return -1 return -1
id = str(uuid4()) id = str(uuid4())

View File

@ -3,7 +3,7 @@ from uuid import UUID, uuid4
import pickle import pickle
from alpaca.data.historical import StockHistoricalDataClient from alpaca.data.historical import StockHistoricalDataClient
from alpaca.data.requests import StockTradesRequest, StockBarsRequest from alpaca.data.requests import StockTradesRequest, StockBarsRequest
from alpaca.data.enums import DataFeed from alpaca.data.enums import DataFeed
from alpaca.data.timeframe import TimeFrame 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
@ -1114,7 +1114,7 @@ def get_all_archived_runners_p(request: DataTablesRequest) -> Tuple[int, RunArch
# Total count query # Total count query
total_count_query = """ total_count_query = """
SELECT COUNT(*) FROM runner_header SELECT COUNT(*) FROM runner_header
WHERE (:search_value = '' OR strat_id LIKE :search_value OR batch_id LIKE :search_value OR symbol like :search_value OR name like :search_value) WHERE (:search_value = '' OR strat_id LIKE :search_value OR batch_id LIKE :search_value)
""" """
c.execute(total_count_query, {'search_value': f'%{search_value}%'}) c.execute(total_count_query, {'search_value': f'%{search_value}%'})
total_count = c.fetchone()[0] total_count = c.fetchone()[0]
@ -1129,7 +1129,7 @@ def get_all_archived_runners_p(request: DataTablesRequest) -> Tuple[int, RunArch
SUM(profit) OVER (PARTITION BY batch_id) AS batch_profit, SUM(profit) OVER (PARTITION BY batch_id) AS batch_profit,
COUNT(*) OVER (PARTITION BY batch_id) AS batch_count COUNT(*) OVER (PARTITION BY batch_id) AS batch_count
FROM runner_header FROM runner_header
WHERE (:search_value = '' OR strat_id LIKE :search_value OR batch_id LIKE :search_value OR symbol like :search_value OR name like :search_value) WHERE (:search_value = '' OR strat_id LIKE :search_value OR batch_id LIKE :search_value)
), ),
InterleavedGroups AS ( InterleavedGroups AS (
SELECT *, SELECT *,
@ -1156,7 +1156,7 @@ def get_all_archived_runners_p(request: DataTablesRequest) -> Tuple[int, RunArch
# Filtered count query # Filtered count query
filtered_count_query = """ filtered_count_query = """
SELECT COUNT(*) FROM runner_header SELECT COUNT(*) FROM runner_header
WHERE (:search_value = '' OR strat_id LIKE :search_value OR batch_id LIKE :search_value OR symbol like :search_value OR name like :search_value) WHERE (:search_value = '' OR strat_id LIKE :search_value OR batch_id LIKE :search_value)
""" """
c.execute(filtered_count_query, {'search_value': f'%{search_value}%'}) c.execute(filtered_count_query, {'search_value': f'%{search_value}%'})
filtered_count = c.fetchone()[0] filtered_count = c.fetchone()[0]

View File

@ -667,14 +667,14 @@
</div> </div>
<div class="form-group mt-3"> <div class="form-group mt-3">
<label for="logHere" class="form-label">Log</label> <label for="logHere" class="form-label">Log</label>
<div id="log-container"style="height:700px;border:1px solid black;"> <div id="log-container">
<!-- <pre id="log-content"></pre> --> <pre id="log-content"></pre>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-primary" id="logRefreshButton" value="Refresh">Refresh</button> <button type="button" class="btn btn-primary" id="logRefreshButton" value="Refresh">Refresh</button>
<button type="button" class="btn btn-secondary" id="closeLogModal" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div> </div>
</div> </div>
</div> </div>
@ -1166,9 +1166,9 @@
<!-- <script src="/static/js/archivetables.js?v=1.05"></script> --> <!-- <script src="/static/js/archivetables.js?v=1.05"></script> -->
<!-- archiveTables split into separate files --> <!-- archiveTables split into separate files -->
<script src="/static/js/tables/archivetable/init.js?v=1.12"></script> <script src="/static/js/tables/archivetable/init.js?v=1.12"></script>
<script src="/static/js/tables/archivetable/functions.js?v=1.11"></script> <script src="/static/js/tables/archivetable/functions.js?v=1.10"></script>
<script src="/static/js/tables/archivetable/modals.js?v=1.07"></script> <script src="/static/js/tables/archivetable/modals.js?v=1.07"></script>
<script src="/static/js/tables/archivetable/handlers.js?v=1.11"></script> <script src="/static/js/tables/archivetable/handlers.js?v=1.09"></script>
<!-- Runmanager functionality --> <!-- Runmanager functionality -->
<script src="/static/js/tables/runmanager/init.js?v=1.1"></script> <script src="/static/js/tables/runmanager/init.js?v=1.1"></script>
@ -1178,7 +1178,7 @@
<script src="/static/js/livewebsocket.js?v=1.02"></script> <script src="/static/js/livewebsocket.js?v=1.02"></script>
<script src="/static/js/realtimechart.js?v=1.02"></script> <script src="/static/js/realtimechart.js?v=1.02"></script>
<script src="/static/js/mytables.js?v=1.03"></script> <script src="/static/js/mytables.js?v=1.02"></script>
<script src="/static/js/testlist.js?v=1.01"></script> <script src="/static/js/testlist.js?v=1.01"></script>
<script src="/static/js/ml.js?v=1.02"></script> <script src="/static/js/ml.js?v=1.02"></script>
<script src="/static/js/common.js?v=1.01"></script> <script src="/static/js/common.js?v=1.01"></script>

View File

@ -90,55 +90,9 @@ $(document).ready(function () {
monaco.languages.register({ id: 'python' }); monaco.languages.register({ id: 'python' });
monaco.languages.register({ id: 'json' }); monaco.languages.register({ id: 'json' });
//Register mylogs language
monaco.languages.register({ id: 'mylogs' });
// Register the TOML language // Register the TOML language
monaco.languages.setLanguageConfiguration('mylogs', {
comments: {
lineComment: '//', // Adjust if your logs use a different comment symbol
},
brackets: [['[', ']'], ['{', '}']], // Array and object brackets
autoClosingPairs: [
{ open: '{', close: '}', notIn: ['string'] },
{ open: '"', close: '"', notIn: ['string', 'comment'] },
{ open: "'", close: "'", notIn: ['string', 'comment'] },
],
});
monaco.languages.setMonarchTokensProvider('mylogs', {
tokenizer: {
root: [
[/#.*/, 'comment'], // Comments (if applicable)
// Timestamps
[/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+/, 'timestamp'],
// Log Levels
[/\b(INFO|DEBUG|WARNING|ERROR|CRITICAL)\b/, 'log-level'],
// Strings
[/".*"/, 'string'],
[/'.*'/, 'string'],
// Key-Value Pairs
[/[A-Za-z_]+\s*:/, 'key'],
[/-?\d+\.\d+/, 'number.float'], // Floating-point
[/-?\d+/, 'number.integer'], // Integers
[/\btrue\b/, 'boolean.true'],
[/\bfalse\b/, 'boolean.false'],
// Other Words and Symbols
[/[A-Za-z_]+/, 'identifier'],
[/[ \t\r\n]+/, 'white'],
[/[\[\]{}(),]/, 'delimiter'], // Expand if more delimiters exist
]
}
});
monaco.languages.register({ id: 'toml' }); monaco.languages.register({ id: 'toml' });
// Define the TOML language configuration // Define the TOML language configuration
monaco.languages.setLanguageConfiguration('toml', { monaco.languages.setLanguageConfiguration('toml', {
comments: { comments: {

View File

@ -6,7 +6,6 @@ let editor_diff_arch1
let editor_diff_arch2 let editor_diff_arch2
var archData = null var archData = null
var batchHeaders = [] var batchHeaders = []
var editorLog = null
function refresh_arch_and_callback(row, callback) { function refresh_arch_and_callback(row, callback) {
//console.log("entering refresh") //console.log("entering refresh")
@ -473,34 +472,13 @@ function refresh_logfile() {
contentType: "application/json", contentType: "application/json",
dataType: "json", dataType: "json",
success:function(response){ success:function(response){
if (editorLog) {
editorLog.dispose();
}
if (response.lines.length == 0) { if (response.lines.length == 0) {
value = "no records"; $('#log-content').html("no records");
// $('#log-content').html("no records");
} }
else { else {
//console.log(response.lines) var escapedLines = response.lines.map(line => escapeHtml(line));
//var escapedLines = response.lines.map(line => escapeHtml(line)); $('#log-content').html(escapedLines.join('\n'));
value = response.lines.join('\n') }
// $('#log-content').html(escapedLines.join('\n'));
}
require(["vs/editor/editor.main"], () => {
editorLog = monaco.editor.create(document.getElementById('log-container'), {
value: value,
language: 'mylogs',
theme: 'tomlTheme-dark',
automaticLayout: 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 + ")");

View File

@ -265,8 +265,8 @@ $(document).ready(function () {
$('#diff_first').text(record1.name); $('#diff_first').text(record1.name);
$('#diff_second').text(record2.name); $('#diff_second').text(record2.name);
$('#diff_first_id').text(data1.id + ' Batch: ' + data1.batch_id); $('#diff_first_id').text(data1.id);
$('#diff_second_id').text(data2.id + ' Batch: ' + data2.batch_id); $('#diff_second_id').text(data2.id);
//monaco //monaco
require(["vs/editor/editor.main"], () => { require(["vs/editor/editor.main"], () => {
@ -358,13 +358,8 @@ $(document).ready(function () {
}) })
}); });
$('#closeLogModal').click(function () {
editorLog.dispose()
});
//button to query log //button to query log
$('#logRefreshButton').click(function () { $('#logRefreshButton').click(function () {
editorLog.dispose()
refresh_logfile() refresh_logfile()
}); });

View File

@ -35,62 +35,40 @@ 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):
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)}" 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)}")
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(msg) 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)}")
if hard_cutoff: self.signal_stop = True
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):
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)}" 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)}")
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(msg) 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)}")
if hard_cutoff: self.signal_stop = True
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):
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)}" 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)}")
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(msg) 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)}")
if hard_cutoff: self.signal_stop = True
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):
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)}" 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)}")
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(msg) 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)}")
if hard_cutoff: self.signal_stop = True
self.hard_stop = True
else:
self.soft_stop = True
return True return True
return False return False
@ -436,7 +414,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 or self.soft_stop: if self.mode == Mode.PREP:
return return
else: else:
self.next(item, self.state) self.next(item, self.state)

View File

@ -80,8 +80,7 @@ class Strategy:
self.pe = pe self.pe = pe
self.se = se self.se = se
#signal stop - internal #signal stop - internal
self.hard_stop = False #indikuje hard stop, tedy vypnuti strategie self.signal_stop = False
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
@ -434,7 +433,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.hard_stop: if self.signal_stop:
print(current_thread().name, "Stopping signal - internal") print(current_thread().name, "Stopping signal - internal")
break break
@ -455,7 +454,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.hard_stop: elif self.signal_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():

View File

@ -5,108 +5,99 @@ 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) if res < 0:
if res < 0: if runner.batch_id is None:
if runner.batch_id is None: print(f"No batch_id found for runner {runner.id}")
print(f"No batch_id found for runner {runner.id}")
else:
print(f"Couldnt get previous runner {state.runner_id} error: {runner}")
return None
batch_id = runner.batch_id
#batch_id = "6a6b0bcf"
res, runner_ids =cs.get_archived_runnerslist_byBatchID(batch_id, "desc")
if res < 0:
msg = f"error whne fetching runners of batch {batch_id} {runner_ids}"
print(msg)
return None
if runner_ids is None or len(runner_ids) == 0:
print(f"NO runners found for batch {batch_id} {runner_ids}")
return None
last_runner = runner_ids[0]
print("Previous runner identified:", last_runner)
#get archived header - to get transferables
runner_header : RunArchive = None
res, runner_header = cs.get_archived_runner_header_byID(last_runner)
if res < 0:
print(f"Error when fetching runner header {last_runner}")
return None
state.vars["transferables"] = runner_header.transferables
print("INITIALIZED transferables", state.vars["transferables"])
#get details from the runner
print(f"Fetching runner details of {last_runner}")
res, val = cs.get_archived_runner_details_byID(last_runner)
if res < 0:
print(f"no archived runner {last_runner}")
return None
detail = RunArchiveDetail(**val)
#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
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)
#indicators datetime utc
indicators = slice_dict_lists(d=detail.indicators[0],last_item=attach_previous_bar_data, time_to_datetime=True)
#time -datetime utc, updated - timestamp float
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
if attach_previous_tick_data is None:
oldest_timestamp = bars["updated"][0]
#returns only values older that oldest_timestamp
cbar_inds = filter_timeseries_by_timestamp(detail.indicators[1], oldest_timestamp)
else: else:
cbar_inds = slice_dict_lists(d=detail.indicators[1],last_item=attach_previous_tick_data) print(f"Couldnt get previous runner {state.runner_id} error: {runner}")
#USE these as INITs - TADY SI TO JESTE ZASTAVIT a POROVNAT
#print("state.indicatorsL", state.indicators, "NEW:", indicators)
state.indicators = AttributeDict(**indicators)
print("transfered indicators:", len(state.indicators["time"]))
#print("state.bars", state.bars, "NEW:", bars)
state.bars = AttributeDict(bars)
print("transfered bars:", len(state.bars["time"]))
#print("state.cbar_indicators", state.cbar_indicators, "NEW:", cbar_inds)
state.cbar_indicators = AttributeDict(cbar_inds)
print("transfered ticks:", len(state.cbar_indicators["time"]))
print("TRANSFERABLEs INITIALIZED")
#bars
#transferable_state_vars = ["martingale", "batch_profit"]
#1. pri initu se tyto klice v state vars se namapuji do ext_data ext_data["transferrables"]["martingale"] = state.vars["martingale"]
#2. pri transferu se vse z ext_data["trasferrables"] dá do stejnénné state.vars["martingale"]
#3. na konci dne se uloží do sloupce transferables v RunArchive
#pridavame dailyBars z extData
# if hasattr(detail, "ext_data") and "dailyBars" in detail.ext_data:
# state.dailyBars = detail.ext_data["dailyBars"]
return
except Exception as e:
print(str(e)+format_exc())
return None return None
batch_id = runner.batch_id
#batch_id = "6a6b0bcf"
res, runner_ids =cs.get_archived_runnerslist_byBatchID(batch_id, "desc")
if res < 0:
msg = f"error whne fetching runners of batch {batch_id} {runner_ids}"
print(msg)
return None
if runner_ids is None or len(runner_ids) == 0:
print(f"NO runners found for batch {batch_id} {runner_ids}")
return None
last_runner = runner_ids[0]
print("Previous runner identified:", last_runner)
#get archived header - to get transferables
runner_header : RunArchive = None
res, runner_header = cs.get_archived_runner_header_byID(last_runner)
if res < 0:
print(f"Error when fetching runner header {last_runner}")
return None
state.vars["transferables"] = runner_header.transferables
print("INITIALIZED transferables", state.vars["transferables"])
#get details from the runner
print(f"Fetching runner details of {last_runner}")
res, val = cs.get_archived_runner_details_byID(last_runner)
if res < 0:
print(f"no archived runner {last_runner}")
return None
detail = RunArchiveDetail(**val)
#print("toto jsme si dotahnuli", detail.bars)
# from stratvars directives
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)
#indicators datetime utc
indicators = slice_dict_lists(d=detail.indicators[0],last_item=attach_previous_bar_data, time_to_datetime=True)
#time -datetime utc, updated - timestamp float
bars = slice_dict_lists(d=detail.bars, last_item=attach_previous_bar_data, time_to_datetime=True)
#zarovname tick spolu s bar daty
if attach_previous_tick_data is None:
oldest_timestamp = bars["updated"][0]
#returns only values older that oldest_timestamp
cbar_inds = filter_timeseries_by_timestamp(detail.indicators[1], oldest_timestamp)
else:
cbar_inds = slice_dict_lists(d=detail.indicators[1],last_item=attach_previous_tick_data)
#USE these as INITs - TADY SI TO JESTE ZASTAVIT a POROVNAT
#print("state.indicatorsL", state.indicators, "NEW:", indicators)
state.indicators = AttributeDict(**indicators)
print("transfered indicators:", len(state.indicators["time"]))
#print("state.bars", state.bars, "NEW:", bars)
state.bars = AttributeDict(bars)
print("transfered bars:", len(state.bars["time"]))
#print("state.cbar_indicators", state.cbar_indicators, "NEW:", cbar_inds)
state.cbar_indicators = AttributeDict(cbar_inds)
print("transfered ticks:", len(state.cbar_indicators["time"]))
print("TRANSFERABLEs INITIALIZED")
#bars
#transferable_state_vars = ["martingale", "batch_profit"]
#1. pri initu se tyto klice v state vars se namapuji do ext_data ext_data["transferrables"]["martingale"] = state.vars["martingale"]
#2. pri transferu se vse z ext_data["trasferrables"] dá do stejnénné state.vars["martingale"]
#3. na konci dne se uloží do sloupce transferables v RunArchive
#pridavame dailyBars z extData
# if hasattr(detail, "ext_data") and "dailyBars" in detail.ext_data:
# state.dailyBars = detail.ext_data["dailyBars"]
return
# if __name__ == "__main__": # if __name__ == "__main__":
# attach_previous_data(state) # attach_previous_data(state)

View File

@ -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=int(multiplier*state.vars.chunk), size=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=int(multiplier*state.vars.chunk), size=multiplier*state.vars.chunk,
size_multiplier = multiplier, size_multiplier = multiplier,
direction=TradeDirection.SHORT, direction=TradeDirection.SHORT,
entry_price=None, entry_price=None,

View File

@ -151,17 +151,13 @@ 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 = base ** cont_loss_series_cnt multiplier = 2 ** 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:
state.ilog(lvl=1,e=f"SIZER - Mame nekde problem MULTIPLIER mimo RANGE ERROR {multiplier}", options=options, time=state.time) state.ilog(lvl=1,e=f"SIZER - Mame nekde problem MULTIPLIER mimo RANGE ERROR {multiplier}", options=options, time=state.time)
multiplier = 1 multiplier = 1