MultiMa: TEMA Stack Comparisons for Long Entries and Exits
Summary
MultiMa is a Freqtrade strategy that builds a collection of triple exponential moving averages (TEMAs) at periods derived from two adjustable parameters: count and gap. For entries, it checks whether consecutive selected TEMA values are decreasing and requires all constructed comparisons to hold. For exits, it checks whether any consecutive values are increasing. Both rules apply to long positions, and the strategy uses a four-hour timeframe.
The source lists optimized settings, a return objective, and a small set of trade statistics, but these are configuration-specific and do not establish performance beyond the stated run. The code also sets a large fixed stop loss and a staged return-on-investment schedule, with trailing stops disabled. Its usefulness depends on the TEMA ordering logic and parameter choices; the document provides no market, date range, benchmark, or validation details for the reported figures. It therefore describes an implementable signal concept, not evidence of robust results.
Key ideas
- The strategy calculates many TEMA series using periods formed from a count and gap grid.
- Long entries require each applicable adjacent pair of selected TEMA values to be ordered downward.
- Long exits are triggered when any applicable adjacent pair is ordered upward.
- The strategy uses a four-hour timeframe with configured stop loss and staged profit targets.
- The reported trade metrics are not accompanied by enough context to assess generalizability.
Tags
Full text
# MultiMa
# MultiMa
## Source (GPL-3.0)
```python
# MultiMa Strategy V2
# Author: @Mablue (Masoud Azizi)
# github: https://github.com/mablue/
# --- Do not remove these libs ---
from freqtrade.strategy import IntParameter, IStrategy
from pandas import DataFrame
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
from functools import reduce
class MultiMa(IStrategy):
# 111/2000: 18 trades. 12/4/2 Wins/Draws/Losses. Avg profit 9.72%. Median profit 3.01%. Total profit 733.01234143 USDT ( 73.30%). Avg duration 2 days, 18:40:00 min. Objective: 1.67048
INTERFACE_VERSION: int = 3
# Buy hyperspace params:
buy_params = {
"buy_ma_count": 4,
"buy_ma_gap": 15,
}
# Sell hyperspace params:
sell_params = {
"sell_ma_count": 12,
"sell_ma_gap": 68,
}
# ROI table:
minimal_roi = {
"0": 0.523,
"1553": 0.123,
"2332": 0.076,
"3169": 0
}
# Stoploss:
stoploss = -0.345
# Trailing stop:
trailing_stop = False # value loaded from strategy
trailing_stop_positive = None # value loaded from strategy
trailing_stop_positive_offset = 0.0 # value loaded from strategy
trailing_only_offset_is_reached = False # value loaded from strategy
# Opimal Timeframe
timeframe = "4h"
count_max = 20
gap_max = 100
buy_ma_count = IntParameter(1, count_max, default=7, space="buy")
buy_ma_gap = IntParameter(1, gap_max, default=7, space="buy")
sell_ma_count = IntParameter(1, count_max, default=7, space="sell")
sell_ma_gap = IntParameter(1, gap_max, default=94, space="sell")
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
for count in range(self.count_max):
for gap in range(self.gap_max):
if count*gap > 1 and count*gap not in dataframe.keys():
dataframe[count*gap] = ta.TEMA(
dataframe, timeperiod=int(count*gap)
)
print(" ", metadata['pair'], end="\t\r")
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
# I used range(self.buy_ma_count.value) instade of self.buy_ma_count.range
# Cuz it returns range(7,8) but we need range(8) for all modes hyperopt, backtest and etc
for ma_count in range(self.buy_ma_count.value):
key = ma_count*self.buy_ma_gap.value
past_key = (ma_count-1)*self.buy_ma_gap.value
if past_key > 1 and key in dataframe.keys() and past_key in dataframe.keys():
conditions.append(dataframe[key] < dataframe[past_key])
if conditions:
dataframe.loc[reduce(lambda x, y: x & y, conditions), "enter_long"] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
for ma_count in range(self.sell_ma_count.value):
key = ma_count*self.sell_ma_gap.value
past_key = (ma_count-1)*self.sell_ma_gap.value
if past_key > 1 and key in dataframe.keys() and past_key in dataframe.keys():
conditions.append(dataframe[key] > dataframe[past_key])
if conditions:
dataframe.loc[reduce(lambda x, y: x | y, conditions), "exit_long"] = 1
return dataframe
```Shown in full with attribution under the source's licence. Licence: GPL-3.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.