Template Jurnal Khusus Untuk Metode "Beli Sore Jual Pagi"
Template Jurnal Khusus Untuk Metode "Beli Sore Jual Pagi"
Baik! Saya buatkan dua hal sekaligus: (1) Template Jurnal khusus metode "Beli Sore Jual Pagi" dan (2) Kalkulator Risiko untuk menghitung stop loss 1–3%.
Keduanya bisa Anda implementasikan langsung di aplikasi T Trading sebagai fitur baru.
URL Link Aplikasi T Trading: Di Sini T Trading
---
📓 BAGIAN 1: TEMPLATE JURNAL "BELI SORE JUAL PAGI"
📄 FILE: src/data/jurnalTemplate.json (BARU)
```json
{
"versi": "1.0",
"metode": "Beli Sore Jual Pagi",
"deskripsi": "Jurnal khusus untuk strategi day trading dengan holding overnight",
"fieldWajib": [
"tanggal",
"kodeSaham",
"hargaBeli",
"lot",
"hargaJual",
"profit",
"emosi",
"pilar"
],
"fieldOpsional": [
"catatan",
"alasanEntry",
"alasanExit",
"kondisiPasar"
],
"pilarOptions": [
{ "value": "rajaMakro", "label": "Raja Makro" },
{ "value": "pembunuh", "label": "Pembunuh Jangka Pendek" },
{ "value": "sentuhanEmas", "label": "Sentuhan Emas" },
{ "value": "dewaFundamental", "label": "Dewa Fundamental" }
],
"emosiOptions": [
{ "value": "tenang", "label": "Tenang", "icon": "😌" },
{ "value": "cemas", "label": "Cemas", "icon": "😰" },
{ "value": "serakah", "label": "Serakah", "icon": "🤑" },
{ "value": "ragu", "label": "Ragu", "icon": "🤔" },
{ "value": "puas", "label": "Puas", "icon": "😊" },
{ "value": "kecewa", "label": "Kecewa", "icon": "😞" }
],
"kondisiPasar": [
{ "value": "bullish", "label": "Bullish" },
{ "value": "bearish", "label": "Bearish" },
{ "value": "sideways", "label": "Sideways" }
]
}
```
---
📄 FILE: src/pages/JurnalBSP/index.jsx (BARU)
```jsx
import { useState } from 'react'
import Card from '../../components/ui/Card'
import Badge from '../../components/ui/Badge'
import Button from '../../components/ui/Button'
import { storage, STORAGE_KEYS } from '../../utils/storage'
export default function JurnalBSP() {
const [jurnal, setJurnal] = useState(() => storage.get('jurnalBSP', []))
const [form, setForm] = useState({
tanggal: new Date().toISOString().split('T')[0],
kodeSaham: '',
hargaBeli: '',
lot: 1,
hargaJual: '',
emosi: 'tenang',
pilar: 'pembunuh',
kondisiPasar: 'sideways',
alasanEntry: '',
alasanExit: '',
catatan: '',
})
const formatRupiah = (angka) =>
new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
}).format(angka || 0)
const hitungProfit = () => {
const beli = parseFloat(form.hargaBeli) || 0
const jual = parseFloat(form.hargaJual) || 0
const lot = parseInt(form.lot) || 0
return (jual - beli) * lot * 100
}
const hitungProfitPersen = () => {
const beli = parseFloat(form.hargaBeli) || 0
const jual = parseFloat(form.hargaJual) || 0
if (beli === 0) return 0
return ((jual - beli) / beli) * 100
}
const handleSubmit = (e) => {
e.preventDefault()
const profit = hitungProfit()
const profitPersen = hitungProfitPersen()
const amal = profit > 0 ? profit * 0.02 : 0
const newEntry = {
id: Date.now(),
...form,
profit,
profitPersen,
amal,
createdAt: new Date().toISOString(),
}
const updated = [newEntry, ...jurnal]
setJurnal(updated)
storage.set('jurnalBSP', updated)
// Reset form
setForm({
tanggal: new Date().toISOString().split('T')[0],
kodeSaham: '',
hargaBeli: '',
lot: 1,
hargaJual: '',
emosi: 'tenang',
pilar: 'pembunuh',
kondisiPasar: 'sideways',
alasanEntry: '',
alasanExit: '',
catatan: '',
})
}
const handleHapus = (id) => {
const updated = jurnal.filter((j) => j.id !== id)
setJurnal(updated)
storage.set('jurnalBSP', updated)
}
// Statistik
const totalTrade = jurnal.length
const totalProfit = jurnal.reduce((sum, j) => sum + j.profit, 0)
const winRate =
totalTrade > 0
? (jurnal.filter((j) => j.profit > 0).length / totalTrade) * 100
: 0
const totalAmal = jurnal.reduce((sum, j) => sum + j.amal, 0)
const getWarnaProfit = (profit) => {
if (profit > 0) return 'text-green-600'
if (profit < 0) return 'text-red-600'
return 'text-slate-600'
}
const getIconEmosi = (emosi) => {
const map = {
tenang: '😌',
cemas: '😰',
serakah: '🤑',
ragu: '🤔',
puas: '😊',
kecewa: '😞',
}
return map[emosi] || '😐'
}
return (
<div className="space-y-6 fade-in">
<div>
<h1 className="text-3xl font-bold text-slate-800 dark:text-white">
📓 Jurnal Beli Sore Jual Pagi
</h1>
<p className="text-slate-500 dark:text-slate-400 mt-1">
Catat setiap trade metode day trading holding overnight.
</p>
</div>
{/* STATISTIK */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
<Card className="text-center">
<p className="text-xs text-slate-500 dark:text-slate-400">Total Trade</p>
<p className="text-2xl font-bold text-slate-800 dark:text-white">{totalTrade}</p>
</Card>
<Card className="text-center">
<p className="text-xs text-slate-500 dark:text-slate-400">Total Profit</p>
<p className={`text-2xl font-bold ${getWarnaProfit(totalProfit)}`}>
{formatRupiah(totalProfit)}
</p>
</Card>
<Card className="text-center">
<p className="text-xs text-slate-500 dark:text-slate-400">Win Rate</p>
<p className="text-2xl font-bold text-amber-500">
{winRate.toFixed(1)}%
</p>
</Card>
<Card className="text-center">
<p className="text-xs text-slate-500 dark:text-slate-400">Total Amal</p>
<p className="text-2xl font-bold text-pink-500">{formatRupiah(totalAmal)}</p>
</Card>
</div>
{/* FORM ENTRI */}
<Card title="✍️ Entri Jurnal Baru" icon="">
<form onSubmit={handleSubmit} className="space-y-4">
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Tanggal
</label>
<input
type="date"
value={form.tanggal}
onChange={(e) => setForm({ ...form, tanggal: e.target.value })}
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Kode Saham
</label>
<input
type="text"
value={form.kodeSaham}
onChange={(e) => setForm({ ...form, kodeSaham: e.target.value.toUpperCase() })}
placeholder="BRIS"
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
</div>
<div className="grid grid-cols-3 gap-3">
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Harga Beli
</label>
<input
type="number"
value={form.hargaBeli}
onChange={(e) => setForm({ ...form, hargaBeli: e.target.value })}
placeholder="1800"
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Lot
</label>
<input
type="number"
value={form.lot}
onChange={(e) => setForm({ ...form, lot: e.target.value })}
min="1"
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Harga Jual
</label>
<input
type="number"
value={form.hargaJual}
onChange={(e) => setForm({ ...form, hargaJual: e.target.value })}
placeholder="1830"
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
</div>
{/* PREVIEW PROFIT */}
{form.hargaBeli && form.hargaJual && (
<div className="p-3 bg-slate-50 dark:bg-slate-700 rounded-xl">
<div className="flex justify-between items-center">
<span className="text-sm text-slate-600 dark:text-slate-300">
Estimasi Profit:
</span>
<span className={`font-bold ${getWarnaProfit(hitungProfit())}`}>
{formatRupiah(hitungProfit())} ({hitungProfitPersen().toFixed(2)}%)
</span>
</div>
{hitungProfit() > 0 && (
<div className="flex justify-between items-center mt-1">
<span className="text-xs text-slate-500 dark:text-slate-400">
Amal 2%:
</span>
<span className="text-xs font-semibold text-pink-500">
{formatRupiah(hitungProfit() * 0.02)}
</span>
</div>
)}
</div>
)}
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Emosi
</label>
<select
value={form.emosi}
onChange={(e) => setForm({ ...form, emosi: e.target.value })}
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
>
<option value="tenang">😌 Tenang</option>
<option value="cemas">😰 Cemas</option>
<option value="serakah">🤑 Serakah</option>
<option value="ragu">🤔 Ragu</option>
<option value="puas">😊 Puas</option>
<option value="kecewa">😞 Kecewa</option>
</select>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Pilar
</label>
<select
value={form.pilar}
onChange={(e) => setForm({ ...form, pilar: e.target.value })}
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
>
<option value="rajaMakro">🧘 Raja Makro</option>
<option value="pembunuh">🐺 Pembunuh</option>
<option value="sentuhanEmas">✨ Sentuhan Emas</option>
<option value="dewaFundamental">💎 Dewa Fundamental</option>
</select>
</div>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Kondisi Pasar
</label>
<select
value={form.kondisiPasar}
onChange={(e) => setForm({ ...form, kondisiPasar: e.target.value })}
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
>
<option value="bullish">🐂 Bullish</option>
<option value="bearish">🐻 Bearish</option>
<option value="sideways">➡️ Sideways</option>
</select>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Alasan Entry
</label>
<input
type="text"
value={form.alasanEntry}
onChange={(e) => setForm({ ...form, alasanEntry: e.target.value })}
placeholder="Contoh: breakout MA50, volume naik"
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Alasan Exit
</label>
<input
type="text"
value={form.alasanExit}
onChange={(e) => setForm({ ...form, alasanExit: e.target.value })}
placeholder="Contoh: sudah target profit 2%"
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Catatan
</label>
<textarea
value={form.catatan}
onChange={(e) => setForm({ ...form, catatan: e.target.value })}
rows="2"
placeholder="Pelajaran hari ini..."
className="w-full px-3 py-2 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white text-sm"
/>
</div>
<Button type="submit" className="w-full">
💾 Simpan Jurnal
</Button>
</form>
</Card>
{/* DAFTAR JURNAL */}
<Card title="📚 Riwayat Jurnal" icon="">
{jurnal.length === 0 ? (
<p className="text-center text-slate-400 py-6">
Belum ada jurnal. Mulai catat trade pertama Anda!
</p>
) : (
<div className="space-y-3 max-h-[600px] overflow-y-auto">
{jurnal.map((j) => (
<div
key={j.id}
className="p-4 bg-slate-50 dark:bg-slate-700 rounded-xl"
>
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2 flex-wrap">
<span className="font-bold text-slate-800 dark:text-white">
{j.kodeSaham}
</span>
<Badge
color={j.profit > 0 ? 'green' : j.profit < 0 ? 'red' : 'gray'}
size="sm"
>
{j.profit > 0 ? '✅ Profit' : j.profit < 0 ? '❌ Loss' : '➖ Impas'}
</Badge>
<span className="text-xs text-slate-500 dark:text-slate-400">
{getIconEmosi(j.emosi)} {j.emosi}
</span>
</div>
<button
onClick={() => handleHapus(j.id)}
className="text-red-500 hover:text-red-700 text-sm"
>
✕
</button>
</div>
<div className="grid grid-cols-3 gap-2 text-sm mb-2">
<div>
<p className="text-xs text-slate-500 dark:text-slate-400">Beli</p>
<p className="font-semibold text-slate-800 dark:text-white">
{formatRupiah(j.hargaBeli)}
</p>
</div>
<div>
<p className="text-xs text-slate-500 dark:text-slate-400">Jual</p>
<p className="font-semibold text-slate-800 dark:text-white">
{formatRupiah(j.hargaJual)}
</p>
</div>
<div>
<p className="text-xs text-slate-500 dark:text-slate-400">Profit</p>
<p className={`font-bold ${getWarnaProfit(j.profit)}`}>
{formatRupiah(j.profit)} ({j.profitPersen.toFixed(2)}%)
</p>
</div>
</div>
{j.alasanEntry && (
<p className="text-xs text-slate-500 dark:text-slate-400 mb-1">
🎯 Entry: {j.alasanEntry}
</p>
)}
{j.alasanExit && (
<p className="text-xs text-slate-500 dark:text-slate-400 mb-1">
🚪 Exit: {j.alasanExit}
</p>
)}
{j.catatan && (
<p className="text-xs text-slate-500 dark:text-slate-400 italic mb-1">
💭 {j.catatan}
</p>
)}
<div className="flex items-center justify-between text-xs text-slate-400 mt-2">
<span>{j.tanggal}</span>
{j.amal > 0 && (
<span className="text-pink-500 font-semibold">
Amal: {formatRupiah(j.amal)}
</span>
)}
</div>
</div>
))}
</div>
)}
</Card>
{/* INFO */}
<Card className="bg-blue-50 dark:bg-slate-700">
<p className="text-sm text-slate-600 dark:text-slate-300">
💡 <strong>Tips:</strong> Catat setiap trade untuk melihat pola kesalahan
dan perbaikan. Target konsisten: profit 1–3% per hari, stop loss maksimal
1–3%. Sisihkan 2% profit untuk amal.
</p>
</Card>
</div>
)
}
```
---
Kalkulator Risiko Untuk Menghitung Stop Loss 1–3%
🧮 BAGIAN 2: KALKULATOR RISIKO STOP LOSS 1–3%
📄 FILE: src/pages/KalkulatorRisiko/index.jsx (BARU)
```jsx
import { useState } from 'react'
import Card from '../../components/ui/Card'
import Badge from '../../components/ui/Badge'
import Button from '../../components/ui/Button'
export default function KalkulatorRisiko() {
const [modal, setModal] = useState(1000000)
const [hargaBeli, setHargaBeli] = useState(1800)
const [riskPersen, setRiskPersen] = useState(1)
const [targetPersen, setTargetPersen] = useState(2)
const formatRupiah = (angka) =>
new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
}).format(angka || 0)
// Perhitungan
const maxRisikoRp = modal * (riskPersen / 100)
const stopLossRp = hargaBeli * (1 - riskPersen / 100)
const targetProfitRp = hargaBeli * (1 + targetPersen / 100)
// Maksimal lot berdasarkan risiko
const selisihHarga = hargaBeli - stopLossRp
const maxLot = selisihHarga > 0 ? Math.floor(maxRisikoRp / (selisihHarga * 100)) : 0
// Maksimal lot berdasarkan modal (cash)
const maxLotModal = Math.floor(modal / (hargaBeli * 100))
// Lot efektif (yang terkecil antara risiko & modal)
const lotEfektif = Math.min(maxLot, maxLotModal)
// Total nilai transaksi
const nilaiTransaksi = lotEfektif * hargaBeli * 100
const totalRisiko = lotEfektif * selisihHarga * 100
const totalTarget = lotEfektif * (targetProfitRp - hargaBeli) * 100
// Biaya transaksi (0,1513% beli + 0,2513% jual)
const biayaBeli = nilaiTransaksi * 0.001513
const nilaiJual = lotEfektif * targetProfitRp * 100
const biayaJual = nilaiJual * 0.002513
const totalBiaya = biayaBeli + biayaJual
// Profit bersih
const profitBersih = totalTarget - totalBiaya
const profitBersihPersen = nilaiTransaksi > 0 ? (profitBersih / nilaiTransaksi) * 100 : 0
// Risk/Reward Ratio
const riskReward = totalRisiko > 0 ? (totalTarget / totalRisiko).toFixed(2) : 0
// Rekomendasi
const getRekomendasi = () => {
const rr = parseFloat(riskReward)
if (rr >= 2) return { teks: '✅ Risk/Reward sangat baik (≥ 1:2)', warna: 'green' }
if (rr >= 1.5) return { teks: '⚠️ Risk/Reward cukup (1:1.5)', warna: 'yellow' }
if (rr >= 1) return { teks: '⚠️ Risk/Reward minimal (1:1)', warna: 'yellow' }
return { teks: '❌ Risk/Reward buruk (< 1:1)', warna: 'red' }
}
const rekomendasi = getRekomendasi()
return (
<div className="space-y-6 fade-in">
<div>
<h1 className="text-3xl font-bold text-slate-800 dark:text-white">
🧮 Kalkulator Risiko
</h1>
<p className="text-slate-500 dark:text-slate-400 mt-1">
Hitung stop loss, take profit, dan ukuran posisi yang tepat.
</p>
</div>
{/* INPUT */}
<Card title="📝 Input" icon="">
<div className="space-y-4">
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Modal (Rp)
</label>
<input
type="number"
value={modal}
onChange={(e) => setModal(parseFloat(e.target.value) || 0)}
className="w-full px-4 py-3 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white"
/>
</div>
<div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Harga Beli (Rp)
</label>
<input
type="number"
value={hargaBeli}
onChange={(e) => setHargaBeli(parseFloat(e.target.value) || 0)}
className="w-full px-4 py-3 rounded-xl border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-800 dark:text-white"
/>
</div>
<div>
<label className="flex justify-between text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
<span>Risk Tolerance (Stop Loss)</span>
<span className="text-red-500">{riskPersen}%</span>
</label>
<input
type="range"
min="0.5"
max="5"
step="0.5"
value={riskPersen}
onChange={(e) => setRiskPersen(parseFloat(e.target.value))}
className="w-full accent-red-500"
/>
<div className="flex justify-between text-xs text-slate-500 dark:text-slate-400 mt-1">
<span>0.5% (Konservatif)</span>
<span>3% (Maksimal)</span>
<span>5% (Agresif)</span>
</div>
</div>
<div>
<label className="flex justify-between text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
<span>Target Profit (Take Profit)</span>
<span className="text-green-500">{targetPersen}%</span>
</label>
<input
type="range"
min="1"
max="10"
step="0.5"
value={targetPersen}
onChange={(e) => setTargetPersen(parseFloat(e.target.value))}
className="w-full accent-green-500"
/>
<div className="flex justify-between text-xs text-slate-500 dark:text-slate-400 mt-1">
<span>1% (Konservatif)</span>
<span>5% (Moderat)</span>
<span>10% (Agresif)</span>
</div>
</div>
</div>
</Card>
{/* HASIL UTAMA */}
<div className="grid grid-cols-2 gap-3">
<Card className="bg-gradient-to-br from-red-50 to-rose-50 dark:from-slate-800 dark:to-slate-700">
<p className="text-xs text-slate-500 dark:text-slate-400 mb-1">Stop Loss</p>
<p className="text-2xl font-bold text-red-600">
{formatRupiah(stopLossRp)}
</p>
<p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
-{riskPersen}% dari harga beli
</p>
</Card>
<Card className="bg-gradient-to-br from-green-50 to-emerald-50 dark:from-slate-800 dark:to-slate-700">
<p className="text-xs text-slate-500 dark:text-slate-400 mb-1">Take Profit</p>
<p className="text-2xl font-bold text-green-600">
{formatRupiah(targetProfitRp)}
</p>
<p className="text-xs text-slate-500 dark:text-slate-400 mt-1">
+{targetPersen}% dari harga beli
</p>
</Card>
</div>
{/* UKURAN POSISI */}
<Card title="📏 Ukuran Posisi yang Tepat" icon="">
<div className="space-y-4">
<div className="grid grid-cols-3 gap-3">
<div className="p-3 bg-slate-50 dark:bg-slate-700 rounded-xl text-center">
<p className="text-xs text-slate-500 dark:text-slate-400">Maks Lot (Risiko)</p>
<p className="text-xl font-bold text-slate-800 dark:text-white">{maxLot}</p>
</div>
<div className="p-3 bg-slate-50 dark:bg-slate-700 rounded-xl text-center">
<p className="text-xs text-slate-500 dark:text-slate-400">Maks Lot (Modal)</p>
<p className="text-xl font-bold text-slate-800 dark:text-white">{maxLotModal}</p>
</div>
<div className="p-3 bg-amber-50 dark:bg-amber-900/20 rounded-xl text-center border-2 border-amber-400">
<p className="text-xs text-amber-700 dark:text-amber-400">Lot Efektif</p>
<p className="text-xl font-bold text-amber-600">{lotEfektif}</p>
</div>
</div>
<div className="p-3 bg-slate-50 dark:bg-slate-700 rounded-xl">
<p className="text-xs text-slate-500 dark:text-slate-400 mb-1">Nilai Transaksi</p>
<p className="font-bold text-slate-800 dark:text-white text-lg">
{formatRupiah(nilaiTransaksi)}
</p>
<p className="text-xs text-slate-500 dark:text-slate-400">
{lotEfektif} lot × {formatRupiah(hargaBeli)} × 100
</p>
</div>
</div>
</Card>
{/* SIMULASI PROFIT & LOSS */}
<Card title="📊 Simulasi Profit & Loss" icon="">
<div className="space-y-3">
<div className="flex justify-between items-center p-3 bg-red-50 dark:bg-red-900/20 rounded-xl">
<span className="text-sm text-slate-600 dark:text-slate-300">
Jika kena Stop Loss
</span>
<span className="font-bold text-red-600">
-{formatRupiah(totalRisiko)}
</span>
</div>
<div className="flex justify-between items-center p-3 bg-green-50 dark:bg-green-900/20 rounded-xl">
<span className="text-sm text-slate-600 dark:text-slate-300">
Jika kena Take Profit (kotor)
</span>
<span className="font-bold text-green-600">
+{formatRupiah(totalTarget)}
</span>
</div>
<div className="flex justify-between items-center p-3 bg-amber-50 dark:bg-amber-900/20 rounded-xl">
<span className="text-sm text-slate-600 dark:text-slate-300">
Biaya Transaksi (beli + jual)
</span>
<span className="font-bold text-amber-600">
-{formatRupiah(totalBiaya)}
</span>
</div>
<div className="flex justify-between items-center p-3 bg-blue-50 dark:bg-blue-900/20 rounded-xl border-2 border-blue-400">
<span className="text-sm font-semibold text-slate-700 dark:text-slate-200">
Profit Bersih (jika TP)
</span>
<span className={`font-bold text-lg ${profitBersih > 0 ? 'text-blue-600' : 'text-red-600'}`}>
{formatRupiah(profitBersih)} ({profitBersihPersen.toFixed(2)}%)
</span>
</div>
<div className="flex justify-between items-center p-3 bg-pink-50 dark:bg-pink-900/20 rounded-xl">
<span className="text-sm text-slate-600 dark:text-slate-300">
Amal 2% (dari profit bersih)
</span>
<span className="font-bold text-pink-500">
{formatRupiah(profitBersih > 0 ? profitBersih * 0.02 : 0)}
</span>
</div>
</div>
</Card>
{/* RISK/REWARD */}
<Card className="bg-gradient-to-br from-indigo-50 to-purple-50 dark:from-slate-800 dark:to-slate-700">
<div className="flex items-center justify-between mb-3">
<h3 className="font-bold text-slate-800 dark:text-white">
⚖️ Risk/Reward Ratio
</h3>
<span className="text-3xl font-bold text-indigo-600">
1:{riskReward}
</span>
</div>
<Badge color={rekomendasi.warna}>
{rekomendasi.teks}
</Badge>
<p className="text-xs text-slate-500 dark:text-slate-400 mt-3">
Semakin tinggi R/R, semakin baik. Dengan R/R 1:2, Anda hanya perlu menang
33% untuk tetap profit.
</p>
</Card>
{/* PANDUAN */}
<Card className="bg-blue-50 dark:bg-slate-700">
<p className="text-sm text-slate-600 dark:text-slate-300">
💡 <strong>Tips:</strong> Untuk metode "Beli Sore Jual Pagi",
gunakan <strong>Stop Loss 1–3%</strong> dan <strong>Target Profit 1–3%</strong>.
Risk/Reward minimal 1:1. Jangan entry jika R/R kurang dari 1:1.
</p>
</Card>
</div>
)
}
```
---
🚀 CARA APPLY DI TERMUX
```bash
cd ~/TTrading
# 1. Buat folder baru
mkdir -p src/pages/JurnalBSP
mkdir -p src/pages/KalkulatorRisiko
# 2. Buat file baru
nano src/data/jurnalTemplate.json
# Paste FILE 1
nano src/pages/JurnalBSP/index.jsx
# Paste FILE 2
nano src/pages/KalkulatorRisiko/index.jsx
# Paste FILE 3
# 3. Ganti App.jsx (tambah 2 route)
nano src/App.jsx
# Tambah:
# import JurnalBSP from './pages/JurnalBSP'
# import KalkulatorRisiko from './pages/KalkulatorRisiko'
# <Route path="/jurnal-bsp" element={<JurnalBSP />} />
# <Route path="/kalkulator-risiko" element={<KalkulatorRisiko />} />
# 4. Ganti Sidebar.jsx (tambah 2 menu)
nano src/components/layout/Sidebar.jsx
# Tambah:
# { path: '/jurnal-bsp', label: 'Jurnal BSP', icon: '📓' },
# { path: '/kalkulator-risiko', label: 'Kalkulator Risiko', icon: '🧮' },
# 5. Test build
npm run build
# 6. Commit & push
git add .
git commit -m "feat: tambah Jurnal BSP & Kalkulator Risiko"
git push origin main
```
---
📋 CHECKLIST
No Fitur Status
1 Menu Jurnal BSP muncul di sidebar ☐
2 Form entri jurnal lengkap (saham, harga, lot, emosi, pilar) ☐
3 Preview profit muncul real-time ☐
4 Amal 2% dihitung otomatis ☐
5 Statistik (total trade, profit, win rate, amal) ☐
6 Menu Kalkulator Risiko muncul di sidebar ☐
7 Slider risk tolerance (0.5–5%) ☐
8 Slider target profit (1–10%) ☐
9 Stop Loss & Take Profit dihitung otomatis ☐
10 Lot efektif berdasarkan risiko & modal ☐
11 Simulasi P&L termasuk biaya transaksi ☐
12 Risk/Reward Ratio dengan rekomendasi ☐
---
💎 KESIMPULAN
Fitur baru:
· 📓 Jurnal BSP — catat trade metode beli sore jual pagi
· 🧮 Kalkulator Risiko — hitung SL, TP, lot, R/R otomatis
· 💰 Amal 2% terintegrasi
· 📊 Statistik win rate & total profit
· ⚖️ Risk/Reward Ratio dengan rekomendasi warna
Manfaat:
1. Disiplin — catat setiap trade
2. Objektif — hitung risiko dengan angka, bukan feeling
3. Edukasi — belajar dari pola kesalahan
4. Berkah — amal 2% otomatis
Motto:
"Trader yang paling bagus adalah yang kalau untung biasa aja, kalau rugi biasa aja. Tenang, objektif, penuh perhitungan — mirip robot." — Bro Nelson
"Hati adalah grafik Candlestick terbesar. Kalau hati kacau, sejelas apa pun pergerakan pasar pasti akan sia-sia." — T Trading
Apakah Anda ingin saya bantu buatkan template laporan mingguan untuk metode BSP ini, atau fitur tambahan seperti notifikasi otomatis saat mendekati SL/TP? 😊
Comments
Post a Comment