Freqtrade 是一個(gè)用 Python 編寫的免費(fèi)開源加密貨幣交易機(jī)器人。它旨在支持所有主要交易所并通過 Telegram 或 webUI 進(jìn)行控制。功能包含回測、繪圖和資金管理工具以及通過機(jī)器學(xué)習(xí)的策略優(yōu)化。
特性:
1. 基于 Python 3.8+ :適用于任何操作系統(tǒng) - Windows、macOS 和 Linux。
2. 持久性 :持久性是通過 sqlite 實(shí)現(xiàn)的。
3. Dry-run :不花錢運(yùn)行機(jī)器人。
4. 回測 :模擬買入/賣出策略。
5. 通過機(jī)器學(xué)習(xí)進(jìn)行策略優(yōu)化 :使用機(jī)器學(xué)習(xí)通過真實(shí)的交易所數(shù)據(jù)優(yōu)化買入/賣出策略參數(shù)。
6. 邊緣頭寸規(guī)模計(jì)算您的勝率、風(fēng)險(xiǎn)回報(bào)率、最佳止損位并在為每個(gè)特定市場建立頭寸之前調(diào)整頭寸規(guī)模。
7. 白名單加密貨幣 :選擇你要交易的加密貨幣或使用動(dòng)態(tài)白名單。
8. 黑名單加密貨幣 :選擇你想要避免的加密貨幣。
9. 內(nèi)置 WebUI :內(nèi)置 Web UI 來管理你的機(jī)器人。
10. 可通過 Telegram管理:使用 Telegram 管理機(jī)器人。
11. 以法定貨幣顯示盈虧 :以法定貨幣顯示你的盈虧。
12. 表現(xiàn)狀態(tài)報(bào)告 :提供你當(dāng)前交易的表現(xiàn)狀態(tài)。
1.準(zhǔn)備
開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒有,可以訪問這篇文章:超詳細(xì)Python安裝指南 進(jìn)行安裝。
**(可選1) **如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda:Python數(shù)據(jù)分析與挖掘好幫手—Anaconda,它內(nèi)置了Python和pip.
**(可選2) **此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點(diǎn):Python 編程的最好搭檔—VSCode 詳細(xì)指南。
在Linux/MacOS下,三行命令就能完成安裝:
git clone -b develop https://github.com/freqtrade/freqtrade.git
cd freqtrade
./setup.sh --install
Windows環(huán)境下打開Cmd(開始—運(yùn)行—CMD),輸入命令安裝依賴:
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
# 安裝ta-lib
pip install build_helpers/TA_Lib-0.4.24-cp38-cp38-win_amd64.whl
pip install -r requirements.txt
pip install -e .
freqtrade
請注意,此處安裝ta-lib時(shí)項(xiàng)目方提供了python3.8/3.9/3.10,其他Python版本請自行搜索下載。
輸入freqtrade時(shí),顯示以下信息說明安裝成功:
(freqtrade) D:CODEtraderfreqtrade >freqtrade
2022-02-17 19:40:50,174 - freqtrade - ERROR - Usage of Freqtrade requires a subcommand to be specified.
To have the bot executing trades in live/dry-run modes, depending on the value of the `dry_run` setting in the config, run Freqtrade as `freqtrade trade [options...]`.
To see the full list of options available, please use `freqtrade --help` or `freqtrade < command > --help`.
2.快速開始
下面教你如何開發(fā)一個(gè)簡單的交易策略。
一個(gè)策略文件往往包含這些東西:
- 指標(biāo)
- 購買規(guī)則
- 賣出規(guī)則
- 建議最低投資回報(bào)率
- 強(qiáng)烈推薦止損
Freqtrade使用 Pandas 作為基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),它底層的OHLCV都是以Dataframe的格式存儲(chǔ)的。
Dataframe數(shù)據(jù)流中每一行數(shù)據(jù)代表圖表上的一根K線,最新的K線始終是數(shù)據(jù)庫中最后一根。
dataframe.head()
date open high low close volume
0 2021-11-09 23:25:00+00:00 67279.67 67321.84 67255.01 67300.97 44.62253
1 2021-11-09 23:30:00+00:00 67300.97 67301.34 67183.03 67187.01 61.38076
2 2021-11-09 23:35:00+00:00 67187.02 67187.02 67031.93 67123.81 113.42728
3 2021-11-09 23:40:00+00:00 67123.80 67222.40 67080.33 67160.48 78.96008
4 2021-11-09 23:45:00+00:00 67160.48 67160.48 66901.26 66943.37 111.39292
Pandas 提供了計(jì)算指標(biāo)的快速方法。為了從這種速度中受益,建議不要使用循環(huán),而是使用矢量化方法。
矢量化操作在整個(gè)數(shù)據(jù)范圍內(nèi)執(zhí)行計(jì)算,因此,與遍歷每一行相比,在計(jì)算指標(biāo)時(shí)要快得多。
dataframe.loc[(dataframe['rsi'] > 30), 'buy'] = 1
類似于上面這樣的賦值方法,會(huì)自動(dòng)設(shè)置rsi大于30的數(shù)據(jù)的buy列的值為1。
買入規(guī)則
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) - > DataFrame:
"""
Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame populated with indicators
:param metadata: Additional information, like the currently traded pair
:return: DataFrame with buy column
"""
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
'buy'] = 1
return dataframe
請注意,一定要不修改并返回"open", "high", "low", "close", "volume"列,這些是基礎(chǔ)行情數(shù)據(jù),如果返回錯(cuò)誤的數(shù)據(jù)將可能會(huì)導(dǎo)致一些奇怪?jǐn)?shù)據(jù)的產(chǎn)生。
如上所示的方法中,符合條件的數(shù)據(jù)的buy值會(huì)被設(shè)為1代表買入,否則為0或nan值。
賣出規(guī)則
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) - > DataFrame:
"""
Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame populated with indicators
:param metadata: Additional information, like the currently traded pair
:return: DataFrame with buy column
"""
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
(dataframe['volume'] > 0) # Make sure Volume is not 0
),
'sell'] = 1
return dataframe
與買入類似,這里不贅述了。
最小投資回報(bào)率
在類中增加這個(gè)初始化變量,能控制投資回報(bào)率:
minimal_roi = {
"40": 0.0,
"30": 0.01,
"20": 0.02,
"0": 0.04
}
上述配置意味著:
- 只要達(dá)到 4% 的利潤就賣出
- 達(dá)到 2% 利潤時(shí)賣出(20 分鐘后生效)
- 達(dá)到 1% 利潤時(shí)賣出(30 分鐘后生效)
- 交易未虧損時(shí)賣出(40 分鐘后生效)
此處的計(jì)算包含費(fèi)用。
要完全禁用 ROI,請將其設(shè)置為一個(gè)非常高的數(shù)字:
minimal_roi = {
"0": 100
}
雖然從技術(shù)上講并沒有完全禁用,但一旦交易達(dá)到 10000% 利潤,它就會(huì)賣出。
止損
強(qiáng)烈建議設(shè)置止損,以保護(hù)資金免受不利的劇烈波動(dòng)。
設(shè)置 10% 止損的示例:
stoploss = -0.10
一個(gè)完整代碼如下:
上滑查看更多代碼
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
from reimport A
import numpyas np# noqa
import pandasas pd# noqa
from pandasimport DataFrame
from freqtrade.strategyimport (BooleanParameter, CategoricalParameter, DecimalParameter,
IStrategy, IntParameter)
# --------------------------------
# 你自己所需要的模塊放在這里
import talib.abstractas ta
import freqtrade.vendor.qtpylib.indicatorsas qtpylib
# This class is a sample. Feel free to customize it.
class SampleStrategy(IStrategy):
"""
This is a sample strategy to inspire you.
More information in https://www.freqtrade.io/en/latest/strategy-customization/
You can:
:return: a Dataframe with all mandatory indicators for the strategies
- Rename the class name (Do not forget to update class_name)
- Add any methods you want to build your strategy
- Add any lib you need to build your strategy
You must keep:
- the lib in the section "Do not remove these libs"
- the methods: populate_indicators, populate_buy_trend, populate_sell_trend
You should keep:
- timeframe, minimal_roi, stoploss, trailing_*
"""
# Strategy interface version - allow new iterations of the strategy interface.
# Check the documentation or the Sample strategy to get the latest version.
INTERFACE_VERSION =2
# 設(shè)定最小投資回報(bào)
minimal_roi = {
"60":0.01,
"30":0.02,
"0":0.04
}
# 止損
stoploss =-0.10
# 指標(biāo)參數(shù)
buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True)
# K線時(shí)間
timeframe ='5m'
# 在新K線出現(xiàn)時(shí)執(zhí)行
process_only_new_candles =False
# These values can be overridden in the "ask_strategy" section in the config.
use_sell_signal =True
sell_profit_only =False
ignore_roi_if_buy_signal =False
# 預(yù)準(zhǔn)備K線數(shù)
startup_candle_count: int =30
# 下單類型
order_types = {
'buy':'limit',
'sell':'limit',
'stoploss':'market',
'stoploss_on_exchange':False
}
# 訂單有效時(shí)間(gtc: 除非取消否則一直有效)
order_time_in_force = {
'buy':'gtc',
'sell':'gtc'
}
plot_config = {
'main_plot': {
'tema': {},
'sar': {'color':'white'},
},
'subplots': {
"MACD": {
'macd': {'color':'blue'},
'macdsignal': {'color':'orange'},
},
"RSI": {
'rsi': {'color':'red'},
}
}
}
def informative_pairs(self):
"""
Define additional, informative pair/interval combinations to be cached from the exchange.
These pair/interval combinations are non-tradeable, unless they are part
of the whitelist as well.
For more information, please consult the documentation
:return: List of tuples in the format (pair, interval)
Sample: return [("ETH/USDT", "5m"),
("BTC/USDT", "15m"),
]
"""
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) - > DataFrame:
"""
Adds several different TA indicators to the given DataFrame
Performance Note: For the best performance be frugal on the number of indicators
you are using. Let uncomment only the indicator you are using in your strategies
or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
:param dataframe: Dataframe with data from the exchange
:param metadata: Additional information, like the currently traded pair
:return: a Dataframe with all mandatory indicators for the strategies
"""
# Momentum Indicators
# ------------------------------------
dataframe['adx'] = ta.ADX(dataframe)
dataframe['rsi'] = ta.RSI(dataframe)
stoch_fast = ta.STOCHF(dataframe)
dataframe['fastd'] = stoch_fast['fastd']
dataframe['fastk'] = stoch_fast['fastk']
# MACD
macd = ta.MACD(dataframe)
dataframe['macd'] = macd['macd']
dataframe['macdsignal'] = macd['macdsignal']
dataframe['macdhist'] = macd['macdhist']
# MFI
dataframe['mfi'] = ta.MFI(dataframe)
# Bollinger Bands
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
dataframe['bb_lowerband'] = bollinger['lower']
dataframe['bb_middleband'] = bollinger['mid']
dataframe['bb_upperband'] = bollinger['upper']
dataframe["bb_percent"] = (
(dataframe["close"] - dataframe["bb_lowerband"]) /
(dataframe["bb_upperband"] - dataframe["bb_lowerband"])
)
dataframe["bb_width"] = (
(dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"]
)
# Parabolic SAR
dataframe['sar'] = ta.SAR(dataframe)
# TEMA - Triple Exponential Moving Average
dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
hilbert = ta.HT_SINE(dataframe)
dataframe['htsine'] = hilbert['sine']
dataframe['htleadsine'] = hilbert['leadsine']
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) - > DataFrame:
"""
Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame populated with indicators
:param metadata: Additional information, like the currently traded pair
:return: DataFrame with buy column
"""
dataframe.loc[
(
# Signal: RSI crosses above 30
(qtpylib.crossed_above(dataframe['rsi'], self.buy_rsi.value)) &
(dataframe['tema'] <= dataframe['bb_middleband']) &# Guard: tema below BB middle
(dataframe['tema'] > dataframe['tema'].shift(1)) &# Guard: tema is raising
(dataframe['volume'] >0)# Make sure Volume is not 0
),'buy'] =1
return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) - > DataFrame:
"""
Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame populated with indicators
:param metadata: Additional information, like the currently traded pair
:return: DataFrame with sell column
"""
dataframe.loc[
(
# Signal: RSI crosses above 70
(qtpylib.crossed_above(dataframe['rsi'], self.sell_rsi.value)) &
(dataframe['tema'] > dataframe['bb_middleband']) &# Guard: tema above BB middle
(dataframe['tema'] < dataframe['tema'].shift(1)) &# Guard: tema is falling
(dataframe['volume'] >0)# Make sure Volume is not 0
),'sell'] =1
return dataframe
3.啟動(dòng)機(jī)器人
啟動(dòng)機(jī)器人前還需要設(shè)定配置,配置模板在 config/examples 下面。
比如幣安的配置,你還需要輸入key和secret:
"exchange": {
"name": "binance",
"key": "your_exchange_key",
"secret": "your_exchange_secret",
......
}
}
啟動(dòng)機(jī)器人:
freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory -c path/far/far/away/config.json
--strategy-path 指定策略文件位置
-c 參數(shù)指定配置文件位置
比如我把策略放在了user_data/strategies下,配置放在了config_examples下,這么輸入命令啟動(dòng)機(jī)器人即可:
freqtrade trade --strategy SampleStrategy --strategy-path user_data/strategies -c config_examples/config_binance.example.json
由于篇幅問題,本文只是介紹了freqtrade的冰山一角,在啟動(dòng)機(jī)器人前,一定要進(jìn)行回測并進(jìn)行模擬交易。
-
機(jī)器人
+關(guān)注
關(guān)注
210文章
28191瀏覽量
206506 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6888瀏覽量
88826 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6737瀏覽量
123190 -
python
+關(guān)注
關(guān)注
56文章
4782瀏覽量
84450
發(fā)布評論請先 登錄
相關(guān)推薦
評論