diff --git a/testy/tinyDBselect.py b/testy/tinyDBselect.py new file mode 100644 index 0000000..5a7aae1 --- /dev/null +++ b/testy/tinyDBselect.py @@ -0,0 +1,32 @@ + +from typing import Any, List +from uuid import UUID, uuid4 +import pickle +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.enums.enums import RecordType, StartBarAlign, Mode, Account +from v2realbot.common.model import StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveDetail, RunArchiveChange +from v2realbot.utils.utils import AttributeDict, zoneNY, dict_replace_value, Store, parse_toml_string, json_serial +from datetime import datetime +from threading import Thread, current_thread, Event, enumerate +from v2realbot.config import STRATVARS_UNCHANGEABLES, ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY, DATA_DIR +import importlib +from queue import Queue +from tinydb import TinyDB, Query, where +from tinydb.operations import set +import json +from rich import print + +arch_header_file = DATA_DIR + "/arch_header.json" +arch_detail_file = DATA_DIR + "/arch_detail.json" +#db layer to store runner archive +db_arch_h = TinyDB(arch_header_file, default=json_serial) +db_arch_d = TinyDB(arch_detail_file, default=json_serial) + + +# res = db_arch_h.update(set('note', "ahoj"), where('id') == "74aa524e-3ed4-41fb-8166-f20946520344") +# print(res) +res = db_arch_d.all() +print(res) \ No newline at end of file diff --git a/v2realbot/__pycache__/config.cpython-310.pyc b/v2realbot/__pycache__/config.cpython-310.pyc index 63e3332..e3b2ecb 100644 Binary files a/v2realbot/__pycache__/config.cpython-310.pyc and b/v2realbot/__pycache__/config.cpython-310.pyc differ diff --git a/v2realbot/common/__pycache__/model.cpython-310.pyc b/v2realbot/common/__pycache__/model.cpython-310.pyc index 3759e12..9978461 100644 Binary files a/v2realbot/common/__pycache__/model.cpython-310.pyc and b/v2realbot/common/__pycache__/model.cpython-310.pyc differ diff --git a/v2realbot/common/model.py b/v2realbot/common/model.py index 21cbaaa..e6c038b 100644 --- a/v2realbot/common/model.py +++ b/v2realbot/common/model.py @@ -153,6 +153,11 @@ class TradeUpdate(BaseModel): cash: Optional[float] pos_avg_price: Optional[float] + +class RunArchiveChange(BaseModel): + id: UUID + note: str + #Contains archive of running strategies (runner) - master class RunArchive(BaseModel): #unique id of algorun diff --git a/v2realbot/config.py b/v2realbot/config.py index 376d9fa..a272a83 100644 --- a/v2realbot/config.py +++ b/v2realbot/config.py @@ -3,7 +3,7 @@ from v2realbot.enums.enums import Mode, Account, FillCondition from appdirs import user_data_dir #no print in console -QUIET_MODE = True +QUIET_MODE = False #how many consecutive trades with the fill price are necessary for LIMIT fill to happen in backtesting #0 - optimistic, every knot high will fill the order #N - N consecutive trades required diff --git a/v2realbot/controller/services.py b/v2realbot/controller/services.py index 59e1cd6..c00668b 100644 --- a/v2realbot/controller/services.py +++ b/v2realbot/controller/services.py @@ -6,7 +6,7 @@ from alpaca.data.requests import StockTradesRequest, StockBarsRequest from alpaca.data.enums import DataFeed from alpaca.data.timeframe import TimeFrame from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account -from v2realbot.common.model import StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveDetail +from v2realbot.common.model import StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveDetail, RunArchiveChange from v2realbot.utils.utils import AttributeDict, zoneNY, dict_replace_value, Store, parse_toml_string, json_serial from datetime import datetime from threading import Thread, current_thread, Event, enumerate @@ -37,10 +37,10 @@ def get_all_runners(): if len(db.runners) > 0: #print(db.runners) for i in db.runners: - i.run_profit = round(i.run_instance.state.profit,2) + i.run_profit = round(float(i.run_instance.state.profit),2) i.run_trade_count = len(i.run_instance.state.tradeList) i.run_positions = i.run_instance.state.positions - i.run_avgp = round(i.run_instance.state.avgp,3) + i.run_avgp = round(float(i.run_instance.state.avgp),3) return (0, db.runners) else: return (0, []) @@ -419,10 +419,10 @@ def archive_runner(runner: Runner, strat: StrategyInstance): bt_from=bp_from, bt_to = bp_to, stratvars = strat.state.vars, - profit=round(strat.state.profit,2), + profit=round(float(strat.state.profit),2), trade_count=len(strat.state.tradeList), end_positions=strat.state.positions, - end_positions_avgp=round(strat.state.avgp,3), + end_positions_avgp=round(float(strat.state.avgp),3), open_orders=9999 ) @@ -437,7 +437,7 @@ def archive_runner(runner: Runner, strat: StrategyInstance): print("archive runner finished") return 0, str(resh) + " " + str(resd) except Exception as e: - print(str(e)) + print("Exception in archive_runner: " + str(e)) return -2, str(e) def get_all_archived_runners(): @@ -454,13 +454,23 @@ def delete_archived_runners_byID(id: UUID): return 0, str(resh) + " " + str(resd) except Exception as e: return -2, str(e) + +#edit archived runner note +def edit_archived_runners(runner_id: UUID, archChange: RunArchiveChange): + try: + res = db_arch_h.update(set('note', archChange.note), where('id') == str(runner_id)) + if len(res) == 0: + return -1, "not found "+str(runner_id) + return 0, runner_id + except Exception as e: + return -2, str(e) def get_all_archived_runners_detail(): res = db_arch_d.all() return 0, res def get_archived_runner_details_byID(id: UUID): - res = db_arch_d.get(where('id') == id) + res = db_arch_d.get(where('id') == str(id)) if res==None: return -2, "not found" else: diff --git a/v2realbot/main.py b/v2realbot/main.py index 12391e7..33e2221 100644 --- a/v2realbot/main.py +++ b/v2realbot/main.py @@ -13,7 +13,7 @@ from fastapi.security import APIKeyHeader import uvicorn from uuid import UUID import v2realbot.controller.services as cs -from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest, Trade, RunArchive, RunArchiveDetail, Bar +from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest, Trade, RunArchive, RunArchiveDetail, Bar, RunArchiveChange from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query from fastapi.responses import HTMLResponse, FileResponse from fastapi.staticfiles import StaticFiles @@ -282,6 +282,16 @@ def _delete_archived_runners_byID(runner_id): elif res < 0: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error: {res}:{id}") +#edit archived runner ("note",..) +@app.patch("/archived_runners/{runner_id}", dependencies=[Depends(api_key_auth)]) +def _edit_archived_runners(archChange: RunArchiveChange, runner_id: UUID): + res, id = cs.edit_archived_runners(runner_id=runner_id, archChange=archChange) + if res == 0: return runner_id + elif res == -1: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error not found: {res}:{runner_id}") + else: + raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error not changed: {res}:{runner_id}") + #get all archived runners detail @app.get("/archived_runners_detail/", dependencies=[Depends(api_key_auth)]) def _get_all_archived_runners_detail() -> list[RunArchiveDetail]: diff --git a/v2realbot/static/index.html b/v2realbot/static/index.html index 0fbd44d..7fbdd62 100644 --- a/v2realbot/static/index.html +++ b/v2realbot/static/index.html @@ -149,8 +149,9 @@
"+JSON.stringify(row.stratvars,null,2)+"") + //$('#chartArchive').append(JSON.stringify(data,null,2)); console.log(JSON.stringify(data,null,2)); //if lower res is required call prepare_data otherwise call chart_archived_run() @@ -60,6 +72,43 @@ $(document).ready(function () { }); }) +//edit modal +$("#editModalArchive").on('submit','#editFormArchive', function(event){ + event.preventDefault(); + $('#editarchive').attr('disabled','disabled'); + trow = archiveRecords.row('.selected').data(); + note = $('#editnote').val() + var formData = $(this).serializeJSON(); + row = {} + row["id"] = trow.id + row["note"] = note + jsonString = JSON.stringify(row); + console.log("pred odeslanim json string", jsonString) + $.ajax({ + url:"/archived_runners/"+trow.id, + beforeSend: function (xhr) { + xhr.setRequestHeader('X-API-Key', + API_KEY); }, + method:"PATCH", + contentType: "application/json", + // dataType: "json", + data: jsonString, + success:function(data){ + $('#editFormArchive')[0].reset(); + window.$('#editModalArchive').modal('hide'); + $('#editarchive').attr('disabled', false); + archiveRecords.ajax.reload(); + }, + error: function(xhr, status, error) { + var err = eval("(" + xhr.responseText + ")"); + window.alert(JSON.stringify(xhr)); + console.log(JSON.stringify(xhr)); + $('#editarchive').attr('disabled', false); + } + }) +}); + + //delete modal $("#delModalArchive").on('submit','#delFormArchive', function(event){ event.preventDefault(); @@ -121,12 +170,12 @@ var archiveRecords = {data: 'end_positions_avgp', visible: true}, {data: 'open_orders', visible: true} ], - columnDefs: [{ - targets: [4,5,8,9], - render: function ( data, type, row ) { - return format_date(data) - }, - }], + // columnDefs: [{ + // targets: [4,5,8,9], + // render: function ( data, type, row ) { + // return format_date(data) + // }, + // }], order: [[5, 'desc']], paging: true, lengthChange: false, diff --git a/v2realbot/static/js/livewebsocket.js b/v2realbot/static/js/livewebsocket.js index 37d0999..d51f793 100644 --- a/v2realbot/static/js/livewebsocket.js +++ b/v2realbot/static/js/livewebsocket.js @@ -115,7 +115,7 @@ function connect(event) { logcnt++; - row = '
' + str_row + '