Skip to content

plotly ¤

BotPlotter ¤

BotPlotter(bot: LetTradeBot)

Bases: Plotter

Class help to plot bot result

Source code in lettrade/plot/bot.py
34
35
36
37
38
39
40
41
def __init__(self, bot: "LetTradeBot") -> None:
    self.bot = bot
    self.feeder = bot.feeder
    self.exchange = bot.exchange
    self.account = bot.account
    self.strategy = bot.strategy

    self.datas = self.feeder.datas

data property writable ¤

data: DataFeed

Get plotting main datafeed

Returns:

datas instance-attribute ¤

datas: list[DataFeed] = datas

All plotting datafeeds

jump ¤

jump(
    since: int | str | Timestamp | None = None,
    order_id: str | None = None,
    position_id: str | None = None,
    range: int = 300,
    name: str | None = None,
)

Jump to place on datefeed

Parameters:

  • since (int | str | Timestamp | None, default: None ) –

    Jump to index/datetime. Defaults to None.

  • order_id (str | None, default: None ) –

    Jump to order id. Defaults to None.

  • position_id (str | None, default: None ) –

    Jump to position id. Defaults to None.

  • range (int, default: 300 ) –

    number of candle plot. Defaults to 300.

  • name (str | None, default: None ) –

    description. Defaults to None.

Raises:

Source code in lettrade/plot/bot.py
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def jump(
    self,
    since: int | str | pd.Timestamp | None = None,
    order_id: str | None = None,
    position_id: str | None = None,
    range: int = 300,
    name: str | None = None,
):
    """Jump to place on datefeed

    Args:
        since (int | str | pd.Timestamp | None, optional): Jump to index/datetime. Defaults to None.
        order_id (str | None, optional): Jump to order id. Defaults to None.
        position_id (str | None, optional): Jump to position id. Defaults to None.
        range (int, optional): number of candle plot. Defaults to 300.
        name (str | None, optional): _description_. Defaults to None.

    Raises:
        RuntimeError: _description_
    """
    if self._datas_stored is None:
        self._datas_stored = self.datas.copy()

    if since is None:
        if order_id is not None:  # Jump to order id
            if not isinstance(order_id, str):
                order_id = str(order_id)

            if order_id in self.exchange.orders:
                order = self.exchange.orders[order_id]
            elif order_id in self.exchange.history_orders:
                order = self.exchange.history_orders[order_id]
            else:
                raise RuntimeError(f"Order id {order_id} not found")

            loc = self._data_stored.l.index.get_loc(order.placed_at)
            since = loc - int(range / 2)

        elif position_id is not None:  # Jump to position id
            if not isinstance(position_id, str):
                position_id = str(position_id)

            if position_id in self.exchange.positions:
                position = self.exchange.positions[position_id]
            elif position_id in self.exchange.history_positions:
                position = self.exchange.history_positions[position_id]
            else:
                raise RuntimeError(f"Position id {position_id} not found")

            loc = self._data_stored.l.index.get_loc(position.entry_at)
            since = loc - int(range / 2)
        else:  # Reset
            self.jump_reset()
            return

    elif isinstance(since, str):  # Parse string to pd.Timestamp, then since=index
        since = pd.to_datetime(since, utc=True)
        since = self._data_stored.l.index.get_loc(since)
    elif isinstance(since, pd.Timestamp):  # Get index of Timestamp
        since = self._data_stored.l.index.get_loc(since)

    if name is None:
        name = self._data_stored.name

    # Since min at pointer_start
    if since < self._data_stored.l.pointer_start:
        since = self._data_stored.l.pointer_start
    # Since max at pointer_stop
    if since > self._data_stored.l.pointer_stop - range:
        since = self._data_stored.l.pointer_stop - range

    # Jump
    jump_start_dt = None
    jump_stop_dt = None
    for i, data in enumerate(self._datas_stored):
        if i == 0:
            self.datas[i] = data.__class__(
                data=data.l[since : since + range],
                name=data.name,
                timeframe=data.timeframe,
            )
            jump_start_dt = self.data.index[0]
            jump_stop_dt = self.data.index[-1]
        else:
            self.datas[i] = data.__class__(
                data=data.loc[
                    (data.index >= jump_start_dt) & (data.index <= jump_stop_dt)
                ],
                name=data.name,
                timeframe=data.timeframe,
            )

        if hasattr(data, DATAFRAME_PLOTTERS_NAME):
            object.__setattr__(
                self.datas[i],
                DATAFRAME_PLOTTERS_NAME,
                getattr(data, DATAFRAME_PLOTTERS_NAME),
            )

    # Reload data
    self.load()

jump_reset ¤

jump_reset() -> bool

Reset jump datafeeds back to bot datafeeds

Source code in lettrade/plot/bot.py
162
163
164
165
166
167
168
def jump_reset(self) -> bool:
    """Reset jump datafeeds back to bot datafeeds"""
    if not self._datas_stored or self.data is self._data_stored:
        return False

    self.datas = self._datas_stored.copy()
    return True

load abstractmethod ¤

load()

Load plot config from Strategy.plot() and setup candlestick/equity

Source code in lettrade/plot/plot.py
 9
10
11
@abstractmethod
def load(self):
    """Load plot config from `Strategy.plot()` and setup candlestick/equity"""

plot abstractmethod ¤

plot(**kwargs)

Plot equity, orders, and positions then show

Source code in lettrade/plot/plot.py
13
14
15
@abstractmethod
def plot(self, **kwargs):
    """Plot `equity`, `orders`, and `positions` then show"""

stop abstractmethod ¤

stop()

stop plotter

Source code in lettrade/plot/plot.py
17
18
19
@abstractmethod
def stop(self):
    """stop plotter"""

DataFeed ¤

DataFeed(
    *args,
    name: str,
    timeframe: TimeFrame,
    meta: dict | None = None,
    **kwargs
)

Bases: DataFrame

Data for Strategy. A implement of pandas.DataFrame

Parameters:

  • name (str) –

    description

  • timeframe (TimeFrame) –

    description

  • meta (dict | None, default: None ) –

    description. Defaults to None.

Raises:

Source code in lettrade/data/data.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def __init__(
    self,
    *args,
    name: str,
    timeframe: TimeFrame,
    meta: dict | None = None,
    **kwargs,
) -> None:
    """_summary_

    Args:
        name (str): _description_
        timeframe (TimeFrame): _description_
        meta (dict | None, optional): _description_. Defaults to None.

    Raises:
        RuntimeError: _description_
    """
    # Validate
    if not _data_name_pattern.match(name):
        raise RuntimeError(
            f"Bot name {name} is not valid format {_data_name_pattern}"
        )

    # Init
    super().__init__(*args, **kwargs)
    self._init_index()

    # Metadata
    if not meta:
        meta = dict()
    meta["name"] = name
    meta["timeframe"] = TimeFrame(timeframe)
    self.attrs = {"lt_meta": meta}

    # LetWrapper
    object.__setattr__(self, "l", LetDataFeedWrapper(self))

i property ¤

Alias to lettrade.indicator and using in DataFeed by call: DataFeed.i.indicator_name()

is_main property ¤

is_main: bool

Property to check DataFeed is main DataFeed or not

l instance-attribute ¤

LetTrade DataFeed wrapper using to manage index pointer of DataFeed

meta property ¤

meta: dict

Property to get metadata of DataFeed

name property ¤

name: str

Property to get name of DataFeed

now property ¤

now: Timestamp

Property to get current index value of DataFeed

timeframe property ¤

timeframe: TimeFrame

Property to get timeframe of DataFeed

bar ¤

bar(i: int = 0) -> Timestamp

Get current pd.Timestamp value of DataFeed

Parameters:

  • i (int, default: 0 ) –

    Index. Defaults to 0.

Returns:

  • Timestamp

    pd.Timestamp: description

Source code in lettrade/data/data.py
108
109
110
111
112
113
114
115
116
117
def bar(self, i: int = 0) -> pd.Timestamp:
    """Get current pd.Timestamp value of DataFeed

    Args:
        i (int, optional): Index. Defaults to 0.

    Returns:
        pd.Timestamp: _description_
    """
    return self.l.index[i]

copy ¤

copy(deep: bool = False, **kwargs) -> DataFeed

summary

Parameters:

  • deep (bool, default: False ) –

    description. Defaults to False.

Returns:

Source code in lettrade/data/data.py
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def copy(self, deep: bool = False, **kwargs) -> "DataFeed":
    """_summary_

    Args:
        deep (bool, optional): _description_. Defaults to False.

    Returns:
        DataFeed: _description_
    """
    df = super().copy(deep=deep)
    df = self.__class__(
        data=df,
        name=self.name,
        timeframe=self.timeframe,
        meta=self.meta.copy(),
        **kwargs,
    )
    return df

drop ¤

drop(
    *args,
    since: int | str | Timestamp | None = None,
    to: int | str | Timestamp | None = None,
    **kwargs
) -> None

summary

Parameters:

  • since (int | str | Timestamp | None, default: None ) –

    description. Defaults to None.

  • to (int | str | Timestamp | None, default: None ) –

    description. Defaults to None.

Raises:

Source code in lettrade/data/data.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
def drop(
    self,
    *args,
    since: int | str | pd.Timestamp | None = None,
    to: int | str | pd.Timestamp | None = None,
    **kwargs,
) -> None:
    """_summary_

    Args:
        since (int | str | pd.Timestamp | None, optional): _description_. Defaults to None.
        to (int | str | pd.Timestamp | None, optional): _description_. Defaults to None.

    Raises:
        RuntimeError: _description_
    """
    if since is None and to is None:
        super().drop(*args, **kwargs)
        return

    condiction = None

    # Since
    if since is not None:
        if isinstance(since, int):
            loc = self.l.index[since]
        elif isinstance(since, str):
            loc = pd.to_datetime(since, utc=True)
        elif isinstance(since, pd.Timestamp):
            loc = since
        else:
            raise RuntimeError(f"DataFeed.drop since {since} is invalid")
        condiction = self.index < loc

    # To
    if to is not None:
        if isinstance(to, int):
            loc = self.l.index[to]
        elif isinstance(to, str):
            loc = pd.to_datetime(to, utc=True)
        elif isinstance(to, pd.Timestamp):
            loc = to
        else:
            raise RuntimeError(f"DataFeed.drop to {to} is invalid")

        if condiction is None:
            condiction = self.index > loc
        else:
            condiction = condiction | (self.index > loc)

    index = self[condiction].index
    super().drop(index=index, inplace=True)
    self.l.reset()

    if __debug__:
        logger.debug("BackTestDataFeed %s dropped %s rows", self.name, len(index))

next ¤

next(size=1)

Load next data

Parameters:

  • size (int, default: 1 ) –

    description. Defaults to 1.

Source code in lettrade/data/data.py
100
101
102
103
104
105
106
def next(self, size=1):
    """Load next data

    Args:
        size (int, optional): _description_. Defaults to 1.
    """
    self.l.next(size)

push ¤

push(
    rows: list[list[int | float]],
    unit: str | None = None,
    utc: bool = True,
    **kwargs
)

Push new rows to DataFeed

Parameters:

  • rows (list[list[int | float]]) –

    list of rows [["timestamp", "open price", "high price"...]]

  • unit (str | None, default: None ) –

    pandas.Timestamp parsing unit. Defaults to None.

  • utc (bool, default: True ) –

    description. Defaults to True.

Source code in lettrade/data/data.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def push(
    self,
    rows: list[list[int | float]],
    unit: str | None = None,
    utc: bool = True,
    **kwargs,
):
    """Push new rows to DataFeed

    Args:
        rows (list[list[int | float]]): list of rows `[["timestamp", "open price", "high price"...]]`
        unit (str | None, optional): pandas.Timestamp parsing unit. Defaults to None.
        utc (bool, optional): _description_. Defaults to True.
    """
    for row in rows:
        dt = pd.to_datetime(row[0], unit=unit, utc=utc, **kwargs)
        self.at[
            dt,
            (
                "open",
                "high",
                "low",
                "close",
                "volume",
            ),
        ] = (
            row[1],  # open
            row[2],  # high
            row[3],  # low
            row[4],  # close
            row[5],  # volume
        )

    if __debug__:
        logger.debug("[%s] Update bar: \n%s", self.name, self.tail(len(rows)))

PlotColor ¤

Bases: str, Enum

Enum plot color

AMBER class-attribute instance-attribute ¤

AMBER = '#fa0'

BLUE class-attribute instance-attribute ¤

BLUE = '#4287ff'

CYAN class-attribute instance-attribute ¤

CYAN = '#00bad6'

DEEP_ORANGE class-attribute instance-attribute ¤

DEEP_ORANGE = '#ff6e42'

DEEP_PURPLE class-attribute instance-attribute ¤

DEEP_PURPLE = '#7c4dff'

GREEN class-attribute instance-attribute ¤

GREEN = '#00c753'

INDIGO class-attribute instance-attribute ¤

INDIGO = '#526cfe'

LIGHT_BLUE class-attribute instance-attribute ¤

LIGHT_BLUE = '#0091eb'

LIGHT_GREEN class-attribute instance-attribute ¤

LIGHT_GREEN = '#63de17'

LIGHT_PINK class-attribute instance-attribute ¤

LIGHT_PINK = '#f06292'

LIGHT_RED class-attribute instance-attribute ¤

LIGHT_RED = '#e6695b'

LIGHT_YELLOW class-attribute instance-attribute ¤

LIGHT_YELLOW = '#fff176'

LIME class-attribute instance-attribute ¤

LIME = '#b0eb00'

ORANGE class-attribute instance-attribute ¤

ORANGE = '#ff9100'

PINK class-attribute instance-attribute ¤

PINK = '#f50056'

PURPLE class-attribute instance-attribute ¤

PURPLE = '#df41fb'

RED class-attribute instance-attribute ¤

RED = '#ff1947'

TEAL class-attribute instance-attribute ¤

TEAL = '#00bda4'

YELLOW class-attribute instance-attribute ¤

YELLOW = '#ffd500'

PlotlyBotPlotter ¤

PlotlyBotPlotter(bot: LetTradeBot)

Bases: BotPlotter

Class help to plot lettrade

Source code in lettrade/plot/bot.py
34
35
36
37
38
39
40
41
def __init__(self, bot: "LetTradeBot") -> None:
    self.bot = bot
    self.feeder = bot.feeder
    self.exchange = bot.exchange
    self.account = bot.account
    self.strategy = bot.strategy

    self.datas = self.feeder.datas

data property writable ¤

data: DataFeed

Get plotting main datafeed

Returns:

datas instance-attribute ¤

datas: list[DataFeed] = datas

All plotting datafeeds

jump ¤

jump(
    since: int | str | Timestamp | None = None,
    order_id: str | None = None,
    position_id: str | None = None,
    range: int = 300,
    name: str | None = None,
)

Jump to place on datefeed

Parameters:

  • since (int | str | Timestamp | None, default: None ) –

    Jump to index/datetime. Defaults to None.

  • order_id (str | None, default: None ) –

    Jump to order id. Defaults to None.

  • position_id (str | None, default: None ) –

    Jump to position id. Defaults to None.

  • range (int, default: 300 ) –

    number of candle plot. Defaults to 300.

  • name (str | None, default: None ) –

    description. Defaults to None.

Raises:

Source code in lettrade/plot/bot.py
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def jump(
    self,
    since: int | str | pd.Timestamp | None = None,
    order_id: str | None = None,
    position_id: str | None = None,
    range: int = 300,
    name: str | None = None,
):
    """Jump to place on datefeed

    Args:
        since (int | str | pd.Timestamp | None, optional): Jump to index/datetime. Defaults to None.
        order_id (str | None, optional): Jump to order id. Defaults to None.
        position_id (str | None, optional): Jump to position id. Defaults to None.
        range (int, optional): number of candle plot. Defaults to 300.
        name (str | None, optional): _description_. Defaults to None.

    Raises:
        RuntimeError: _description_
    """
    if self._datas_stored is None:
        self._datas_stored = self.datas.copy()

    if since is None:
        if order_id is not None:  # Jump to order id
            if not isinstance(order_id, str):
                order_id = str(order_id)

            if order_id in self.exchange.orders:
                order = self.exchange.orders[order_id]
            elif order_id in self.exchange.history_orders:
                order = self.exchange.history_orders[order_id]
            else:
                raise RuntimeError(f"Order id {order_id} not found")

            loc = self._data_stored.l.index.get_loc(order.placed_at)
            since = loc - int(range / 2)

        elif position_id is not None:  # Jump to position id
            if not isinstance(position_id, str):
                position_id = str(position_id)

            if position_id in self.exchange.positions:
                position = self.exchange.positions[position_id]
            elif position_id in self.exchange.history_positions:
                position = self.exchange.history_positions[position_id]
            else:
                raise RuntimeError(f"Position id {position_id} not found")

            loc = self._data_stored.l.index.get_loc(position.entry_at)
            since = loc - int(range / 2)
        else:  # Reset
            self.jump_reset()
            return

    elif isinstance(since, str):  # Parse string to pd.Timestamp, then since=index
        since = pd.to_datetime(since, utc=True)
        since = self._data_stored.l.index.get_loc(since)
    elif isinstance(since, pd.Timestamp):  # Get index of Timestamp
        since = self._data_stored.l.index.get_loc(since)

    if name is None:
        name = self._data_stored.name

    # Since min at pointer_start
    if since < self._data_stored.l.pointer_start:
        since = self._data_stored.l.pointer_start
    # Since max at pointer_stop
    if since > self._data_stored.l.pointer_stop - range:
        since = self._data_stored.l.pointer_stop - range

    # Jump
    jump_start_dt = None
    jump_stop_dt = None
    for i, data in enumerate(self._datas_stored):
        if i == 0:
            self.datas[i] = data.__class__(
                data=data.l[since : since + range],
                name=data.name,
                timeframe=data.timeframe,
            )
            jump_start_dt = self.data.index[0]
            jump_stop_dt = self.data.index[-1]
        else:
            self.datas[i] = data.__class__(
                data=data.loc[
                    (data.index >= jump_start_dt) & (data.index <= jump_stop_dt)
                ],
                name=data.name,
                timeframe=data.timeframe,
            )

        if hasattr(data, DATAFRAME_PLOTTERS_NAME):
            object.__setattr__(
                self.datas[i],
                DATAFRAME_PLOTTERS_NAME,
                getattr(data, DATAFRAME_PLOTTERS_NAME),
            )

    # Reload data
    self.load()

jump_reset ¤

jump_reset() -> bool

Reset jump datafeeds back to bot datafeeds

Source code in lettrade/plot/bot.py
162
163
164
165
166
167
168
def jump_reset(self) -> bool:
    """Reset jump datafeeds back to bot datafeeds"""
    if not self._datas_stored or self.data is self._data_stored:
        return False

    self.datas = self._datas_stored.copy()
    return True

load ¤

load()

Load plot config from Strategy.plot() and setup candlestick/equity

Source code in lettrade/plot/plotly/plotly.py
593
594
595
596
597
598
599
600
601
602
603
604
605
def load(self):
    """Load plot config from `Strategy.plot()` and setup candlestick/equity"""

    config = self._config_default()
    config = self._config_strategy(config)
    config = self._config_standard(config)

    params: dict = config.setdefault("params", dict())
    self.figure = make_subplots(**params)

    self._plot_config(config)

    self.figure.update_layout(**config["layout"])

plot ¤

plot(jump: dict | None = None, **kwargs)

Plotly show figure

Parameters:

  • jump (dict | None, default: None ) –

    description. Defaults to None.

Source code in lettrade/plot/plotly/plotly.py
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
def plot(self, jump: dict | None = None, **kwargs):
    """Plotly show figure

    Args:
        jump (dict | None, optional): _description_. Defaults to None.
    """
    if jump is not None:
        self.jump(**jump)
    elif self.figure is None:
        self.load()
    else:
        if self.jump_reset():
            self.load()

    params = dict(layout_xaxis_rangeslider_visible=False)
    params.update(**kwargs)
    self.figure.update(**params)

    self.figure.show()

stop ¤

stop()

stop plotter

Source code in lettrade/plot/plotly/plotly.py
16
17
def stop(self):
    """stop plotter"""

plot_bollinger_bands ¤

plot_bollinger_bands(
    dataframe: DataFrame,
    upper: str | None = "upper",
    basis: str | None = "basis",
    lower: str | None = "lower",
    width: int = 1,
    upper_color: str = "#33BDFF",
    basis_color: str = "#D105F5",
    lower_color: str = "#33BDFF",
    filter: Series | None = None,
) -> dict

summary

Parameters:

  • dataframe (DataFrame) –

    description

  • upper (str, default: 'upper' ) –

    Column name. None mean skip plot. Defaults to "upper".

  • basis (str, default: 'basis' ) –

    Column name. None mean skip plot. Defaults to "basis".

  • lower (str, default: 'lower' ) –

    Column name. None mean skip plot. Defaults to "lower".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • upper_color (str, default: '#33BDFF' ) –

    Color code. Defaults to "#33BDFF".

  • lower_color (str, default: '#33BDFF' ) –

    Color code. Defaults to "#33BDFF".

  • basis_color (str, default: '#D105F5' ) –

    Color code. Defaults to "#D105F5".

  • filter (Series | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
def plot_bollinger_bands(
    dataframe: pd.DataFrame,
    upper: str | None = "upper",
    basis: str | None = "basis",
    lower: str | None = "lower",
    width: int = 1,
    upper_color: str = "#33BDFF",
    basis_color: str = "#D105F5",
    lower_color: str = "#33BDFF",
    filter: pd.Series | None = None,
) -> dict:
    """_summary_

    Args:
        dataframe (pd.DataFrame): _description_
        upper (str, optional): Column name. `None` mean skip plot. Defaults to "upper".
        basis (str, optional): Column name. `None` mean skip plot. Defaults to "basis".
        lower (str, optional): Column name. `None` mean skip plot. Defaults to "lower".
        width (int, optional): _description_. Defaults to 1.
        upper_color (str, optional): Color code. Defaults to "#33BDFF".
        lower_color (str, optional): Color code. Defaults to "#33BDFF".
        basis_color (str, optional): Color code. Defaults to "#D105F5".
        filter (pd.Series | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """
    if filter is not None:
        df_name = dataframe.name
        dataframe = dataframe.loc[filter]
        object.__setattr__(dataframe, "name", df_name)

    items = []

    if upper is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[upper],
                name=upper,
                mode="lines",
                line=dict(color=upper_color, width=width),
            )
        )
    if basis is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[basis],
                name=basis,
                mode="lines",
                line=dict(color=basis_color, width=width),
            )
        )
    if lower is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[lower],
                name=lower,
                mode="lines",
                line=dict(color=lower_color, width=width),
            )
        )
    return {f"{dataframe.name}": dict(items=items)}

plot_candlestick ¤

plot_candlestick(
    dataframe: DataFrame,
    name: str = "Candlestick",
    width: int = 1,
    increasing_line_color="#26c6da",
    decreasing_line_color="#ab47bc",
    row: int = 1,
    col: int = 1,
    filter: Series | None = None,
    **kwargs
) -> dict

summary

Parameters:

  • dataframe (DataFrame) –

    description

  • name (str, default: 'Candlestick' ) –

    description. Defaults to "Candlestick".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • increasing_line_color (str, default: '#26c6da' ) –

    description. Defaults to "#26c6da".

  • decreasing_line_color (str, default: '#ab47bc' ) –

    description. Defaults to "#ab47bc".

  • row (int, default: 1 ) –

    description. Defaults to 1.

  • col (int, default: 1 ) –

    description. Defaults to 1.

  • filter (Series | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
def plot_candlestick(
    dataframe: pd.DataFrame,
    name: str = "Candlestick",
    width: int = 1,
    increasing_line_color="#26c6da",
    decreasing_line_color="#ab47bc",
    row: int = 1,
    col: int = 1,
    filter: pd.Series | None = None,
    **kwargs,
) -> dict:
    """_summary_

    Args:
        dataframe (pd.DataFrame): _description_
        name (str, optional): _description_. Defaults to "Candlestick".
        width (int, optional): _description_. Defaults to 1.
        increasing_line_color (str, optional): _description_. Defaults to "#26c6da".
        decreasing_line_color (str, optional): _description_. Defaults to "#ab47bc".
        row (int, optional): _description_. Defaults to 1.
        col (int, optional): _description_. Defaults to 1.
        filter (pd.Series | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """
    if filter is not None:
        df_name = dataframe.name
        dataframe = dataframe.loc[filter]
        object.__setattr__(dataframe, "name", df_name)

    config = dict(
        items=[
            dict(
                type="candlestick",
                x=dataframe.index,
                open=dataframe["open"],
                high=dataframe["high"],
                low=dataframe["low"],
                close=dataframe["close"],
                name=name,
                line=dict(width=width),
                increasing_line_color=increasing_line_color,
                decreasing_line_color=decreasing_line_color,
                hoverinfo="text",
                hovertext=name,
                row=row,
                col=col,
                **kwargs,
            ),
        ]
    )

    return {f"{dataframe.name}": config}

plot_ichimoku ¤

plot_ichimoku(
    dataframe: DataFrame,
    tenkan_sen="tenkan_sen",
    kijun_sen="kijun_sen",
    senkou_span_a="senkou_span_a",
    senkou_span_b="senkou_span_b",
    chikou_span="chikou_span",
    width=1,
    tenkan_sen_color="#33BDFF",
    kijun_sen_color="#D105F5",
    senkou_span_a_color="#228B22",
    senkou_span_b_color="#FF3342",
    chikou_span_color="#F1F316",
    filter: Series | None = None,
) -> dict

summary

Parameters:

  • dataframe (DataFrame) –

    description

  • tenkan_sen (str, default: 'tenkan_sen' ) –

    description. Defaults to "tenkan_sen".

  • kijun_sen (str, default: 'kijun_sen' ) –

    description. Defaults to "kijun_sen".

  • senkou_span_a (str, default: 'senkou_span_a' ) –

    description. Defaults to "senkou_span_a".

  • senkou_span_b (str, default: 'senkou_span_b' ) –

    description. Defaults to "senkou_span_b".

  • chikou_span (str, default: 'chikou_span' ) –

    description. Defaults to "chikou_span".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • tenkan_sen_color (str, default: '#33BDFF' ) –

    description. Defaults to "#33BDFF".

  • kijun_sen_color (str, default: '#D105F5' ) –

    description. Defaults to "#D105F5".

  • senkou_span_a_color (str, default: '#228B22' ) –

    description. Defaults to "#228B22".

  • senkou_span_b_color (str, default: '#FF3342' ) –

    description. Defaults to "#FF3342".

  • chikou_span_color (str, default: '#F1F316' ) –

    description. Defaults to "#F1F316".

  • filter (Series | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
def plot_ichimoku(
    dataframe: pd.DataFrame,
    tenkan_sen="tenkan_sen",
    kijun_sen="kijun_sen",
    senkou_span_a="senkou_span_a",
    senkou_span_b="senkou_span_b",
    chikou_span="chikou_span",
    width=1,
    tenkan_sen_color="#33BDFF",
    kijun_sen_color="#D105F5",
    senkou_span_a_color="#228B22",
    senkou_span_b_color="#FF3342",
    chikou_span_color="#F1F316",
    filter: pd.Series | None = None,
) -> dict:
    """_summary_

    Args:
        dataframe (pd.DataFrame): _description_
        tenkan_sen (str, optional): _description_. Defaults to "tenkan_sen".
        kijun_sen (str, optional): _description_. Defaults to "kijun_sen".
        senkou_span_a (str, optional): _description_. Defaults to "senkou_span_a".
        senkou_span_b (str, optional): _description_. Defaults to "senkou_span_b".
        chikou_span (str, optional): _description_. Defaults to "chikou_span".
        width (int, optional): _description_. Defaults to 1.
        tenkan_sen_color (str, optional): _description_. Defaults to "#33BDFF".
        kijun_sen_color (str, optional): _description_. Defaults to "#D105F5".
        senkou_span_a_color (str, optional): _description_. Defaults to "#228B22".
        senkou_span_b_color (str, optional): _description_. Defaults to "#FF3342".
        chikou_span_color (str, optional): _description_. Defaults to "#F1F316".
        filter (pd.Series | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """
    if filter is not None:
        df_name = dataframe.name
        dataframe = dataframe.loc[filter]
        object.__setattr__(dataframe, "name", df_name)

    items = []

    if tenkan_sen is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[tenkan_sen],
                name=tenkan_sen,
                mode="lines",
                line=dict(color=tenkan_sen_color, width=width),
            )
        )
    if kijun_sen is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[kijun_sen],
                name=kijun_sen,
                mode="lines",
                line=dict(color=kijun_sen_color, width=width),
            )
        )
    if senkou_span_a is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[senkou_span_a],
                name=senkou_span_a,
                mode="lines",
                line=dict(color=senkou_span_a_color, width=width),
            )
        )
    if senkou_span_b is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[senkou_span_b],
                name=senkou_span_b,
                mode="lines",
                fill="tonexty",
                line=dict(color=senkou_span_b_color, width=width),
            )
        )
    if chikou_span is not None:
        items.append(
            dict(
                type="scatter",
                x=dataframe.index,
                y=dataframe[chikou_span],
                name=chikou_span,
                mode="lines",
                line=dict(color=chikou_span_color, width=width),
            )
        )

    return {f"{dataframe.name}": dict(items=items)}

plot_line ¤

plot_line(
    series: Series | str,
    color: str = "#ffee58",
    width: int = 1,
    name: str | None = None,
    mode: str = "lines",
    fullfill: bool = False,
    dataframe: DataFrame | None = None,
    filter: Series | None = None,
    **kwargs
) -> dict

summary

Parameters:

  • series (Series | str) –

    description

  • color (str, default: '#ffee58' ) –

    description. Defaults to "#ffee58".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • name (str | None, default: None ) –

    description. Defaults to None.

  • mode (str, default: 'lines' ) –

    description. Defaults to "lines".

  • fullfill (bool, default: False ) –

    description. Defaults to False.

  • dataframe (DataFrame | None, default: None ) –

    description. Defaults to None.

  • filter (Series | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
def plot_line(
    series: pd.Series | str,
    color: str = "#ffee58",
    width: int = 1,
    name: str | None = None,
    mode: str = "lines",
    fullfill: bool = False,
    dataframe: pd.DataFrame | None = None,
    filter: pd.Series | None = None,
    **kwargs,
) -> dict:
    """_summary_

    Args:
        series (pd.Series | str): _description_
        color (str, optional): _description_. Defaults to "#ffee58".
        width (int, optional): _description_. Defaults to 1.
        name (str | None, optional): _description_. Defaults to None.
        mode (str, optional): _description_. Defaults to "lines".
        fullfill (bool, optional): _description_. Defaults to False.
        dataframe (pd.DataFrame | None, optional): _description_. Defaults to None.
        filter (pd.Series | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """
    if isinstance(series, str):
        series = dataframe[series]

    if filter is not None:
        series = series.loc[filter]

    config = dict(
        items=[
            dict(
                type="scatter",
                x=series.index,
                y=series,
                line=dict(color=color, width=width),
                name=name or series.name,
                mode=mode,
                fullfill=fullfill,
                **kwargs,
            )
        ]
    )
    if dataframe is None:
        return config

    return {f"{dataframe.name}": config}

plot_lines ¤

plot_lines(
    *serieses: list[Series | str],
    color: str = "#ffee58",
    width: int = 1,
    name: str | None = None,
    mode: str = "lines",
    fullfill: bool = False,
    dataframe: DataFrame | None = None,
    **kwargs
) -> dict

summary

Parameters:

  • color (str, default: '#ffee58' ) –

    description. Defaults to "#ffee58".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • name (str | None, default: None ) –

    description. Defaults to None.

  • mode (str, default: 'lines' ) –

    description. Defaults to "lines".

  • fullfill (bool, default: False ) –

    description. Defaults to False.

  • dataframe (DataFrame | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
def plot_lines(
    *serieses: list[pd.Series | str],
    color: str = "#ffee58",
    width: int = 1,
    name: str | None = None,
    mode: str = "lines",
    fullfill: bool = False,
    dataframe: pd.DataFrame | None = None,
    **kwargs,
) -> dict:
    """_summary_

    Args:
        color (str, optional): _description_. Defaults to "#ffee58".
        width (int, optional): _description_. Defaults to 1.
        name (str | None, optional): _description_. Defaults to None.
        mode (str, optional): _description_. Defaults to "lines".
        fullfill (bool, optional): _description_. Defaults to False.
        dataframe (pd.DataFrame | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """
    result = {}
    for series in serieses:
        plot_merge(
            result,
            plot_line(
                series=series,
                color=color,
                width=width,
                name=name,
                mode=mode,
                fullfill=fullfill,
                dataframe=dataframe,
                **kwargs,
            ),
        )
    return result

plot_mark ¤

plot_mark(
    series: Series | str,
    color: str = "#ffee58",
    width: int = 1,
    mode: str = "markers",
    name: str | None = None,
    fullfill: bool = False,
    dataframe: DataFrame | None = None,
    filter: Series | None = None,
    **kwargs
) -> dict

summary

Parameters:

  • series (Series | str) –

    description

  • color (str, default: '#ffee58' ) –

    description. Defaults to "#ffee58".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • mode (str, default: 'markers' ) –

    description. Defaults to "markers".

  • name (str | None, default: None ) –

    description. Defaults to None.

  • fullfill (bool, default: False ) –

    description. Defaults to False.

  • dataframe (DataFrame | None, default: None ) –

    description. Defaults to None.

  • filter (Series | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
def plot_mark(
    series: pd.Series | str,
    color: str = "#ffee58",
    width: int = 1,
    mode: str = "markers",
    name: str | None = None,
    fullfill: bool = False,
    dataframe: pd.DataFrame | None = None,
    filter: pd.Series | None = None,
    **kwargs,
) -> dict:
    """_summary_

    Args:
        series (pd.Series | str): _description_
        color (str, optional): _description_. Defaults to "#ffee58".
        width (int, optional): _description_. Defaults to 1.
        mode (str, optional): _description_. Defaults to "markers".
        name (str | None, optional): _description_. Defaults to None.
        fullfill (bool, optional): _description_. Defaults to False.
        dataframe (pd.DataFrame | None, optional): _description_. Defaults to None.
        filter (pd.Series | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """

    return plot_line(
        series=series,
        color=color,
        width=width,
        mode=mode,
        name=name,
        fullfill=fullfill,
        dataframe=dataframe,
        filter=filter,
        **kwargs,
    )

plot_parabolic_sar ¤

plot_parabolic_sar(
    dataframe: DataFrame,
    long: str | None = "long",
    short: str | None = "short",
    width: int = 1,
    long_color: str = "#33BDFF",
    short_color: str = "#D105F5",
    filter: Series | None = None,
) -> dict

summary

Parameters:

  • dataframe (DataFrame) –

    description

  • long (str | None, default: 'long' ) –

    description. Defaults to "long".

  • short (str | None, default: 'short' ) –

    description. Defaults to "short".

  • width (int, default: 1 ) –

    description. Defaults to 1.

  • long_color (str, default: '#33BDFF' ) –

    description. Defaults to "#33BDFF".

  • short_color (str, default: '#D105F5' ) –

    description. Defaults to "#D105F5".

  • filter (Series | None, default: None ) –

    description. Defaults to None.

Returns:

  • dict ( dict ) –

    description

Source code in lettrade/plot/plotly/indicator.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def plot_parabolic_sar(
    dataframe: pd.DataFrame,
    long: str | None = "long",
    short: str | None = "short",
    width: int = 1,
    long_color: str = "#33BDFF",
    short_color: str = "#D105F5",
    filter: pd.Series | None = None,
) -> dict:
    """_summary_

    Args:
        dataframe (pd.DataFrame): _description_
        long (str | None, optional): _description_. Defaults to "long".
        short (str | None, optional): _description_. Defaults to "short".
        width (int, optional): _description_. Defaults to 1.
        long_color (str, optional): _description_. Defaults to "#33BDFF".
        short_color (str, optional): _description_. Defaults to "#D105F5".
        filter (pd.Series | None, optional): _description_. Defaults to None.

    Returns:
        dict: _description_
    """
    if filter is not None:
        df_name = dataframe.name
        dataframe = dataframe.loc[filter]
        object.__setattr__(dataframe, "name", df_name)

    config = dict()

    if long is not None:
        plot_merge(
            config,
            plot_mark(
                series=long,
                color=long_color,
                name="psar_long",
                width=width,
                dataframe=dataframe,
            ),
        )
    if short is not None:
        plot_merge(
            config,
            plot_mark(
                series=short,
                color=short_color,
                name="psar_short",
                width=width,
                dataframe=dataframe,
            ),
        )
    return config