Skip to content

Commit

Permalink
feat: add skip_outdated toggle
Browse files Browse the repository at this point in the history
fix: fallback to default sequence config settings when reading config

fix: add sequence args to Sequence __str__
  • Loading branch information
loiccoyle committed Mar 27, 2024
1 parent 72cee58 commit 54efa67
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 14 deletions.
4 changes: 4 additions & 0 deletions tests/data/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
"volume": false
}
],
"sequence": {
"skip_outdated": true,
"skip_empty": true
},
"epd_model": "EPDbc",
"api_key": "SUPERSECRETKEY",
"flip": true
Expand Down
4 changes: 1 addition & 3 deletions tests/unit/test_ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ def setUpClass(cls):

def test_sequence_from_tt_config(self):
tt_config = config.TinytickerConfig.from_file(self.config_path)
sequence = ticker.Sequence.from_tinyticker_config(
tt_config, skip_empty=False, skip_outdated=False
)
sequence = ticker.Sequence.from_tinyticker_config(tt_config)
assert len(sequence.tickers) == len(tt_config.tickers)
assert sequence.skip_empty is False
assert sequence.skip_outdated is False
Expand Down
10 changes: 10 additions & 0 deletions tinyticker/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ class TickerConfig:
volume: bool = False


@dc.dataclass
class SequenceConfig:
skip_outdated: bool = True
skip_empty: bool = True


@dc.dataclass
class TinytickerConfig:
tickers: List[TickerConfig] = dc.field(default_factory=lambda: [TickerConfig()])
sequence: SequenceConfig = dc.field(default_factory=lambda: SequenceConfig())
epd_model: str = "EPD_v3"
api_key: Optional[str] = None
flip: bool = False
Expand All @@ -44,6 +51,9 @@ def from_json(cls, json_: Union[str, bytes, bytearray]) -> "TinytickerConfig":
data["tickers"] = [
TickerConfig(**ticker_data) for ticker_data in data["tickers"]
]
data["sequence"] = SequenceConfig(
**data.get("sequence", dc.asdict(SequenceConfig()))
)
return cls(**data)

def to_json(self) -> str:
Expand Down
20 changes: 10 additions & 10 deletions tinyticker/ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,11 @@ def __str__(self) -> str:

class Sequence:
@classmethod
def from_tinyticker_config(
cls, tt_config: TinytickerConfig, **kwargs
) -> "Sequence":
def from_tinyticker_config(cls, tt_config: TinytickerConfig) -> "Sequence":
"""Create a `Sequence` from a `TinytickerConfig`.
Args:
tt_config: `TinytickerConfig` from which to create the `Sequence`.
**kwargs: Paseed to the `Sequence.__init__` method.
Returns:
The `Sequence` instance.
Expand All @@ -367,7 +364,8 @@ def from_tinyticker_config(
)
for ticker in tt_config.tickers
],
**kwargs,
skip_empty=tt_config.sequence.skip_empty,
skip_outdated=tt_config.sequence.skip_outdated,
)

def __init__(
Expand All @@ -380,10 +378,9 @@ def __init__(
Args:
tickers: list of `Ticker` instances.
skip_empty: if the response doesn't contain any data, move on to the
next ticker.
skip_outdated: if the last candle of the response is too old, move on to the
next ticker. This typically happens when the stock market closes.
skip_empty: if the response doesn't contain any data, move on to the next ticker.
skip_outdated: if the last candle of the response is too old, move on to the next
ticker. This typically happens when the stock market closes.
"""
if len(tickers) == 0:
raise ValueError("No tickers provided.")
Expand Down Expand Up @@ -436,4 +433,7 @@ def start(self) -> Iterator[Tuple[Ticker, Response]]:
time.sleep(ticker.wait_time)

def __str__(self):
return "Sequence: \n" + "\n".join([ticker.__str__() for ticker in self.tickers])
return (
f"Sequence(skip_outdated={self.skip_outdated}, skip_empty={self.skip_empty}): \n"
+ "\n".join([ticker.__str__() for ticker in self.tickers])
)
9 changes: 8 additions & 1 deletion tinyticker/web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from flask import Flask, abort, redirect, render_template, request, send_from_directory

from .. import __version__
from ..config import PLOT_TYPES, TickerConfig, TinytickerConfig
from ..config import PLOT_TYPES, SequenceConfig, TickerConfig, TinytickerConfig
from ..paths import CONFIG_FILE, LOG_DIR
from ..ticker import INTERVAL_LOOKBACKS, INTERVAL_TIMEDELTAS, SYMBOL_TYPES
from ..utils import check_for_update
Expand Down Expand Up @@ -109,6 +109,12 @@ def config():
tickers["mav"] = request.args.getlist("mav", type=no_empty_int)
tickers["volume"] = request.args.getlist("volume", type=str_to_bool)

sequence = SequenceConfig(
skip_outdated=request.args.get("skip_outdated", False, type=bool),
# Note: currently not toggleable from the web app
skip_empty=request.args.get("skip_empty", True, type=bool),
)

# invert the ticker dict of list to list of dict and create ticker list
tickers = [
TickerConfig(**dict(zip(tickers, t))) for t in zip(*tickers.values())
Expand All @@ -118,6 +124,7 @@ def config():
flip=request.args.get("flip", default=False, type=bool),
epd_model=request.args.get("epd_model", "EPD_v3"),
tickers=tickers,
sequence=sequence,
)
LOGGER.debug(tt_config)
tt_config.to_file(config_file)
Expand Down
1 change: 1 addition & 0 deletions tinyticker/web/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ <h4>Tickers</h4>
</div>
</div>
<div class="uk-width-1-1 uk-margin">
<label class="uk-form-label" for="skip_outdated" uk-tooltip="Typically happens when the market is closed."><input class="uk-checkbox uk-margin-small-right" type="checkbox" id="skip_outdated" name="skip_outdated" {% if sequence.skip_outdated | default(True) %}checked{% endif %}>Skip tickers with oudated data</label>
<button type="submit" value="submit" class="uk-button uk-button-primary uk-width-expand">Apply</button>
</div>
</div>
Expand Down

0 comments on commit 54efa67

Please sign in to comment.