How to Customize a Gekko Strategy (Step-by-Step Guide)

Customizing Gekko trading strategies is the key step to making the most of it. If you’ve already installed Gekko and tried a few built-in features, you’re probably wondering: how do I actually adapt and improve these strategies for my own needs? Whether you’re an advanced user or just ready to dig deeper, this guide gives you a practical, step-by-step workflow for customizing, testing, and safely deploying trading bots on Gekko. We’ll look at real code, configuration tips, backtesting techniques – and most importantly, you’ll understand not just “how” to change a strategy, but why each step matters for real-world trading.

Before starting, review Gekko’s core documentation on:

Note: This guide assumes basic JavaScript skills and focuses on the specific workflow for adapting and testing strategies in Gekko—not on generic coding.

We’ll recap testing (UI & CLI), then walk through customizing and backtesting a variant of Gekko’s standard MACD strategy—adding a stoploss, tuning triggers, and troubleshooting.

First Backtest: Getting Started with a Built-in Gekko Strategy

In Gekko, every trading strategy is a JavaScript file stored in /strategies.

  • Strategies appear in the UI’s backtest menu if you create a matching .toml parameter file under /config/strategies.
  • Whether using UI or CLI, you need to have downloaded market datasets for realistic tests or live simulation—see my guide on data import if needed.
  • Always start by backtesting your custom strategies on historical data first—this approach is both fast and safe.
  • Only after you’re satisfied with the results should you move on to simulating live trading with the “paperTrader” mode, before considering any real trades.

Here’s how the standard MACD strategy performed over a long-term Kraken EUR/ETH dataset (Oct 2016 – Jan 2019) using default parameters.

Backtest with standard parameters

Results with standard parameters

As shown in the results above, via the “market” line highlighted in orange, the “natural” evolution of the market price for a constant number of assets—without any buy/sell actions—was 984% at the end of the period. A simple “buy and hold” strategy (buying the asset right away and holding onto it) would therefore have yielded this return.

By using the standard MACD-based strategy with 6-hour candles and the thresholds shown earlier, 168 trades were executed for a gain very slightly lower (835%) than the market’s natural progression. This highlights both the strengths and limits of automation compared to the passive “buy and hold” approach.

Indeed, if the gain percentage seems slightly lower here—while the overall market context was strongly bullish (+984%) over more than two years—this doesn’t mean that the MACD strategy is bad: in some cases, it could actually help protect gains, for example by selling assets that were previously acquired during a bullish period, if a market drop is detected (which the basic “buy and hold” approach simply does not do). That’s why it’s so important to backtest over different periods and market trends, to analyze how a given strategy behaves with the same settings, or by developing parameters that adjust dynamically to market conditions. The complexity of a strategy can go very far… But sometimes, it turns out that the simplest strategies are actually the best ones.

Next, let’s see how tweaking just a few parameters can impact performance…

Changing Parameters

Results with adjusted parameters

Quick analysis

Fine-tuning only a handful of parameters can noticeably boost your backtest results. However, remember that outstanding past performance doesn’t guarantee future profits—this is especially true in volatile real-world markets. By tuning parameters with historical data, we’re optimizing the model for the past—future results can differ greatly, so always remain cautious before deploying new strategies live. We have time to tweak it “as we want to see the result”. But we don’t know if the same parameters will perform well in the future, aka on a live market.

If we zoom a little bit on the timeline, we can see that the strategy won’t perform so bad during strong uptrends or downtrends. We can also see that it could be tweaked as we often see some LONG (buy) orders appearing just before a loss on the market, but followed by a SHORT (sell) orders. Or SELL orders just before a BUY, despite an uptrend market.

Step 2: Cloning and Exploring the MACD Strategy

Cloning the MACD strategy

  • Start by copying the standard MACD strategy (best practice: never edit originals — always clone a strategy first!) to a new “MyMACD” one:
cp <gekko_installdir>/strategies/MACD.js  <gekko_installdir>/strategies/MyMACD.js

  • (Optional but recommended):
    • It’s a good idea to clone the associated TOML configuration file as well so you can experiment with parameters safely in the UI.
cp <gekko_installdir>/config/strategies/MACD.toml <gekko_installdir>/config/strategies/MyMACD.toml

Quick walkthrough: How strategies/MACD.js works

  • init() initializes variables (trend-tracking, requiredHistory via config.js in the tradingAdvisor section, builds the MACD indicator).
  • The MACD indicator (/strategies/indicators/MACD.js) uses three EMAs (short, long, signal), calculates crosses and returns values used for decision logic.
  • The MACD indicator works as follows:
    • It updates the short and long EMAs using the market price (specifically, the close value from the latest candle, as supplied by the strategy).
    • It computes the difference between these two EMAs: the “MACD”.
    • a third EMA is then computed from the “MACD” value: the signal EMA..
    • Ultimately, the indicator returns the difference between this “MACD” and the signal EMA, which is then interpreted by your strategy’s decision logic as a “bullish” or “bearish” trend.
      For further details on the MACD concept, I recommend checking dedicated tutorials or the full Wikipedia article for a comprehensive explanation.
  • log() can output useful info for debugging on each candle update (e.g., EMA values, macd diff).
  • check() is where trading rules live:
    • If MACD indicator exceeds “up” threshold in config.js, and trend persists: BUY
    • If MACD indicator drops under “down” threshold, and trend persists: SELL
    • If MACD indicator between thresholds: DO NOTHING

For further details on the MACD concept, I recommend checking dedicated tutorials or the full Wikipedia article for a comprehensive explanation.


Add an information to be sure the new strategy is used

  • Add a clear log.debug('Running MyMACD!') or similar at the start of your new strategy before testing.
    • For example, edit MyMACD.js and jump to the log function, around line 51 to change “MACD properties” to “MyMACD properties”:
log.debug('calculated MyMACD properties for candle:');
log.debug('\t', 'short:', macd.short.result.toFixed(digits));
log.debug('\t', 'long:', macd.long.result.toFixed(digits));

Step 3: Wire up your config.js for MyMACD

Modify config.js

  • Modify the trading.Advisor plugin to call the right strategy. It’s just the name of your strategy.js file, without the .js extension.
config.tradingAdvisor = {
   enabled: true,
   method: 'MyMACD',
   candleSize: 360, //to reflect the 6 hours candle I used in previous backtest
   historySize: 6, //to reflect the 6 candles of warmup period in backtest UI
 }

  • Provide the parameters to the strategy (beware to line 2):
// MACD settings:
 config.MyMACD = {
   // EMA weight (α)
   // the higher the weight, the more smooth (and delayed) the line
   short: 10,
   long: 21,
   signal: 9,
   // the difference between the EMAs (to act as triggers)
   thresholds: {
     down: -0.7,
     up: 0.3,
     // How many candle intervals should a trend persist
     // before we consider it real?
     persistence: 0
   }
 };

Those 2 modifications will allow use to use our strat with Gekko’s CLI.

Modify MyMACD.toml

  • If using the UI, double-check config/strategies/MyMACD.toml matches your custom params for full control in the backtest menus.
short = 10
long = 21
signal = 9

[thresholds]

down = -0.7
up = 0.3
persistence = 0

Run your first backtest

Using the CLI

node gekko --config config.js --backtest

Confirm in logs you see output with MyMACD : your custom log/debug messages = correct strat is used.

...

2019-01-09 14:07:52 (DEBUG):    calculated MyMACD properties for candle:
 2019-01-09 14:07:52 (DEBUG):             short: 247.91113481
 2019-01-09 14:07:52 (DEBUG):             long: 253.43444971
 2019-01-09 14:07:52 (DEBUG):             macd: -5.52331490
 2019-01-09 14:07:52 (DEBUG):             signal: -4.87686289
 2019-01-09 14:07:52 (DEBUG):             macdiff: -0.64645201
 2019-01-09 14:07:52 (DEBUG):    In no trend
 2019-01-09 14:07:52 (DEBUG):    calculated MyMACD properties for candle:
 2019-01-09 14:07:52 (DEBUG):             short: 249.96729212
 2019-01-09 14:07:52 (DEBUG):             long: 253.96040883
 2019-01-09 14:07:52 (DEBUG):             macd: -3.99311671
 2019-01-09 14:07:52 (DEBUG):             signal: -4.70011365
 2019-01-09 14:07:52 (DEBUG):             macdiff: 0.70699694
 2019-01-09 14:07:52 (DEBUG):    In uptrend since 1 candle(s)
 2019-01-09 14:07:52 (INFO):     2017-10-24 07:29:00: Paper trader simulated a BUY       0.00000000 EUR  => 3.39807550 ETH
...

Using the UI

The strategy “MyMACD” should now show in the backtest and live menus. You can edit parameters directly for quick tuning.

Compare backtests result

Woohoo, same result :] It means we now have a working base to modify the strategy, without altering the original one.

Practical Tips:

  • Always work with separate config and strategy files for every new experiment.
  • Use version control (like Git) or at least regular backups to track changes to your .js and .toml files.
  • Before adding extra complexity, visualize your signals using complementary tools such as TradingView or Kraken charts, to ensure your logic aligns with real market behavior.

Step 4: How to Add Stoploss Management to Your Custom Gekko Strategy

Why adding a new stoploss parameter ?

One thing that isn’t accounted for in this strategy is the “no-trend” (“notrend”) situation. When the MACD result stays between our lower and upper thresholds for a long time, it doesn’t mean the market or the asset price is stable. It simply means there isn’t enough upward or downward movement for our strategy to capitalize on.

However, the market can continue to decrease (or increase) slowly enough to remain below the detection thresholds we have set. The market can also drop sharply enough that our MACD-based strategy—a moving average whose calculation method naturally lags behind fast market movements—does not yet detect this drop. So, in some cases, after a few candles, it may be wise to sell in order to lock in gains by converting our assets back into currency. This is what is called a stoploss. The stoploss feature automatically triggers a sale if the price falls too far below our last purchase, regardless of the classic indicators we use, helping protect against significant losses during flat or stalling markets.

Summary of how it works

  1. We introduce a stoploss parameter in the configuration.
  2. We modify the management of the upward trend (uptrend) to update the stoploss when the market rises.
  3. We create a new “stalling” trend (“notrend”) in the strategy. In this trend, if the current price falls below the defined stoploss, the strategy sells to limit the loss.

Note that there are many different or complementary ways to improve the system. For example, we could also add an OR condition in the downtrend section, to sell if (the MACD difference is below the down threshold OR if the candle price is below the stoploss price).

Add a parameter to config.js

Edit <gekko_installdir>/config.js to add the stoploss parameter so you will be able to adjust it easily. It is a percentage of the last BUY price.

config.MyMACD = {
   // EMA weight (α)
   // the higher the weight, the more smooth (and delayed) the line
   short: 10,
   long: 21,
   signal: 9,
   // the difference between the EMAs (to act as triggers)
   thresholds: {
     down: -0.7,
     up: 0.3,
     stoploss: 10,
     // How many candle intervals should a trend persist
     // before we consider it real?
     persistence: 0
   }
 };

Modify MyMACD.js to handle the stoploss in uptrends & downtrends

Now edit <gekko_installdir>/strategies/MyMACD.js

In the init function, we add the reading of the config file and store it in stoploss_rate. A new variable stoploss_price which will contain the calculated stoploss price. Note that if you define a variable or const in the init() block, it won’t be persisted in the check() block. So we use “this” object to store data as its scope is global.

//get the stoploss rate from conf
 this.stoploss_rate = this.settings.thresholds.stoploss;
 //reset the stoploss_price
 this.stoploss_price = "";

We need to modify the check() function so that it will receive the candle description as input, as we will need to use it to get the candle.price we try to buy, or the candle.price to update the stoploss if the market is uptrend.

method.check = function(candle) {

In the uptrend section, we add this, to update the new stoploss price each time the market is increasing if the new candle price is higher than the stoploss_price, or each time we BUY (long position adviced):

...

log.debug('In uptrend since', this.trend.duration, 'candle(s)');

if (this.stoploss_price != "" && candle.close > this.stoploss_price)
{
     this.stoploss_price = candle.close-candle.close*this.stoploss_rate/100;
     log.info('===> New computed stoploss price is:', this.stoploss_price,'<===');
}

...

if(this.trend.persisted && !this.trend.adviced)
{
	this.trend.adviced = true;
	this.advice('long');
	this.stoploss_price = candle.close-candle.close*this.stoploss_rate/100;

	log.info('===> We BOUGHT at ~',candle.close,' and computed stoploss price is:', this.stoploss_price,'<===');
} else
	this.advice();

...

Now in the downtrend section, if we SELL, we should reset the stoploss_price as we don’t own any assets anymore.

    if(this.trend.persisted && !this.trend.adviced) {
      this.trend.adviced = true;
      this.advice('short');
      this.stoploss_price = "";
      log.debug('===> We SOLD at ~',candle.close,' and reseted stoploss price. <===');
    } else
      this.advice();

...

Backtesting again

Let’s give it a try, just to make sure we didn’t break anything yet; and even if we actually did not change anything yet to the decision tree to sell or buy.

node gekko --config config.js --backtest

So what do we see ?

  • First, that I disabled the debug mode at the beginning of the config.js file and I forgot to write it here 🙂
  • The first BUY displayed has initialized the stoploss_price by computing the stoploss_rate we defined in conf
  • Then, the stoploss_price keeps increasing, because we made sure not to update it if the market price was below the stoploss_price.
  • When we SELL, the stoploss_price is resetted
  • Seems all good so far !

Modify MyMACD.js to handle the stoploss in a new “stalling” trend

Now let’s modify the “notrend” block and create a “stall” trend with a SELL if we detect a persistence and a market price lower than our stoploss_price. The persistence field acts as a safeguard against false signals—requiring a certain history (several candles) in the same trend before taking action.

} else
{
	//log.debug('In no trend');

	// new trend detected
	if(this.trend.direction !== 'stall')
		// reset the state for the new trend
		this.trend = {
			duration: 0,
			persisted: false,
			direction: 'stall',
			adviced: false
		};

	this.trend.duration++;

	log.debug('In stalled trend since', this.trend.duration, 'candle(s)');

	if(this.trend.duration >= this.settings.thresholds.persistence)
		this.trend.persisted = true;

	if (this.trend.persisted && !this.trend.adviced)
	{
		if (this.stoploss_price != "" && candle.close < this.stoploss_price)
		{
			this.trend.adviced = true;
			this.advice('short');
			this.stoploss_price = "";
			log.info('===> We \'Stalled\' SOLD at ~',candle.close,' and reseted stoploss price. <===');
		}

		log.info('===> Market not low enough to \'stall\' sell <===');
	}
	this.advice();
}

Beware that we also need to modify the downtrend block condition, as we don’t need it to SELL another time if the market is really downtrend, after we already sold earlier thanks to our new “stall trend” code:

} else if(macddiff < this.settings.thresholds.down && this.stoploss_price != "") {

Testing the new strategy

And we backtest it again (note that I commented out the last log.info line in the Stall block to reduce verbosity):

It seems to work. Don’t forget to copy the MACD.toml file in a new MyMACD.toml file and to add the stoploss parameter, so you can also use it in the backtest UI.

Backtest & Analysis

So how does it perform ? Well, not so good 🙂 But the goal of the article was to manage to modify a strategy in order to implement custom rules and logic. I will write another post about backtesting, especially how to try to tune the parameters. Because, As we already noticed, tweaking the parameters does require a lot of analysis, and a lot of tests.

Here we coded a new parameter, and here is the result, knowing that I kept the previous test parameters.

So “out of the box” our new strategy is less efficient than the stock MACD. But we gained control over a new kind of trend on the market watched by the strategy. We need to tune it and find better values for the parameters. Probably, the code could also be optimized a bit.

For information, one backtest with this strategy, on my i7 “mid class office” laptop approximately runs during 41 seconds, after I modified all the log.info() functions we used above to use log.debug() instead; and with debug mode unactivated in config.js.

This was just an example to explain how to instantiate and modify a strategy. I make no guarantee that this modification will be profitable. Again, this is at your own risk, from running a non optimized standard Gekko strategy, to running a customized strategy. You could (very probably) lose your investment as there is no magic formula to anticipate the markets without taking huge risks or having very high confidence in your market knowledge.

In a future article, I will explain how I managed to run large-scale tests with random (or not) parameters, in order to find a “winning” combination (again, based on past data), using public tools provided by contributors.

Ideas for more improvements

Other possible improvements you could work on are:

  • Add a parameter in conf to provide your strategy the last type of order (buy or sell) you manually placed on your echange, with its price so that your strategy will be able to use it for its first decision
  • Calculate the stoploss in the init section if the last action in conf was a buy and you know its price, so that you won’t miss to sell if the very first trend your strategy will have to deal with is a long stall-but-decreasing-market.
  • Deal with more indicators than just the MACD, in a unified strategy.
  • Invert the stoploss principle to buy if we detect a slow but persisted market raise,
  • What is currently not allowed in Gekko is to handle multiple candle size at the same time, so that you could have one same strategy working on short terms trends, and long term trends, and take decisions based on the two (or N candle sizes). It seems there are some forks allowing it, but I didn’t give it a try yet.

Wrap-up: Customizing and Testing Gekko Strategies – What Next?

Personalizing your own Gekko strategies unlocks powerful trading opportunities—yet, it demands a careful and iterative workflow.

  • Always test thoroughly on historical datasets first, then simulate your approach with a “paper trading” bot: real live market, but no real orders
  • Only move to live trading when you’re confident in the strategy’s robustness and your risk control.
  • Markets evolve, so regularly revisit your parameters and logic.
  • Be wary of overfitting—exceptional past performance rarely predicts the future.
  • For best results, consider automating your backtests to systematically compare and refine multiple setups.

Suggested Next Reads on This Blog

Selected external links for further learning

2 thoughts on “How to Customize a Gekko Strategy (Step-by-Step Guide)

  1. Hey, i just want you to know, that i love the idea what you are doing. But you have a mistake in the section where you explain the sell function. There is the same code as in the long position.
    Maybe you can help me with that ;D

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.