nextrade-engine 0.5.0__tar.gz → 0.6.0__tar.gz

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.
Files changed (27) hide show
  1. {nextrade_engine-0.5.0/nextrade_engine.egg-info → nextrade_engine-0.6.0}/PKG-INFO +2 -12
  2. nextrade_engine-0.6.0/nextrade/nextrade/__init__.py +194 -0
  3. nextrade_engine-0.6.0/nextrade/nextrade/lang.py +320 -0
  4. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/utils/terminal_ui.py +29 -31
  5. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0/nextrade/nextrade_engine.egg-info}/PKG-INFO +2 -12
  6. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0/nextrade}/nextrade_engine.egg-info/SOURCES.txt +6 -6
  7. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/pyproject.toml +5 -15
  8. nextrade_engine-0.5.0/nextrade/nextrade/__init__.py +0 -277
  9. nextrade_engine-0.5.0/nextrade/setup.py +0 -10
  10. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/LICENSE +0 -0
  11. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/README.md +0 -0
  12. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/backtest/__init__.py +0 -0
  13. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/backtest/engine.py +0 -0
  14. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/core/__init__.py +0 -0
  15. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/core/brain.py +0 -0
  16. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/core/regime.py +0 -0
  17. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/data/__init__.py +0 -0
  18. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/data/fetcher.py +0 -0
  19. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/indicators/__init__.py +0 -0
  20. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/indicators/adaptive.py +0 -0
  21. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/indicators/confluence.py +0 -0
  22. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/indicators/pattern.py +0 -0
  23. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/nextrade/nextrade/utils/__init__.py +0 -0
  24. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0/nextrade}/nextrade_engine.egg-info/dependency_links.txt +0 -0
  25. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0/nextrade}/nextrade_engine.egg-info/requires.txt +0 -0
  26. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0/nextrade}/nextrade_engine.egg-info/top_level.txt +0 -0
  27. {nextrade_engine-0.5.0 → nextrade_engine-0.6.0}/setup.cfg +0 -0
@@ -1,23 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextrade-engine
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: AI Trading Engine — Ringan, Multi-Market, Bisa di HP
5
5
  Author-email: NexTrade <wafiqrazy035@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/nextrade-ai/nextrade
8
- Project-URL: Issues, https://github.com/nextrade-ai/nextrade/issues
6
+ License-Expression: MIT
9
7
  Keywords: trading,ai,forex,crypto,backtest,signal
10
8
  Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Financial and Insurance Industry
12
9
  Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
10
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Classifier: Topic :: Office/Business :: Financial :: Investment
21
11
  Requires-Python: >=3.8
22
12
  Description-Content-Type: text/markdown
23
13
  License-File: LICENSE
@@ -0,0 +1,194 @@
1
+ """
2
+ NexTrade — AI Trading Engine
3
+ import nextrade → wizard muncul otomatis di terminal
4
+ """
5
+
6
+ from nextrade.lang import set_language, list_languages, get, current as _lang
7
+ from nextrade.utils.terminal_ui import (
8
+ print_welcome, print_signal, print_error,
9
+ print_loading, print_success, list_strategies, STRATEGIES
10
+ )
11
+ from nextrade.indicators.confluence import confluence_score
12
+ from nextrade.core.regime import detect_regime
13
+ from nextrade.core.brain import Brain
14
+ from nextrade.data.fetcher import fetch, fetch_multi, list_markets
15
+ import numpy as np
16
+
17
+ __version__ = "0.6.0"
18
+ __author__ = "NexTrade"
19
+
20
+ # Tampilkan wizard saat pertama kali import
21
+ print_welcome()
22
+
23
+ # Instance brain global
24
+ _brain = Brain.__new__(Brain)
25
+ _brain.state = None
26
+
27
+ def _get_brain():
28
+ global _brain
29
+ if _brain.state is None:
30
+ _brain = Brain()
31
+ return _brain
32
+
33
+ # ─────────────────────────────────────────
34
+ # PUBLIC API
35
+ # ─────────────────────────────────────────
36
+
37
+ def start(strategy: str = "adaptive",
38
+ market: str = "BTCUSD",
39
+ timeframe: str = "H1",
40
+ data: dict = None):
41
+ """
42
+ Jalankan NexTrade dengan strategi pilihan.
43
+
44
+ Contoh:
45
+ nextrade.start("momentum", market="BTCUSD")
46
+ nextrade.start("reversal", market="EURUSD", timeframe="H4")
47
+ """
48
+ strategy = strategy.lower().strip()
49
+
50
+ if strategy not in STRATEGIES:
51
+ print_error(f"{get('error_strategy')}: {', '.join(STRATEGIES)}")
52
+ list_strategies()
53
+ return
54
+
55
+ print_loading(f"{get('loading_strategy')} {strategy.upper()}...")
56
+
57
+ if data is None:
58
+ data = fetch(market, timeframe, bars=500)
59
+ if data is None:
60
+ print_error(get('error_data'))
61
+ return
62
+
63
+ print_loading(f"{get('loading_indicators')}...")
64
+
65
+ result = confluence_score(
66
+ opens = data["open"],
67
+ highs = data["high"],
68
+ lows = data["low"],
69
+ closes = data["close"],
70
+ )
71
+
72
+ brain = _get_brain()
73
+ threshold = brain.get_confidence_threshold()
74
+ confidence = result["confidence"]
75
+
76
+ if confidence >= threshold and result["details"]["pattern"]["direction"] != "bear":
77
+ signal = "BUY"
78
+ elif confidence <= (100 - threshold) or result["details"]["pattern"]["direction"] == "bear":
79
+ signal = "SELL"
80
+ else:
81
+ signal = "HOLD"
82
+
83
+ print_signal(signal=signal, confidence=confidence,
84
+ strategy=strategy, market=market)
85
+
86
+ regime = result["details"]["regime"]["regime"]
87
+ rsi = result["details"]["rsi"]
88
+ mom = result["details"]["momentum"]
89
+ price = data["price_now"]
90
+
91
+ print(f" \033[2m{get('detail_analysis')}:\033[0m")
92
+ print(f" \033[36m{get('price_now'):<18}:\033[0m {price:,.5f}")
93
+ print(f" \033[36m{get('market_condition'):<18}:\033[0m {get(regime)}")
94
+ print(f" \033[36mRSI Adaptif :\033[0m {rsi:.1f}")
95
+ print(f" \033[36m{get('iq_model'):<18}:\033[0m {brain.state['iq']} / 100")
96
+ print(f" \033[36m{get('agresivitas'):<18}:\033[0m {brain.state['agresivitas']}%")
97
+ print()
98
+
99
+ return {**result, "signal": signal, "market": market,
100
+ "price": price, "strategy": strategy}
101
+
102
+
103
+ def train(mode: str = "hybrid", market: str = "BTCUSD",
104
+ timeframe: str = "D1", bars: int = 1000):
105
+ """Latih brain NexTrade dengan data real market."""
106
+ print(f"\n \033[1m\033[37m Training NexTrade Brain\033[0m")
107
+ print(f" \033[36m{'─' * 40}\033[0m")
108
+ data = fetch(market, timeframe, bars=bars)
109
+ if data is None:
110
+ print_error(get('error_data'))
111
+ return
112
+ _get_brain().train(mode=mode, data=data)
113
+
114
+
115
+ def brain_status():
116
+ """Tampilkan status otak NexTrade."""
117
+ _get_brain().status()
118
+
119
+
120
+ def set_agresivitas(pct: int):
121
+ """Set agresivitas sinyal (0-100)."""
122
+ _get_brain().set_agresivitas(pct)
123
+
124
+
125
+ def scan(markets: list = None, timeframe: str = "H1"):
126
+ """Scan banyak market sekaligus."""
127
+ if markets is None:
128
+ markets = ["BTCUSD", "EURUSD", "XAUUSD", "AAPL", "TSLA"]
129
+
130
+ print(f"\n \033[1m\033[37m NexTrade Market Scanner\033[0m")
131
+ print(f" \033[36m{'─' * 55}\033[0m")
132
+ print(f" \033[2m{'MARKET':<12} {'HARGA':>14} {get('signal'):>8} "
133
+ f"{'CONFIDENCE':>12} {get('market_condition')}\033[0m")
134
+ print(f" \033[36m{'─' * 55}\033[0m")
135
+
136
+ results = []
137
+ for market in markets:
138
+ data = fetch(market, timeframe, bars=300, silent=True)
139
+ if data is None: continue
140
+ result = confluence_score(
141
+ opens=data["open"], highs=data["high"],
142
+ lows=data["low"], closes=data["close"],
143
+ )
144
+ signal = result["signal"]
145
+ confidence = result["confidence"]
146
+ regime = result["details"]["regime"]["regime"]
147
+ price = data["price_now"]
148
+ sc = "\033[32m" if signal=="BUY" else "\033[31m" if signal=="SELL" else "\033[33m"
149
+ print(f" {market:<12} {price:>14,.5f} {sc}{signal:>8}\033[0m "
150
+ f"{confidence:>10.1f}% \033[2m{regime}\033[0m")
151
+ results.append({**result, "market": market, "price": price})
152
+
153
+ print(f" \033[36m{'─' * 55}\033[0m\n")
154
+ buys = [r for r in results if r["signal"]=="BUY"]
155
+ sells = [r for r in results if r["signal"]=="SELL"]
156
+ if buys:
157
+ best = max(buys, key=lambda x: x["confidence"])
158
+ print(f" \033[32m★ BUY : {best['market']} ({best['confidence']:.1f}%)\033[0m")
159
+ if sells:
160
+ best = max(sells, key=lambda x: x["confidence"])
161
+ print(f" \033[31m★ SELL : {best['market']} ({best['confidence']:.1f}%)\033[0m")
162
+ print()
163
+ return results
164
+
165
+
166
+ def backtest(strategy: str = "adaptive", market: str = "BTCUSD",
167
+ timeframe: str = "D1", bars: int = 500,
168
+ agresivitas: int = 30, sl_pct: float = 2.0, tp_pct: float = 4.0):
169
+ """Backtest strategi dengan data real historis."""
170
+ from nextrade.backtest.engine import run as _run
171
+ data = fetch(market, timeframe, bars=bars)
172
+ if data is None:
173
+ print_error(get('error_data'))
174
+ return
175
+ return _run(data=data, strategy=strategy, agresivitas=agresivitas,
176
+ sl_pct=sl_pct, tp_pct=tp_pct)
177
+
178
+
179
+ def info():
180
+ """Tampilkan semua strategi dan market."""
181
+ list_strategies()
182
+ list_markets()
183
+
184
+
185
+ def regime(market: str = "BTCUSD", timeframe: str = "H1") -> dict:
186
+ """Deteksi kondisi pasar saat ini."""
187
+ data = fetch(market, timeframe, bars=100, silent=True)
188
+ if data is None: return {}
189
+ return detect_regime(data["close"])
190
+
191
+
192
+ def language():
193
+ """Tampilkan semua bahasa yang tersedia."""
194
+ list_languages()
@@ -0,0 +1,320 @@
1
+ """
2
+ NexTrade — Language System
3
+ Support: Indonesia (id), English (en), Melayu (my), Arab (ar)
4
+ """
5
+
6
+ LANGUAGES = {
7
+ "id": "Indonesia",
8
+ "en": "English",
9
+ "my": "Melayu",
10
+ "ar": "العربية",
11
+ }
12
+
13
+ TRANSLATIONS = {
14
+
15
+ # ── WELCOME ───────────────────────────────────────────
16
+ "welcome_title": {
17
+ "id": "Selamat datang di NexTrade!",
18
+ "en": "Welcome to NexTrade!",
19
+ "my": "Selamat datang ke NexTrade!",
20
+ "ar": "!مرحباً بك في NexTrade",
21
+ },
22
+ "welcome_sub": {
23
+ "id": "Engine AI trading ringan yang bisa jalan di HP sekalipun.",
24
+ "en": "Lightweight AI trading engine that runs even on mobile.",
25
+ "my": "Enjin dagangan AI ringan yang boleh berjalan di telefon.",
26
+ "ar": ".محرك تداول ذكاء اصطناعي خفيف يعمل حتى على الهاتف",
27
+ },
28
+ "strategies_title": {
29
+ "id": "Strategi tersedia",
30
+ "en": "Available strategies",
31
+ "my": "Strategi tersedia",
32
+ "ar": "الاستراتيجيات المتاحة",
33
+ },
34
+
35
+ # ── STRATEGI ──────────────────────────────────────────
36
+ "momentum": {
37
+ "id": "Ikut tren kuat · cocok market trending",
38
+ "en": "Follow strong trends · best for trending markets",
39
+ "my": "Ikut tren kuat · sesuai pasaran trending",
40
+ "ar": "اتبع الاتجاهات القوية · مناسب للأسواق المتجهة",
41
+ },
42
+ "reversal": {
43
+ "id": "Cari pembalikan arah · counter-trend",
44
+ "en": "Seek reversals · counter-trend strategy",
45
+ "my": "Cari pembalikan arah · strategi counter-trend",
46
+ "ar": "ابحث عن الانعكاسات · استراتيجية معاكسة للاتجاه",
47
+ },
48
+ "scalping": {
49
+ "id": "Entry cepat · target kecil · frekuensi tinggi",
50
+ "en": "Quick entries · small targets · high frequency",
51
+ "my": "Masuk cepat · sasaran kecil · frekuensi tinggi",
52
+ "ar": "دخول سريع · أهداف صغيرة · تكرار عالي",
53
+ },
54
+ "swing": {
55
+ "id": "Hold beberapa jam/hari · ikut swing besar",
56
+ "en": "Hold hours/days · follow major swings",
57
+ "my": "Tahan beberapa jam/hari · ikut swing besar",
58
+ "ar": "احتفظ لساعات/أيام · اتبع التأرجحات الكبيرة",
59
+ },
60
+ "adaptive": {
61
+ "id": "AI pilih strategi otomatis sesuai kondisi pasar",
62
+ "en": "AI auto-selects strategy based on market conditions",
63
+ "my": "AI pilih strategi secara automatik mengikut pasaran",
64
+ "ar": "الذكاء الاصطناعي يختار الاستراتيجية تلقائياً",
65
+ },
66
+
67
+ # ── HOW TO START ──────────────────────────────────────
68
+ "how_to_start": {
69
+ "id": "Cara mulai",
70
+ "en": "How to start",
71
+ "my": "Cara untuk mulakan",
72
+ "ar": "كيفية البدء",
73
+ },
74
+ "cmd_start": {
75
+ "id": "# langsung pakai strategi",
76
+ "en": "# use a strategy directly",
77
+ "my": "# guna strategi terus",
78
+ "ar": "# استخدم الاستراتيجية مباشرة",
79
+ },
80
+ "cmd_backtest": {
81
+ "id": "# test dulu sebelum live",
82
+ "en": "# test before going live",
83
+ "my": "# uji dahulu sebelum live",
84
+ "ar": "# اختبر قبل التداول الحي",
85
+ },
86
+ "cmd_info": {
87
+ "id": "# lihat semua pilihan",
88
+ "en": "# view all options",
89
+ "my": "# lihat semua pilihan",
90
+ "ar": "# عرض جميع الخيارات",
91
+ },
92
+
93
+ # ── SIGNAL ────────────────────────────────────────────
94
+ "signal": {
95
+ "id": "Sinyal",
96
+ "en": "Signal",
97
+ "my": "Isyarat",
98
+ "ar": "إشارة",
99
+ },
100
+ "confidence": {
101
+ "id": "Kepercayaan",
102
+ "en": "Confidence",
103
+ "my": "Keyakinan",
104
+ "ar": "الثقة",
105
+ },
106
+ "strategy": {
107
+ "id": "Strategi",
108
+ "en": "Strategy",
109
+ "my": "Strategi",
110
+ "ar": "الاستراتيجية",
111
+ },
112
+ "market": {
113
+ "id": "Market",
114
+ "en": "Market",
115
+ "my": "Pasaran",
116
+ "ar": "السوق",
117
+ },
118
+
119
+ # ── DETAIL ANALISIS ───────────────────────────────────
120
+ "detail_analysis": {
121
+ "id": "Detail Analisis",
122
+ "en": "Analysis Detail",
123
+ "my": "Butiran Analisis",
124
+ "ar": "تفاصيل التحليل",
125
+ },
126
+ "price_now": {
127
+ "id": "Harga Sekarang",
128
+ "en": "Current Price",
129
+ "my": "Harga Semasa",
130
+ "ar": "السعر الحالي",
131
+ },
132
+ "market_condition": {
133
+ "id": "Kondisi Pasar",
134
+ "en": "Market Condition",
135
+ "my": "Keadaan Pasaran",
136
+ "ar": "حالة السوق",
137
+ },
138
+ "iq_model": {
139
+ "id": "IQ Model",
140
+ "en": "Model IQ",
141
+ "my": "IQ Model",
142
+ "ar": "ذكاء النموذج",
143
+ },
144
+ "agresivitas": {
145
+ "id": "Agresivitas",
146
+ "en": "Aggressiveness",
147
+ "my": "Keagresifan",
148
+ "ar": "العدوانية",
149
+ },
150
+
151
+ # ── BRAIN ─────────────────────────────────────────────
152
+ "brain_title": {
153
+ "id": "NexTrade Brain — Status Model",
154
+ "en": "NexTrade Brain — Model Status",
155
+ "my": "NexTrade Brain — Status Model",
156
+ "ar": "NexTrade Brain — حالة النموذج",
157
+ },
158
+ "neurons_active": {
159
+ "id": "Neuron Aktif",
160
+ "en": "Active Neurons",
161
+ "my": "Neuron Aktif",
162
+ "ar": "الخلايا العصبية النشطة",
163
+ },
164
+ "last_trained": {
165
+ "id": "Terakhir Belajar",
166
+ "en": "Last Trained",
167
+ "my": "Latihan Terakhir",
168
+ "ar": "آخر تدريب",
169
+ },
170
+ "winrate": {
171
+ "id": "Winrate",
172
+ "en": "Win Rate",
173
+ "my": "Kadar Menang",
174
+ "ar": "معدل الفوز",
175
+ },
176
+
177
+ # ── LOADING ───────────────────────────────────────────
178
+ "loading_strategy": {
179
+ "id": "Memuat strategi",
180
+ "en": "Loading strategy",
181
+ "my": "Memuatkan strategi",
182
+ "ar": "جارٍ تحميل الاستراتيجية",
183
+ },
184
+ "loading_indicators": {
185
+ "id": "Menghitung indikator AI",
186
+ "en": "Calculating AI indicators",
187
+ "my": "Mengira penunjuk AI",
188
+ "ar": "جارٍ حساب مؤشرات الذكاء الاصطناعي",
189
+ },
190
+ "loading_data": {
191
+ "id": "Mengambil data",
192
+ "en": "Fetching data",
193
+ "my": "Mengambil data",
194
+ "ar": "جارٍ جلب البيانات",
195
+ },
196
+ "data_success": {
197
+ "id": "Data berhasil diambil",
198
+ "en": "Data fetched successfully",
199
+ "my": "Data berjaya diambil",
200
+ "ar": "تم جلب البيانات بنجاح",
201
+ },
202
+
203
+ # ── MARKET CONDITIONS ─────────────────────────────────
204
+ "TRENDING": {
205
+ "id": "TRENDING — Pasar sedang bergerak kuat",
206
+ "en": "TRENDING — Market moving strongly",
207
+ "my": "TRENDING — Pasaran bergerak kuat",
208
+ "ar": "TRENDING — السوق يتحرك بقوة",
209
+ },
210
+ "RANGING": {
211
+ "id": "RANGING — Pasar sedang sideways",
212
+ "en": "RANGING — Market moving sideways",
213
+ "my": "RANGING — Pasaran bergerak mendatar",
214
+ "ar": "RANGING — السوق يتحرك جانبياً",
215
+ },
216
+ "VOLATILE": {
217
+ "id": "VOLATILE — Pasar sedang tidak stabil",
218
+ "en": "VOLATILE — Market is unstable",
219
+ "my": "VOLATILE — Pasaran tidak stabil",
220
+ "ar": "VOLATILE — السوق غير مستقر",
221
+ },
222
+
223
+ # ── ERRORS ────────────────────────────────────────────
224
+ "error_strategy": {
225
+ "id": "Strategi tidak ditemukan. Pilih",
226
+ "en": "Strategy not found. Choose from",
227
+ "my": "Strategi tidak dijumpai. Pilih dari",
228
+ "ar": "الاستراتيجية غير موجودة. اختر من",
229
+ },
230
+ "error_data": {
231
+ "id": "Gagal ambil data market. Cek koneksi internet.",
232
+ "en": "Failed to fetch market data. Check your internet connection.",
233
+ "my": "Gagal mendapatkan data pasaran. Semak sambungan internet.",
234
+ "ar": "فشل في جلب بيانات السوق. تحقق من اتصالك بالإنترنت.",
235
+ },
236
+
237
+ # ── SET LANGUAGE ──────────────────────────────────────
238
+ "language_set": {
239
+ "id": "Bahasa diubah ke",
240
+ "en": "Language changed to",
241
+ "my": "Bahasa ditukar ke",
242
+ "ar": "تم تغيير اللغة إلى",
243
+ },
244
+ "language_invalid": {
245
+ "id": "Bahasa tidak tersedia. Pilih",
246
+ "en": "Language not available. Choose from",
247
+ "my": "Bahasa tidak tersedia. Pilih dari",
248
+ "ar": "اللغة غير متاحة. اختر من",
249
+ },
250
+
251
+ # ── BACKTEST ──────────────────────────────────────────
252
+ "backtest_title": {
253
+ "id": "NexTrade Backtest Engine",
254
+ "en": "NexTrade Backtest Engine",
255
+ "my": "NexTrade Enjin Ujian Balik",
256
+ "ar": "محرك الاختبار الخلفي NexTrade",
257
+ },
258
+ "total_trades": {
259
+ "id": "Total Trade",
260
+ "en": "Total Trades",
261
+ "my": "Jumlah Dagangan",
262
+ "ar": "إجمالي الصفقات",
263
+ },
264
+ "total_return": {
265
+ "id": "Total Return",
266
+ "en": "Total Return",
267
+ "my": "Jumlah Pulangan",
268
+ "ar": "إجمالي العائد",
269
+ },
270
+ "max_drawdown": {
271
+ "id": "Max Drawdown",
272
+ "en": "Max Drawdown",
273
+ "my": "Susutan Maksimum",
274
+ "ar": "أقصى تراجع",
275
+ },
276
+ "grade": {
277
+ "id": "Grade Model",
278
+ "en": "Model Grade",
279
+ "my": "Gred Model",
280
+ "ar": "تقييم النموذج",
281
+ },
282
+ }
283
+
284
+ # ── State bahasa aktif ─────────────────────────────────────
285
+ _current_lang = "id" # default Indonesia
286
+
287
+ def set_language(lang: str) -> bool:
288
+ """
289
+ Set bahasa NexTrade.
290
+ lang: 'id' | 'en' | 'my' | 'ar'
291
+ """
292
+ global _current_lang
293
+ lang = lang.lower().strip()
294
+ if lang not in LANGUAGES:
295
+ available = ", ".join([f"'{k}' ({v})" for k, v in LANGUAGES.items()])
296
+ print(f"\n \033[31m✗\033[0m {get('language_invalid')}: {available}\n")
297
+ return False
298
+ _current_lang = lang
299
+ lang_name = LANGUAGES[lang]
300
+ print(f"\n \033[32m✓\033[0m {get('language_set')}: \033[1m{lang_name}\033[0m\n")
301
+ return True
302
+
303
+ def get(key: str, lang: str = None) -> str:
304
+ """Ambil teks dalam bahasa aktif."""
305
+ lang = lang or _current_lang
306
+ if key not in TRANSLATIONS:
307
+ return key
308
+ return TRANSLATIONS[key].get(lang, TRANSLATIONS[key].get("en", key))
309
+
310
+ def current() -> str:
311
+ """Return kode bahasa aktif."""
312
+ return _current_lang
313
+
314
+ def list_languages():
315
+ """Tampilkan semua bahasa yang tersedia."""
316
+ print(f"\n \033[1m\033[37m Bahasa tersedia / Available languages:\033[0m\n")
317
+ for code, name in LANGUAGES.items():
318
+ active = " \033[32m← aktif\033[0m" if code == _current_lang else ""
319
+ print(f" \033[33mnextrade.set_language('{code}')\033[0m → {name}{active}")
320
+ print()
@@ -1,9 +1,11 @@
1
1
  """
2
2
  NexTrade — Terminal UI
3
3
  Semua tampilan, warna, dan wizard di terminal.
4
+ Support multi-bahasa via lang.py
4
5
  """
5
6
  import sys
6
7
  import time
8
+ from nextrade.lang import get, current
7
9
 
8
10
  class Color:
9
11
  RESET = "\033[0m"
@@ -17,15 +19,10 @@ class Color:
17
19
 
18
20
  C = Color()
19
21
 
20
- STRATEGIES = {
21
- "momentum" : "Ikut tren kuat · cocok market trending",
22
- "reversal" : "Cari pembalikan arah · counter-trend",
23
- "scalping" : "Entry cepat · target kecil · frekuensi tinggi",
24
- "swing" : "Hold beberapa jam/hari · ikut swing besar",
25
- "adaptive" : "AI pilih strategi otomatis sesuai kondisi pasar",
26
- }
22
+ STRATEGIES = ["momentum", "reversal", "scalping", "swing", "adaptive"]
27
23
 
28
- SEP = "─" * 68
24
+ SEP = "─" * 68
25
+ SEP2 = "─" * 50
29
26
 
30
27
  def print_banner():
31
28
  print(f"""
@@ -41,16 +38,17 @@ def print_banner():
41
38
 
42
39
  def print_welcome():
43
40
  print_banner()
44
- print(f"{C.BOLD}{C.WHITE} Selamat datang di NexTrade!{C.RESET}")
45
- print(f"{C.DIM} Engine AI trading ringan yang bisa jalan di HP sekalipun.{C.RESET}\n")
46
- print(f"{C.CYAN} ┌─ Strategi tersedia ─────────────────────────────────┐{C.RESET}")
47
- for i, (name, desc) in enumerate(STRATEGIES.items(), 1):
41
+ print(f"{C.BOLD}{C.WHITE} {get('welcome_title')}{C.RESET}")
42
+ print(f"{C.DIM} {get('welcome_sub')}{C.RESET}\n")
43
+ print(f"{C.CYAN} ┌─ {get('strategies_title')} ──────────────────────────────┐{C.RESET}")
44
+ for i, name in enumerate(STRATEGIES, 1):
45
+ desc = get(name)
48
46
  print(f"{C.CYAN} │{C.RESET} {C.BOLD}{C.YELLOW}{i}. {name:<12}{C.RESET} {C.DIM}-> {desc}{C.RESET}")
49
47
  print(f"{C.CYAN} └─────────────────────────────────────────────────────┘{C.RESET}\n")
50
- print(f" {C.DIM}Cara mulai:{C.RESET}")
51
- print(f" {C.GREEN}nextrade.start(\"momentum\"){C.RESET} {C.DIM}# langsung pakai strategi{C.RESET}")
52
- print(f" {C.GREEN}nextrade.backtest(\"momentum\"){C.RESET} {C.DIM}# test dulu sebelum live{C.RESET}")
53
- print(f" {C.GREEN}nextrade.info(){C.RESET} {C.DIM}# lihat semua pilihan{C.RESET}\n")
48
+ print(f" {C.DIM}{get('how_to_start')}:{C.RESET}")
49
+ print(f" {C.GREEN}nextrade.start(\"momentum\"){C.RESET} {C.DIM}# {get('cmd_start')}{C.RESET}")
50
+ print(f" {C.GREEN}nextrade.backtest(\"momentum\"){C.RESET} {C.DIM}# {get('cmd_backtest')}{C.RESET}")
51
+ print(f" {C.GREEN}nextrade.info(){C.RESET} {C.DIM}# {get('cmd_info')}{C.RESET}\n")
54
52
 
55
53
  def print_loading(text: str, delay: float = 0.03):
56
54
  steps = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]
@@ -58,30 +56,30 @@ def print_loading(text: str, delay: float = 0.03):
58
56
  sys.stdout.write(f"\r {C.CYAN}{steps[i % len(steps)]}{C.RESET} {text}")
59
57
  sys.stdout.flush()
60
58
  time.sleep(delay)
61
- sys.stdout.write(f"\r {C.GREEN}v{C.RESET} {text}\n")
59
+ sys.stdout.write(f"\r {C.GREEN}{C.RESET} {text}\n")
62
60
  sys.stdout.flush()
63
61
 
64
- def print_signal(signal: str, confidence: float, strategy: str, market: str = ""):
62
+ def print_signal(signal: str, confidence: float,
63
+ strategy: str, market: str = ""):
65
64
  color = C.GREEN if signal == "BUY" else C.RED if signal == "SELL" else C.YELLOW
66
65
  bar_len = int(confidence / 5)
67
66
  bar = "█" * bar_len + "░" * (20 - bar_len)
68
- sep2 = "" * 50
69
- print(f"\n{C.CYAN}{sep2}{C.RESET}")
70
- print(f" {C.BOLD}Strategi :{C.RESET} {strategy}")
67
+ print(f"\n{C.CYAN}{SEP2}{C.RESET}")
68
+ print(f" {C.BOLD}{get('strategy'):<14}:{C.RESET} {strategy}")
71
69
  if market:
72
- print(f" {C.BOLD}Market :{C.RESET} {market}")
73
- print(f" {C.BOLD}Sinyal :{C.RESET} {color}{C.BOLD} {signal} {C.RESET}")
74
- print(f" {C.BOLD}Confidence:{C.RESET} {color}{bar}{C.RESET} {confidence:.1f}%")
75
- print(f"{C.CYAN}{sep2}{C.RESET}\n")
70
+ print(f" {C.BOLD}{get('market'):<14}:{C.RESET} {market}")
71
+ print(f" {C.BOLD}{get('signal'):<14}:{C.RESET} {color}{C.BOLD} {signal} {C.RESET}")
72
+ print(f" {C.BOLD}{get('confidence'):<14}:{C.RESET} {color}{bar}{C.RESET} {confidence:.1f}%")
73
+ print(f"{C.CYAN}{SEP2}{C.RESET}\n")
76
74
 
77
75
  def print_error(msg: str):
78
- print(f"\n {C.RED}x Error:{C.RESET} {msg}\n")
76
+ print(f"\n {C.RED} {C.RESET}{msg}\n")
79
77
 
80
78
  def print_success(msg: str):
81
- print(f" {C.GREEN}v{C.RESET} {msg}")
79
+ print(f" {C.GREEN}{C.RESET} {msg}")
82
80
 
83
81
  def list_strategies():
84
- print(f"\n{C.BOLD}{C.WHITE} Strategi NexTrade:{C.RESET}\n")
85
- for name, desc in STRATEGIES.items():
86
- print(f" {C.YELLOW}{C.BOLD}{name:<14}{C.RESET} {desc}")
87
- print()
82
+ print(f"\n{C.BOLD}{C.WHITE} {get('strategies_title')}:{C.RESET}\n")
83
+ for name in STRATEGIES:
84
+ print(f" {C.YELLOW}{C.BOLD}{name:<14}{C.RESET} {get(name)}")
85
+ print()
@@ -1,23 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextrade-engine
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: AI Trading Engine — Ringan, Multi-Market, Bisa di HP
5
5
  Author-email: NexTrade <wafiqrazy035@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/nextrade-ai/nextrade
8
- Project-URL: Issues, https://github.com/nextrade-ai/nextrade/issues
6
+ License-Expression: MIT
9
7
  Keywords: trading,ai,forex,crypto,backtest,signal
10
8
  Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Financial and Insurance Industry
12
9
  Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
10
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Classifier: Topic :: Office/Business :: Financial :: Investment
21
11
  Requires-Python: >=3.8
22
12
  Description-Content-Type: text/markdown
23
13
  License-File: LICENSE
@@ -1,8 +1,8 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
- nextrade/setup.py
5
4
  nextrade/nextrade/__init__.py
5
+ nextrade/nextrade/lang.py
6
6
  nextrade/nextrade/backtest/__init__.py
7
7
  nextrade/nextrade/backtest/engine.py
8
8
  nextrade/nextrade/core/__init__.py
@@ -16,8 +16,8 @@ nextrade/nextrade/indicators/confluence.py
16
16
  nextrade/nextrade/indicators/pattern.py
17
17
  nextrade/nextrade/utils/__init__.py
18
18
  nextrade/nextrade/utils/terminal_ui.py
19
- nextrade_engine.egg-info/PKG-INFO
20
- nextrade_engine.egg-info/SOURCES.txt
21
- nextrade_engine.egg-info/dependency_links.txt
22
- nextrade_engine.egg-info/requires.txt
23
- nextrade_engine.egg-info/top_level.txt
19
+ nextrade/nextrade_engine.egg-info/PKG-INFO
20
+ nextrade/nextrade_engine.egg-info/SOURCES.txt
21
+ nextrade/nextrade_engine.egg-info/dependency_links.txt
22
+ nextrade/nextrade_engine.egg-info/requires.txt
23
+ nextrade/nextrade_engine.egg-info/top_level.txt
@@ -4,26 +4,18 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "nextrade-engine"
7
- version = "0.5.0"
7
+ version = "0.6.0"
8
8
  description = "AI Trading Engine — Ringan, Multi-Market, Bisa di HP"
9
9
  readme = "README.md"
10
- license = {text = "MIT"}
10
+ license = "MIT"
11
11
  authors = [
12
12
  {name = "NexTrade", email = "wafiqrazy035@gmail.com"}
13
13
  ]
14
14
  keywords = ["trading", "ai", "forex", "crypto", "backtest", "signal"]
15
15
  classifiers = [
16
16
  "Development Status :: 4 - Beta",
17
- "Intended Audience :: Financial and Insurance Industry",
18
17
  "Intended Audience :: Developers",
19
- "License :: OSI Approved :: MIT License",
20
18
  "Programming Language :: Python :: 3",
21
- "Programming Language :: Python :: 3.8",
22
- "Programming Language :: Python :: 3.9",
23
- "Programming Language :: Python :: 3.10",
24
- "Programming Language :: Python :: 3.11",
25
- "Programming Language :: Python :: 3.12",
26
- "Topic :: Office/Business :: Financial :: Investment",
27
19
  ]
28
20
  requires-python = ">=3.8"
29
21
  dependencies = [
@@ -31,10 +23,8 @@ dependencies = [
31
23
  "yfinance",
32
24
  ]
33
25
 
34
- [project.urls]
35
- Homepage = "https://github.com/nextrade-ai/nextrade"
36
- Issues = "https://github.com/nextrade-ai/nextrade/issues"
26
+ [tool.setuptools]
27
+ package-dir = {"" = "nextrade"}
37
28
 
38
29
  [tool.setuptools.packages.find]
39
- where = ["."]
40
- include = ["nextrade*"]
30
+ where = ["nextrade"]
@@ -1,277 +0,0 @@
1
- """
2
- NexTrade — AI Trading Engine
3
- import nextrade → wizard muncul otomatis di terminal
4
- """
5
-
6
- from nextrade.utils.terminal_ui import (
7
- print_welcome, print_signal, print_error,
8
- print_loading, print_success, list_strategies, STRATEGIES
9
- )
10
- from nextrade.indicators.confluence import confluence_score
11
- from nextrade.core.regime import detect_regime
12
- from nextrade.core.brain import Brain
13
- from nextrade.data.fetcher import fetch, fetch_multi, list_markets
14
- import numpy as np
15
-
16
- __version__ = "0.3.0"
17
- __author__ = "NexTrade"
18
-
19
- # Tampilkan wizard saat pertama kali import
20
- print_welcome()
21
-
22
- # Instance brain global
23
- _brain = Brain.__new__(Brain)
24
- _brain.state = None
25
-
26
- def _get_brain():
27
- global _brain
28
- if _brain.state is None:
29
- _brain = Brain()
30
- return _brain
31
-
32
- # ─────────────────────────────────────────
33
- # PUBLIC API
34
- # ─────────────────────────────────────────
35
-
36
- def start(strategy: str = "adaptive",
37
- market: str = "BTCUSD",
38
- timeframe: str = "H1",
39
- data: dict = None):
40
- """
41
- Jalankan NexTrade — ambil data real lalu keluarkan sinyal.
42
-
43
- Contoh:
44
- nextrade.start("momentum", market="BTCUSD")
45
- nextrade.start("reversal", market="EURUSD", timeframe="M15")
46
- nextrade.start("adaptive", market="AAPL")
47
- """
48
- strategy = strategy.lower().strip()
49
-
50
- if strategy not in STRATEGIES:
51
- print_error(f"Strategi '{strategy}' tidak ditemukan.")
52
- list_strategies()
53
- return
54
-
55
- print_loading(f"Memuat strategi {strategy.upper()}...")
56
-
57
- # Ambil data real kalau tidak ada data manual
58
- if data is None:
59
- data = fetch(market, timeframe, bars=500)
60
- if data is None:
61
- print_error("Gagal ambil data market. Cek koneksi internet.")
62
- return
63
-
64
- print_loading("Menghitung indikator AI...")
65
-
66
- # Hitung sinyal pakai confluence score
67
- result = confluence_score(
68
- opens = data["open"],
69
- highs = data["high"],
70
- lows = data["low"],
71
- closes = data["close"],
72
- )
73
-
74
- # Sesuaikan confidence threshold dengan agresivitas brain
75
- brain = _get_brain()
76
- threshold = brain.get_confidence_threshold()
77
- confidence = result["confidence"]
78
-
79
- # Adjust sinyal berdasarkan threshold agresivitas
80
- if confidence >= threshold and result["details"]["pattern"]["direction"] != "bear":
81
- signal = "BUY"
82
- elif confidence <= (100 - threshold) or result["details"]["pattern"]["direction"] == "bear":
83
- signal = "SELL"
84
- else:
85
- signal = "HOLD"
86
-
87
- # Tampilkan sinyal
88
- print_signal(
89
- signal = signal,
90
- confidence = confidence,
91
- strategy = strategy,
92
- market = market,
93
- )
94
-
95
- # Tampilkan detail tambahan
96
- regime = result["details"]["regime"]["regime"]
97
- rsi = result["details"]["rsi"]
98
- mom = result["details"]["momentum"]
99
- price = data["price_now"]
100
-
101
- print(f" \033[2mDetail Analisis:\033[0m")
102
- print(f" \033[36mHarga Sekarang :\033[0m {price:,.5f}")
103
- print(f" \033[36mKondisi Pasar :\033[0m {regime}")
104
- print(f" \033[36mRSI Adaptif :\033[0m {rsi:.1f}")
105
- print(f" \033[36mMomentum Score :\033[0m {mom:.1f}")
106
- print(f" \033[36mIQ Model :\033[0m {brain.state['iq']} / 100")
107
- print(f" \033[36mAgresivitas :\033[0m {brain.state['agresivitas']}%")
108
- print()
109
-
110
- return {**result, "signal": signal, "market": market,
111
- "price": price, "strategy": strategy}
112
-
113
-
114
- def train(mode: str = "hybrid", market: str = "BTCUSD",
115
- timeframe: str = "D1", bars: int = 1000):
116
- """
117
- Latih brain NexTrade dengan data real market.
118
-
119
- Contoh:
120
- nextrade.train("offline", market="BTCUSD", timeframe="D1")
121
- nextrade.train("hybrid", market="EURUSD", timeframe="H4")
122
- nextrade.train("online", market="AAPL", timeframe="D1")
123
- """
124
- print(f"\n \033[1m\033[37m Training NexTrade Brain\033[0m")
125
- print(f" \033[36m{'─' * 40}\033[0m")
126
-
127
- # Ambil data real untuk training
128
- data = fetch(market, timeframe, bars=bars)
129
- if data is None:
130
- print_error("Gagal ambil data untuk training.")
131
- return
132
-
133
- brain = _get_brain()
134
- brain.train(mode=mode, data=data)
135
-
136
-
137
- def brain_status():
138
- """Tampilkan status otak NexTrade."""
139
- _get_brain().status()
140
-
141
-
142
- def set_agresivitas(pct: int):
143
- """
144
- Set seberapa agresif NexTrade dalam mengambil sinyal.
145
- 0 = sangat selektif (sedikit sinyal tapi akurat)
146
- 100 = sangat agresif (banyak sinyal)
147
-
148
- Contoh:
149
- nextrade.set_agresivitas(20) # konservatif
150
- nextrade.set_agresivitas(50) # moderat
151
- nextrade.set_agresivitas(80) # agresif
152
- """
153
- _get_brain().set_agresivitas(pct)
154
-
155
-
156
- def scan(markets: list = None, strategy: str = "adaptive",
157
- timeframe: str = "H1"):
158
- """
159
- Scan banyak market sekaligus — cari peluang trading terbaik.
160
-
161
- Contoh:
162
- nextrade.scan(["BTCUSD", "EURUSD", "AAPL"])
163
- nextrade.scan(["BTCUSD", "ETHUSD", "SOLUSD"], timeframe="H4")
164
- """
165
- if markets is None:
166
- markets = ["BTCUSD", "EURUSD", "XAUUSD", "AAPL", "TSLA"]
167
-
168
- print(f"\n \033[1m\033[37m NexTrade Market Scanner\033[0m")
169
- print(f" \033[36m{'─' * 55}\033[0m")
170
- print(f" \033[2m{'MARKET':<12} {'HARGA':>14} {'SINYAL':>8} {'CONFIDENCE':>12} {'REGIME'}\033[0m")
171
- print(f" \033[36m{'─' * 55}\033[0m")
172
-
173
- results = []
174
- for market in markets:
175
- data = fetch(market, timeframe, bars=300, silent=True)
176
- if data is None:
177
- continue
178
-
179
- result = confluence_score(
180
- opens = data["open"],
181
- highs = data["high"],
182
- lows = data["low"],
183
- closes = data["close"],
184
- )
185
-
186
- signal = result["signal"]
187
- confidence = result["confidence"]
188
- regime = result["details"]["regime"]["regime"]
189
- price = data["price_now"]
190
-
191
- # Warna sinyal
192
- if signal == "BUY":
193
- sc = "\033[32m"
194
- elif signal == "SELL":
195
- sc = "\033[31m"
196
- else:
197
- sc = "\033[33m"
198
-
199
- print(f" {market:<12} {price:>14,.5f} {sc}{signal:>8}\033[0m "
200
- f"{confidence:>10.1f}% \033[2m{regime}\033[0m")
201
-
202
- results.append({**result, "market": market, "price": price})
203
-
204
- print(f" \033[36m{'─' * 55}\033[0m\n")
205
-
206
- # Highlight sinyal terkuat
207
- buys = [r for r in results if r["signal"] == "BUY"]
208
- sells = [r for r in results if r["signal"] == "SELL"]
209
-
210
- if buys:
211
- best = max(buys, key=lambda x: x["confidence"])
212
- print(f" \033[32m★ Peluang BUY terkuat : {best['market']} "
213
- f"({best['confidence']:.1f}%)\033[0m")
214
- if sells:
215
- best = max(sells, key=lambda x: x["confidence"])
216
- print(f" \033[31m★ Peluang SELL terkuat : {best['market']} "
217
- f"({best['confidence']:.1f}%)\033[0m")
218
- print()
219
- return results
220
-
221
-
222
- def backtest(strategy: str = "adaptive", market: str = "BTCUSD",
223
- timeframe: str = "D1"):
224
- """Jalankan backtest strategi (coming soon v0.4.0)."""
225
- print_loading("Menyiapkan backtest engine...")
226
- print_success("Backtest engine hadir di v0.4.0!")
227
-
228
-
229
- def info():
230
- """Tampilkan semua strategi dan market yang tersedia."""
231
- list_strategies()
232
- list_markets()
233
-
234
-
235
- def regime(market: str = "BTCUSD", timeframe: str = "H1") -> dict:
236
- """
237
- Deteksi kondisi pasar saat ini.
238
-
239
- Contoh:
240
- r = nextrade.regime("EURUSD")
241
- print(r["regime"]) # TRENDING / RANGING / VOLATILE
242
- """
243
- data = fetch(market, timeframe, bars=100, silent=True)
244
- if data is None:
245
- return {}
246
- return detect_regime(data["close"])
247
-
248
-
249
- def backtest(strategy: str = "adaptive",
250
- market: str = "BTCUSD",
251
- timeframe: str = "D1",
252
- bars: int = 500,
253
- agresivitas: int = 30,
254
- sl_pct: float = 2.0,
255
- tp_pct: float = 4.0):
256
- """
257
- Backtest strategi NexTrade dengan data real historis.
258
-
259
- Contoh:
260
- nextrade.backtest("momentum", market="BTCUSD", timeframe="D1")
261
- nextrade.backtest("adaptive", market="EURUSD", agresivitas=50)
262
- nextrade.backtest("reversal", market="AAPL", sl_pct=1.5, tp_pct=3.0)
263
- """
264
- from nextrade.backtest.engine import run as _run
265
-
266
- data = fetch(market, timeframe, bars=bars)
267
- if data is None:
268
- print_error("Gagal ambil data untuk backtest.")
269
- return
270
-
271
- return _run(
272
- data = data,
273
- strategy = strategy,
274
- agresivitas = agresivitas,
275
- sl_pct = sl_pct,
276
- tp_pct = tp_pct,
277
- )
@@ -1,10 +0,0 @@
1
- from setuptools import setup, find_packages
2
-
3
- setup(
4
- name="nextrade",
5
- version="0.1.0",
6
- description="AI Trading Engine — Ringan, Multi-Market, Bisa di HP",
7
- packages=find_packages(),
8
- install_requires=["numpy"],
9
- python_requires=">=3.8",
10
- )
File without changes