Move `Allocator` to module level, `OrderPane` over to pp mod
							parent
							
								
									6be6f25797
								
							
						
					
					
						commit
						58afe07a88
					
				| 
						 | 
					@ -633,29 +633,6 @@ def mk_fill_status_bar(
 | 
				
			||||||
    return hbox, bar
 | 
					    return hbox, bar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderPane(pydantic.BaseModel):
 | 
					 | 
				
			||||||
    '''Set of widgets plus an allocator model
 | 
					 | 
				
			||||||
    for configuring order entry sizes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    class Config:
 | 
					 | 
				
			||||||
        arbitrary_types_allowed = True
 | 
					 | 
				
			||||||
        underscore_attrs_are_private = False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # config for and underlying validation model
 | 
					 | 
				
			||||||
    form: FieldsForm
 | 
					 | 
				
			||||||
    model: pydantic.BaseModel
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # fill status + labels
 | 
					 | 
				
			||||||
    fill_status_bar: FillStatusBar
 | 
					 | 
				
			||||||
    step_label: QLabel
 | 
					 | 
				
			||||||
    pnl_label: QLabel
 | 
					 | 
				
			||||||
    limit_label: QLabel
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def config_ui_from_model(self) -> None:
 | 
					 | 
				
			||||||
        ...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def mk_order_pane_layout(
 | 
					def mk_order_pane_layout(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parent: QWidget,
 | 
					    parent: QWidget,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,6 @@ from enum import Enum
 | 
				
			||||||
from functools import partial
 | 
					from functools import partial
 | 
				
			||||||
from math import floor
 | 
					from math import floor
 | 
				
			||||||
# from pprint import pprint
 | 
					# from pprint import pprint
 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
from typing import Optional
 | 
					from typing import Optional
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +41,7 @@ from ..data._source import Symbol
 | 
				
			||||||
from ._label import Label
 | 
					from ._label import Label
 | 
				
			||||||
from ._lines import LevelLine, level_line
 | 
					from ._lines import LevelLine, level_line
 | 
				
			||||||
from ._style import _font
 | 
					from ._style import _font
 | 
				
			||||||
from ._forms import FieldsForm
 | 
					from ._forms import FieldsForm, FillStatusBar, QLabel
 | 
				
			||||||
from ..log import get_logger
 | 
					from ..log import get_logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,59 +64,36 @@ class Position(BaseModel):
 | 
				
			||||||
    fills: list[Status] = []
 | 
					    fills: list[Status] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mk_alloc(
 | 
					_size_units = bidict({
 | 
				
			||||||
 | 
					 | 
				
			||||||
    accounts: dict[str, Optional[str]] = {
 | 
					 | 
				
			||||||
        'paper': None,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
) -> Allocator:  # noqa
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    from ..brokers import config
 | 
					 | 
				
			||||||
    conf, path = config.load()
 | 
					 | 
				
			||||||
    section = conf.get('accounts')
 | 
					 | 
				
			||||||
    if section is None:
 | 
					 | 
				
			||||||
        log.warning('No accounts config found?')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for brokername, account_labels in section.items():
 | 
					 | 
				
			||||||
        for name, value in account_labels.items():
 | 
					 | 
				
			||||||
            accounts[f'{brokername}.{name}'] = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # lol we have to do this module patching bc ``pydantic``
 | 
					 | 
				
			||||||
    # needs types to exist at module level:
 | 
					 | 
				
			||||||
    # https://pydantic-docs.helpmanual.io/usage/postponed_annotations/
 | 
					 | 
				
			||||||
    mod = sys.modules[__name__]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    accounts = bidict(accounts)
 | 
					 | 
				
			||||||
    Account = mod.Account = Enum('Account', accounts)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    size_units = bidict({
 | 
					 | 
				
			||||||
    'currency': '$ size',
 | 
					    'currency': '$ size',
 | 
				
			||||||
    'units': '# units',
 | 
					    'units': '# units',
 | 
				
			||||||
        # 'percent_of_port': '% of port',  # TODO:
 | 
					    # TODO: but we'll need a `<brokermod>.get_accounts()` or something
 | 
				
			||||||
 | 
					    # 'percent_of_port': '% of port',
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
    SizeUnit = mod.SizeUnit = Enum(
 | 
					SizeUnit = Enum(
 | 
				
			||||||
    'SizeUnit',
 | 
					    'SizeUnit',
 | 
				
			||||||
        size_units,
 | 
					    _size_units,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Allocator(BaseModel):
 | 
					class Allocator(BaseModel):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Config:
 | 
					    class Config:
 | 
				
			||||||
        validate_assignment = True
 | 
					        validate_assignment = True
 | 
				
			||||||
        copy_on_model_validation = False
 | 
					        copy_on_model_validation = False
 | 
				
			||||||
        extra = 'allow'
 | 
					        extra = 'allow'
 | 
				
			||||||
 | 
					        # underscore_attrs_are_private = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        account: Account = None
 | 
					    account: Optional[str] = 'paper'
 | 
				
			||||||
        _accounts: dict[str, Optional[str]] = accounts
 | 
					    _accounts: bidict[str, Optional[str]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @validator('account', pre=True)
 | 
					    @validator('account', pre=True)
 | 
				
			||||||
        def set_account(cls, v):
 | 
					    def set_account(cls, v, values):
 | 
				
			||||||
        if v:
 | 
					        if v:
 | 
				
			||||||
                return cls._accounts[v]
 | 
					            return values['_accounts'][v]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_unit: SizeUnit = 'currency'
 | 
					    size_unit: SizeUnit = 'currency'
 | 
				
			||||||
        _size_units: dict[str, Optional[str]] = size_units
 | 
					    _size_units: dict[str, Optional[str]] = _size_units
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @validator('size_unit')
 | 
					    @validator('size_unit')
 | 
				
			||||||
    def lookup_key(cls, v):
 | 
					    def lookup_key(cls, v):
 | 
				
			||||||
| 
						 | 
					@ -226,14 +202,60 @@ def mk_alloc(
 | 
				
			||||||
        else:  # likely an alert
 | 
					        else:  # likely an alert
 | 
				
			||||||
            return {'size': 0}
 | 
					            return {'size': 0}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def mk_alloc(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    accounts: dict[str, Optional[str]] = {
 | 
				
			||||||
 | 
					        'paper': None,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					) -> Allocator:  # noqa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from ..brokers import config
 | 
				
			||||||
 | 
					    conf, path = config.load()
 | 
				
			||||||
 | 
					    section = conf.get('accounts')
 | 
				
			||||||
 | 
					    if section is None:
 | 
				
			||||||
 | 
					        log.warning('No accounts config found?')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for brokername, account_labels in section.items():
 | 
				
			||||||
 | 
					        for name, value in account_labels.items():
 | 
				
			||||||
 | 
					            accounts[f'{brokername}.{name}'] = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Allocator(
 | 
					    return Allocator(
 | 
				
			||||||
        account=None,
 | 
					        account=None,
 | 
				
			||||||
        size_unit=size_units['currency'],
 | 
					        _accounts=bidict(accounts),
 | 
				
			||||||
 | 
					        size_unit=_size_units['currency'],
 | 
				
			||||||
        size=5e3,
 | 
					        size=5e3,
 | 
				
			||||||
        slots=4,
 | 
					        slots=4,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OrderPane(BaseModel):
 | 
				
			||||||
 | 
					    '''Set of widgets plus an allocator model
 | 
				
			||||||
 | 
					    for configuring order entry sizes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    class Config:
 | 
				
			||||||
 | 
					        arbitrary_types_allowed = True
 | 
				
			||||||
 | 
					        # underscore_attrs_are_private = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # config for and underlying validation model
 | 
				
			||||||
 | 
					    form: FieldsForm
 | 
				
			||||||
 | 
					    model: BaseModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # fill status + labels
 | 
				
			||||||
 | 
					    fill_status_bar: FillStatusBar
 | 
				
			||||||
 | 
					    step_label: QLabel
 | 
				
			||||||
 | 
					    pnl_label: QLabel
 | 
				
			||||||
 | 
					    limit_label: QLabel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def config_ui_from_model(self) -> None:
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def transform_to(self, size_unit: str) -> None:
 | 
				
			||||||
 | 
					        ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PositionTracker:
 | 
					class PositionTracker:
 | 
				
			||||||
    '''Track and display a real-time position for a single symbol
 | 
					    '''Track and display a real-time position for a single symbol
 | 
				
			||||||
    on a chart.
 | 
					    on a chart.
 | 
				
			||||||
| 
						 | 
					@ -509,6 +531,7 @@ class PositionTracker:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return line
 | 
					        return line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # TODO: per account lines on a single (or very related) symbol
 | 
				
			||||||
    def update_line(
 | 
					    def update_line(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue