"Back load" exits, always abs the order size, `SettingsPane` is better name
parent
942cbc2743
commit
ee377e6d6b
|
@ -22,7 +22,7 @@ from __future__ import annotations
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from math import floor
|
from math import floor, ceil
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,24 +147,25 @@ class Allocator(BaseModel):
|
||||||
sym = self.symbol
|
sym = self.symbol
|
||||||
ld = sym.lot_size_digits
|
ld = sym.lot_size_digits
|
||||||
|
|
||||||
live_size = abs(live_pp.size)
|
live_size = live_pp.size
|
||||||
startup_size = abs(startup_pp.size)
|
abs_live_size = abs(live_size)
|
||||||
|
abs_startup_size = abs(startup_pp.size)
|
||||||
|
|
||||||
u_per_slot, currency_per_slot = self.step_sizes()
|
u_per_slot, currency_per_slot = self.step_sizes()
|
||||||
|
|
||||||
if self.size_unit == 'units':
|
if self.size_unit == 'units':
|
||||||
enter_step = u_per_slot
|
enter_step = u_per_slot
|
||||||
l_sub_pp = self.units_limit - live_size
|
l_sub_pp = self.units_limit - abs_live_size
|
||||||
|
|
||||||
elif self.size_unit == 'currency':
|
elif self.size_unit == 'currency':
|
||||||
live_cost_basis = live_size * live_pp.avg_price
|
live_cost_basis = abs_live_size * live_pp.avg_price
|
||||||
enter_step = currency_per_slot / price
|
enter_step = currency_per_slot / price
|
||||||
l_sub_pp = (self.currency_limit - live_cost_basis) / price
|
l_sub_pp = (self.currency_limit - live_cost_basis) / price
|
||||||
|
|
||||||
# an entry (adding-to or starting a pp)
|
# an entry (adding-to or starting a pp)
|
||||||
if (
|
if (
|
||||||
action == 'buy' and startup_size > 0 or
|
action == 'buy' and live_size > 0 or
|
||||||
action == 'sell' and startup_size < 0 or
|
action == 'sell' and live_size < 0 or
|
||||||
live_size == 0
|
live_size == 0
|
||||||
):
|
):
|
||||||
|
|
||||||
|
@ -172,30 +173,36 @@ class Allocator(BaseModel):
|
||||||
|
|
||||||
# an exit (removing-from or going to net-zero pp)
|
# an exit (removing-from or going to net-zero pp)
|
||||||
else:
|
else:
|
||||||
# always exit "at least" a unit-limit slot's worth of units
|
# when exiting a pp we always slot the position
|
||||||
# since higher-level per-slot-calcs can result in
|
# in the instrument's units, since doing so in a derived
|
||||||
# non-uniform exit sizes per price, port alloc, etc.
|
# size measure (eg. currency value, percent of port) would
|
||||||
exit_step = max(
|
# result in a mis-mapping of slots sizes in unit terms
|
||||||
startup_size / self.slots,
|
# (i.e. it would take *more* slots to exit at a profit and
|
||||||
enter_step,
|
# *less* slots to exit at a loss).
|
||||||
)
|
|
||||||
|
|
||||||
# exit at a slot size's worth of units or the remaining
|
slot_size = abs_startup_size / self.slots
|
||||||
# units left for the position to be net-zero, whichever
|
|
||||||
# is smaller
|
if (
|
||||||
order_size = min(
|
live_size < slot_size or
|
||||||
exit_step,
|
slot_size < live_size > 2*slot_size
|
||||||
live_size,
|
):
|
||||||
)
|
# the remaining pp is in between 0-2 slots
|
||||||
|
# so dump the whole position in this last exit
|
||||||
|
# therefore conducting so called "back loading"
|
||||||
|
# but **without** going past a net-zero pp.
|
||||||
|
order_size = abs_live_size
|
||||||
|
|
||||||
|
else:
|
||||||
|
order_size = slot_size
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'size': round(order_size, ndigits=ld),
|
'size': abs(round(order_size, ndigits=ld)),
|
||||||
'size_digits': ld
|
'size_digits': ld
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class OrderModePane:
|
class SettingsPane:
|
||||||
'''Composite set of widgets plus an allocator model for configuring
|
'''Composite set of widgets plus an allocator model for configuring
|
||||||
order entry sizes and position limits per tradable instrument.
|
order entry sizes and position limits per tradable instrument.
|
||||||
|
|
||||||
|
@ -379,7 +386,8 @@ class OrderModePane:
|
||||||
# TODO: what should we do for fractional slot pps?
|
# TODO: what should we do for fractional slot pps?
|
||||||
self.fill_bar.set_slots(
|
self.fill_bar.set_slots(
|
||||||
slots,
|
slots,
|
||||||
min(round(prop * slots), slots)
|
# min(round(prop * slots), slots)
|
||||||
|
min(ceil(prop * slots), slots)
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_level_change_update_next_order_info(
|
def on_level_change_update_next_order_info(
|
||||||
|
@ -471,6 +479,10 @@ 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.
|
||||||
|
|
||||||
|
Graphically composed of a level line and marker as well as labels
|
||||||
|
for indcating current position information. Updates are made to the
|
||||||
|
corresponding "settings pane" for the chart's "order mode" UX.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# inputs
|
# inputs
|
||||||
chart: 'ChartPlotWidget' # noqa
|
chart: 'ChartPlotWidget' # noqa
|
||||||
|
|
Loading…
Reference in New Issue