dijkies 0.0.3__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,19 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dijkies
3
- Version: 0.0.3
3
+ Version: 0.1.1
4
4
  Summary: A python framework that can be used to create, test and deploy trading algorithms.
5
5
  Author: Arnold Dijk
6
6
  Author-email: Arnold Dijk <arnold.dijk@teamrockstars.nl>
7
7
  License: MIT
8
- Requires-Dist: mlflow>=3.7.0
9
8
  Requires-Dist: pandas>=2.3.3
10
- Requires-Dist: pre-commit>=4.5.0
11
9
  Requires-Dist: pydantic>=2.12.5
12
- Requires-Dist: pytest>=9.0.2
13
10
  Requires-Dist: python-binance>=1.0.33
14
11
  Requires-Dist: python-bitvavo-api>=1.4.3
15
- Requires-Dist: ta>=0.11.0
16
- Requires-Dist: tenacity>=9.1.2
17
12
  Requires-Python: >=3.11
13
+ Project-URL: Documentation, https://github.com/ArnoldDijk/dijkies/blob/dev/README.md
14
+ Project-URL: Homepage, https://github.com/ArnoldDijk/dijkies
15
+ Project-URL: Issues, https://github.com/ArnoldDijk/dijkies/issues
16
+ Project-URL: Source, https://github.com/ArnoldDijk/dijkies
18
17
  Description-Content-Type: text/markdown
19
18
 
20
19
  # Dijkies
@@ -53,19 +52,19 @@ At a high level, Dijkies operates as follows:
53
52
 
54
53
  ## Key Design Principles
55
54
 
56
- - **Strategy–Executor separation**
55
+ - **Strategy–Executor separation**
57
56
  Trading logic is completely decoupled from execution logic.
58
57
 
59
- - **Single interface for backtesting and live trading**
58
+ - **Single interface for backtesting and live trading**
60
59
  Switching between backtesting and live trading requires no strategy changes.
61
60
 
62
- - **Explicit state management**
61
+ - **Explicit state management**
63
62
  All balances and positions are tracked in a transparent `State` object.
64
63
 
65
- - **Minimal assumptions**
64
+ - **Minimal assumptions**
66
65
  Dijkies does not enforce indicators, timeframes, or asset types.
67
66
 
68
- - **Composable and extensible**
67
+ - **Composable and extensible**
69
68
  New exchanges, execution models, and risk layers can be added easily.
70
69
 
71
70
  ## Who Is This For?
@@ -92,19 +91,25 @@ This quick start shows how to define a strategy, fetch market data, and run a ba
92
91
 
93
92
  ### 1. Define a Strategy
94
93
 
95
- A strategy is a class that inherits from `Strategy` and implements the `execute` method.
94
+ A strategy is a class that inherits from `Strategy` and implements the `execute` method.
96
95
  It receives a rolling dataframe of candles and decides when to place orders.
97
96
 
98
97
  ```python
99
- from dijkies.strategy import Strategy
98
+ # create strategy
99
+
100
100
  from dijkies.executors import ExchangeAssetClient
101
+ from dijkies.strategy import Strategy
102
+
101
103
  from ta.momentum import RSIIndicator
102
- import pandas as pd
104
+ from pandas.core.frame import DataFrame as PandasDataFrame
105
+
106
+ from dijkies.executors import BacktestExchangeAssetClient, State
107
+
108
+ from dijkies.data_pipeline import DataPipeline, NoDataPipeline
103
109
 
104
110
 
105
111
  class RSIStrategy(Strategy):
106
- # Amount of historical data passed into execute()
107
- analysis_dataframe_size_in_minutes = 60 * 24 * 30 # 30 days
112
+ analysis_dataframe_size_in_minutes = 60*24*30
108
113
 
109
114
  def __init__(
110
115
  self,
@@ -116,25 +121,39 @@ class RSIStrategy(Strategy):
116
121
  self.higher_threshold = higher_threshold
117
122
  super().__init__(executor)
118
123
 
119
- def execute(self, candle_df: pd.DataFrame) -> None:
120
- candle_df["rsi"] = RSIIndicator(candle_df.close).rsi()
124
+ def execute(self, candle_df: PandasDataFrame) -> None:
125
+ candle_df["momentum_rsi"] = RSIIndicator(candle_df.close).rsi()
121
126
 
122
- previous = candle_df.iloc[-2]
123
- current = candle_df.iloc[-1]
127
+ previous_candle = candle_df.iloc[-2]
128
+ current_candle = candle_df.iloc[-1]
124
129
 
125
- # Buy when RSI crosses below lower threshold
126
- if previous.rsi > self.lower_threshold and current.rsi < self.lower_threshold:
130
+ is_buy_signal = (
131
+ previous_candle.momentum_rsi > self.lower_threshold
132
+ and current_candle.momentum_rsi < self.lower_threshold
133
+ )
134
+
135
+ if is_buy_signal:
127
136
  self.executor.place_market_buy_order(
128
137
  self.executor.state.base,
129
138
  self.executor.state.quote_available,
130
139
  )
131
140
 
132
- # Sell when RSI crosses above higher threshold
133
- if previous.rsi < self.higher_threshold and current.rsi > self.higher_threshold:
141
+ is_sell_signal = (
142
+ previous_candle.momentum_rsi < self.higher_threshold
143
+ and current_candle.momentum_rsi > self.higher_threshold
144
+ )
145
+
146
+ if is_sell_signal:
134
147
  self.executor.place_market_sell_order(
135
148
  self.executor.state.base,
136
149
  self.executor.state.base_available,
137
150
  )
151
+
152
+ def get_data_pipeline(self) -> DataPipeline:
153
+ """
154
+ Implement this metho
155
+ """
156
+ return NoDataPipeline()
138
157
  ```
139
158
 
140
159
  ### 2. fetch data for your backtest
@@ -143,8 +162,9 @@ Market data is provided as a pandas DataFrame containing OHLCV candles.
143
162
  ```python
144
163
  from dijkies.exchange_market_api import BitvavoMarketAPI
145
164
 
146
- market_api = BitvavoMarketAPI()
147
- candle_df = market_api.get_candles(base="XRP", lookback_in_minutest=60*24*365)
165
+ bitvavo_market_api = BitvavoMarketAPI()
166
+
167
+ candle_df = bitvavo_market_api.get_candles()
148
168
  ```
149
169
 
150
170
  ### 3. Set Up State and BacktestingExecutor
@@ -179,13 +199,129 @@ strategy = RSIStrategy(
179
199
  higher_threshold=65,
180
200
  )
181
201
 
182
- backtester = Backtester()
183
-
184
- results = backtester.run(
202
+ results = strategy.backtest(
185
203
  candle_df=candle_df,
186
- strategy=strategy,
187
204
  )
188
205
 
189
206
  results.total_value_strategy.plot()
190
207
  results.total_value_hodl.plot()
191
- ```
208
+ ```
209
+
210
+ ## Deployment & Live Trading
211
+
212
+ Dijkies supports deploying strategies to live trading environments using the **same strategy code** that is used for backtesting. Deployment is built around a small set of composable components that handle persistence, credentials, execution switching, and bot lifecycle management.
213
+
214
+ At a high level, deployment works by:
215
+
216
+ 1. Persisting a configured strategy
217
+ 2. Attaching a live exchange executor
218
+ 3. Running the strategy via a `Bot`
219
+ 4. Managing lifecycle states such as *active*, *paused*, and *stopped*
220
+
221
+ ---
222
+
223
+ ## Core Deployment Concepts
224
+
225
+ ### Strategy Persistence
226
+
227
+ Strategies are **serialized and stored** so they can be resumed, paused, or stopped without losing state.
228
+
229
+ This includes:
230
+ - Strategy parameters
231
+ - Internal indicators or buffers
232
+ - Account state (balances, open orders, etc.)
233
+
234
+ Persistence is handled through a `StrategyRepository`.
235
+
236
+ ---
237
+
238
+ ### Strategy Status
239
+
240
+ Each deployed strategy (bot) exists in one of the following states:
241
+
242
+ - **active** — strategy is running normally
243
+ - **paused** — strategy execution stopped due to an error
244
+ - **stopped** — strategy has been intentionally stopped
245
+
246
+ Status transitions are managed automatically by the deployment system.
247
+
248
+ ---
249
+
250
+ ### Executor Switching
251
+
252
+ One of Dijkies’ key design goals is that **strategies do not know whether they are backtesting or live trading**.
253
+
254
+ At deployment time, the executor is injected dynamically:
255
+
256
+ - `BacktestExchangeAssetClient` for backtesting
257
+ - `BitvavoExchangeAssetClient` for live trading
258
+
259
+ No strategy code changes are required.
260
+
261
+ ---
262
+
263
+ ## Strategy Repository
264
+
265
+ The `StrategyRepository` abstraction defines how strategies are stored and retrieved.
266
+
267
+ ```python
268
+ class StrategyRepository(ABC):
269
+ def store(...)
270
+ def read(...)
271
+ def change_status(...)
272
+ ```
273
+
274
+ ### LocalStrategyRepository
275
+
276
+ The provided implementation stores strategies locally using pickle.
277
+
278
+ #### Directory Structure
279
+
280
+ root/
281
+ └── person_id/
282
+ └── exchange/
283
+ └── status/
284
+ └── bot_id.pkl
285
+
286
+ ```python
287
+ from pathlib import Path
288
+ from dijkies.bot import LocalStrategyRepository
289
+
290
+ repo = LocalStrategyRepository(Path("./strategies"))
291
+
292
+ # read
293
+
294
+ strategy = repo.read(
295
+ person_id="ArnoldDijk",
296
+ exchange="bitvavo",
297
+ bot_id="rsi_bot",
298
+ status="active"
299
+ )
300
+
301
+ # store
302
+
303
+ repo.store(
304
+ strategy=strategy,
305
+ person_id="ArnoldDijk",
306
+ exchange="bitvavo",
307
+ bot_id="berend_botje",
308
+ status="active"
309
+ )
310
+
311
+ # change status
312
+
313
+ repo.change_status(
314
+ person_id="ArnoldDijk",
315
+ exchange="bitvavo",
316
+ bot_id="berend_botje",
317
+ from_status="active",
318
+ to_status="stopped",
319
+ )
320
+ ```
321
+
322
+ This makes it easy to:
323
+
324
+ - Resume bots after restarts
325
+ - Inspect stored strategies
326
+ - Build higher-level orchestration around the filesystem
327
+
@@ -0,0 +1,12 @@
1
+ dijkies/__init__.py,sha256=FmmEOqu9R1gE1wBWWIrAIFTF1rI5sEjpsCdrw4RC5Z8,167
2
+ dijkies/data_pipeline.py,sha256=-0557jmH4o4jghDiQzYVU3hzRXOKejIDFpcJWhcW-GY,1395
3
+ dijkies/deployment.py,sha256=8T4b91TRCcZCFe92gIqoCbk0vetbuhrORmDHq6M_5x8,7138
4
+ dijkies/exceptions.py,sha256=Sgbzm3GXSTfKnGf9BMEOjg7ksebjSIg53DqGU6KOUmg,2418
5
+ dijkies/exchange_market_api.py,sha256=RqA59y0f3O8GB8Za9DXkyH5XocVG0wiKuxJ7tRNijkg,7602
6
+ dijkies/executors.py,sha256=oPK62s11uCYooOizm8sNB0oJLevHDHnfAsOa5QNWlig,19386
7
+ dijkies/logger.py,sha256=yrxNyzriXO_WITRsIEWkVQeqLRavHVklFainDO18p7Y,432
8
+ dijkies/performance.py,sha256=bqY3d9-F1NtATwO7FK9JsD-MThEAqLsmWt_ty5Fowzc,5414
9
+ dijkies/strategy.py,sha256=5KJJuBA6_cwD6CZ4_c3_LSJXfMR_wphQ0S9sIv0eXRo,4242
10
+ dijkies-0.1.1.dist-info/WHEEL,sha256=RRVLqVugUmFOqBedBFAmA4bsgFcROUBiSUKlERi0Hcg,79
11
+ dijkies-0.1.1.dist-info/METADATA,sha256=xfWlwdi42OU2aTb3s1MuHG1yXwqGvQ8swP7PKoLLGKI,8881
12
+ dijkies-0.1.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.18
2
+ Generator: uv 0.9.21
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
dijkies/backtest.py DELETED
@@ -1,98 +0,0 @@
1
- from datetime import datetime, timedelta
2
- from typing import Optional
3
-
4
- import pandas as pd
5
- from pandas.core.frame import DataFrame as PandasDataFrame
6
-
7
- from dijkies.evaluate import EvaluationFramework
8
- from dijkies.executors import BacktestExchangeAssetClient
9
- from dijkies.performance import PerformanceInformationRow
10
- from dijkies.exceptions import (
11
- DataTimeWindowShorterThanSuggestedAnalysisWindowError,
12
- InvalidExchangeAssetClientError,
13
- InvalidTypeForTimeColumnError,
14
- MissingOHLCVColumnsError,
15
- TimeColumnNotDefinedError,
16
- )
17
- from dijkies.strategy import Strategy
18
-
19
-
20
- class Backtester:
21
- def __init__(
22
- self,
23
- evaluation: Optional[EvaluationFramework] = None,
24
- ):
25
- self.evaluation = evaluation
26
-
27
- @staticmethod
28
- def get_analysis_df(
29
- data: PandasDataFrame, current_time: datetime, look_back_in_min: int
30
- ) -> PandasDataFrame:
31
- start_analysis_df = current_time - timedelta(minutes=look_back_in_min)
32
-
33
- analysis_df = data.loc[
34
- (data.time >= start_analysis_df) & (data.time <= current_time)
35
- ]
36
-
37
- return analysis_df
38
-
39
- def simulate(
40
- self,
41
- data: PandasDataFrame,
42
- strategy: Strategy,
43
- ) -> PandasDataFrame:
44
- """
45
- This method runs the backtest. It expects data, this should have the following properties:
46
- """
47
-
48
- # validate args
49
-
50
- if "time" not in data.columns:
51
- raise TimeColumnNotDefinedError()
52
-
53
- if not pd.api.types.is_datetime64_any_dtype(data.time):
54
- raise InvalidTypeForTimeColumnError()
55
-
56
- lookback_in_min = strategy.analysis_dataframe_size_in_minutes
57
- timespan_data_in_min = (data.time.max() - data.time.min()).total_seconds() / 60
58
-
59
- if lookback_in_min > timespan_data_in_min:
60
- raise DataTimeWindowShorterThanSuggestedAnalysisWindowError()
61
-
62
- if not {"open", "high", "low", "close", "volume"}.issubset(data.columns):
63
- raise MissingOHLCVColumnsError()
64
-
65
- if not isinstance(strategy.executor, BacktestExchangeAssetClient):
66
- raise InvalidExchangeAssetClientError()
67
-
68
- start_time = data.iloc[0].time + timedelta(minutes=lookback_in_min)
69
- simulation_df: PandasDataFrame = data.loc[data.time >= start_time]
70
- start_candle = simulation_df.iloc[0]
71
- start_value_in_quote = strategy.state.total_value_in_quote(start_candle.open)
72
- result = []
73
-
74
- for _, candle in simulation_df.iterrows():
75
- analysis_df = self.get_analysis_df(data, candle.time, lookback_in_min)
76
- strategy.executor.update_current_candle(candle)
77
-
78
- strategy.run(analysis_df)
79
-
80
- result.append(
81
- PerformanceInformationRow.from_objects(
82
- candle, start_candle, strategy.state, start_value_in_quote
83
- )
84
- )
85
-
86
- return pd.DataFrame([r.dict() for r in result])
87
-
88
- def run(
89
- self,
90
- candle_df: PandasDataFrame,
91
- strategy: Strategy,
92
- ) -> PandasDataFrame:
93
-
94
- results = self.simulate(candle_df, strategy)
95
- if isinstance(self.evaluation, EvaluationFramework):
96
- self.evaluation.evaluate(results)
97
-
98
- return results
dijkies/credentials.py DELETED
@@ -1,6 +0,0 @@
1
- from pydantic import BaseModel
2
-
3
-
4
- class Credentials(BaseModel):
5
- api_key: str
6
- api_secret_key: str
dijkies/evaluate.py DELETED
@@ -1,235 +0,0 @@
1
- import logging
2
- import os
3
- import tempfile
4
- from abc import ABC, abstractmethod
5
- from datetime import datetime, timezone
6
- from typing import Optional, Union
7
-
8
- import matplotlib.pyplot as plt
9
- import mlflow
10
- import pandas as pd
11
- from pandas.core.frame import DataFrame as PandasDataFrame
12
-
13
- from dijkies.performance import Metric
14
-
15
-
16
- class EvaluationFramework(ABC):
17
- @abstractmethod
18
- def evaluate(self, performance_results: PandasDataFrame) -> None:
19
- pass
20
-
21
-
22
- class MLFlowEvaluator(ABC):
23
- @abstractmethod
24
- def evaluate(self, performance_results: PandasDataFrame) -> None:
25
- pass
26
-
27
-
28
- class MLFlowEvaluationFramework(EvaluationFramework):
29
- def __init__(
30
- self,
31
- evaluators: list[MLFlowEvaluator],
32
- experiment_name: str,
33
- logger: logging.Logger,
34
- strategy_parameters: Optional[dict[str, Union[int, str, float, bool]]],
35
- log_dataset: bool = False,
36
- ) -> None:
37
- self.evaluators = evaluators
38
- self.logger = logger
39
- self.experiment_name = experiment_name
40
- self.log_dataset = log_dataset
41
- self.strategy_parameters = strategy_parameters
42
-
43
- def evaluate(self, performance_results: PandasDataFrame) -> None:
44
- mlflow.set_experiment(self.experiment_name)
45
- # for results:
46
- # poetry run mlflow server --host 127.0.0.1 --port 8080
47
-
48
- run_name = "run__" + datetime.now(tz=timezone.utc).strftime("%Y_%m_%d_%H_%M%Z")
49
-
50
- with mlflow.start_run(run_name=run_name) as run:
51
- run_id = run.info.run_id
52
- self.logger.info("Run created: " + run_id)
53
- if self.log_dataset:
54
- dataset = mlflow.data.from_pandas(
55
- performance_results, source="local", name="training_data"
56
- )
57
- mlflow.log_input(dataset, context="training")
58
- mlflow.log_params(self.strategy_parameters)
59
- with tempfile.TemporaryDirectory() as tmpdir:
60
- file_path = os.path.join(tmpdir, "data.csv")
61
- performance_results.to_csv(file_path, index=False)
62
- mlflow.log_artifact(file_path)
63
-
64
- [
65
- evaluator.evaluate(performance_results) for evaluator in self.evaluators
66
- ] # type: ignore
67
-
68
-
69
- class MLFlowOverallEvaluator(MLFlowEvaluator):
70
- def __init__(self, metrics: list[Metric], logger: logging.Logger) -> None:
71
- self.metrics = metrics
72
- self.logger = logger
73
-
74
- def log_metrics(self, performance_results: PandasDataFrame) -> None:
75
- for metric in self.metrics:
76
- mlflow.log_metric(
77
- "strategy_" + metric.metric_name,
78
- round(metric.calculate(performance_results.total_value_strategy), 2),
79
- )
80
- mlflow.log_metric(
81
- "hodl_" + metric.metric_name,
82
- round(metric.calculate(performance_results.total_value_hodl), 2),
83
- )
84
-
85
- @staticmethod
86
- def plot_fee(performance_results: PandasDataFrame) -> None:
87
- plt.figure(figsize=(8, 5))
88
- plt.plot(
89
- performance_results.candle_time,
90
- performance_results.total_fee_paid,
91
- color="blue",
92
- label="fee",
93
- )
94
- plt.xlabel("Time")
95
- plt.xticks(rotation=45)
96
- plt.ylabel("fee paid in €")
97
- plt.title("total transaction fee paid to Exchange")
98
- plt.grid(True)
99
- plt.legend()
100
-
101
- # Log figure directly to MLflow
102
- mlflow.log_figure(plt.gcf(), "total_fee_paid.png")
103
-
104
- plt.close() # free memory
105
-
106
- @staticmethod
107
- def plot_balance_fractions(performance_results: PandasDataFrame) -> None:
108
- perc_in_quote = (
109
- performance_results.balance_total_quote
110
- / performance_results.total_value_strategy
111
- )
112
- perc_in_base = (
113
- performance_results.balance_total_base
114
- / performance_results.total_value_strategy
115
- * performance_results.candle_close
116
- )
117
-
118
- plt.figure(figsize=(8, 5))
119
- plt.plot(
120
- performance_results.candle_time,
121
- perc_in_quote,
122
- color="blue",
123
- label="percentage value in quote",
124
- )
125
- plt.plot(
126
- performance_results.candle_time,
127
- perc_in_base,
128
- color="red",
129
- label="percentage value in base",
130
- )
131
- plt.xlabel("Time")
132
- plt.xticks(rotation=45)
133
- plt.ylabel("fraction")
134
- plt.title("fraction of total value in quote")
135
- plt.grid(True)
136
- plt.legend()
137
-
138
- # Log figure directly to MLflow
139
- mlflow.log_figure(plt.gcf(), "balance_fractions.png")
140
-
141
- plt.close() # free memory
142
-
143
- @staticmethod
144
- def plot_strategy_vs_hodl(performance_results: PandasDataFrame) -> None:
145
- plt.figure(figsize=(8, 5))
146
- plt.plot(
147
- performance_results.candle_time,
148
- performance_results.total_value_strategy,
149
- color="blue",
150
- label="strategy",
151
- )
152
- plt.plot(
153
- performance_results.candle_time,
154
- performance_results.total_value_hodl,
155
- color="red",
156
- label="hodl",
157
- )
158
- plt.xlabel("Time")
159
- plt.xticks(rotation=45)
160
- plt.ylabel("Value")
161
- plt.title("strategy vs. hodl")
162
- plt.grid(True)
163
- plt.legend()
164
-
165
- # Log figure directly to MLflow
166
- mlflow.log_figure(plt.gcf(), "overal_result.png")
167
-
168
- plt.close() # free memory
169
-
170
- def plot_results(self, performance_results: PandasDataFrame) -> None:
171
- self.plot_strategy_vs_hodl(performance_results)
172
- self.plot_fee(performance_results)
173
- self.plot_balance_fractions(performance_results)
174
-
175
- def evaluate(self, performance_results: PandasDataFrame) -> None:
176
- self.log_metrics(performance_results)
177
- self.plot_results(performance_results)
178
-
179
-
180
- class MLFlowSliceEvaluator(MLFlowEvaluator):
181
- def __init__(
182
- self, window_size_in_min: int, metrics: list[Metric], logger: logging.Logger
183
- ) -> None:
184
- self.window_size_in_min = window_size_in_min
185
- self.metrics = metrics
186
- self.logger = logger
187
-
188
- def results_window_slicer(self, results: PandasDataFrame) -> PandasDataFrame:
189
- candle_interval_in_minutes = (
190
- results.iloc[1].candle_time - results.iloc[0].candle_time
191
- ).total_seconds() / 60
192
- window_size = self.window_size_in_min / candle_interval_in_minutes
193
-
194
- evaluation = []
195
-
196
- for sub_result in [
197
- results.loc[i : i + window_size]
198
- for i in range(len(results) - (int(window_size) + 1))
199
- ]:
200
- row = {}
201
- for metric in self.metrics:
202
- row["strategy_" + metric.metric_name] = metric.calculate(
203
- sub_result.total_value_strategy
204
- )
205
- row["hodl_" + metric.metric_name] = metric.calculate(
206
- sub_result.total_value_hodl
207
- )
208
- evaluation.append(row)
209
-
210
- return pd.DataFrame(evaluation)
211
-
212
- def plot_results(self, slicer_results: PandasDataFrame) -> None:
213
- for col in slicer_results.columns:
214
- self.logger.info(f"create plot {col}")
215
- plt.figure(figsize=(8, 5))
216
- plt.hist(slicer_results[col])
217
- plt.title(f"Column: {col}")
218
- plt.xlabel(col)
219
- plt.grid(True)
220
-
221
- # Log figure directly to MLflow
222
- mlflow.log_figure(plt.gcf(), f"{col}.png")
223
-
224
- plt.close() # free memory
225
-
226
- def log_metrics(self, slicer_results: PandasDataFrame) -> None:
227
- for col in slicer_results.columns:
228
- self.logger.info(f"compute metrics for {col}")
229
- mlflow.log_metric(f"{col}_mean", round(slicer_results[col].mean(), 3))
230
- mlflow.log_metric(f"{col}_std", round(slicer_results[col].std(), 3))
231
-
232
- def evaluate(self, performance_results: PandasDataFrame) -> None:
233
- slicer_results = self.results_window_slicer(performance_results)
234
- self.log_metrics(slicer_results)
235
- self.plot_results(slicer_results)
@@ -1,15 +0,0 @@
1
- dijkies/__init__.py,sha256=FmmEOqu9R1gE1wBWWIrAIFTF1rI5sEjpsCdrw4RC5Z8,167
2
- dijkies/backtest.py,sha256=Z3U8pijdNwGh_h4dlPtORk3znIOBlTKOaGR-IK-swys,3206
3
- dijkies/credentials.py,sha256=pwhRsTFnaDOinnRwnplnxAIDS778dPd2awFDmjo3dpY,104
4
- dijkies/data_pipeline.py,sha256=SK5NCpI5okhwiPOAPTzoDVLgqPH6SGPsT4khNXcf7jI,313
5
- dijkies/deployment.py,sha256=N8xtF2YTU1wA0RAcwVmJEaXKZnNH94XjutIs7aOFyYo,3638
6
- dijkies/evaluate.py,sha256=52H87f4E7-1eTDN2CLSKkswtydTIeDSMZdCoXo56woA,8064
7
- dijkies/exceptions.py,sha256=BLqK0-rmpqx3wtZ8abu19u8ClnsAjkcpz4B22p-YYt0,1907
8
- dijkies/exchange_market_api.py,sha256=ZH2gD_Z7PkX3KLT1GtG20Xr-bacj4B3IGsJNP7Hz5AE,7606
9
- dijkies/executors.py,sha256=7GJznhlv2WMP6UjqQeE6s9VQsvzD0Y0okXdJd4rmMdk,20896
10
- dijkies/logger.py,sha256=yrxNyzriXO_WITRsIEWkVQeqLRavHVklFainDO18p7Y,432
11
- dijkies/performance.py,sha256=1EoGx0_riiAyOP8G7UQcYwmjt8b8hw4c3UzAgsbpOuE,5416
12
- dijkies/strategy.py,sha256=4UZpuZcDvtol6RbarUw-K846bZritSDqDirz9w8ycPw,1804
13
- dijkies-0.0.3.dist-info/WHEEL,sha256=ZyFSCYkV2BrxH6-HRVRg3R9Fo7MALzer9KiPYqNxSbo,79
14
- dijkies-0.0.3.dist-info/METADATA,sha256=zgh4Zr4w3-yFTLg0le_rKDHMIsMpltd68ZT9AAkTx1w,5717
15
- dijkies-0.0.3.dist-info/RECORD,,