prvni verze dynamicky ind

This commit is contained in:
David Brazda
2023-10-23 21:36:15 +02:00
parent dd90b03a30
commit 0c4fb20c66
26 changed files with 4812 additions and 580 deletions

19
testy/previewindicator.py Normal file
View File

@ -0,0 +1,19 @@
import v2realbot.controller.services as cs
#[stratvars.indicators.vwma]
runner_id = "b44d6d8f-b44d-45b1-ad7a-7ee8b0facead"
toml = """
type = "custom"
subtype = "vwma"
on_confirmed_only = true
cp.source = "vwap"
cp.ref_source = "volume"
cp.lookback = 50
"""
res, vals = cs.preview_indicator_byTOML(id=runner_id, toml=toml)
print(res)
print(vals)

View File

@ -267,6 +267,8 @@ class RunArchiveDetail(BaseModel):
trades: List[TradeUpdate] trades: List[TradeUpdate]
ext_data: Optional[dict] ext_data: Optional[dict]
class TomlInput(BaseModel):
toml: str
# class Trade(BaseModel): # class Trade(BaseModel):
# order: Order # order: Order
# value: float # value: float

View File

@ -5,9 +5,10 @@ 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.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 from v2realbot.common.model import RunDay, StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveView, RunArchiveDetail, RunArchiveChange, Bar, TradeEvent, TestList, Intervals, ConfigItem
from v2realbot.utils.utils import AttributeDict, zoneNY, zonePRG, 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
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
@ -30,6 +31,9 @@ from datetime import timedelta, time
from threading import Lock from threading import Lock
from v2realbot.common.db import pool, execute_with_retry, row_to_runarchive, row_to_runarchiveview from v2realbot.common.db import pool, execute_with_retry, row_to_runarchive, row_to_runarchiveview
from sqlite3 import OperationalError, Row from sqlite3 import OperationalError, Row
import v2realbot.strategyblocks.indicators.custom as ci
from v2realbot.interfaces.backtest_interface import BacktestInterface
#from pyinstrument import Profiler #from pyinstrument import Profiler
#adding lock to ensure thread safety of TinyDB (in future will be migrated to proper db) #adding lock to ensure thread safety of TinyDB (in future will be migrated to proper db)
lock = Lock() lock = Lock()
@ -1107,6 +1111,103 @@ def get_testlists():
# endregion # endregion
#WIP - possibility to add TOML indicator
# open issues: hodnoty dalsich indikatoru
def preview_indicator_byTOML(id: UUID, toml: str):
try:
res, toml_parsed = parse_toml_string(toml)
if res < 0:
return (-2, "toml invalid")
print("parsed toml", toml_parsed)
subtype = safe_get(toml_parsed, 'subtype', False)
if subtype is None:
return (-2, "subtype invalid")
custom_params = safe_get(toml_parsed, "cp", None)
print("custom params",custom_params)
#dotahne runner details
res, val = get_archived_runner_details_byID(id)
if res < 0:
return (-2, "no archived runner {id}")
# class RunArchiveDetail(BaseModel):
# id: UUID
# name: str
# bars: dict
# #trades: Optional[dict]
# indicators: List[dict]
# statinds: dict
# trades: List[TradeUpdate]
# ext_data: Optional[dict]
#TODO - conditional udelat podminku
# if value == "conditional":
# conditions = state.vars.indicators[indname]["cp"]["conditions"]
# for condname,condsettings in conditions.items():
# state.vars.indicators[indname]["cp"]["conditions"][condname]["cond_dict"] = get_conditions_from_configuration(action=KW.change_val+"_if", section=condsettings)
# printanyway(f'creating workdict for {condname} value {state.vars.indicators[indname]["cp"]["conditions"][condname]["cond_dict"]}')
#TODO - podporit i jine nez custom?
detail = RunArchiveDetail(**val)
#print("toto jsme si dotahnuli", detail.bars)
#new dicts
new_bars = {key: [] for key in detail.bars.keys()}
new_bars = AttributeDict(**new_bars)
new_inds = {key: [] for key in detail.indicators[0].keys()}
new_inds = AttributeDict(**new_inds)
interface = BacktestInterface(symbol="X", bt=None)
state = StrategyState(name="XX", symbol = "X", stratvars = toml, interface=interface)
state.bars = new_bars
state.indicators = new_inds
new_inds["new"] = []
print("delka",len(detail.bars["close"]))
#intitialize indicator mapping - in order to use eval in expression
local_dict_inds = {key: state.indicators[key] for key in state.indicators.keys() if key != "time"}
local_dict_bars = {key: state.bars[key] for key in state.bars.keys() if key != "time"}
state.ind_mapping = {**local_dict_inds, **local_dict_bars}
print("IND MAPPING DONE:", state.ind_mapping)
print("subtype")
function = "ci."+subtype+"."+subtype
print("funkce", function)
custom_function = eval(function)
#iterujeme nad bary a on the fly pridavame novou hodnotu do vsech indikatoru a nakonec nad tim spustime indikator
#tak muzeme v toml pouzit i hodnoty ostatnich indikatoru
for i in range(len(detail.bars["close"])):
for key in detail.bars:
state.bars[key].append(detail.bars[key][i])
for key in detail.indicators[0]:
state.indicators[key].append(detail.indicators[0][key][i])
new_inds["new"].append(0)
try:
res_code, new_val = custom_function(state, custom_params)
if res_code == 0:
new_inds["new"][-1]=new_val
except Exception as e:
print(str(e) + format_exc())
print("Done", f"delka {len(new_inds['new'])}", new_inds["new"])
return 0, new_inds["new"]
except Exception as e:
print(str(e) + format_exc())
return -2, str(e)
# region CONFIG db services # region CONFIG db services
#TODO vytvorit modul pro dotahovani z pythonu (get_from_config(var_name, def_value) {)- stejne jako v js #TODO vytvorit modul pro dotahovani z pythonu (get_from_config(var_name, def_value) {)- stejne jako v js
#TODO zvazit presunuti do TOML z JSONu #TODO zvazit presunuti do TOML z JSONu

View File

@ -11,7 +11,7 @@ import uvicorn
from uuid import UUID from uuid import UUID
import v2realbot.controller.services as cs import v2realbot.controller.services as cs
from v2realbot.utils.ilog import get_log_window from v2realbot.utils.ilog import get_log_window
from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest, Trade, RunArchive, RunArchiveView, RunArchiveDetail, Bar, RunArchiveChange, TestList, ConfigItem from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest, Trade, RunArchive, RunArchiveView, RunArchiveDetail, Bar, RunArchiveChange, TestList, ConfigItem, TomlInput
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
@ -429,6 +429,19 @@ def _delete_archived_runners_byIDs(runner_ids: list[UUID]):
elif res < 0: elif res < 0:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error: {res}:{id}") raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error: {res}:{id}")
#WIP - TOM indicator preview from frontend
#return indicator value for archived runner
@app.put("/archived_runners/{runner_id}/previewindicator", dependencies=[Depends(api_key_auth)], status_code=status.HTTP_200_OK)
def _preview_indicator_byTOML(runner_id: UUID, toml: TomlInput) -> list[float]:
#mozna pak pridat name
res, vals = cs.preview_indicator_byTOML(id=runner_id, toml=toml.toml)
if res == 0: return vals
elif res == -1:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error: {res}:{vals}")
else:
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error not changed: {res}:{runner_id}:{vals}")
#edit archived runner ("note",..) #edit archived runner ("note",..)
@app.patch("/archived_runners/{runner_id}", dependencies=[Depends(api_key_auth)]) @app.patch("/archived_runners/{runner_id}", dependencies=[Depends(api_key_auth)])
def _edit_archived_runners(archChange: RunArchiveChange, runner_id: UUID): def _edit_archived_runners(archChange: RunArchiveChange, runner_id: UUID):

View File

@ -7,7 +7,7 @@ import v2realbot.ml.mlutils as mu
from v2realbot.utils.utils import slice_dict_lists from v2realbot.utils.utils import slice_dict_lists
import numpy as np import numpy as np
from copy import deepcopy from copy import deepcopy
from v2realbot.controller.services import get_archived_runnerslist_byBatchID import v2realbot.controller.services as cs
#Basic classes for machine learning #Basic classes for machine learning
#drzi model a jeho zakladni nastaveni #drzi model a jeho zakladni nastaveni
@ -138,10 +138,10 @@ class ModelML:
print("loading runners for ",str(runner_id_list)) print("loading runners for ",str(runner_id_list))
elif batch_id is not None: elif batch_id is not None:
print("Loading runners for train_batch_id:", batch_id) print("Loading runners for train_batch_id:", batch_id)
res, runner_ids = get_archived_runnerslist_byBatchID(batch_id) res, runner_ids = cs.get_archived_runnerslist_byBatchID(batch_id)
elif self.train_batch_id is not None: elif self.train_batch_id is not None:
print("Loading runners for TRAINING BATCH self.train_batch_id:", self.train_batch_id) print("Loading runners for TRAINING BATCH self.train_batch_id:", self.train_batch_id)
res, runner_ids = get_archived_runnerslist_byBatchID(self.train_batch_id) res, runner_ids = cs.get_archived_runnerslist_byBatchID(self.train_batch_id)
#pripadne bereme z listu runneru #pripadne bereme z listu runneru
else: else:
runner_ids = self.train_runner_ids runner_ids = self.train_runner_ids

View File

@ -1,5 +1,5 @@
import numpy as np import numpy as np
from v2realbot.controller.services import get_archived_runner_details_byID import v2realbot.controller.services as cs
from joblib import load from joblib import load
from v2realbot.config import DATA_DIR from v2realbot.config import DATA_DIR
@ -43,7 +43,7 @@ def merge_dicts(dict_list):
# return merged_dict # return merged_dict
def load_runner(runner_id): def load_runner(runner_id):
res, sada = get_archived_runner_details_byID(runner_id) res, sada = cs.get_archived_runner_details_byID(runner_id)
if res == 0: if res == 0:
print("ok") print("ok")
else: else:

View File

@ -59,7 +59,16 @@
<script src="/static/js/libs/mousetrap.min.js"></script> <script src="/static/js/libs/mousetrap.min.js"></script>
<!-- <script src="https://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script> --> <!-- <script src="https://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script> -->
<script src="/static/js/fast-toml.js" type="text/javascript"></script> <!-- <script src="/static/js/fast-toml.js" type="text/javascript"></script> -->
<!-- <script src="/static/js/libs/j-toml/j-toml.min.js" type="module">
import TOML from 'j-toml';
</script> -->
<script src="/static/js/libs/j-toml/j-toml.js">
// console.log(TOML.parse("ddd"))
</script>
<!-- <script> <!-- <script>
// require is provided by loader.min.js. // require is provided by loader.min.js.
@ -132,6 +141,7 @@
</form> </form>
</div> </div>
<div id="statusHeader" data-bs-toggle="collapse" data-bs-target="#statusDetail"> <div id="statusHeader" data-bs-toggle="collapse" data-bs-target="#statusDetail">
<div id="statusArchId" class="headerItem"></div>
<div id="statusRegime" class="headerItem"></div> <div id="statusRegime" class="headerItem"></div>
<div id="statusName" class="headerItem"></div> <div id="statusName" class="headerItem"></div>
<div id="statusMode" class="headerItem"></div> <div id="statusMode" class="headerItem"></div>
@ -156,6 +166,44 @@
</div> </div>
<div class="lowercontainer" id="lowercontainer"></div> <div class="lowercontainer" id="lowercontainer"></div>
</div> </div>
<div id="indicatorModal" class="modal fade" style="--bs-modal-width: 591px;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><i class="fa fa-plus"></i>Add/Edit Indicator - <div id="indicatorNameTitle"></div></h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="indicatorId" class="form-label">Id</label>
<input type="text" class="form-control" id="indicatorId" name="indicatorId" placeholder="id">
</div>
</div>
<div class="modal-body">
<div class="form-group">
<label for="indicatorName" class="form-label">Name</label>
<input type="text" class="form-control" id="indicatorName" name="indicatorName">
</div>
</div>
<div class="modal-body">
<div class="form-group">
<label for="indicatorTOML_editor" class="form-label">TOML</label>
<div id="indicatorTOML_editor" style="height:266px;border:1px solid black;"></div>
</div>
</div>
<div class="modal-footer d-flex justify-content-between">
<div>
<button type="button" name="delete" id="deleteIndicatorButton" class="btn btn-primary">Delete</button>
</div>
<div>
<!-- <button type="button" name="new" id="newIndicatorButton" class="btn btn-primary">New</button> -->
<button type="button" name="update" id="saveIndicatorButton" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-secondary" id="closeIndicatorButton" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<div id="hist-trades" class="flex-items"> <div id="hist-trades" class="flex-items">
<div id="form-trades"> <div id="form-trades">

View File

@ -1,7 +1,9 @@
var tradeDetails = new Map(); var tradeDetails = new Map();
var toolTip = null var toolTip = null
var CHART_SHOW_TEXT = get_from_config("CHART_SHOW_TEXT", false) var CHART_SHOW_TEXT = get_from_config("CHART_SHOW_TEXT", false)
// const myLibrary = _export;
// const TOML = window['j-toml']
//console.log("TOML je", window)
console.log("CHART_SHOW_TEXT archchart", CHART_SHOW_TEXT) console.log("CHART_SHOW_TEXT archchart", CHART_SHOW_TEXT)
// var vwapSeries = null // var vwapSeries = null
// var volumeSeries = null // var volumeSeries = null
@ -33,7 +35,7 @@ function transform_data(data) {
if ((data.ext_data !== null) && (data.ext_data.sl_history)) { if ((data.ext_data !== null) && (data.ext_data.sl_history)) {
data.ext_data.sl_history.forEach((histRecord, index, array) => { data.ext_data.sl_history.forEach((histRecord, index, array) => {
console.log("plnime") //console.log("plnime")
//nova sada //nova sada
if (prev_id !== histRecord.id) { if (prev_id !== histRecord.id) {
@ -69,7 +71,7 @@ function transform_data(data) {
sline_markers["position"] = "inBar" sline_markers["position"] = "inBar"
sline_markers["color"] = "#f5aa42" sline_markers["color"] = "#f5aa42"
//sline_markers["shape"] = "circle" //sline_markers["shape"] = "circle"
console.log("SHOW_SL_DIGITS",SHOW_SL_DIGITS) //console.log("SHOW_SL_DIGITS",SHOW_SL_DIGITS)
sline_markers["text"] = SHOW_SL_DIGITS ? histRecord.sl_val.toFixed(3) : "" sline_markers["text"] = SHOW_SL_DIGITS ? histRecord.sl_val.toFixed(3) : ""
sl_line_markers_sada.push(sline_markers) sl_line_markers_sada.push(sline_markers)
@ -245,7 +247,7 @@ function transform_data(data) {
transformed["markers_line"] = markers_line transformed["markers_line"] = markers_line
transformed["sl_line"] = sl_line transformed["sl_line"] = sl_line
transformed["sl_line_markers"] = sl_line_markers transformed["sl_line_markers"] = sl_line_markers
console.log("naplnene", sl_line, sl_line_markers) //console.log("naplnene", sl_line, sl_line_markers)
//console_log(JSON.stringify(transformed["sl_line"],null,2)) //console_log(JSON.stringify(transformed["sl_line"],null,2))
//console_log(JSON.stringify(transformed["sl_line_markers"],null,2)) //console_log(JSON.stringify(transformed["sl_line_markers"],null,2))
//get additional indicators //get additional indicators
@ -306,116 +308,8 @@ function prepare_data(archRunner, timeframe_amount, timeframe_unit, archivedRunn
}) })
} }
//render chart of archived runs //pomocna sluzba pro naplneni indListu a charting indikatoru
function chart_archived_run(archRecord, data, oneMinuteBars) { function chart_indicators(data, visible, offset) {
cleanup_chart()
var transformed_data = transform_data(data)
data["archRecord"] = archRecord
//initialize resolutions
var native_resolution = data.bars.resolution[0]+"s"
//console.log("native", native_resolution)
//available intervals zatim jen 1m
var intervals = [native_resolution, '1m'];
nativeData = transformed_data["bars"]
//get one minute data
//tbd prepare volume
//console.log("oneMinuteData",oneMinuteBars)
var AllCandleSeriesesData = new Map([
[native_resolution, nativeData ],
["1m", oneMinuteBars ],
]);
var switcherElement = createSimpleSwitcher(intervals, intervals[1], switch_to_interval);
//define tooltip
const container1 = document.getElementById('chart');
const containerlower = document.getElementById('lowercontainer');
const toolTipWidth = 90;
const toolTipHeight = 90;
const toolTipMargin = 15;
// Create and style the tooltip html element
toolTip = document.createElement('div');
//width: 90px; , height: 80px;
toolTip.style = `position: absolute; display: none; padding: 8px; box-sizing: border-box; font-size: 12px; text-align: left; z-index: 1000; top: 12px; left: 12px; pointer-events: none; border: 1px solid; border-radius: 2px;font-family: -apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;`;
toolTip.style.backgroundColor = '#2d323e';
toolTip.style.color = '#babfcd';
toolTip.style.borderColor = "#a7a9b0";
//'#2962FF';
container1.appendChild(toolTip);
//initialize chart
document.getElementById("chart").style.display = "block"
initialize_chart()
containerlower.append(switcherElement)
candlestickSeries = null
//v pripade, ze neprojde get bars, nastavit na intervals[0]
switch_to_interval(intervals[1])
chart.timeScale().fitContent();
function switch_to_interval(interval) {
//prip prpenuti prepisujeme candlestick a markery
if (candlestickSeries) {
last_range = chart.timeScale().getVisibleRange()
chart.removeSeries(candlestickSeries);
candlestickSeries = null
}
else {
last_range = null
}
intitialize_candles()
candlestickSeries.setData(AllCandleSeriesesData.get(interval));
remove_indicators();
btnElement = document.getElementById("indicatorsButtons")
if (btnElement) {
containerlower.removeChild(btnElement);
}
if (interval == native_resolution) {
//indicators are in native resolution only
display_indicators(data, false);
var indbuttonElement = populate_indicator_buttons(false);
}
else {
//na nepuvodnim grafu zobrazit jako offset a zobrazit jako neviditelne
display_indicators(data,false,30)
//buttonky jako vypnute
var indbuttonElement = populate_indicator_buttons(false);
}
containerlower.append(indbuttonElement);
display_buy_markers();
//TADY JSEM SKONCIL - toto nize predelat na hide button pro display bar markers
// btnElement = document.getElementById("pricelineButtons")
// var indbuttonElement = populate_indicator_buttons(false);
// if (btnElement) {
// container1.removeChild(btnElement);
// }
//container1.append(indbuttonElement);
if (last_range) {
chart.timeScale().setVisibleRange(last_range);
}
}
//TBD
//pro kazdy identifikator zobrazime button na vypnuti zapnuti
//vybereme barvu pro kazdy identifikator
//zjistime typ idenitfikatoru - zatim right vs left
// input: data, offset(zobrazovat pouze hodnoty kazdych N sekund, visible)
function display_indicators(data, visible, offset) {
//console.log("indikatory", JSON.stringify(data.indicators,null,2)) //console.log("indikatory", JSON.stringify(data.indicators,null,2))
//podobne v livewebsokcets.js - dat do jedne funkce //podobne v livewebsokcets.js - dat do jedne funkce
if (data.hasOwnProperty("indicators")) { if (data.hasOwnProperty("indicators")) {
@ -425,8 +319,15 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
var indicatorList = data.indicators var indicatorList = data.indicators
//ze stratvars daneho runnera si dotahneme nastaveni indikatoru - pro zobrazeni v tooltipu //ze stratvars daneho runnera si dotahneme nastaveni indikatoru - pro zobrazeni v tooltipu
//TOML parse
//console.log("PUVODNI", data.archRecord.stratvars_toml)
var stratvars_toml = TOML.parse(data.archRecord.stratvars_toml) var stratvars_toml = TOML.parse(data.archRecord.stratvars_toml)
//console.log(stratvars_toml.stratvars.indicators)
//console.log("ZPETNE STRINGIFIED", TOML.stringify(TOML.parse(data.archRecord.stratvars_toml), {newline: '\n'}))
//indicatory
//console.log("indicatory TOML", stratvars_toml.stratvars.indicators)
indicatorList.forEach((indicators, index, array) => { indicatorList.forEach((indicators, index, array) => {
@ -437,21 +338,36 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
if (key !== "time") { if (key !== "time") {
//get cnf of indicator to display in the button tooltip //get cnf of indicator to display in the button tooltip
var cnf = null var cnf = null
//pokud je v nastaveni scale, pouzijeme tu
var scale = null
try { try {
cnf = JSON.stringify(stratvars_toml.stratvars.indicators[key], null, 2) if (addedInds[key]) {
cnf = addedInds[key]
scale = TOML.parse(cnf).scale
}
else
{
cnf = "#[stratvars.indicators."+key+"]"+TOML.stringify(stratvars_toml.stratvars.indicators[key], {newline: '\n'})
scale = stratvars_toml.stratvars.indicators[key].scale
//cnf = TOML.stringify(stratvars_toml.stratvars.indicators[key], {newline: '\n'})
//a = TOML.parse(cnf)
//console.log("PARSED again",a)
}
} }
catch (e) { catch (e) {
//nic //nic
} }
//initialize indicator and store reference to array //initialize indicator and store reference to array
var obj = {name: key, series: null, cnf:cnf} var obj = {name: key, series: null, cnf:cnf, added: ((addedInds[key])?1:null)}
//start //start
//console.log(key) //console.log(key)
//get configuation of indicator to display //get configuation of indicator to display
conf = get_ind_config(key) conf = get_ind_config(key)
//pokud neni v configuraci - zobrazujeme defaultne
//INIT INDICATOR BASED on CONFIGURATION //INIT INDICATOR BASED on CONFIGURATION
//DO BUDOUCNA zde udelat sorter a pripadny handling duplicit jako //DO BUDOUCNA zde udelat sorter a pripadny handling duplicit jako
@ -529,12 +445,11 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
if (conf.histogram) { if (conf.histogram) {
obj.series = chart.addHistogramSeries({ obj.series = chart.addHistogramSeries({
title: (conf.titlevisible?conf.name:""), title: (conf.titlevisible?key:""),
color: colors.shift(), color: colors.shift(),
priceFormat: {type: 'volume'}, priceFormat: {type: 'volume'},
priceScaleId: conf.priceScaleId, priceScaleId: (scale)?scale:conf.priceScaleId,
lastValueVisible: conf.lastValueVisible, lastValueVisible: conf.lastValueVisible,
priceScaleId: conf.priceScaleId,
visible: conf.display}); visible: conf.display});
obj.series.priceScale().applyOptions({ obj.series.priceScale().applyOptions({
@ -550,8 +465,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
var barva = colors.shift() var barva = colors.shift()
obj.series = chart.addLineSeries({ obj.series = chart.addLineSeries({
color: barva, color: barva,
priceScaleId: conf.priceScaleId, priceScaleId: (scale)?scale:conf.priceScaleId,
title: (conf.titlevisible?conf.name:""), title: (conf.titlevisible?key:""),
lineWidth: 1, lineWidth: 1,
visible: conf.display visible: conf.display
}); });
@ -597,9 +512,17 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
//INDICATOR on new pane //INDICATOR on new pane
else { console.log("not implemented")} else { console.log("not implemented")}
//console.log("v chartovani",activatedButtons)
//pokud existuje v aktivnich pak zobrazujeme jako aktivni
if ((activatedButtons) && (activatedButtons.includes(obj.name))) {
//console.log("true",active?active:conf.display)
active = true
}
else {active = false}
//add options //add options
obj.series.applyOptions({ obj.series.applyOptions({
visible: visible, visible: active?active:visible,
lastValueVisible: false, lastValueVisible: false,
priceLineVisible: false, priceLineVisible: false,
}); });
@ -623,14 +546,15 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
if (!offset) { if (!offset) {
//display vwap and volume //display vwap and volume
initialize_vwap() initialize_vwap()
vwapSeries.setData(transformed_data["vwap"]) vwapSeries.setData(data.transformed_data["vwap"])
initialize_volume() initialize_volume()
volumeSeries.setData(transformed_data["volume"]) volumeSeries.setData(data.transformed_data["volume"])
console.log("volume") console.log("volume")
} }
} }
//pomocna
function remove_indicators() { function remove_indicators() {
//reset COLORS //reset COLORS
colors = reset_colors.slice() colors = reset_colors.slice()
@ -655,9 +579,65 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
} }
} }
//displays (redraws) buy markers //switch to interval pomocna funkce
function display_buy_markers() { function switch_to_interval(interval, data) {
if (!data) {
window.alert("no data switch to interval")
}
//prip prpenuti prepisujeme candlestick a markery
if (candlestickSeries) {
last_range = chart.timeScale().getVisibleRange()
chart.removeSeries(candlestickSeries);
candlestickSeries = null
}
else {
last_range = null
}
intitialize_candles()
candlestickSeries.setData(data.AllCandleSeriesesData.get(interval));
var containerlower = document.getElementById('lowercontainer');
remove_indicators();
btnElement = document.getElementById("indicatorsButtons")
if (btnElement) {
containerlower.removeChild(btnElement);
}
if (interval == data.native_resolution) {
//indicators are in native resolution only
chart_indicators(data, false);
var indbuttonElement = populate_indicator_buttons(false);
}
else {
//na nepuvodnim grafu zobrazit jako offset a zobrazit jako neviditelne
chart_indicators(data,false,30)
//buttonky jako vypnute
var indbuttonElement = populate_indicator_buttons(false);
}
containerlower.append(indbuttonElement);
display_buy_markers(data);
//TADY JSEM SKONCIL - toto nize predelat na hide button pro display bar markers
// btnElement = document.getElementById("pricelineButtons")
// var indbuttonElement = populate_indicator_buttons(false);
// if (btnElement) {
// container1.removeChild(btnElement);
// }
//container1.append(indbuttonElement);
if (last_range) {
chart.timeScale().setVisibleRange(last_range);
}
}
//displays (redraws) buy markers
function display_buy_markers(data) {
transformed_data = data.transformed_data
// if (profitLine) { // if (profitLine) {
// console.log(profitLine) // console.log(profitLine)
// chart.removeSeries(profitLine) // chart.removeSeries(profitLine)
@ -716,8 +696,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
if (transformed_data["sum_profit_line"].length > 0) { if (transformed_data["sum_profit_line"].length > 0) {
profitLine = chart.addLineSeries({ profitLine = chart.addLineSeries({
// title: "avgpbuyline", // title: "avgpbuyline", e8c76d
color: '#e8c76d', color: '#99912b',
// color: 'transparent', // color: 'transparent',
lineWidth: 1, lineWidth: 1,
lastValueVisible: false lastValueVisible: false
@ -726,7 +706,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
profitLine.applyOptions({ profitLine.applyOptions({
lastValueVisible: false, lastValueVisible: false,
priceLineVisible: false, priceLineVisible: false,
priceScaleId: "own" priceScaleId: "own",
visible: false
}); });
@ -768,6 +749,8 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
markersLine.setData(transformed_data["markers_line"]); markersLine.setData(transformed_data["markers_line"]);
markersLine.setMarkers(transformed_data["markers"]) markersLine.setMarkers(transformed_data["markers"])
const container1 = document.getElementById('chart');
//chart.subscribeCrosshairMove(param => { //chart.subscribeCrosshairMove(param => {
chart.subscribeCrosshairMove(param => { chart.subscribeCrosshairMove(param => {
//LEGEND SECTIOIN //LEGEND SECTIOIN
@ -836,6 +819,66 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
}); });
} }
//render chart of archived runs
function chart_archived_run(archRecord, data, oneMinuteBars) {
cleanup_chart()
var transformed_data = transform_data(data)
data["transformed_data"] = transformed_data
data["archRecord"] = archRecord
//initialize resolutions
data["native_resolution"] = data.bars.resolution[0]+"s"
//console.log("native", native_resolution)
//available intervals zatim jen 1m
var intervals = [data.native_resolution, '1m'];
nativeData = transformed_data["bars"]
//get one minute data
//tbd prepare volume
//console.log("oneMinuteData",oneMinuteBars)
data["AllCandleSeriesesData"] = new Map([
[data.native_resolution, nativeData ],
["1m", oneMinuteBars ],
]);
//dame si data do globalni, abychom je mohli pouzivat jinde (trochu prasarna, predelat pak)
archData = data
var switcherElement = createSimpleSwitcher(intervals, intervals[1], switch_to_interval, data);
//define tooltip
const container1 = document.getElementById('chart');
const containerlower = document.getElementById('lowercontainer');
const toolTipWidth = 90;
const toolTipHeight = 90;
const toolTipMargin = 15;
// Create and style the tooltip html element
toolTip = document.createElement('div');
//width: 90px; , height: 80px;
toolTip.style = `position: absolute; display: none; padding: 8px; box-sizing: border-box; font-size: 12px; text-align: left; z-index: 1000; top: 12px; left: 12px; pointer-events: none; border: 1px solid; border-radius: 2px;font-family: -apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto, Ubuntu, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;`;
toolTip.style.backgroundColor = '#2d323e';
toolTip.style.color = '#babfcd';
toolTip.style.borderColor = "#a7a9b0";
//'#2962FF';
container1.appendChild(toolTip);
//initialize chart
document.getElementById("chart").style.display = "block"
initialize_chart()
containerlower.append(switcherElement)
candlestickSeries = null
//v pripade, ze neprojde get bars, nastavit na intervals[0]
switch_to_interval(intervals[1], data)
chart.timeScale().fitContent();
chart.subscribeClick(param => { chart.subscribeClick(param => {
$('#trade-timestamp').val(param.time) $('#trade-timestamp').val(param.time)
//toggle_vertical_line(param.time); //toggle_vertical_line(param.time);
@ -899,6 +942,7 @@ function chart_archived_run(archRecord, data, oneMinuteBars) {
//add status //add status
$("#statusArchId").text(archRecord.id)
$("#statusRegime").text("PAST RUN: "+archRecord.id) $("#statusRegime").text("PAST RUN: "+archRecord.id)
$("#statusName").text(archRecord.name) $("#statusName").text(archRecord.name)
$("#statusMode").text(archRecord.mode) $("#statusMode").text(archRecord.mode)

View File

@ -0,0 +1,277 @@
export as namespace TOML;
export = exports;
declare namespace exports {
export const version :'1.38.0';
export const parse :
& {
(this :void, source :Source, specificationVersion :1.0 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1, multilineStringJoiner? :string, useBigInt? :boolean | number, xOptions? :XOptions ) :Table;
(this :void, source :Source, multilineStringJoiner? :string, useBigInt? :boolean | number, xOptions? :XOptions ) :Table;
(this :void, source :Source, options? :{ readonly joiner? :string, readonly bigint? :boolean | number, readonly x ? :XOptions }) :Table;
}
& {
readonly [SpecificationVersion in 1.0 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1] :{
(this :void, source :Source, multilineStringJoiner? :string, useBigInt? :boolean | number, xOptions? :XOptions ) :Table;
(this :void, source :Source, options? :{ readonly joiner? :string, readonly bigint? :boolean | number, readonly x ? :XOptions }) :Table;
}
};
export function stringify (this :void, rootTable :ReadonlyTable, options? :{
readonly integer? :number
readonly newline? :'\n' | '\r\n'
readonly newlineAround? :'document' | 'section' | 'header' | 'pairs' | 'pair'
readonly indent? :string | number
readonly T? :'T' | 't' | ' '
readonly Z? :'Z' | 'z'
readonly xNull? :boolean
readonly xBeforeNewlineInMultilineTable? :',' | ''
readonly forceInlineArraySpacing? :0 | 1 | 2 | 3
}) :string;
export function isSection (this :void, table :ReadonlyTable) :boolean;
export function isInline (this :void, value :ReadonlyTable | ReadonlyArray) :boolean;
export function Section<T extends ReadonlyTable> (this :void, table :T) :T;
export function inline<T extends ReadonlyArray> (this :void, value :T, inlineMode? :0 | 1 | 2 | 3) :T;
export function inline<T extends ReadonlyTable> (this :void, value :T) :T;
export const multiline :{
readonly array :{
<T extends ReadonlyArray>
(this :void, array :T ) :T
}
<T extends ReadonlyTable>
(this :void, table :T ) :T
(this :void, value :string ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] | [ `'''`, ...string[], `${string}'''` ] } & object & String
(this :void, lines :readonly string[] ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] | [ `'''`, ...string[], `${string}'''` ] } & object
(this :void, lines :readonly string[], value :string) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] | [ `'''`, ...string[], `${string}'''` ] } & object & String
readonly basic :{
(this :void, value :string ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] } & object & String
(this :void, lines :readonly string[] ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] } & object
(this :void, lines :readonly string[], value :string) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] } & object & String
}
};
export function basic (this :void, value :string ) :{ [_literal] :`"${string}"` } & object & String;
export function literal (this :void, literal :string ) :{ [_literal] :string | [ string, ...string[] ] } & object ;
export function literal (this :void, literal :string, value :string ) :{ [_literal] :string | [ string, ...string[] ] } & object & String;
export function literal (this :void, literal :string, value :number ) :{ [_literal] :string | [ string, ...string[] ] } & object & Number;
export function literal (this :void, literal :string, value :bigint ) :{ [_literal] :string | [ string, ...string[] ] } & object & BigInt;
export function literal (this :void, literal :TemplateStringsArray, ...chars :string[]) :{ [_literal] :string | [ string, ...string[] ] } & object ;
export function commentFor (this :void, key :string) :symbol;
export const commentForThis :unique symbol;
export { OffsetDateTime, LocalDateTime, LocalDate, LocalTime, Keys };
export { exports as default };
}
declare class OffsetDateTime {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'OffsetDateTime';
readonly toISOString :(this :Readonly<OffsetDateTime>) => `${number}-${number}-${number}T${number}:${number}:${number}${'' | `.${number}`}${'Z' | `${'+' | '-'}${number}:${number}`}`;
readonly valueOf :(this :Readonly<OffsetDateTime>) => `${number}${'' | `.${number}`}`;
private [OffsetDateTime_ISOString] :string;
private [OffsetDateTime_value] :string;
constructor (literal :`${number}-${number}-${number}${'T' | 't' | ' '}${number}:${number}:${number}${'' | `.${number}`}${'Z' | 'z' | `${'+' | '-'}${number}:${number}`}`);
readonly getUTCFullYear :(this :Readonly<OffsetDateTime>) => _1_10000;
readonly getUTCMonth :(this :Readonly<OffsetDateTime>) => _0_11;
readonly getUTCDate :(this :Readonly<OffsetDateTime>) => _1_31;
readonly getUTCHours :(this :Readonly<OffsetDateTime>) => _0_23;
readonly getUTCMinutes :(this :Readonly<OffsetDateTime>) => _0_59;
readonly getUTCSeconds :(this :Readonly<OffsetDateTime>) => _0_59;
readonly getUTCMilliseconds :(this :Readonly<OffsetDateTime>) => _0_999;
readonly getUTCDay :(this :Readonly<OffsetDateTime>) => _0_6;
readonly getTimezoneOffset :(this :Readonly<OffsetDateTime>) => _1439_1439;
readonly getTime :(this :Readonly<OffsetDateTime>) => number;
}
declare class LocalDateTime {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'LocalDateTime';
readonly toISOString :(this :Readonly<LocalDateTime>) => `${number}-${number}-${number}T${number}:${number}:${number}${'' | `.${number}`}`;
readonly valueOf :(this :Readonly<LocalDateTime>) => `${number}`;
private [LocalDateTime_ISOString] :string;
private [LocalDateTime_value] :string;
constructor (literal :`${number}-${number}-${number}${'T' | 't' | ' '}${number}:${number}:${number}${'' | `.${number}`}`);
readonly getFullYear :(this :Readonly<LocalDateTime>) => _0_9999;
readonly setFullYear :(this :LocalDateTime, year :_0_9999) => void;
readonly getMonth :(this :Readonly<LocalDateTime>) => _0_11;
readonly setMonth :(this :LocalDateTime, month :_0_11) => void;
readonly getDate :(this :Readonly<LocalDateTime>) => _1_31;
readonly setDate :(this :LocalDateTime, date :_1_31) => void;
readonly getHours :(this :Readonly<LocalDateTime>) => _0_23;
readonly setHours :(this :LocalDateTime, hours :_0_23) => void;
readonly getMinutes :(this :Readonly<LocalDateTime>) => _0_59;
readonly setMinutes :(this :LocalDateTime, min :_0_59) => void;
readonly getSeconds :(this :Readonly<LocalDateTime>) => _0_59;
readonly setSeconds :(this :LocalDateTime, sec :_0_59) => void;
readonly getMilliseconds :(this :Readonly<LocalDateTime>) => _0_999;
readonly setMilliseconds :(this :LocalDateTime, ms :_0_999) => void;
}
declare class LocalDate {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'LocalDate';
readonly toISOString :(this :Readonly<LocalDate>) => `${number}-${number}-${number}`;
readonly valueOf :(this :Readonly<LocalDate>) => `${number}`;
private [LocalDate_ISOString] :string;
private [LocalDate_value] :string;
constructor (literal :`${number}-${number}-${number}`);
readonly getFullYear :(this :Readonly<LocalDate>) => _0_9999;
readonly setFullYear :(this :LocalDate, year :_0_9999) => void;
readonly getMonth :(this :Readonly<LocalDate>) => _0_11;
readonly setMonth :(this :LocalDate, month :_0_11) => void;
readonly getDate :(this :Readonly<LocalDate>) => _1_31;
readonly setDate :(this :LocalDate, date :_1_31) => void;
}
declare class LocalTime {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'LocalTime';
readonly toISOString :(this :Readonly<LocalTime>) => `${number}:${number}:${number}${'' | `.${number}`}`;
readonly valueOf :(this :Readonly<LocalTime>) => `${number}`;
private [LocalTime_ISOString] :string;
private [LocalTime_value] :string;
constructor (literal :`${number}:${number}:${number}${'' | `.${number}`}`);
readonly getHours :(this :Readonly<LocalTime>) => _0_23;
readonly setHours :(this :LocalTime, hours :_0_23) => void;
readonly getMinutes :(this :Readonly<LocalTime>) => _0_59;
readonly setMinutes :(this :LocalTime, min :_0_59) => void;
readonly getSeconds :(this :Readonly<LocalTime>) => _0_59;
readonly setSeconds :(this :LocalTime, sec :_0_59) => void;
readonly getMilliseconds :(this :Readonly<LocalTime>) => _0_999;
readonly setMilliseconds :(this :LocalTime, ms :_0_999) => void;
}
declare class Keys extends RegExp {
readonly lastIndex :number;
constructor (keys :ArrayLike<string>);
readonly test :(this :Keys, key :string) => boolean;
}
declare const _literal :unique symbol;
type Source = string | ArrayBufferLike
| {
readonly path :string,
readonly data? :undefined,
readonly require :
| {
readonly resolve? :{ readonly paths? :undefined }
(this :void, id :'fs') :{
readonly readFileSync :(this :void, path :string) => ArrayBufferLike
}
}
| {
readonly resolve :{ readonly paths :(this :void, request :string) => null | string[] }
(this :void, id :'path') :{
readonly resolve :(this :void, dirname :string, filename :string) => string
}
(this :void, id :'fs') :{
readonly readFileSync :(this :void, path :string) => ArrayBufferLike
}
},
}
| {
readonly path :string,
readonly data :string | ArrayBufferLike,
readonly require? :
| {
readonly resolve? :{ readonly paths? :undefined }
}
| {
readonly resolve :{ readonly paths :(this :void, request :string) => null | string[] }
(this :void, id :'path') :{
readonly resolve :(this :void, dirname :string, filename :string) => string
}
},
};
type XOptions = null | {
readonly keys? :null | Keys,
readonly order? :boolean,
readonly exact? :boolean,
readonly multi? :boolean,
readonly longer? :boolean,
readonly string? :boolean,
readonly comment? :boolean,
readonly literal? :boolean,
readonly null? :boolean,
readonly tag? :null | (
<Table extends object & { [key :string | symbol] :any }, Key extends string | symbol, Array extends any[], Index extends number, Tag extends string>
(this :void, each :
| { table :Table, key :Key, tag :Tag }
| { array :Array, index :Index, tag :Tag }
| { table :Table, key :Key, array :Array, index :Index, tag :Tag }
) => void
),
};
type ReadonlyTable = object & { readonly [key :string] :ReadonlyValue };
type ReadonlyArray = readonly ReadonlyValue[];
type ReadonlyValue =
| { readonly [_literal] :string | readonly [ string, ...string[] ] } & object
| null | boolean | bigint | number | string
| ReadonlyDatetime | ReadonlyArray | ReadonlyTable
;
interface ReadonlyDatetime { readonly toISOString :(this :this) => string }
type Table = object & { [key :string] :Value };
type Array = Value[];
type Value =
| object & BigInt & { [_literal] :string }
| object & Number & { [_literal] :string }
| object & String & { [_literal] :string | [ string, ...string[] ] }
| null | boolean | bigint | number | string
| Datetime | Array | Table
;
type Datetime = OffsetDateTime | LocalDateTime | LocalDate | LocalTime;
declare const OffsetDateTime_ISOString :unique symbol;
declare const OffsetDateTime_value :unique symbol;
declare const LocalDateTime_ISOString :unique symbol;
declare const LocalDateTime_value :unique symbol;
declare const LocalDate_ISOString :unique symbol;
declare const LocalDate_value :unique symbol;
declare const LocalTime_ISOString :unique symbol;
declare const LocalTime_value :unique symbol;
type _1439_1439 = -1439 | {} & number | 1439;
type _1_10000 = -1 | {} & number | 10000;
type _0_9999 = 0 | {} & number | 9999;
type _0_999 = 0 | {} & number | 999;
type _0_6 = 0 | 1 | 2 | 3 | 4 | 5 | 6;
type _0_11 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
type _0_23 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23;
type _1_31 = | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31;
type _0_59 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,277 @@
export as namespace TOML;
export = exports;
declare namespace exports {
export const version :'1.38.0';
export const parse :
& {
(this :void, source :Source, specificationVersion :1.0 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1, multilineStringJoiner? :string, useBigInt? :boolean | number, xOptions? :XOptions ) :Table;
(this :void, source :Source, multilineStringJoiner? :string, useBigInt? :boolean | number, xOptions? :XOptions ) :Table;
(this :void, source :Source, options? :{ readonly joiner? :string, readonly bigint? :boolean | number, readonly x ? :XOptions }) :Table;
}
& {
readonly [SpecificationVersion in 1.0 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1] :{
(this :void, source :Source, multilineStringJoiner? :string, useBigInt? :boolean | number, xOptions? :XOptions ) :Table;
(this :void, source :Source, options? :{ readonly joiner? :string, readonly bigint? :boolean | number, readonly x ? :XOptions }) :Table;
}
};
export function stringify (this :void, rootTable :ReadonlyTable, options? :{
readonly integer? :number
readonly newline? :'\n' | '\r\n'
readonly newlineAround? :'document' | 'section' | 'header' | 'pairs' | 'pair'
readonly indent? :string | number
readonly T? :'T' | 't' | ' '
readonly Z? :'Z' | 'z'
readonly xNull? :boolean
readonly xBeforeNewlineInMultilineTable? :',' | ''
readonly forceInlineArraySpacing? :0 | 1 | 2 | 3
}) :string;
export function isSection (this :void, table :ReadonlyTable) :boolean;
export function isInline (this :void, value :ReadonlyTable | ReadonlyArray) :boolean;
export function Section<T extends ReadonlyTable> (this :void, table :T) :T;
export function inline<T extends ReadonlyArray> (this :void, value :T, inlineMode? :0 | 1 | 2 | 3) :T;
export function inline<T extends ReadonlyTable> (this :void, value :T) :T;
export const multiline :{
readonly array :{
<T extends ReadonlyArray>
(this :void, array :T ) :T
}
<T extends ReadonlyTable>
(this :void, table :T ) :T
(this :void, value :string ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] | [ `'''`, ...string[], `${string}'''` ] } & object & String
(this :void, lines :readonly string[] ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] | [ `'''`, ...string[], `${string}'''` ] } & object
(this :void, lines :readonly string[], value :string) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] | [ `'''`, ...string[], `${string}'''` ] } & object & String
readonly basic :{
(this :void, value :string ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] } & object & String
(this :void, lines :readonly string[] ) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] } & object
(this :void, lines :readonly string[], value :string) :{ [_literal] :[ `"""`, ...string[], `${string}"""` ] } & object & String
}
};
export function basic (this :void, value :string ) :{ [_literal] :`"${string}"` } & object & String;
export function literal (this :void, literal :string ) :{ [_literal] :string | [ string, ...string[] ] } & object ;
export function literal (this :void, literal :string, value :string ) :{ [_literal] :string | [ string, ...string[] ] } & object & String;
export function literal (this :void, literal :string, value :number ) :{ [_literal] :string | [ string, ...string[] ] } & object & Number;
export function literal (this :void, literal :string, value :bigint ) :{ [_literal] :string | [ string, ...string[] ] } & object & BigInt;
export function literal (this :void, literal :TemplateStringsArray, ...chars :string[]) :{ [_literal] :string | [ string, ...string[] ] } & object ;
export function commentFor (this :void, key :string) :symbol;
export const commentForThis :unique symbol;
export { OffsetDateTime, LocalDateTime, LocalDate, LocalTime, Keys };
export { exports as default };
}
declare class OffsetDateTime {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'OffsetDateTime';
readonly toISOString :(this :Readonly<OffsetDateTime>) => `${number}-${number}-${number}T${number}:${number}:${number}${'' | `.${number}`}${'Z' | `${'+' | '-'}${number}:${number}`}`;
readonly valueOf :(this :Readonly<OffsetDateTime>) => `${number}${'' | `.${number}`}`;
private [OffsetDateTime_ISOString] :string;
private [OffsetDateTime_value] :string;
constructor (literal :`${number}-${number}-${number}${'T' | 't' | ' '}${number}:${number}:${number}${'' | `.${number}`}${'Z' | 'z' | `${'+' | '-'}${number}:${number}`}`);
readonly getUTCFullYear :(this :Readonly<OffsetDateTime>) => _1_10000;
readonly getUTCMonth :(this :Readonly<OffsetDateTime>) => _0_11;
readonly getUTCDate :(this :Readonly<OffsetDateTime>) => _1_31;
readonly getUTCHours :(this :Readonly<OffsetDateTime>) => _0_23;
readonly getUTCMinutes :(this :Readonly<OffsetDateTime>) => _0_59;
readonly getUTCSeconds :(this :Readonly<OffsetDateTime>) => _0_59;
readonly getUTCMilliseconds :(this :Readonly<OffsetDateTime>) => _0_999;
readonly getUTCDay :(this :Readonly<OffsetDateTime>) => _0_6;
readonly getTimezoneOffset :(this :Readonly<OffsetDateTime>) => _1439_1439;
readonly getTime :(this :Readonly<OffsetDateTime>) => number;
}
declare class LocalDateTime {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'LocalDateTime';
readonly toISOString :(this :Readonly<LocalDateTime>) => `${number}-${number}-${number}T${number}:${number}:${number}${'' | `.${number}`}`;
readonly valueOf :(this :Readonly<LocalDateTime>) => `${number}`;
private [LocalDateTime_ISOString] :string;
private [LocalDateTime_value] :string;
constructor (literal :`${number}-${number}-${number}${'T' | 't' | ' '}${number}:${number}:${number}${'' | `.${number}`}`);
readonly getFullYear :(this :Readonly<LocalDateTime>) => _0_9999;
readonly setFullYear :(this :LocalDateTime, year :_0_9999) => void;
readonly getMonth :(this :Readonly<LocalDateTime>) => _0_11;
readonly setMonth :(this :LocalDateTime, month :_0_11) => void;
readonly getDate :(this :Readonly<LocalDateTime>) => _1_31;
readonly setDate :(this :LocalDateTime, date :_1_31) => void;
readonly getHours :(this :Readonly<LocalDateTime>) => _0_23;
readonly setHours :(this :LocalDateTime, hours :_0_23) => void;
readonly getMinutes :(this :Readonly<LocalDateTime>) => _0_59;
readonly setMinutes :(this :LocalDateTime, min :_0_59) => void;
readonly getSeconds :(this :Readonly<LocalDateTime>) => _0_59;
readonly setSeconds :(this :LocalDateTime, sec :_0_59) => void;
readonly getMilliseconds :(this :Readonly<LocalDateTime>) => _0_999;
readonly setMilliseconds :(this :LocalDateTime, ms :_0_999) => void;
}
declare class LocalDate {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'LocalDate';
readonly toISOString :(this :Readonly<LocalDate>) => `${number}-${number}-${number}`;
readonly valueOf :(this :Readonly<LocalDate>) => `${number}`;
private [LocalDate_ISOString] :string;
private [LocalDate_value] :string;
constructor (literal :`${number}-${number}-${number}`);
readonly getFullYear :(this :Readonly<LocalDate>) => _0_9999;
readonly setFullYear :(this :LocalDate, year :_0_9999) => void;
readonly getMonth :(this :Readonly<LocalDate>) => _0_11;
readonly setMonth :(this :LocalDate, month :_0_11) => void;
readonly getDate :(this :Readonly<LocalDate>) => _1_31;
readonly setDate :(this :LocalDate, date :_1_31) => void;
}
declare class LocalTime {
readonly toJSON :Date['toJSON'];
readonly [Symbol.toStringTag] :'LocalTime';
readonly toISOString :(this :Readonly<LocalTime>) => `${number}:${number}:${number}${'' | `.${number}`}`;
readonly valueOf :(this :Readonly<LocalTime>) => `${number}`;
private [LocalTime_ISOString] :string;
private [LocalTime_value] :string;
constructor (literal :`${number}:${number}:${number}${'' | `.${number}`}`);
readonly getHours :(this :Readonly<LocalTime>) => _0_23;
readonly setHours :(this :LocalTime, hours :_0_23) => void;
readonly getMinutes :(this :Readonly<LocalTime>) => _0_59;
readonly setMinutes :(this :LocalTime, min :_0_59) => void;
readonly getSeconds :(this :Readonly<LocalTime>) => _0_59;
readonly setSeconds :(this :LocalTime, sec :_0_59) => void;
readonly getMilliseconds :(this :Readonly<LocalTime>) => _0_999;
readonly setMilliseconds :(this :LocalTime, ms :_0_999) => void;
}
declare class Keys extends RegExp {
readonly lastIndex :number;
constructor (keys :ArrayLike<string>);
readonly test :(this :Keys, key :string) => boolean;
}
declare const _literal :unique symbol;
type Source = string | ArrayBufferLike
| {
readonly path :string,
readonly data? :undefined,
readonly require :
| {
readonly resolve? :{ readonly paths? :undefined }
(this :void, id :'fs') :{
readonly readFileSync :(this :void, path :string) => ArrayBufferLike
}
}
| {
readonly resolve :{ readonly paths :(this :void, request :string) => null | string[] }
(this :void, id :'path') :{
readonly resolve :(this :void, dirname :string, filename :string) => string
}
(this :void, id :'fs') :{
readonly readFileSync :(this :void, path :string) => ArrayBufferLike
}
},
}
| {
readonly path :string,
readonly data :string | ArrayBufferLike,
readonly require? :
| {
readonly resolve? :{ readonly paths? :undefined }
}
| {
readonly resolve :{ readonly paths :(this :void, request :string) => null | string[] }
(this :void, id :'path') :{
readonly resolve :(this :void, dirname :string, filename :string) => string
}
},
};
type XOptions = null | {
readonly keys? :null | Keys,
readonly order? :boolean,
readonly exact? :boolean,
readonly multi? :boolean,
readonly longer? :boolean,
readonly string? :boolean,
readonly comment? :boolean,
readonly literal? :boolean,
readonly null? :boolean,
readonly tag? :null | (
<Table extends object & { [key :string | symbol] :any }, Key extends string | symbol, Array extends any[], Index extends number, Tag extends string>
(this :void, each :
| { table :Table, key :Key, tag :Tag }
| { array :Array, index :Index, tag :Tag }
| { table :Table, key :Key, array :Array, index :Index, tag :Tag }
) => void
),
};
type ReadonlyTable = object & { readonly [key :string] :ReadonlyValue };
type ReadonlyArray = readonly ReadonlyValue[];
type ReadonlyValue =
| { readonly [_literal] :string | readonly [ string, ...string[] ] } & object
| null | boolean | bigint | number | string
| ReadonlyDatetime | ReadonlyArray | ReadonlyTable
;
interface ReadonlyDatetime { readonly toISOString :(this :this) => string }
type Table = object & { [key :string] :Value };
type Array = Value[];
type Value =
| object & BigInt & { [_literal] :string }
| object & Number & { [_literal] :string }
| object & String & { [_literal] :string | [ string, ...string[] ] }
| null | boolean | bigint | number | string
| Datetime | Array | Table
;
type Datetime = OffsetDateTime | LocalDateTime | LocalDate | LocalTime;
declare const OffsetDateTime_ISOString :unique symbol;
declare const OffsetDateTime_value :unique symbol;
declare const LocalDateTime_ISOString :unique symbol;
declare const LocalDateTime_value :unique symbol;
declare const LocalDate_ISOString :unique symbol;
declare const LocalDate_value :unique symbol;
declare const LocalTime_ISOString :unique symbol;
declare const LocalTime_value :unique symbol;
type _1439_1439 = -1439 | {} & number | 1439;
type _1_10000 = -1 | {} & number | 10000;
type _0_9999 = 0 | {} & number | 9999;
type _0_999 = 0 | {} & number | 999;
type _0_6 = 0 | 1 | 2 | 3 | 4 | 5 | 6;
type _0_11 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
type _0_23 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23;
type _1_31 = | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31;
type _0_59 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59;

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -23,6 +23,7 @@ function populate_rt_status_header(runnerId) {
success:function(data){ success:function(data){
//console.log(JSON.stringify(data)) //console.log(JSON.stringify(data))
//add status on chart //add status on chart
$("#statusArchId").text(data.id)
$("#statusRegime").text("REALTIME: "+data.id) $("#statusRegime").text("REALTIME: "+data.id)
$("#statusName").text(data.run_name) $("#statusName").text(data.run_name)
$("#statusMode").text(data.run_mode) $("#statusMode").text(data.run_mode)

View File

@ -50,8 +50,8 @@ function refresh_stratin_and_callback(row, callback) {
contentType: "application/json", contentType: "application/json",
dataType: "json", dataType: "json",
success:function(data){ success:function(data){
console.log("fetched data ok") //console.log("fetched data ok")
console.log(JSON.stringify(data,null,2)); //console.log(JSON.stringify(data,null,2));
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")"); var err = eval("(" + xhr.responseText + ")");
@ -65,7 +65,7 @@ function refresh_stratin_and_callback(row, callback) {
// Both requests have completed successfully // Both requests have completed successfully
//console.log("Result from request:", result); //console.log("Result from request:", result);
console.log("calling calbback") //console.log("calling calbback")
//call callback function //call callback function
callback(response) callback(response)
@ -236,19 +236,19 @@ $(document).ready(function () {
filterList[i] = filterList[i].trim(); filterList[i] = filterList[i].trim();
} }
console.log("filter list") //console.log("filter list")
console.log(filterList) //console.log(filterList)
console.log(minsize) //console.log(minsize)
var row = "" var row = ""
//zakrouhleno na milisekundy //zakrouhleno na milisekundy
var puvodni = parseFloat(parseInt(parseFloat($('#trade-timestamp').val())*1000))/1000 var puvodni = parseFloat(parseInt(parseFloat($('#trade-timestamp').val())*1000))/1000
console.log(puvodni) //console.log(puvodni)
$('#trades-data-table').html(row); $('#trades-data-table').html(row);
data.forEach((tradeLine) => { data.forEach((tradeLine) => {
//console.log(JSON.stringify(tradeLine)) //console.log(JSON.stringify(tradeLine))
date = new Date(tradeLine.timestamp) date = new Date(tradeLine.timestamp)
timestamp = date.getTime()/1000 timestamp = date.getTime()/1000
console.log(timestamp) //console.log(timestamp)
//trade contains filtered condition or size<minsize //trade contains filtered condition or size<minsize
bg = (findCommonElements3(filterList, tradeLine.conditions) || (parseInt(tradeLine.size) < minsize) ? 'style="background-color: #411e1e;"' : '') bg = (findCommonElements3(filterList, tradeLine.conditions) || (parseInt(tradeLine.size) < minsize) ? 'style="background-color: #411e1e;"' : '')
@ -398,8 +398,8 @@ $(document).ready(function () {
contentType: "application/json", contentType: "application/json",
dataType: "json", dataType: "json",
success:function(data){ success:function(data){
console.log("first request ok") //("first request ok")
console.log(JSON.stringify(data,null,2)); //console.log(JSON.stringify(data,null,2));
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")"); var err = eval("(" + xhr.responseText + ")");
@ -417,8 +417,8 @@ $(document).ready(function () {
contentType: "application/json", contentType: "application/json",
dataType: "json", dataType: "json",
success:function(data){ success:function(data){
console.log("first request ok") //console.log("first request ok")
console.log(JSON.stringify(data,null,2)); //console.log(JSON.stringify(data,null,2));
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")"); var err = eval("(" + xhr.responseText + ")");
@ -433,9 +433,9 @@ $(document).ready(function () {
// Both requests have completed successfully // Both requests have completed successfully
var result1 = response1[0]; var result1 = response1[0];
var result2 = response2[0]; var result2 = response2[0];
console.log("Result from first request:", result1); // console.log("Result from first request:", result1);
console.log("Result from second request:", result2); // console.log("Result from second request:", result2);
console.log("calling compare") // console.log("calling compare")
perform_compare(result1, result2) perform_compare(result1, result2)
// Perform your action with the results from both requests // Perform your action with the results from both requests
// Example: // Example:

View File

@ -13,14 +13,16 @@ var candlestickSeries = null
var volumeSeries = null var volumeSeries = null
var vwapSeries = null var vwapSeries = null
var statusBarConfig = JSON.parse(localStorage.getItem("statusBarConfig")); var statusBarConfig = JSON.parse(localStorage.getItem("statusBarConfig"));
var activatedButtons = []
if (statusBarConfig == null) { if (statusBarConfig == null) {
statusBarConfig = {} statusBarConfig = {}
} }
var index_ind = 0
const sorter = (a, b) => a.time > b.time ? 1 : -1; const sorter = (a, b) => a.time > b.time ? 1 : -1;
var ind_editor = null
var indConfig = null var indConfig = null
settings = {} settings = {}
settings settings
@ -56,6 +58,13 @@ var indConfig_default = [ {name: "ema", titlevisible: false, embed: true, displa
{name: "sec_price", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},] {name: "sec_price", titlevisible: true, embed: true, display: true, priceScaleId: "right", lastValueVisible: false},]
//console.log(JSON.stringify(indConfig_default, null,null, 2)) //console.log(JSON.stringify(indConfig_default, null,null, 2))
function store_activated_buttons_state() {
activatedButtons = []
//ulozime si stav aktivovaných buttonků před změnou - mozna do sluzby
$('#indicatorsButtons .switcher-active-item').each(function() {
activatedButtons.push($(this).text());
});
}
function initialize_statusheader() { function initialize_statusheader() {
@ -132,9 +141,11 @@ function initialize_statusheader() {
} }
//pokud neni v configuraci vracime default
function get_ind_config(indName) { function get_ind_config(indName) {
def = {name: "ema", titlevisible: false, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false}
if (indConfig == null) { if (indConfig == null) {
indConfig = get_from_config("indConfig", indConfig_default) indConfig = get_from_config("indConfig", indConfig_default)
} }
@ -144,7 +155,7 @@ function get_ind_config(indName) {
{ {
return indConfig[i] return indConfig[i]
} }
return null return def
} }
function toggle_vertical_line(time) { function toggle_vertical_line(time) {
@ -328,39 +339,65 @@ function remove_indicator_buttons() {
elem1.remove() elem1.remove()
} }
function populate_indicator_buttons(def) { //pomocna funkce pro vytvoreni buttonu indiaktoru
var buttonElement = document.createElement('div'); function create_indicator_button(item, index, def) {
buttonElement.id = "indicatorsButtons" // //div pro kazdy button
buttonElement.classList.add('switcher'); // var buttonContainer = document.createElement('div');
// buttonContainer.classList.add('button-container');
indList.forEach(function (item, index) {
var itemEl = document.createElement('button'); var itemEl = document.createElement('button');
itemEl.innerText = item.name; itemEl.innerText = item.name;
itemEl.id = "IND"+index; itemEl.id = "IND"+index;
itemEl.title = item.cnf itemEl.title = item.cnf
itemEl.style.color = item.series.options().color; itemEl.style.color = item.series.options().color;
//pokud jde o pridanou on the fly - vybarvime jinak
if (item.added) {
itemEl.style.outline = "solid 1px"
}
itemEl.classList.add('switcher-item'); itemEl.classList.add('switcher-item');
if (def) { if (def) {
itemEl.classList.add('switcher-active-item'); itemEl.classList.add('switcher-active-item');
} }
// //jeste vytvorime pod tim overlay a nad to az dame linky
// // Create the overlay element.
// const overlay = document.createElement("div");
// overlay.id = "OVR"+index;
// overlay.classList.add("overlayLayer");
// overlay.classList.add("hidden");
// // Create the action buttons.
// const actionShow = document.createElement("div");
// actionShow.id = "actionShow";
// actionShow.textContent = "Show";
itemEl.addEventListener('click', function() { itemEl.addEventListener('click', function() {
onItemClicked1(index); onItemClickedToggle(index);
});
buttonElement.appendChild(itemEl);
}); });
//create toggle all button // const actionEdit = document.createElement("div");
var itemEl = document.createElement('button'); // actionEdit.id = "actionEdit";
itemEl.innerText = "all" // actionEdit.textContent = "Edit";
itemEl.classList.add('switcher-item');
if (def) { itemEl.addEventListener('contextmenu', function(e) {
itemEl.classList.add('switcher-active-item'); //edit modal zatim nemame
onItemClickedEdit(e, index);
});
// // Append the action buttons to the overlay.
// overlay.appendChild(actionShow);
// overlay.appendChild(actionEdit);
// // Add a hover listener to the button.
// itemEl.addEventListener("mouseover", toggleOverlay(index));
// itemEl.addEventListener("mouseout", toggleOverlay(index));
// buttonContainer.appendChild(itemEl)
// buttonContainer.appendChild(overlay)
return itemEl
} }
itemEl.addEventListener('click', function() {
onResetClicked();
});
buttonElement.appendChild(itemEl);
//pomocne funkce
function onResetClicked() { function onResetClicked() {
indList.forEach(function (item, index) { indList.forEach(function (item, index) {
vis = true; vis = true;
@ -376,7 +413,64 @@ function populate_indicator_buttons(def) {
}) })
} }
function onItemClicked1(index) {
function generateIndicators(e) {
alert("stratvars generated to clipboard from selected indicators")
}
//editace indikatoru, vcetne vytvoreni noveho
function onItemClickedEdit(e, index) {
if (ind_editor) {
ind_editor.dispose()
}
title = `#[stratvars.indicators.name]
`
const elem = document.getElementById("IND"+index);
//console.log("element",elem)
//jde o update
if (elem) {
elem.classList.replace('switcher-item', 'switcher-item-highlighted');
$('#indicatorName').val(elem.textContent)
$('#indicatorNameTitle').text(elem.textContent)
title = elem.title
}
//jde o novy zaznam - davame pryc delete
else {
$('#deleteIndicatorButton').hide();
}
e.preventDefault()
//$('#stratvar_id').val(row.id);
$('#indicatorId').val(index)
require(["vs/editor/editor.main"], () => {
ind_editor = monaco.editor.create(document.getElementById('indicatorTOML_editor'), {
value: title,
language: 'toml',
theme: 'tomlTheme-dark',
automaticLayout: true
});
});
window.$('#indicatorModal').modal('show');
}
//togle profit line
function profitLineToggle() {
vis = true;
const elem = document.getElementById("profitLine");
if (elem.classList.contains("switcher-active-item")) {
vis = false;
}
elem.classList.toggle("switcher-active-item");
//v ifu kvuli workaroundu
if (profitLine) {
profitLine.applyOptions({
visible: vis });
}
}
//toggle indiktoru
function onItemClickedToggle(index) {
vis = true; vis = true;
const elem = document.getElementById("IND"+index); const elem = document.getElementById("IND"+index);
if (elem.classList.contains("switcher-active-item")) { if (elem.classList.contains("switcher-active-item")) {
@ -397,15 +491,86 @@ function populate_indicator_buttons(def) {
} }
} }
} }
//funkce pro vytvoreni buttonku indikatoru
function populate_indicator_buttons(def) {
//vytvoreni outer button divu
var buttonElement = document.createElement('div');
buttonElement.id = "indicatorsButtons"
buttonElement.classList.add('switcher');
//iterace nad indikatory a vytvareni buttonků
indList.forEach(function (item, index) {
index_ind = index
active = false
//console.log("activatedButtons", activatedButtons)
//console.log("obsahuje item.name", activatedButtons.includes(item.name), item.name)
//pokud existuje v aktivnich pak
if ((activatedButtons) && (activatedButtons.includes(item.name))) {
active = true
}
//vytvoreni buttonku
itemEl = create_indicator_button(item, index, def||active);
//prirazeni do divu
buttonElement.appendChild(itemEl); ;
});
//create toggle all button
var itemEl = document.createElement('button');
itemEl.innerText = "all"
itemEl.classList.add('switcher-item');
if (def) {
itemEl.classList.add('switcher-active-item');
}
itemEl.addEventListener('click', function() {
onResetClicked();
});
buttonElement.appendChild(itemEl);
//button pro toggle profitu
var itemEl = document.createElement('button');
itemEl.innerText = "prof"
itemEl.classList.add('switcher-item');
itemEl.style.color = "#99912b"
itemEl.id = "profitLine"
itemEl.addEventListener('click', function(e) {
profitLineToggle();
});
buttonElement.appendChild(itemEl);
//create plus button to create new button
var itemEl = document.createElement('button');
itemEl.innerText = "+"
itemEl.classList.add('switcher-item');
//na tomto je navesena jquery pro otevreni modalu
itemEl.id = "button_addindicator"
itemEl.addEventListener('click', function(e) {
index_ind++
onItemClickedEdit(e, index_ind);
});
buttonElement.appendChild(itemEl);
//save indicator buttons - will generate indicators to stratvars
var itemEl = document.createElement('button');
itemEl.innerText = "generate"
itemEl.classList.add('switcher-item');
//na tomto je navesena jquery pro otevreni modalu
itemEl.id = "save_indicators"
itemEl.addEventListener('click', function(e) {
index_ind++
generateIndicators(e);
});
buttonElement.appendChild(itemEl);
return buttonElement; return buttonElement;
} }
//range switch pro chart https://jsfiddle.net/TradingView/qrb9a850/ //range switch pro chart https://jsfiddle.net/TradingView/qrb9a850/
function createSimpleSwitcher(items, activeItem, activeItemChangedCallback) { function createSimpleSwitcher(items, activeItem, activeItemChangedCallback, data) {
var switcherElement = document.createElement('div'); var switcherElement = document.createElement('div');
switcherElement.classList.add('switcher'); switcherElement.classList.add('switcher');
@ -432,7 +597,7 @@ function createSimpleSwitcher(items, activeItem, activeItemChangedCallback) {
activeItem = item; activeItem = item;
activeItemChangedCallback(item); activeItemChangedCallback(item, data);
} }
return switcherElement; return switcherElement;
@ -485,6 +650,7 @@ function format_date(datum, markettime = false, timeonly = false) {
} }
function clear_status_header() { function clear_status_header() {
$("#statusArchId").text("")
$("#statusRegime").text("") $("#statusRegime").text("")
$("#statusName").text("") $("#statusName").text("")
$("#statusMode").text("") $("#statusMode").text("")

View File

@ -372,12 +372,64 @@ pre {
/* color: var(--bs-dark-text-emphasis); */ /* color: var(--bs-dark-text-emphasis); */
/* } */ /* } */
.overlayLayer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: inline-table;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
transition: opacity 0.3s;
/* z-index: 2; */
}
.actionText {
color: white;
}
/* #indicatorModal {
position: absolute;
top: 10px;
left: 10px;
z-index: 1000;
} */
.highlighted { .highlighted {
color: #989393; color: #989393;
background-color: #242a31; background-color: #242a31;
/* color: var(--bs-dark-text-emphasis); */ /* color: var(--bs-dark-text-emphasis); */
} }
.switcher-item-highlighted {
position: relative;
z-index: 1;
/* cursor: pointer; */
text-decoration: double;
display: inline-block;
padding: 1px 6px;
font-size: 14px;
/* color: #262b3e; */
/* background-color: #818581; */
background-color: #0202022e;
margin-right: 8px;
margin-bottom: 6px;
/* border: 1px; */
border-radius: 4px;
outline: solid 1px;
outline-color: #73df4d;
/* outline-width: 1px; */
border-style: none;
}
/* .switcher { /* .switcher {
display: flex; display: flex;
align-items: center; align-items: center;
@ -426,7 +478,15 @@ pre {
outline: none; outline: none;
} */ } */
.button-container {
position: relative;
display: inline-block;
margin-bottom: 10px;
}
.switcher-item { .switcher-item {
position: relative;
z-index: 1;
/* cursor: pointer; */ /* cursor: pointer; */
text-decoration: double; text-decoration: double;
display: inline-block; display: inline-block;
@ -445,6 +505,10 @@ pre {
border-style: none; border-style: none;
} }
.switcher-item:hover + .overlayLayer {
opacity: 1;
}
.switcher-item:hover { .switcher-item:hover {
background-color: #f2f3f521; background-color: #f2f3f521;
} }

View File

@ -104,13 +104,13 @@ class StrategyClassicSL(Strategy):
rel_profit = 0 rel_profit = 0
#spoctene celkovy relativni profit za trade v procentech ((trade_profit/vstup_naklady)*100) #spoctene celkovy relativni profit za trade v procentech ((trade_profit/vstup_naklady)*100)
if vstup_cena != 0 and int(data.order.qty) != 0: if vstup_cena != 0 and int(data.order.qty) != 0:
rel_profit = (trade_profit / (vstup_cena * float(data.order.qty))) * 100 rel_profit = round((trade_profit / (vstup_cena * float(data.order.qty))) * 100,5)
#pokud jde o finalni FILL - pridame do pole tento celkovy relativnich profit (ze ktereho se pocita kumulativni relativni profit) #pokud jde o finalni FILL - pridame do pole tento celkovy relativnich profit (ze ktereho se pocita kumulativni relativni profit)
rel_profit_cum_calculated = 0 rel_profit_cum_calculated = 0
if data.event == TradeEvent.FILL: if data.event == TradeEvent.FILL:
self.state.rel_profit_cum.append(rel_profit) self.state.rel_profit_cum.append(rel_profit)
rel_profit_cum_calculated = np.mean(self.state.rel_profit_cum) rel_profit_cum_calculated = round(np.mean(self.state.rel_profit_cum),5)
self.state.ilog(e=f"BUY notif - SHORT PROFIT:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum=str(self.state.rel_profit_cum), bought_amount=bought_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id)) self.state.ilog(e=f"BUY notif - SHORT PROFIT:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum=str(self.state.rel_profit_cum), bought_amount=bought_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id))
@ -216,13 +216,13 @@ class StrategyClassicSL(Strategy):
rel_profit = 0 rel_profit = 0
#spoctene celkovy relativni profit za trade v procentech ((trade_profit/vstup_naklady)*100) #spoctene celkovy relativni profit za trade v procentech ((trade_profit/vstup_naklady)*100)
if vstup_cena != 0 and data.order.qty != 0: if vstup_cena != 0 and data.order.qty != 0:
rel_profit = (trade_profit / (vstup_cena * float(data.order.qty))) * 100 rel_profit = round((trade_profit / (vstup_cena * float(data.order.qty))) * 100,5)
rel_profit_cum_calculated = 0 rel_profit_cum_calculated = 0
#pokud jde o finalni FILL - pridame do pole relativnich profit (ze ktereho se pocita kumulativni relativni profit) #pokud jde o finalni FILL - pridame do pole relativnich profit (ze ktereho se pocita kumulativni relativni profit)
if data.event == TradeEvent.FILL: if data.event == TradeEvent.FILL:
self.state.rel_profit_cum.append(rel_profit) self.state.rel_profit_cum.append(rel_profit)
rel_profit_cum_calculated = np.mean(self.state.rel_profit_cum) rel_profit_cum_calculated = round(np.mean(self.state.rel_profit_cum),5)
self.state.ilog(e=f"SELL notif - PROFIT:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum = str(self.state.rel_profit_cum), sold_amount=sold_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id)) self.state.ilog(e=f"SELL notif - PROFIT:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum = str(self.state.rel_profit_cum), sold_amount=sold_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id))

View File

@ -692,7 +692,7 @@ class StrategyState:
self.bars = AttributeDict(bars) self.bars = AttributeDict(bars)
self.trades = AttributeDict(trades) self.trades = AttributeDict(trades)
self.indicators = AttributeDict(time=[]) self.indicators = AttributeDict(time=[])
#pro mapping indikatoru pro pouziti v operation statementu #pro mapping indikatoru pro pouziti v operation expressionu
self.ind_mapping = {} self.ind_mapping = {}
self.cbar_indicators = AttributeDict(time=[]) self.cbar_indicators = AttributeDict(time=[])
#secondary timeframe indicators #secondary timeframe indicators

View File

@ -3,6 +3,8 @@ from v2realbot.strategy.base import StrategyState
from v2realbot.indicators.indicators import ema, natr, roc from v2realbot.indicators.indicators import ema, natr, roc
from v2realbot.indicators.oscillators import rsi from v2realbot.indicators.oscillators import rsi
from traceback import format_exc from traceback import format_exc
from v2realbot.strategyblocks.indicators.helpers import get_source_series
#RSI INDICATOR #RSI INDICATOR
# type = RSI, source = [close, vwap, hlcc4], rsi_length = [14], MA_length = int (optional), on_confirmed_only = [true, false] # type = RSI, source = [close, vwap, hlcc4], rsi_length = [14], MA_length = int (optional), on_confirmed_only = [true, false]
# pokud existuje MA, vytvarime i stejnojnojmenny MAcko # pokud existuje MA, vytvarime i stejnojnojmenny MAcko
@ -20,15 +22,13 @@ def populate_dynamic_RSI_indicator(data, state: StrategyState, name):
#poustet kazdy tick nebo jenom na confirmed baru (on_confirmed_only = true) #poustet kazdy tick nebo jenom na confirmed baru (on_confirmed_only = true)
on_confirmed_only = safe_get(options, 'on_confirmed_only', False) on_confirmed_only = safe_get(options, 'on_confirmed_only', False)
req_source = safe_get(options, 'source', 'vwap') req_source = safe_get(options, 'source', 'vwap')
if req_source not in ["close", "vwap","hlcc4"]: rsi_length = int(safe_get(options, "length",14))
state.ilog(lvl=1,e=f"Unknown source error {req_source} for {name}")
return
rsi_length = int(safe_get(options, "RSI_length",14))
rsi_MA_length = safe_get(options, "MA_length", None) rsi_MA_length = safe_get(options, "MA_length", None)
if on_confirmed_only is False or (on_confirmed_only is True and data['confirmed']==1): if on_confirmed_only is False or (on_confirmed_only is True and data['confirmed']==1):
try: try:
source = state.bars[req_source] #source = state.bars[req_source]
source = get_source_series(state, req_source)
#cekame na dostatek dat #cekame na dostatek dat
if len(source) > rsi_length: if len(source) > rsi_length:
rsi_res = rsi(source, rsi_length) rsi_res = rsi(source, rsi_length)

View File

@ -25,6 +25,8 @@ def upscaledrsi(state, params):
#pokud potrebuju jen close nebo open muzu pouzit toto #pokud potrebuju jen close nebo open muzu pouzit toto
# vezme to N-th element z pole # vezme to N-th element z pole
#TODO resample any series
def resample_close_prices(bars, new_resolution): def resample_close_prices(bars, new_resolution):
# Check that the new resolution is a multiple of the old resolution. # Check that the new resolution is a multiple of the old resolution.
if new_resolution % bars['resolution'][-1] != 0: if new_resolution % bars['resolution'][-1] != 0:

View File

@ -7,6 +7,7 @@ from traceback import format_exc
from v2realbot.ml.ml import ModelML from v2realbot.ml.ml import ModelML
import numpy as np import numpy as np
from collections import defaultdict from collections import defaultdict
from scipy.stats import linregress
#vstupem je bud indicator nebo bar parametr #vstupem je bud indicator nebo bar parametr
#na tomto vstupu dokaze provest zakladni statisticke funkce pro subpole X hodnot zpatky #na tomto vstupu dokaze provest zakladni statisticke funkce pro subpole X hodnot zpatky
@ -61,6 +62,26 @@ def basestats(state, params):
#val = 2 * (angle_deg / 180) - 1 #val = 2 * (angle_deg / 180) - 1
elif func =="stdev": elif func =="stdev":
val = np.std(source_array) val = np.std(source_array)
#linregres slope
elif func == "slope":
if len(source_array) < 4:
return -2, "less than 4 elmnts"
try:
np.seterr(all="raise")
val, _, _, _, _ = linregress(np.arange(len(source_array)), source_array)
val = round(val, 4)
except FloatingPointError:
return -2, "FloatingPointError"
#zatim takto, dokud nebudou podporovany indikatory s vice vystupnimi
elif func == "intercept":
if len(source_array) < 4:
return -2, "less than 4 elmnts"
try:
np.seterr(all="raise")
_, val, _, _, _ = linregress(np.arange(len(source_array)), source_array)
val = round(val, 4)
except FloatingPointError:
return -2, "FloatingPointError"
else: else:
return -2, "wrong function" return -2, "wrong function"

View File

@ -2,17 +2,17 @@ from v2realbot.utils.utils import isrising, isfalling,zoneNY, price2dec, print,
from v2realbot.strategy.base import StrategyState from v2realbot.strategy.base import StrategyState
import numpy as np import numpy as np
#allows executing a statement - pozor neni sanitized a zatim se spousti i v globalni scopu #allows executing a expression - pozor neni sanitized a zatim se spousti i v globalni scopu
#v pripade jineho nez soukromeho uziti zabezpecit #v pripade jineho nez soukromeho uziti zabezpecit
#do budoucna prozkoumat NUMEXPR - ten omezuje jen na operatory a univerzalni funkce #do budoucna prozkoumat NUMEXPR - ten omezuje jen na operatory a univerzalni funkce
#eval nyni umi i user-defined function, string operation and control statements #eval nyni umi i user-defined function, string operation and control statements
#teroeticky se dá pouzit i SYMPY - kde se daji vytvorit jednotlive symboly s urcitou funkcni #teroeticky se dá pouzit i SYMPY - kde se daji vytvorit jednotlive symboly s urcitou funkcni
def statement(state: StrategyState, params): def expression(state: StrategyState, params):
funcName = "statement" funcName = "expression"
#indicator name #indicator name
operation = safe_get(params, "statement", None) operation = safe_get(params, "expression", None)
if operation is None : if operation is None :
return -2, "required param missing" return -2, "required param missing"
@ -20,7 +20,7 @@ def statement(state: StrategyState, params):
state.ilog(lvl=1,e=f"BEFORE {funcName} {operation=}", **params) state.ilog(lvl=1,e=f"BEFORE {funcName} {operation=}", **params)
#pro zacatek eval #pro zacatek eval
val = eval(operation, None, state.ind_mapping) val = eval(operation, {'state': state}, state.ind_mapping)
if not np.isfinite(val): if not np.isfinite(val):

View File

@ -10,7 +10,7 @@ from collections import defaultdict
from v2realbot.strategyblocks.indicators.helpers import value_or_indicator from v2realbot.strategyblocks.indicators.helpers import value_or_indicator
#IMPLEMENTS different types of moving averages #IMPLEMENTS different types of moving averages in package v2realbot.indicators.moving_averages
def ma(state, params): def ma(state, params):
funcName = "ma" funcName = "ma"
type = safe_get(params, "type", "ema") type = safe_get(params, "type", "ema")