368 lines
11 KiB
Python
368 lines
11 KiB
Python
from uuid import UUID, uuid4
|
|
from alpaca.trading.enums import OrderSide, OrderStatus, TradeEvent,OrderType
|
|
#from utils import AttributeDict
|
|
from rich import print
|
|
from typing import Any, Optional, List, Union
|
|
from datetime import datetime, date
|
|
from pydantic import BaseModel, Field
|
|
from v2realbot.enums.enums import Mode, Account, SchedulerStatus, Moddus
|
|
from alpaca.data.enums import Exchange
|
|
|
|
|
|
|
|
|
|
#models for server side datatables
|
|
# Model for individual column data
|
|
class ColumnData(BaseModel):
|
|
data: str
|
|
name: str
|
|
searchable: bool
|
|
orderable: bool
|
|
search: dict
|
|
|
|
# Model for the search value
|
|
class SearchValue(BaseModel):
|
|
value: str
|
|
regex: bool
|
|
|
|
class OrderValue(BaseModel):
|
|
column: int
|
|
dir: str
|
|
|
|
# Model for incoming DataTables request
|
|
class DataTablesRequest(BaseModel):
|
|
draw: int
|
|
start: int
|
|
length: int
|
|
search: SearchValue
|
|
order: List[OrderValue]
|
|
columns: List[ColumnData]
|
|
|
|
#tu samou variantu pak UpdateStrategyInstanceWhileRunning
|
|
|
|
#only those that can be changed UUID id prijde v parametru
|
|
# @app.put("/api/v1/users/{id}")
|
|
# async def update_user(user_update: UpdateUser, id: UUID):
|
|
# for user in db:
|
|
# if user.id == id:
|
|
# if user_update.first_name is not None:
|
|
# user.first_name = user_update.first_name
|
|
# if user_update.last_name is not None:
|
|
# userbase.last_name = user_update.last_name
|
|
# if user_update.roles is not None:
|
|
# user.roles = user_update.roles
|
|
# return user.id
|
|
# raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")
|
|
|
|
|
|
#obecny vstup pro analyzera (vstupem muze byt bud batch_id nebo seznam runneru)
|
|
class AnalyzerInputs(BaseModel):
|
|
function: str
|
|
batch_id: Optional[str] = None
|
|
runner_ids: Optional[List[UUID]] = None
|
|
#additional parameter
|
|
params: Optional[dict] = {}
|
|
|
|
class RunDay(BaseModel):
|
|
"""
|
|
Helper object for batch run - carries list of days in format required by run batch manager
|
|
"""
|
|
start: datetime
|
|
end: datetime
|
|
name: Optional[str] = None
|
|
note: Optional[str] = None
|
|
id: Optional[str] = None
|
|
|
|
# Define a Pydantic model for input data
|
|
class ConfigItem(BaseModel):
|
|
id: Optional[int] = None
|
|
item_name: str
|
|
json_data: str
|
|
|
|
class Intervals(BaseModel):
|
|
start: str
|
|
end: str
|
|
note: Optional[str] = None
|
|
|
|
# Define the data model for the TestLists
|
|
class TestList(BaseModel):
|
|
id: Optional[UUID | str | None] = None
|
|
name: str
|
|
dates: List[Intervals]
|
|
|
|
#for GUI to fetch historical trades on given symbol
|
|
class Trade(BaseModel):
|
|
symbol: str
|
|
timestamp: datetime
|
|
exchange: Optional[Union[Exchange, str]] = None
|
|
price: float
|
|
size: float
|
|
id: int
|
|
conditions: Optional[List[str]] = None
|
|
tape: Optional[str] = None
|
|
|
|
|
|
#persisted object in pickle
|
|
class StrategyInstance(BaseModel):
|
|
id: Optional[UUID | str | None] = None
|
|
id2: int
|
|
name: str
|
|
symbol: str
|
|
class_name: str
|
|
script: str
|
|
open_rush: int = 0
|
|
close_rush: int = 0
|
|
stratvars_conf: str
|
|
add_data_conf: str
|
|
note: Optional[str] = None
|
|
history: Optional[str] = None
|
|
|
|
def __setstate__(self, state: dict[Any, Any]) -> None:
|
|
"""
|
|
Hack to allow unpickling models stored from pydantic V1
|
|
"""
|
|
state.setdefault("__pydantic_extra__", {})
|
|
state.setdefault("__pydantic_private__", {})
|
|
|
|
if "__pydantic_fields_set__" not in state:
|
|
state["__pydantic_fields_set__"] = state.get("__fields_set__")
|
|
|
|
super().__setstate__(state)
|
|
|
|
class RunRequest(BaseModel):
|
|
id: UUID
|
|
account: Account
|
|
mode: Mode
|
|
note: Optional[str] = None
|
|
debug: bool = False
|
|
strat_json: Optional[str] = None
|
|
ilog_save: bool = False
|
|
bt_from: Optional[datetime] = None
|
|
bt_to: Optional[datetime] = None
|
|
#weekdays filter
|
|
#pokud je uvedeny filtrujeme tyto dny
|
|
weekdays_filter: Optional[list] = None
|
|
#id testovaciho intervalu TODO prejmenovat
|
|
test_batch_id: Optional[str] = None
|
|
#GENERATED ID v ramci runu, vaze vsechny runnery v batchovem behu
|
|
batch_id: Optional[str] = None
|
|
cash: int = 100000
|
|
skip_cache: Optional[bool] = False
|
|
|
|
#Trida, která je nadstavbou runrequestu a pouzivame ji v scheduleru, je zde navic jen par polí
|
|
class RunManagerRecord(BaseModel):
|
|
moddus: Moddus
|
|
id: UUID = Field(default_factory=uuid4)
|
|
strat_id: UUID
|
|
symbol: Optional[str] = None
|
|
account: Account
|
|
mode: Mode
|
|
note: Optional[str] = None
|
|
ilog_save: bool = False
|
|
bt_from: Optional[datetime] = None
|
|
bt_to: Optional[datetime] = None
|
|
#weekdays filter
|
|
#pokud je uvedeny filtrujeme tyto dny
|
|
weekdays_filter: Optional[list] = None #list of strings 0-6 representing days to run
|
|
#GENERATED ID v ramci runu, vaze vsechny runnery v batchovem behu
|
|
batch_id: Optional[str] = None
|
|
testlist_id: Optional[str] = None
|
|
start_time: str #time (HH:MM) that start function is called
|
|
stop_time: Optional[str] = None #time (HH:MM) that stop function is called
|
|
status: SchedulerStatus
|
|
last_processed: Optional[datetime] = None
|
|
history: Optional[str] = None
|
|
valid_from: Optional[datetime] = None # US East time zone daetime
|
|
valid_to: Optional[datetime] = None # US East time zone daetime
|
|
runner_id: Optional[UUID] = None #last runner_id from scheduler after stratefy is started
|
|
strat_running: Optional[bool] = None #automatically updated field based on status of runner_id above, it is added by row_to_RunManagerRecord
|
|
class RunnerView(BaseModel):
|
|
id: UUID
|
|
strat_id: UUID
|
|
run_started: Optional[datetime] = None
|
|
run_mode: Mode
|
|
run_name: Optional[str] = None
|
|
run_note: Optional[str] = None
|
|
run_account: Account
|
|
run_ilog_save: Optional[bool] = False
|
|
run_symbol: Optional[str] = None
|
|
run_trade_count: Optional[int] = 0
|
|
run_profit: Optional[float] = 0
|
|
run_positions: Optional[int] = 0
|
|
run_avgp: Optional[float] = 0
|
|
run_stopped: Optional[datetime] = None
|
|
run_paused: Optional[datetime] = None
|
|
|
|
#Running instance - not persisted
|
|
class Runner(BaseModel):
|
|
id: UUID
|
|
strat_id: UUID
|
|
batch_id: Optional[str] = None
|
|
run_started: Optional[datetime] = None
|
|
run_mode: Mode
|
|
run_account: Account
|
|
run_symbol: Optional[str] = None
|
|
run_name: Optional[str] = None
|
|
run_note: Optional[str] = None
|
|
run_ilog_save: Optional[bool] = False
|
|
run_trade_count: Optional[int] = None
|
|
run_profit: Optional[float] = None
|
|
run_positions: Optional[int] = None
|
|
run_avgp: Optional[float] = None
|
|
run_strat_json: Optional[str] = None
|
|
run_stopped: Optional[datetime] = None
|
|
run_paused: Optional[datetime] = None
|
|
run_thread: Optional[object] = None
|
|
run_instance: Optional[object] = None
|
|
run_pause_ev: Optional[object] = None
|
|
run_stop_ev: Optional[object] = None
|
|
run_stratvars_toml: Optional[str] = None
|
|
|
|
|
|
class Bar(BaseModel):
|
|
"""Represents one bar/candlestick of aggregated trade data over a specified interval.
|
|
|
|
Attributes:
|
|
symbol (str): The ticker identifier for the security whose data forms the bar.
|
|
timestamp (datetime): The closing timestamp of the bar.
|
|
open (float): The opening price of the interval.
|
|
high (float): The high price during the interval.
|
|
low (float): The low price during the interval.
|
|
close (float): The closing price of the interval.
|
|
volume (float): The volume traded over the interval.
|
|
trade_count (Optional[float]): The number of trades that occurred.
|
|
vwap (Optional[float]): The volume weighted average price.
|
|
exchange (Optional[float]): The exchange the bar was formed on.
|
|
"""
|
|
|
|
symbol: str
|
|
timestamp: datetime
|
|
open: float
|
|
high: float
|
|
low: float
|
|
close: float
|
|
volume: float
|
|
trade_count: Optional[float] = 0
|
|
vwap: Optional[float] = 0
|
|
|
|
class Order(BaseModel):
|
|
id: UUID
|
|
submitted_at: datetime
|
|
filled_at: Optional[datetime] = None
|
|
canceled_at: Optional[datetime] = None
|
|
symbol: str
|
|
qty: int
|
|
status: OrderStatus
|
|
order_type: OrderType
|
|
filled_qty: Optional[int] = None
|
|
filled_avg_price: Optional[float] = None
|
|
side: OrderSide
|
|
limit_price: Optional[float] = None
|
|
|
|
#entita pro kazdy kompletni FILL, je navazana na prescribed_trade
|
|
class TradeUpdate(BaseModel):
|
|
event: Union[TradeEvent, str]
|
|
execution_id: Optional[UUID] = None
|
|
order: Order
|
|
timestamp: datetime
|
|
position_qty: Optional[float] = None
|
|
price: Optional[float] = None
|
|
qty: Optional[float] = None
|
|
value: Optional[float] = None
|
|
cash: Optional[float] = None
|
|
pos_avg_price: Optional[float] = None
|
|
profit: Optional[float] = None
|
|
profit_sum: Optional[float] = None
|
|
rel_profit: Optional[float] = None
|
|
rel_profit_cum: Optional[float] = None
|
|
signal_name: Optional[str] = None
|
|
prescribed_trade_id: Optional[str] = None
|
|
|
|
|
|
class RunArchiveChange(BaseModel):
|
|
id: UUID
|
|
note: str
|
|
|
|
#do budoucna pouzit SQLAlchemy
|
|
#Contains archive of running strategies (runner) - master
|
|
class RunArchive(BaseModel):
|
|
#unique id of algorun
|
|
id: UUID
|
|
#id of running strategy (stratin/runner)
|
|
strat_id: UUID
|
|
batch_id: Optional[str] = None
|
|
symbol: str
|
|
name: str
|
|
note: Optional[str] = None
|
|
started: datetime
|
|
stopped: Optional[datetime] = None
|
|
mode: Mode
|
|
account: Account
|
|
bt_from: Optional[datetime] = None
|
|
bt_to: Optional[datetime] = None
|
|
strat_json: Optional[str] = None
|
|
##bude decomiss, misto toho stratvars_toml
|
|
stratvars: Optional[dict] = None
|
|
settings: Optional[dict] = None
|
|
ilog_save: Optional[bool] = False
|
|
profit: float = 0
|
|
trade_count: int = 0
|
|
end_positions: int = 0
|
|
end_positions_avgp: float = 0
|
|
metrics: Union[dict, str] = None
|
|
stratvars_toml: Optional[str] = None
|
|
|
|
#For gui view master table
|
|
class RunArchiveView(BaseModel):
|
|
id: UUID
|
|
strat_id: UUID
|
|
batch_id: Optional[str] = None
|
|
symbol: str
|
|
name: str
|
|
note: Optional[str] = None
|
|
started: datetime
|
|
stopped: Optional[datetime] = None
|
|
mode: Mode
|
|
account: Account
|
|
bt_from: Optional[datetime] = None
|
|
bt_to: Optional[datetime] = None
|
|
ilog_save: Optional[bool] = False
|
|
profit: float = 0
|
|
trade_count: int = 0
|
|
end_positions: int = 0
|
|
end_positions_avgp: float = 0
|
|
metrics: Union[dict, str] = None
|
|
batch_profit: float = 0 # Total profit for the batch - now calculated during query
|
|
batch_count: int = 0 # Count of runs in the batch - now calculated during query
|
|
|
|
#same but with pagination
|
|
class RunArchiveViewPagination(BaseModel):
|
|
draw: int
|
|
recordsTotal: int
|
|
recordsFiltered: int
|
|
data: List[RunArchiveView]
|
|
|
|
#trida pro ukladani historie stoplossy do ext_data
|
|
class SLHistory(BaseModel):
|
|
id: Optional[UUID] = None
|
|
time: datetime
|
|
sl_val: float
|
|
|
|
#Contains archive of running strategies (runner) - detail data
|
|
class RunArchiveDetail(BaseModel):
|
|
id: UUID
|
|
name: str
|
|
bars: dict
|
|
#trades: Optional[dict]
|
|
indicators: List[dict]
|
|
statinds: dict
|
|
trades: List[TradeUpdate]
|
|
ext_data: Optional[dict] = None
|
|
|
|
|
|
class InstantIndicator(BaseModel):
|
|
name: str
|
|
toml: str
|
|
|
|
|