tradepose-client 0.1.0__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.

Potentially problematic release.


This version of tradepose-client might be problematic. Click here for more details.

@@ -0,0 +1,576 @@
1
+ Metadata-Version: 2.4
2
+ Name: tradepose-client
3
+ Version: 0.1.0
4
+ Summary: Python client for Tradepose quantitative trading API
5
+ Author: Tradepose Team
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: api-client,backtesting,financial,polars,quantitative,technical-analysis,trading
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Financial and Insurance Industry
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Office/Business :: Financial :: Investment
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Requires-Python: >=3.13
19
+ Requires-Dist: polars>=1.34.0
20
+ Requires-Dist: pydantic>=2.12.1
21
+ Requires-Dist: redis>=6.4.0
22
+ Requires-Dist: requests>=2.32.5
23
+ Requires-Dist: streamlit>=1.50.0
24
+ Provides-Extra: all
25
+ Requires-Dist: altair>=5.5.0; extra == 'all'
26
+ Requires-Dist: black>=24.0.0; extra == 'all'
27
+ Requires-Dist: fastmcp>=1.0.0; extra == 'all'
28
+ Requires-Dist: hvplot>=0.12.1; extra == 'all'
29
+ Requires-Dist: ipykernel>=7.0.0; extra == 'all'
30
+ Requires-Dist: ipywidgets>=8.1.7; extra == 'all'
31
+ Requires-Dist: jupyterlab>=4.0.0; extra == 'all'
32
+ Requires-Dist: matplotlib>=3.8.0; extra == 'all'
33
+ Requires-Dist: mypy>=1.8.0; extra == 'all'
34
+ Requires-Dist: plotly>=6.3.1; extra == 'all'
35
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'all'
36
+ Requires-Dist: pytest>=8.0.0; extra == 'all'
37
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'all'
38
+ Requires-Dist: ruff>=0.1.0; extra == 'all'
39
+ Requires-Dist: st-click-detector>=0.1.3; extra == 'all'
40
+ Requires-Dist: streamlit>=1.30.0; extra == 'all'
41
+ Requires-Dist: watchdog>=6.0.0; extra == 'all'
42
+ Provides-Extra: dev
43
+ Requires-Dist: black>=24.0.0; extra == 'dev'
44
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
45
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
46
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
47
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
48
+ Provides-Extra: jupyter
49
+ Requires-Dist: ipykernel>=7.0.0; extra == 'jupyter'
50
+ Requires-Dist: ipywidgets>=8.1.7; extra == 'jupyter'
51
+ Requires-Dist: jupyterlab>=4.0.0; extra == 'jupyter'
52
+ Provides-Extra: mcp
53
+ Requires-Dist: fastmcp>=1.0.0; extra == 'mcp'
54
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'mcp'
55
+ Provides-Extra: streamlit
56
+ Requires-Dist: st-click-detector>=0.1.3; extra == 'streamlit'
57
+ Requires-Dist: streamlit>=1.30.0; extra == 'streamlit'
58
+ Requires-Dist: watchdog>=6.0.0; extra == 'streamlit'
59
+ Provides-Extra: viz
60
+ Requires-Dist: altair>=5.5.0; extra == 'viz'
61
+ Requires-Dist: hvplot>=0.12.1; extra == 'viz'
62
+ Requires-Dist: matplotlib>=3.8.0; extra == 'viz'
63
+ Requires-Dist: plotly>=6.3.1; extra == 'viz'
64
+ Description-Content-Type: text/markdown
65
+
66
+ # Tradepose Python Client
67
+
68
+ 易於使用的 Tradepose API 客戶端和數據分析工具,專為 Jupyter Notebook 互動式開發設計。
69
+
70
+ ## 特點
71
+
72
+ ✅ **易於導入** - 簡潔的 Python API
73
+ ✅ **無需 PostgreSQL** - 純 API + Redis 模式
74
+ ✅ **Parquet 下載** - 直接下載並讀取 Parquet 文件
75
+ ✅ **Jupyter 友好** - 專為 notebook 環境優化
76
+ ✅ **自動等待** - 自動監控任務完成
77
+ ✅ **Polars 支援** - 高效數據處理
78
+ ✅ **Schema 驗證** - 完整的 schema 處理工具
79
+ ✅ **可視化** - 內建 Plotly 圖表支援
80
+ ✅ **分析工具** - 豐富的技術分析函數
81
+
82
+ ## 安裝依賴
83
+
84
+ ```bash
85
+ cd tradepose-client
86
+
87
+ # 核心依賴
88
+ uv add polars redis plotly hvplot
89
+
90
+ # Jupyter 環境
91
+ uv add jupyterlab ipykernel ipywidgets
92
+
93
+ # 可選:金融數據視覺化
94
+ uv add mplfinance matplotlib
95
+ ```
96
+
97
+ ## 快速開始
98
+
99
+ ### 🚀 推薦方式:使用 Parquet 下載(無需 PostgreSQL)
100
+
101
+ ```python
102
+ from tradepose_client import TradeposeClient
103
+
104
+ client = TradeposeClient()
105
+
106
+ # 完整工作流程:創建任務 -> 下載 Parquet -> 讀取
107
+ df = client.quick_workflow(
108
+ strategy_name="txf_1h_sma30_50",
109
+ start_date="2020-01-01T00:00:00",
110
+ save_path="./data/my_data.parquet"
111
+ )
112
+
113
+ # 開始分析
114
+ print(df.describe())
115
+ ```
116
+
117
+ ### 方法一:最簡單(一行搞定)
118
+
119
+ ```python
120
+ from tradepose_client import quick_export
121
+
122
+ # 一行代碼導出數據(下載 Parquet)
123
+ df = quick_export(
124
+ strategy_name="txf_1h_sma30_50",
125
+ start_date="2020-01-01T00:00:00",
126
+ end_date="2024-12-31T23:59:59",
127
+ save_path="./data/my_data.parquet"
128
+ )
129
+
130
+ # 開始分析
131
+ print(df.describe())
132
+ ```
133
+
134
+ ### 方法二:使用客戶端(更多控制)
135
+
136
+ ```python
137
+ from tradepose_client import TradeposeClient
138
+
139
+ # 初始化
140
+ client = TradeposeClient()
141
+
142
+ # 列出策略
143
+ strategies = client.list_strategies()
144
+ print(strategies)
145
+
146
+ # 創建 export 任務
147
+ task_id = client.create_export(
148
+ strategy_name="txf_1h_sma30_50",
149
+ blueprint_name="txf_base_trend",
150
+ start_date="2020-01-01T00:00:00"
151
+ )
152
+
153
+ # 等待並下載 Parquet
154
+ df = client.wait_and_download(task_id, output_path="./data/output.parquet")
155
+ ```
156
+
157
+ ### 方法三:分步驟執行(Parquet 下載)
158
+
159
+ ```python
160
+ # 1. 創建任務
161
+ task_id = client.create_export(
162
+ strategy_name="txf_1h_sma30_50",
163
+ blueprint_name="txf_base_trend",
164
+ start_date="2020-01-01T00:00:00"
165
+ )
166
+
167
+ # 2. 等待完成
168
+ client.wait_for_export(task_id)
169
+
170
+ # 3. 下載 Parquet 文件
171
+ parquet_path = client.download_parquet(task_id, "./data/output.parquet")
172
+
173
+ # 4. 讀取並應用 schema
174
+ df = client.load_parquet_with_schema(parquet_path)
175
+ ```
176
+
177
+ ### 方法四:使用 Parquet 工具模組
178
+
179
+ ```python
180
+ from parquet_utils import (
181
+ read_enhanced_ohlcv,
182
+ extract_all_trading_contexts,
183
+ validate_schema,
184
+ print_validation_report,
185
+ get_column_info
186
+ )
187
+
188
+ # 讀取 Parquet
189
+ df = read_enhanced_ohlcv("./data/output.parquet")
190
+
191
+ # 驗證 schema
192
+ report = validate_schema(df)
193
+ print_validation_report(report)
194
+
195
+ # 展開 trading context
196
+ df = extract_all_trading_contexts(df)
197
+
198
+ # 查看列分類
199
+ col_info = get_column_info(df)
200
+ ```
201
+
202
+ ## 數據分析工具
203
+
204
+ ```python
205
+ from analysis_utils import *
206
+
207
+ # 計算收益率
208
+ df = calculate_returns(df)
209
+
210
+ # 計算波動率
211
+ df = calculate_volatility(df, window=20)
212
+
213
+ # 重採樣為日線
214
+ daily_df = resample_to_daily(df)
215
+
216
+ # 計算回撤
217
+ df = calculate_drawdown(df)
218
+ max_dd = get_max_drawdown(df)
219
+
220
+ # 打印統計摘要
221
+ print_summary(df)
222
+
223
+ # 查找技術指標
224
+ indicators = find_indicator_columns(df)
225
+ print(indicators)
226
+
227
+ # 按日期過濾
228
+ df_2023 = filter_by_date_range(df, "2023-01-01", "2023-12-31")
229
+
230
+ # 分割訓練/測試集
231
+ train, test = split_train_test(df, train_ratio=0.8)
232
+ ```
233
+
234
+ ## Jupyter Notebook 示例
235
+
236
+ 項目包含兩個示例 notebook:
237
+
238
+ ### 1. 快速開始 (`examples/01_quick_start.ipynb`)
239
+
240
+ - 初始化客戶端
241
+ - 查看可用策略
242
+ - 三種導出方式
243
+ - 數據預覽和保存
244
+
245
+ ### 2. 數據分析 (`examples/02_data_analysis.ipynb`)
246
+
247
+ - OHLCV 統計分析
248
+ - 技術指標分析
249
+ - K 線圖可視化
250
+ - 成交量分析
251
+ - 相關性分析
252
+
253
+ ### 啟動 Jupyter Lab
254
+
255
+ ```bash
256
+ cd tradepose-client
257
+ uv run jupyter lab
258
+ ```
259
+
260
+ 瀏覽器會自動打開,可以直接運行示例 notebook。
261
+
262
+ ## API 參考
263
+
264
+ ### TradeposeClient
265
+
266
+ #### `__init__(api_url, redis_url)`
267
+
268
+ 初始化客戶端
269
+
270
+ #### `list_strategies() -> List[Dict]`
271
+
272
+ 列出所有可用策略
273
+
274
+ #### `get_strategy_detail(strategy_name) -> Dict`
275
+
276
+ 獲取策略詳情
277
+
278
+ #### `create_export(strategy_name, blueprint_name, export_type, start_date, end_date) -> str`
279
+
280
+ 創建 export 任務,返回 task_id
281
+
282
+ **參數**:
283
+
284
+ - `strategy_name`: 策略名稱
285
+ - `blueprint_name`: 藍圖名稱
286
+ - `export_type`: 導出類型 (enhanced-ohlcv, backtest-results, latest-trades)
287
+ - `start_date`: 起始日期(ISO 8601 格式,如 "2020-01-01T00:00:00")
288
+ - `end_date`: 終止日期(可選,默認當前時間)
289
+
290
+ #### `get_export_status(task_id) -> Dict`
291
+
292
+ 查詢任務狀態
293
+
294
+ #### `wait_for_export(task_id, timeout, poll_interval) -> Dict`
295
+
296
+ 等待任務完成
297
+
298
+ #### `get_metadata_from_redis(task_id) -> Dict`
299
+
300
+ 從 Redis 讀取任務 metadata(注意:只有 metadata,實際數據在 Parquet 文件中)
301
+
302
+ #### `wait_and_download(task_id, output_path, timeout, verbose) -> pl.DataFrame`
303
+
304
+ 等待並下載 Parquet(推薦方法)
305
+
306
+ #### `save_to_parquet(df, output_path) -> Path`
307
+
308
+ 保存為 Parquet 文件
309
+
310
+ #### `download_parquet(task_id, output_path) -> Path`
311
+
312
+ 直接從 API 下載 Parquet 文件
313
+
314
+ **參數**:
315
+
316
+ - `task_id`: Export task ID
317
+ - `output_path`: 輸出文件路徑(可選,自動生成)
318
+
319
+ #### `load_parquet_with_schema(file_path) -> pl.DataFrame`
320
+
321
+ 讀取 Parquet 文件並應用正確的 schema
322
+
323
+ **參數**:
324
+
325
+ - `file_path`: Parquet 文件路徑
326
+
327
+ #### `quick_export(strategy_name, blueprint_name, start_date, end_date, save_path) -> pl.DataFrame`
328
+
329
+ 一鍵導出(下載 Parquet)
330
+
331
+ **參數**:
332
+
333
+ - `save_path`: 保存路徑(如果為 None,自動生成臨時文件)
334
+
335
+ #### `quick_workflow(strategy_name, blueprint_name, start_date, end_date, save_path) -> pl.DataFrame`
336
+
337
+ 完整工作流程(推薦使用,與 quick_export 相同)
338
+
339
+ **說明**:
340
+
341
+ - 完全不依賴 PostgreSQL 或 Redis 數據存儲
342
+ - 只需要 API server 運行即可
343
+
344
+ ## 便捷函數
345
+
346
+ ### `quick_export(...)`
347
+
348
+ 全局便捷函數,無需創建客戶端實例
349
+
350
+ ```python
351
+ df = quick_export("txf_1h_sma30_50", start_date="2020-01-01T00:00:00")
352
+ ```
353
+
354
+ ### `get_client(api_url, redis_url)`
355
+
356
+ 獲取客戶端實例
357
+
358
+ ## Parquet 工具 API
359
+
360
+ 從 `parquet_utils` 模組導入:
361
+
362
+ ### `read_enhanced_ohlcv(file_path, apply_schema=True) -> pl.DataFrame`
363
+
364
+ 讀取並正確處理 enhanced OHLCV Parquet 文件
365
+
366
+ ### `extract_struct_field(df, struct_col, field_name, new_col_name) -> pl.DataFrame`
367
+
368
+ 從 Struct 欄位中提取單個字段
369
+
370
+ ### `extract_all_struct_fields(df, struct_col) -> pl.DataFrame`
371
+
372
+ 展開 Struct 欄位的所有字段為獨立列
373
+
374
+ ### `extract_all_trading_contexts(df) -> pl.DataFrame`
375
+
376
+ 展開所有 trading context Struct 欄位
377
+
378
+ ### `validate_schema(df) -> Dict`
379
+
380
+ 驗證 DataFrame schema 完整性
381
+
382
+ ### `print_validation_report(report)`
383
+
384
+ 打印 schema 驗證報告
385
+
386
+ ### `get_column_info(df, verbose=True) -> Dict`
387
+
388
+ 獲取列分類信息(ohlcv, signals, indicators 等)
389
+
390
+ ### `filter_columns(df, include, exclude) -> pl.DataFrame`
391
+
392
+ 根據模式過濾列
393
+
394
+ ## 文件結構
395
+
396
+ ```
397
+ tradepose-client/
398
+ ├── tradepose_client.py # 主要客戶端模組
399
+ ├── parquet_utils.py # Parquet 工具模組(NEW)
400
+ ├── pl_schema.py # Enhanced OHLCV schema 定義
401
+ ├── analysis_utils.py # 數據分析工具函數
402
+ ├── strategy_models.py # 策略模型(Pydantic)
403
+ ├── export_to_parquet.py # CLI 工具(獨立使用)
404
+ ├── example_no_postgres.py # 無 PostgreSQL 示例(NEW)
405
+ ├── example_usage.py # 使用示例
406
+ ├── workflow_example.sh # Shell 腳本示例
407
+ ├── examples/
408
+ │ ├── 01_quick_start.ipynb # 快速開始
409
+ │ ├── 02_data_analysis.ipynb # 數據分析
410
+ │ └── 03_strategy_models.ipynb # 策略模型示例
411
+ ├── README.md
412
+ └── pyproject.toml
413
+ ```
414
+
415
+ ## 使用場景
416
+
417
+ ### 1. 無 PostgreSQL 完整工作流程(推薦)
418
+
419
+ ```python
420
+ from tradepose_client import TradeposeClient
421
+ from parquet_utils import read_enhanced_ohlcv, extract_all_trading_contexts
422
+
423
+ # 1. 下載數據
424
+ client = TradeposeClient()
425
+ df = client.quick_workflow(
426
+ strategy_name="txf_1h_sma30_50",
427
+ download_parquet=True,
428
+ save_path="./data/my_strategy.parquet"
429
+ )
430
+
431
+ # 2. 讀取並處理
432
+ df = read_enhanced_ohlcv("./data/my_strategy.parquet")
433
+ df = extract_all_trading_contexts(df)
434
+
435
+ # 3. 分析
436
+ from analysis_utils import print_summary
437
+ print_summary(df)
438
+ ```
439
+
440
+ ### 2. 快速探索數據
441
+
442
+ ```python
443
+ # 一行導出
444
+ df = quick_export("txf_1h_sma30_50", start_date="2023-01-01T00:00:00")
445
+
446
+ # 快速統計
447
+ print_summary(df)
448
+
449
+ # 查看指標
450
+ indicators = find_indicator_columns(df)
451
+ df.select(indicators).describe()
452
+ ```
453
+
454
+ ### 2. 策略回測分析
455
+
456
+ ```python
457
+ # 導出多個時間段
458
+ df_2023 = quick_export(..., start_date="2023-01-01", end_date="2023-12-31")
459
+ df_2024 = quick_export(..., start_date="2024-01-01", end_date="2024-12-31")
460
+
461
+ # 比較表現
462
+ print_summary(df_2023)
463
+ print_summary(df_2024)
464
+ ```
465
+
466
+ ### 3. 技術指標研究
467
+
468
+ ```python
469
+ # 導出數據
470
+ df = quick_export(...)
471
+
472
+ # 找出所有 SMA
473
+ sma_cols = [col for col in df.columns if 'SMA' in col]
474
+
475
+ # 分析相關性
476
+ df.select(sma_cols).to_pandas().corr()
477
+ ```
478
+
479
+ ### 4. 可視化分析
480
+
481
+ ```python
482
+ import plotly.graph_objects as go
483
+
484
+ # K線圖
485
+ fig = go.Figure(data=[go.Candlestick(
486
+ x=df['ts'],
487
+ open=df['open'],
488
+ high=df['high'],
489
+ low=df['low'],
490
+ close=df['close']
491
+ )])
492
+ fig.show()
493
+ ```
494
+
495
+ ## 完整示例
496
+
497
+ 查看 `example_no_postgres.py` 獲取完整的無 PostgreSQL 工作流程示例:
498
+
499
+ ```bash
500
+ # 運行完整示例
501
+ uv run --python 3.13 example_no_postgres.py
502
+ ```
503
+
504
+ 示例包含:
505
+
506
+ 1. Quick workflow - 一鍵下載並分析
507
+ 2. 分步驟工作流程
508
+ 3. Parquet 工具函數使用
509
+ 4. 數據分析
510
+ 5. 可視化
511
+
512
+ ## CLI 工具
513
+
514
+ 如果不需要 Jupyter,仍可使用命令行工具:
515
+
516
+ ```bash
517
+ # 直接轉換
518
+ uv run --python 3.13 export_to_parquet.py --task-id <task-id>
519
+
520
+ # 完整工作流程
521
+ ./workflow_example.sh
522
+ ```
523
+
524
+ ## 故障排除
525
+
526
+ ### Redis 連接錯誤
527
+
528
+ ```python
529
+ # 檢查密碼
530
+ # docker exec tradepose-api-dev env | grep REDIS_URL
531
+
532
+ # 使用正確的 URL
533
+ client = TradeposeClient(redis_url="redis://:tradepose_password@localhost:6379")
534
+ ```
535
+
536
+ ### 導入模組錯誤
537
+
538
+ ```python
539
+ # 確保路徑正確
540
+ import sys
541
+ sys.path.append('..') # 在 examples/ 目錄中時
542
+
543
+ # 或使用絕對導入
544
+ sys.path.append('/Users/ender/workspace/tradepose-rust/tradepose-client')
545
+ ```
546
+
547
+ ### Jupyter Kernel 問題
548
+
549
+ ```bash
550
+ # 重新安裝 kernel
551
+ uv run python -m ipykernel install --user --name=tradepose
552
+
553
+ # 在 Jupyter 中選擇 tradepose kernel
554
+ ```
555
+
556
+ ## 最佳實踐
557
+
558
+ 1. **使用 `quick_export()` 進行探索**
559
+ 2. **保存中間結果為 Parquet**
560
+ 3. **使用 `print_summary()` 快速檢查數據**
561
+ 4. **利用 Polars 的惰性執行優化性能**
562
+ 5. **在 notebook 中記錄分析思路**
563
+
564
+ ## 依賴
565
+
566
+ - **Python 3.13+**
567
+ - **polars** - 高效數據處理
568
+ - **redis** - Redis 連接
569
+ - **plotly** - 互動式圖表
570
+ - **hvplot** - 高階可視化
571
+ - **ipykernel** - Jupyter kernel
572
+ - **ipywidgets** - 互動式小工具
573
+
574
+ ## 授權
575
+
576
+ 此工具是 Tradepose 項目的一部分。
@@ -0,0 +1,15 @@
1
+ tradepose_client/__init__.py,sha256=cZL8Feo-ZkQ5bR7E-G7afg740Cu-oXaZ_s1ox6bPDqs,3549
2
+ tradepose_client/analysis.py,sha256=RNpk3i9_1uUXM_-K-xYbG3Ckg-MoOwQ6gSExua2N4N8,7563
3
+ tradepose_client/client.py,sha256=1qD4pnIjCXKgE3VXeB6EgkNuCXvDJEbmPldIjIzAVmk,1798
4
+ tradepose_client/models.py,sha256=j1UmUqGEIHObyAxfTETg5Kc83ipylr-Y0IivGuJB16M,66374
5
+ tradepose_client/schema.py,sha256=lPcJU-1xKcGFRoeuvqovrg4LUiOLO5bRZiMVyDkKHUQ,6357
6
+ tradepose_client/viz.py,sha256=qu9zyAXa_Q7D4rxdgN55JyYiY24ZD3r0jf2SWtqGZYg,22989
7
+ tradepose_client/api/__init__.py,sha256=ezeMxOBrUDRhlqZNO-X0X9KbNJGccDseKQ95zAvyhFY,218
8
+ tradepose_client/api/engine.py,sha256=IRmQPu7ECfFeIkve2b3txxt_D--v4arHvsVRZ0orx1w,1423
9
+ tradepose_client/api/export.py,sha256=gYW6yIHm1e0HZxvUA4k15tYqLfrihmssosJ2vXimT5k,27838
10
+ tradepose_client/api/health.py,sha256=NBZstYvVQszxDOstCmBt3A3anjNv7wuCsMOjup0DS5g,1889
11
+ tradepose_client/api/strategy.py,sha256=7cPurXqf9XCxyxSHaG_78GmEtg-KNJJhzNZNdn93ji8,7316
12
+ tradepose_client-0.1.0.dist-info/METADATA,sha256=Ked6fn17kxv90zUewN9-cGiv-wzCqFyT27YQMXhfv88,14056
13
+ tradepose_client-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
+ tradepose_client-0.1.0.dist-info/licenses/LICENSE,sha256=6qYWNkUbxmJl1iN7c4DoM1_8ASsZyXemFO1D0wXtiHk,1071
15
+ tradepose_client-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tradepose Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.