Skip to content

Releases: eq19/maps

v0.3.8

Choose a tag to compare

@eq19 eq19 released this 17 Jun 11:41
332cd56

Full Changelog: v0.3.7...v0.3.8

eq19/maps@v8' (SHA:332cd561eabbd064e0b1f79822aaa5bd56fe7d48)
eq19/feed@v6' (SHA:f0eddfb41d92df349f01f353f30cfe20afbfae90)
eq19/lexer@v4' (SHA:5285ef05b81b7573fa024b2a16aef65e35333174)
eq19/eq19@v2' (SHA:4af9451e0f2ffcfe438b2872ecb81723cf3d41d9)

Screenshot_2026-06-17-18-38-38-234_org telegram messenger

v0.3.7

Choose a tag to compare

@eq19 eq19 released this 03 Jun 12:39

Full Changelog: v0.3.5...v0.3.7

Screenshot_2026-06-03-19-36-54-041_com android chrome

v0.3.6

Choose a tag to compare

@eq19 eq19 released this 18 May 20:00
b819210

Full Changelog: v0.3.5...v0.3.6

class Fibbo(IStrategy)
    def informative_pairs(self):
        """
        Define informative pairs safely
        Compatible with:
        - Dynamic pairlists
        - FreqAI enabled/disabled
        - Missing candle history
        """

        informative_pairs = []

        # Skip completely if FreqAI disabled
        if not self.config.get("freqai", {}).get("enabled", False):
            return informative_pairs

        whitelist_pairs = self.dp.current_whitelist()

        feature_params = self.config["freqai"].get(
            "feature_parameters", {}
        )

        include_timeframes = feature_params.get(
            "include_timeframes",
            [self.informative_timeframe]
        )

        corr_pairs = feature_params.get(
            "include_corr_pairlist",
            []
        )

        # Process whitelist pairs
        for tf in include_timeframes:

            for pair in whitelist_pairs:

                try:
                    if not self.dp.market(pair):
                        continue

                    dataframe = self.dp.get_pair_dataframe(
                        pair=pair,
                        timeframe=tf
                    )

                    if dataframe is None or dataframe.empty:
                        logger.debug(
                            f"Skipping informative pair "
                            f"{pair} {tf} - no candles"
                        )
                        continue

                    informative_pairs.append((pair, tf))

                except Exception as e:
                    logger.debug(
                        f"Informative pair failed "
                        f"{pair} {tf}: {e}"
                    )
                    continue

        # Correlation pairs
        for tf in include_timeframes:

            for pair in corr_pairs:

                if pair in whitelist_pairs:
                    continue

                try:
                    if not self.dp.market(pair):
                        continue

                    dataframe = self.dp.get_pair_dataframe(
                        pair=pair,
                        timeframe=tf
                    )

                    if dataframe is None or dataframe.empty:
                        continue

                    informative_pairs.append((pair, tf))

                except Exception:
                    continue

        informative_pairs = list(set(informative_pairs))

        logger.debug(f"Informative pairs data: {informative_pairs}")

        return informative_pairs

v0.3.5

Choose a tag to compare

@eq19 eq19 released this 11 May 13:22
6d10fc9

Full Changelog: v0.3.3...v0.3.5

Screenshot_2026-05-11-20-20-53-536_org telegram messenger

v0.3.4

Choose a tag to compare

@eq19 eq19 released this 06 May 03:15
c0495b4

Full Changelog: v0.3.3...v0.3.4

Screenshot_2026-05-06-07-05-08-974_com android chrome

Last working #2163
'eq19/maps@v7' (SHA:ca8cefbb767aaba97ceb6899be9230f077f658ff)
'eq19/eq19@v1' (SHA:004da987a57447183c14289b5390f139f16029b2)

v0.3.3

Choose a tag to compare

@eq19 eq19 released this 22 Apr 05:18
82eef33

supervisord.conf

Full Changelog: v0.3.2...v0.3.3

[supervisord]
nodaemon=true

[unix_http_server]
file=/var/run/supervisor.sock
chmod=0770
chown=root:root

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface


[program:postgres]
command=docker-entrypoint.sh postgres
autostart=false
autorestart=false


[program:freqtrade_live]
command=/bin/bash -c "
set -e

CONFIG_SRC=/home/runner/data_live/config_examples/config_exchange.example.json
DOWNLOAD_CFG=/home/runner/data_live/download_config.json
DATA_FLAG=/home/runner/data_live/.data_ready

jq '{exchange:{name:.exchange.name},pair_whitelist:((.exchange.core_whitelist//[])+(.exchange.pair_reserved//[])|unique)}' \"$CONFIG_SRC\" > \"$DOWNLOAD_CFG\"

test -s \"$DOWNLOAD_CFG\"

if [ ! -f \"$DATA_FLAG\" ]; then
  freqtrade download-data --config \"$DOWNLOAD_CFG\" --userdir /home/runner/data_live --timeframes \"15m 1h\" --days 30
  touch \"$DATA_FLAG\"
fi

exec freqtrade trade -v \
  --config /home/runner/data_live/config.json \
  --userdir /home/runner/data_live \
  --freqaimodel FREQAIMODEL_LIVE \
  --log-file /home/runner/data_live/logs/freqtrade.log
"
environment=RUN_MODE="live",FREQAI_MODEL="FREQAIMODEL_LIVE"
autostart=false
autorestart=true


[program:freqtrade_dry]
command=/bin/bash -c "
set -e

CONFIG_SRC=/home/runner/data_dry/config_examples/config_exchange.example.json
DOWNLOAD_CFG=/home/runner/data_dry/download_config.json
DATA_FLAG=/home/runner/data_dry/.data_ready

jq '{exchange:{name:.exchange.name},pair_whitelist:((.exchange.core_whitelist//[])+(.exchange.pair_reserved//[])|unique)}' \"$CONFIG_SRC\" > \"$DOWNLOAD_CFG\"

test -s \"$DOWNLOAD_CFG\"

if [ ! -f \"$DATA_FLAG\" ]; then
  freqtrade download-data --config \"$DOWNLOAD_CFG\" --userdir /home/runner/data_dry --timeframes \"15m 1h\" --days 30
  touch \"$DATA_FLAG\"
fi

exec freqtrade trade -v \
  --config /home/runner/data_dry/config.json \
  --userdir /home/runner/data_dry \
  --freqaimodel FREQAIMODEL_DRY \
  --log-file /home/runner/data_dry/logs/freqtrade.log
"
environment=RUN_MODE="dry",FREQAI_MODEL="FREQAIMODEL_DRY"
autostart=false
autorestart=true


[program:monitor_freqtrade]
command=/freqtrade.sh
autostart=false
autorestart=true

v0.3.2

Choose a tag to compare

@eq19 eq19 released this 13 Apr 02:57
05385eb

Full Changelog: v0.3.1...v0.3.2

Download action repository 'eq19/maps@v8' (SHA:05385eba14057c52cba8f4b6e357eefb43a6d1af)
Download action repository 'eq19/feed@v6' (SHA:2740ae59b6a76c3799523cd21df4db5e5169024f)
Download action repository 'eq19/lexer@v4' (SHA:5635fea849281dc1dc5ab591881d7171381b1427)
Download action repository 'eq19/eq19@v2' (SHA:e2b2107712ebc0f1d47156488157bf64abeb9566)

v0.3.1

Choose a tag to compare

@eq19 eq19 released this 01 Apr 13:24
2c87f5a

Full Changelog: v0.2.20...v0.3.1

FreqAI

class Fibbo(Istrategy):

    def feature_engineering_expand_all(
        self, dataframe: DataFrame, period: int, metadata: dict, **kwargs
    ) -> DataFrame:
        """
        *Only functional with FreqAI enabled strategies*
        This function will automatically expand the defined features on the config defined
        `indicator_periods_candles`, `include_timeframes`, `include_shifted_candles`, and
        `include_corr_pairs`. In other words, a single feature defined in this function
        will automatically expand to a total of
        `indicator_periods_candles` * `include_timeframes` * `include_shifted_candles` *
        `include_corr_pairs` numbers of features added to the model.

        All features must be prepended with `%` to be recognized by FreqAI internals.

        More details on how these config defined parameters accelerate feature engineering
        in the documentation at:

        https://www.freqtrade.io/en/latest/freqai-parameter-table/#feature-parameters

        https://www.freqtrade.io/en/latest/freqai-feature-engineering/#defining-the-features

        :param dataframe: strategy dataframe which will receive the features
        :param period: period of the indicator - usage example:
        :param metadata: metadata of current pair
        dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)
        """

        dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
        dataframe["%-mfi-period"] = ta.MFI(dataframe, timeperiod=period)
        dataframe["%-adx-period"] = ta.ADX(dataframe, timeperiod=period)
        dataframe["%-sma-period"] = ta.SMA(dataframe, timeperiod=period)
        dataframe["%-ema-period"] = ta.EMA(dataframe, timeperiod=period)

        bollinger = qtpylib.bollinger_bands(
            qtpylib.typical_price(dataframe), window=period, stds=2.2
        )
        dataframe["bb_lowerband-period"] = bollinger["lower"]
        dataframe["bb_middleband-period"] = bollinger["mid"]
        dataframe["bb_upperband-period"] = bollinger["upper"]

        dataframe["%-bb_width-period"] = (
            dataframe["bb_upperband-period"] - dataframe["bb_lowerband-period"]
        ) / dataframe["bb_middleband-period"]
        dataframe["%-close-bb_lower-period"] = dataframe["close"] / dataframe["bb_lowerband-period"]

        dataframe["%-roc-period"] = ta.ROC(dataframe, timeperiod=period)

        dataframe["%-relative_volume-period"] = (
            dataframe["volume"] / dataframe["volume"].rolling(period).mean()
        )

        return dataframe

    def set_freqai_targets(
        self,
        dataframe: DataFrame,
        metadata: dict,
        **kwargs
    ) -> DataFrame:
        """
        FreqAI target definition for:
        - Classifier
        - ClassifierMultiTarget
        - Regressor
        - RegressorMultiTarget
        """

        model_name = self.model_name.lower()
        is_classifier = "classifier" in model_name
        is_multi_target = "multitarget" in model_name

        label_period = self.freqai_info["feature_parameters"]["label_period_candles"]

        if is_classifier:
            # ==================================================
            # CLASSIFIERS
            # ==================================================

            if is_multi_target:
                # CatboostClassifierMultiTarget
                # IMPORTANT:
                # - class labels must be UNIQUE across targets
                # - target 1 uses {0, 1}
                # - target 2 uses {2, 3}
                self.freqai.class_names = [0, 1, 2, 3]

                # Target 1: direction (0 = down, 1 = up)
                dataframe["&s-up_or_down"] = (
                    dataframe["close"].shift(-label_period) > dataframe["close"]
                ).astype(int)

                # Target 2: volatility (2 = low, 3 = high)
                dataframe["&s-volatility"] = (
                    (
                        dataframe["close"].rolling(label_period).std()
                        > dataframe["close"].rolling(label_period).std().median()
                    ).astype(int)
                    + 2
                )

            else:
                # CatboostClassifier (single target)
                self.freqai.class_names = [0, 1]

                dataframe["&s-up_or_down"] = (
                    dataframe["close"].shift(-label_period) > dataframe["close"]
                ).astype(int)

        else:
            # ==================================================
            # REGRESSORS
            # ==================================================
            if is_multi_target:
                # CatboostRegressorMultiTarget
                dataframe["&-s_close"] = (
                    dataframe["close"]
                    .shift(-label_period)
                    .rolling(label_period)
                    .mean()
                    / dataframe["close"]
                    - 1
                )

                dataframe["&-s_range"] = (
                    dataframe["close"]
                    .shift(-label_period)
                    .rolling(label_period)
                    .max()
                    -
                    dataframe["close"]
                    .shift(-label_period)
                    .rolling(label_period)
                    .min()
                )

            else:
                # CatboostRegressor
                dataframe["&-s_close"] = (
                    dataframe["close"]
                    .shift(-label_period)
                    .rolling(label_period)
                    .mean()
                    / dataframe["close"]
                    - 1
                )

        return dataframe

Fibbo Indicator

class Fibbo(Istrategy):

     def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        pair = metadata["pair"]

        # --- FreqAI (robust for dynamic pairs) ---
        if self.freqai is not None and self.freqai_enabled:
            try:
                # Start FreqAI
                dataframe = self.freqai.start(dataframe, metadata, self)
                
                # Process DI_values if available
                if 'DI_values' in dataframe.columns:
                    # Check if we have enough data for meaningful percentile
                    if len(dataframe) >= self.di_rolling_window:
                        dataframe['di_percentile'] = (dataframe['DI_values']
                                                      .rolling(self.di_rolling_window)
                                                      .rank(pct=True))
                        logger.debug(f"FreqAI DI_percentile calculated for {pair}")
                    else:
                        # Not enough data yet, use neutral value
                        dataframe['di_percentile'] = 0.5
                        logger.debug(f"FreqAI: Insufficient data for {pair}, using neutral confidence")
                        
                    # Log DI_values stats for debugging
                    logger.debug(f"DI_values - min: {dataframe['DI_values'].min():.3f}, "
                                     f"max: {dataframe['DI_values'].max():.3f}, "
                                     f"mean: {dataframe['DI_values'].mean():.3f}")
                
                # Also log do_predict stats
                if 'do_predict' in dataframe.columns:
                    buy_signals = (dataframe['do_predict'] == 1).sum()
                    sell_signals = (dataframe['do_predict'] == -1).sum()
                    logger.debug(f"FreqAI signals for {pair}: {buy_signals} buy, {sell_signals} sell")
                    
            except KeyError:
                # Pair introduced dynamically without FreqAI history/model
                logger.debug(f"FreqAI model not ready for {pair} - skipping AI signals")
            except Exception as e:
                # Extra safety: never let AI crash the strategy
                logger.warning(f"FreqAI error for {pair}: {e}")
        else:
            if self.freqai is None:
                logger.debug("FreqAI not initialized for this strategy")

        # --- Classical indicators (always run) ---

       # SWING high/low for Fibonacci levels
        dataframe['swing_high'] = dataframe['high'].rolling(self.buy_swing_period.value).max()
        dataframe['swing_low'] = dataframe['low'].rolling(self.buy_swing_period.value).min()
        swing_range = dataframe['swing_high'] - dataframe['swing_low']

        # LONG (retracement in uptrend)
        dataframe['fib_long_0236'] = dataframe['swing_high'] - swing_range * 0.236
        dataframe['fib_long_0382'] = dataframe['swing_high'] - swing_range * 0.382
        dataframe['fib_long_0618'] = dataframe['swing_high'] - swing_range * 0.618
        dataframe['fib_long_0786'] = dataframe['swing_high'] - swing_range * 0.786

        # SHORT (retracement in downtrend)
        dataframe['fib_short_0236'] = dataframe['swing_low'] + swing_range * 0.236
        dataframe['fib_short_0382'] = dataframe['swing_low'] + swing_range * 0.382
        dataframe['fib_short_0618'] = dataframe['swing_low'] + swing_range * 0.618
        dataframe['fib_short_0786'] = dataframe['swing_low'] + swing_range * 0.786
 
       return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Combine your Fibbo strategy with FreqAI predictions.
        FreqAI columns are now available in the dataframe.
        """
        logger.debug(f"Generating entry signals for {metadata['pair']}")
        
        entry_long_conditions = []
        entry_short_conditions = []
        
  ...
Read more

v0.2.20

Choose a tag to compare

@eq19 eq19 released this 03 Mar 22:20
85c51b4

Full Changelog: v0.2.18...v0.2.20

    calculate_score
    NEW_SCORE=$SCORE

    OLD_SCORE=$(gh variable get SCORE)
    if (( $(echo "$NEW_SCORE > $OLD_SCORE" | bc -l) )); then
      cat $STRATEGY
      curl -L -s -X PATCH \
        -H "Accept: application/vnd.github+json" \
        -H "Authorization: Bearer $GH_TOKEN" \
        -H "X-GitHub-Api-Version: 2022-11-28" \
        -d "$(jq -n '{name:"PARAMS_JSON", value:$value}' --arg value "$(cat "$STRATEGY")")" \
         https://api.github.com/repos/$( [[ "$GITHUB_JOB" == "lexering" ]] && echo "$TARGET_REPOSITORY" || echo "$GITHUB_REPOSITORY" )/actions/variables/PARAMS_JSON
      gh variable set FREQAIMODEL --body "${FREQAI_MODEL}" && gh variable set HYPEROPT --body "${HYPEROPT:-$loss}" && gh variable set SCORE --body "${NEW_SCORE}" && gh variable set JOB --body "${GITHUB_JOB}"
      if [[ "$GITHUB_JOB" != "lexering" ]]; then
        gh workflow run "main.yml" --raw-field "FREQAI_MODEL=$FREQAI_MODEL" --raw-field "REDUCE_EPOCH=$REDUCE_EPOCH"
      else
        if [[ "$FREQAI_NEXT" != "false" ]]; then gh workflow run "main.yml" --raw-field "FREQAI_MODEL=$FREQAI_NEXT"; fi      
      fi
    elif (( $(echo "$NEW_SCORE < $OLD_SCORE" | bc -l) )); then
      if [[ "$GITHUB_JOB" == "lexering" ]]; then
        if [[ "$(gh variable get JOB)" != "lexering" ]]; then
          gh workflow run "main.yml" --raw-field "FREQAI_MODEL=$FREQAI_MODEL" --raw-field "REDUCE_EPOCH=$REDUCE_EPOCH"
        else
          if [[ "$FREQAI_NEXT" != "false" ]]; then gh workflow run "main.yml" --raw-field "FREQAI_MODEL=$FREQAI_NEXT"; fi
        fi
      fi
    # Environment SCORE is unchanged in case calculation is failed
    elif (( $(echo "$NEW_SCORE == $OLD_SCORE" | bc -l) )); then
      if [[ "$GITHUB_JOB" == "lexering" && "$CALCULATION" != "false" ]]; then
        gh workflow run "main.yml" --raw-field "FREQAI_MODEL=$FREQAI_NEXT"
      fi
    fi

17725871866978639554485627109887

IMG_20260310_211126

2207.13946v1.pdf

17726321800273968617913653082180

1909.05014v1.pdf

17730638039591623958083121420479 file_00000000ad2471fa8939d0ade1087ed9 file_00000000f8e47208ad759efb5bc02ea7 (1)

v0.2.19

Choose a tag to compare

@eq19 eq19 released this 25 Dec 13:58
1f9c13a

Full Changelog: v0.2.18...v0.2.19

COmpendium of RElations – Modulo 6

Download action repository 'eq19/maps@v8' (SHA:c6194cc0e448d1e91083b1856e8689fb098b7eae)
Download action repository 'eq19/feed@v6' (SHA:0c2fc49365e51ae87aa1e8c999927773643ec827)
Download action repository 'eq19/lexer@v4' (SHA:1a7f40bbd717a5e78e8259464f34256f02b547db)
Download action repository 'eq19/eq19@v2' (SHA:af444f788505ab2e38d768875795bce2d3859419)