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

Popular posts from this blog

Bermain Saham Harian/Jangka Panjang

INDEKS ACUAN SAHAM INDONESIA

Panduan Memulai Beli Saham/Reksa Dana di Aplikasi Ajaib