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]
ext_data: Optional[dict]
class TomlInput(BaseModel):
toml: str
# class Trade(BaseModel):
# order: Order
# value: float

View File

@ -5,9 +5,10 @@ from alpaca.data.historical import StockHistoricalDataClient
from alpaca.data.requests import StockTradesRequest, StockBarsRequest
from alpaca.data.enums import DataFeed
from alpaca.data.timeframe import TimeFrame
from v2realbot.strategy.base import StrategyState
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.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.common.PrescribedTradeModel import Trade, TradeDirection, TradeStatus, TradeStoplossType
from datetime import datetime
@ -30,6 +31,9 @@ from datetime import timedelta, time
from threading import Lock
from v2realbot.common.db import pool, execute_with_retry, row_to_runarchive, row_to_runarchiveview
from sqlite3 import OperationalError, Row
import v2realbot.strategyblocks.indicators.custom as ci
from v2realbot.interfaces.backtest_interface import BacktestInterface
#from pyinstrument import Profiler
#adding lock to ensure thread safety of TinyDB (in future will be migrated to proper db)
lock = Lock()
@ -1107,6 +1111,103 @@ def get_testlists():
# 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
#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

View File

@ -11,7 +11,7 @@ import uvicorn
from uuid import UUID
import v2realbot.controller.services as cs
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.responses import FileResponse
from fastapi.staticfiles import StaticFiles
@ -429,6 +429,19 @@ def _delete_archived_runners_byIDs(runner_ids: list[UUID]):
elif res < 0:
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",..)
@app.patch("/archived_runners/{runner_id}", dependencies=[Depends(api_key_auth)])
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
import numpy as np
from copy import deepcopy
from v2realbot.controller.services import get_archived_runnerslist_byBatchID
import v2realbot.controller.services as cs
#Basic classes for machine learning
#drzi model a jeho zakladni nastaveni
@ -138,10 +138,10 @@ class ModelML:
print("loading runners for ",str(runner_id_list))
elif batch_id is not None:
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:
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
else:
runner_ids = self.train_runner_ids

View File

@ -1,5 +1,5 @@
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 v2realbot.config import DATA_DIR
@ -43,7 +43,7 @@ def merge_dicts(dict_list):
# return merged_dict
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:
print("ok")
else:

View File

@ -59,8 +59,17 @@
<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="/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>
// require is provided by loader.min.js.
require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs' }});
@ -132,6 +141,7 @@
</form>
</div>
<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="statusName" class="headerItem"></div>
<div id="statusMode" class="headerItem"></div>
@ -156,6 +166,44 @@
</div>
<div class="lowercontainer" id="lowercontainer"></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 id="hist-trades" class="flex-items">
<div id="form-trades">

File diff suppressed because it is too large Load Diff

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){
//console.log(JSON.stringify(data))
//add status on chart
$("#statusArchId").text(data.id)
$("#statusRegime").text("REALTIME: "+data.id)
$("#statusName").text(data.run_name)
$("#statusMode").text(data.run_mode)

View File

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

View File

@ -13,14 +13,16 @@ var candlestickSeries = null
var volumeSeries = null
var vwapSeries = null
var statusBarConfig = JSON.parse(localStorage.getItem("statusBarConfig"));
var activatedButtons = []
if (statusBarConfig == null) {
statusBarConfig = {}
}
var index_ind = 0
const sorter = (a, b) => a.time > b.time ? 1 : -1;
var ind_editor = null
var indConfig = null
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},]
//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() {
@ -132,9 +141,11 @@ function initialize_statusheader() {
}
//pokud neni v configuraci vracime default
function get_ind_config(indName) {
def = {name: "ema", titlevisible: false, embed: true, display: true, priceScaleId: "middle", lastValueVisible: false}
if (indConfig == null) {
indConfig = get_from_config("indConfig", indConfig_default)
}
@ -144,7 +155,7 @@ function get_ind_config(indName) {
{
return indConfig[i]
}
return null
return def
}
function toggle_vertical_line(time) {
@ -328,25 +339,183 @@ function remove_indicator_buttons() {
elem1.remove()
}
//pomocna funkce pro vytvoreni buttonu indiaktoru
function create_indicator_button(item, index, def) {
// //div pro kazdy button
// var buttonContainer = document.createElement('div');
// buttonContainer.classList.add('button-container');
var itemEl = document.createElement('button');
itemEl.innerText = item.name;
itemEl.id = "IND"+index;
itemEl.title = item.cnf
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');
if (def) {
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() {
onItemClickedToggle(index);
});
// const actionEdit = document.createElement("div");
// actionEdit.id = "actionEdit";
// actionEdit.textContent = "Edit";
itemEl.addEventListener('contextmenu', function(e) {
//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
}
//pomocne funkce
function onResetClicked() {
indList.forEach(function (item, index) {
vis = true;
const elem = document.getElementById("IND"+index);
if (elem.classList.contains("switcher-active-item")) {
vis = false;
}
elem.classList.toggle("switcher-active-item");
if (indList[index].series) {
indList[index].series.applyOptions({
visible: vis });
}
})
}
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;
const elem = document.getElementById("IND"+index);
if (elem.classList.contains("switcher-active-item")) {
vis = false;
}
elem.classList.toggle("switcher-active-item");
//v ifu kvuli workaroundu
if (indList[index].series) {
indList[index].series.applyOptions({
visible: vis });
}
//zatim takto workaround, pak vymyslet systemove pro vsechny tickbased indikatory
if (indList[index].name == "tick_price") {
if (!vis && indList[index].series) {
chart.removeSeries(indList[index].series)
chart.timeScale().fitContent();
indList[index].series = null
}
}
}
//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) {
var itemEl = document.createElement('button');
itemEl.innerText = item.name;
itemEl.id = "IND"+index;
itemEl.title = item.cnf
itemEl.style.color = item.series.options().color;
itemEl.classList.add('switcher-item');
if (def) {
itemEl.classList.add('switcher-active-item');
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
}
itemEl.addEventListener('click', function() {
onItemClicked1(index);
});
buttonElement.appendChild(itemEl);
//vytvoreni buttonku
itemEl = create_indicator_button(item, index, def||active);
//prirazeni do divu
buttonElement.appendChild(itemEl); ;
});
//create toggle all button
@ -361,51 +530,47 @@ function populate_indicator_buttons(def) {
});
buttonElement.appendChild(itemEl);
function onResetClicked() {
indList.forEach(function (item, index) {
vis = true;
const elem = document.getElementById("IND"+index);
if (elem.classList.contains("switcher-active-item")) {
vis = false;
}
elem.classList.toggle("switcher-active-item");
if (indList[index].series) {
indList[index].series.applyOptions({
visible: vis });
}
})
}
//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);
function onItemClicked1(index) {
vis = true;
const elem = document.getElementById("IND"+index);
if (elem.classList.contains("switcher-active-item")) {
vis = false;
}
elem.classList.toggle("switcher-active-item");
//v ifu kvuli workaroundu
if (indList[index].series) {
indList[index].series.applyOptions({
visible: vis });
}
//zatim takto workaround, pak vymyslet systemove pro vsechny tickbased indikatory
if (indList[index].name == "tick_price") {
if (!vis && indList[index].series) {
chart.removeSeries(indList[index].series)
chart.timeScale().fitContent();
indList[index].series = null
}
}
//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/
function createSimpleSwitcher(items, activeItem, activeItemChangedCallback) {
function createSimpleSwitcher(items, activeItem, activeItemChangedCallback, data) {
var switcherElement = document.createElement('div');
switcherElement.classList.add('switcher');
@ -432,7 +597,7 @@ function createSimpleSwitcher(items, activeItem, activeItemChangedCallback) {
activeItem = item;
activeItemChangedCallback(item);
activeItemChangedCallback(item, data);
}
return switcherElement;
@ -485,6 +650,7 @@ function format_date(datum, markettime = false, timeonly = false) {
}
function clear_status_header() {
$("#statusArchId").text("")
$("#statusRegime").text("")
$("#statusName").text("")
$("#statusMode").text("")

View File

@ -372,12 +372,64 @@ pre {
/* 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 {
color: #989393;
background-color: #242a31;
/* 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 {
display: flex;
align-items: center;
@ -426,7 +478,15 @@ pre {
outline: none;
} */
.button-container {
position: relative;
display: inline-block;
margin-bottom: 10px;
}
.switcher-item {
position: relative;
z-index: 1;
/* cursor: pointer; */
text-decoration: double;
display: inline-block;
@ -445,6 +505,10 @@ pre {
border-style: none;
}
.switcher-item:hover + .overlayLayer {
opacity: 1;
}
.switcher-item:hover {
background-color: #f2f3f521;
}

View File

@ -104,13 +104,13 @@ class StrategyClassicSL(Strategy):
rel_profit = 0
#spoctene celkovy relativni profit za trade v procentech ((trade_profit/vstup_naklady)*100)
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)
rel_profit_cum_calculated = 0
if data.event == TradeEvent.FILL:
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))
@ -216,13 +216,13 @@ class StrategyClassicSL(Strategy):
rel_profit = 0
#spoctene celkovy relativni profit za trade v procentech ((trade_profit/vstup_naklady)*100)
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
#pokud jde o finalni FILL - pridame do pole relativnich profit (ze ktereho se pocita kumulativni relativni profit)
if data.event == TradeEvent.FILL:
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))

View File

@ -692,7 +692,7 @@ class StrategyState:
self.bars = AttributeDict(bars)
self.trades = AttributeDict(trades)
self.indicators = AttributeDict(time=[])
#pro mapping indikatoru pro pouziti v operation statementu
#pro mapping indikatoru pro pouziti v operation expressionu
self.ind_mapping = {}
self.cbar_indicators = AttributeDict(time=[])
#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.oscillators import rsi
from traceback import format_exc
from v2realbot.strategyblocks.indicators.helpers import get_source_series
#RSI INDICATOR
# 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
@ -19,16 +21,14 @@ def populate_dynamic_RSI_indicator(data, state: StrategyState, name):
#poustet kazdy tick nebo jenom na confirmed baru (on_confirmed_only = true)
on_confirmed_only = safe_get(options, 'on_confirmed_only', False)
req_source = safe_get(options, 'source', 'vwap')
if req_source not in ["close", "vwap","hlcc4"]:
state.ilog(lvl=1,e=f"Unknown source error {req_source} for {name}")
return
rsi_length = int(safe_get(options, "RSI_length",14))
req_source = safe_get(options, 'source', 'vwap')
rsi_length = int(safe_get(options, "length",14))
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):
try:
source = state.bars[req_source]
#source = state.bars[req_source]
source = get_source_series(state, req_source)
#cekame na dostatek dat
if len(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
# vezme to N-th element z pole
#TODO resample any series
def resample_close_prices(bars, new_resolution):
# Check that the new resolution is a multiple of the old resolution.
if new_resolution % bars['resolution'][-1] != 0:

View File

@ -7,6 +7,7 @@ from traceback import format_exc
from v2realbot.ml.ml import ModelML
import numpy as np
from collections import defaultdict
from scipy.stats import linregress
#vstupem je bud indicator nebo bar parametr
#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
elif func =="stdev":
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:
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
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
#do budoucna prozkoumat NUMEXPR - ten omezuje jen na operatory a univerzalni funkce
#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
def statement(state: StrategyState, params):
funcName = "statement"
def expression(state: StrategyState, params):
funcName = "expression"
#indicator name
operation = safe_get(params, "statement", None)
operation = safe_get(params, "expression", None)
if operation is None :
return -2, "required param missing"
@ -20,7 +20,7 @@ def statement(state: StrategyState, params):
state.ilog(lvl=1,e=f"BEFORE {funcName} {operation=}", **params)
#pro zacatek eval
val = eval(operation, None, state.ind_mapping)
val = eval(operation, {'state': state}, state.ind_mapping)
if not np.isfinite(val):

View File

@ -10,7 +10,7 @@ from collections import defaultdict
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):
funcName = "ma"
type = safe_get(params, "type", "ema")