Strategi Freqtrade adalah program Python yang mengubah candle menjadi keputusan. Untuk membuat strategi yang dapat dipercaya, setiap keputusan harus mempunyai alasan yang jelas: indikator apa yang digunakan, kapan sinyal dianggap valid, bagaimana posisi ditutup, dan berapa kerugian maksimum yang diperbolehkan.
Bentuk Dasar Class Strategi
Strategi biasanya mewarisi IStrategy dan menetapkan beberapa properti utama:
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
class EmaTrendStarter(IStrategy):
INTERFACE_VERSION = 3
timeframe = "1h"
can_short = False
startup_candle_count = 200
stoploss = -0.08
minimal_roi = {
"0": 0.08,
"240": 0.03,
"720": 0
}Nama class harus sama dengan nilai yang diberikan pada --strategy. Timeframe menentukan candle utama, sedangkan startup_candle_count memberi ruang agar indikator panjang seperti EMA 200 terisi sebelum sinyal digunakan.
populate_indicators: Membangun Data
Fungsi ini menambahkan kolom indikator ke dataframe:
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["ema_fast"] = ta.EMA(dataframe, timeperiod=50)
dataframe["ema_slow"] = ta.EMA(dataframe, timeperiod=200)
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
return dataframeSetiap baris dataframe mewakili candle. Strategi harus mengambil keputusan menggunakan informasi yang tersedia sampai candle tersebut, bukan informasi setelahnya.
Kesalahan umum adalah menggunakan nilai masa depan melalui shift(-1), normalisasi seluruh dataframe, atau operasi agregasi tanpa rolling window. Kesalahan ini dapat menghasilkan lookahead bias.
populate_entry_trend: Menentukan Entry
Sinyal entry ditulis ke kolom enter_long atau enter_short:
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
long_condition = (
(dataframe["ema_fast"] > dataframe["ema_slow"])
& (dataframe["rsi"] > 50)
& (dataframe["rsi"] < 70)
& (dataframe["volume"] > 0)
)
dataframe.loc[long_condition, ["enter_long", "enter_tag"]] = (
1,
"ema_trend_long",
)
return dataframeenter_tag sangat berguna untuk mengevaluasi keluarga sinyal. Jika strategi memiliki beberapa mesin entry, hasil backtest dapat dipisahkan berdasarkan tag untuk melihat mana yang benar-benar memberikan profit.
Sinyal sebaiknya tidak hanya banyak; ia harus dapat dijelaskan dan diuji pada beberapa regime pasar.
populate_exit_trend: Exit Berbasis Sinyal
Exit dapat didefinisikan melalui dataframe:
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
exit_condition = (
(dataframe["ema_fast"] < dataframe["ema_slow"])
| (dataframe["rsi"] > 75)
)
dataframe.loc[exit_condition, "exit_long"] = 1
return dataframeExit signal cocok ketika posisi harus ditutup akibat perubahan struktur pasar. Tetapi strategi masih dapat ditutup melalui ROI, stoploss, perintah manual, atau callback.
Memahami minimal_roi
ROI table menetapkan profit minimum berdasarkan usia trade. Contoh:
minimal_roi = {
"0": 0.08,
"240": 0.03,
"720": 0
}Artinya target awal 8%, turun menjadi 3% setelah 240 menit, dan menjadi 0% setelah 720 menit. Angka ROI perlu dibaca bersama leverage. Pada futures, profit ratio trade sudah dipengaruhi leverage sehingga target yang tampak kecil dapat memiliki dampak besar.
ROI bukan kewajiban. Strategi dapat menggunakan {} jika seluruh exit dikelola lewat sinyal atau callback, tetapi keputusan tersebut meningkatkan tanggung jawab pada logika exit.
Stoploss: Batas yang Tidak Boleh Diabaikan
stoploss = -0.08 berarti posisi ditutup ketika kerugian mencapai sekitar 8% menurut perhitungan trade. Dalam futures, jarak pergerakan harga yang diperlukan lebih kecil karena leverage.
Stoploss terlalu longgar dapat membuat posisi mendekati likuidasi. Stoploss terlalu ketat dapat menghasilkan banyak kerugian kecil karena noise. Nilainya harus berhubungan dengan volatilitas, timeframe, leverage, dan ukuran posisi.
Gunakan stoploss on-exchange ketika sesuai agar perlindungan tidak sepenuhnya bergantung pada proses bot. Tetap pahami bahwa gap, slippage, dan gangguan exchange dapat membuat harga aktual berbeda dari harga stop.
custom_exit dan custom_stoploss
custom_exit memungkinkan exit berdasarkan informasi trade, waktu, profit, dan candle terkini. Contohnya adalah menutup posisi setelah durasi maksimum.
custom_stoploss dapat mengubah level stop secara dinamis, misalnya mengikuti ATR atau mengunci profit. Callback ini kuat, tetapi harus memahami apakah nilai yang dikembalikan relatif terhadap current rate, open rate, dan leverage.
Jangan hanya menguji callback pada timeframe utama. Jika stop harus bereaksi intrabar, gunakan --timeframe-detail dalam backtest dan bandingkan dengan perilaku dry-run.
Position Sizing dan Leverage
custom_stake_amount dapat menentukan stake berdasarkan saldo, volatilitas, atau jarak stop. Kerangka risk-based sizing adalah:
risiko nominal = ekuitas × risiko per trade
ukuran posisi = risiko nominal ÷ jarak stop
Dalam implementasi futures, perhatikan leverage dan definisi stake di Freqtrade. Uji hasil aktual melalui log, bukan hanya mengandalkan rumus di atas kertas.
Callback leverage sebaiknya memiliki batas keras. Leverage yang tinggi tidak menciptakan edge; ia hanya mengubah distribusi profit dan kecepatan kerugian.
Informative Timeframe
Strategi dapat memakai timeframe utama 30 menit lalu membaca tren dari 1 jam atau 4 jam. Data informative harus digabungkan tanpa membawa candle masa depan.
Gunakan fasilitas informative Freqtrade dan pastikan candle tinggi yang belum selesai tidak digunakan seolah-olah sudah final. Setelah menggabungkan timeframe, jalankan lookahead dan recursive analysis.
Prinsip Desain yang Sehat
- Mulai dengan sedikit indikator dan aturan.
- Beri tag pada setiap keluarga entry.
- Pisahkan entry, exit, dan position sizing secara konseptual.
- Tetapkan batas risiko sebelum mengoptimalkan return.
- Hindari kondisi yang hanya berfungsi pada satu pair atau satu tahun.
- Catat alasan setiap parameter agar perubahan dapat diaudit.
- Uji strategi setelah restart untuk callback yang menyimpan state.
Kesimpulan
Struktur strategi yang baik bukan yang paling panjang, melainkan yang perilakunya dapat dijelaskan. Entry menentukan kesempatan, exit menentukan realisasi, dan position sizing menentukan apakah rangkaian kerugian dapat ditanggung.
Artikel berikutnya membahas data historis—bahan baku yang menentukan apakah pengujian strategi menghasilkan bukti atau sekadar angka yang menyesatkan.
Bacaan lanjutan
Kode di atas adalah contoh edukatif dan perlu diuji sebelum digunakan pada pasar nyata.




