top of page

Chart Logic Documentation

speersd1

Updated: Apr 25, 2024

Introduction


Chart Logic is an EA for MT4 that lets you define your own instructions for performing actions on your charts. There are simple building blocks that let you describe the conditions that must be true, and the actions that are performed; and there are rules for how these building blocks are put together. You can create very simple "If A then B" kinds of statements to do simple, everyday tasks (if price crosses above Yesterday's High and then closes back below Yesterday's High, send me an alert). And you can combine these into incredibly complex and sophisticated trading strategies. Chart Logic strategies can be run in the MT4 strategy tester to prove them out, and can then be run on live charts when you're ready to trade them live.


Chart Logic showing candlestick patterns

Whether you want simple automation of everyday tasks on your charts, or you want to write complex trading strategies, Chart Logic lets you do it.


Contents


  • Building Blocks

    • Conditions

    • Actions

  • Logic Sets

  • Strategies

  • Threads

  • Variables

  • Strategy Viewer

  • Strategy Tester

  • Persistence


Chart Logic Building Blocks

If A, B and C; then X, Y and Z

The statements represented by the A, B and C are the conditions, things that must be true. And the X, Y and Z are the actions, the things that we do when all our conditions are true. This is the foundation of Chart Logic, to describe the Conditions and Actions relating to charts and trading.


Let's start with a high-level overview. When you're looking at your charts often there are things you might want to do when some conditions occur. These things may depend on where price is, whether you have a trade open, what some indicator is telling you and so on. By default the kinds of things you can do in MT4 are pretty limited. You can open and close trades if you're ready to act now; or if you want to wait for price to get to some level you can put a pending order on the chart. And you can set alerts. But there's no more sophisticated if/then logic available, unless you get into writing your own scripts, indicators or EAs. If you want to wait for price to cross above some level, or send a notification on an MA cross but only if you're in a trade short, or let you know when drawdown on a trade reaches some value, or when your daily profit exceeds some target, and on and on, there is simply no native way to do these things. We either have to code them, buy a tool to do them, or be chained to our charts and hope we see the important thing happen so we can act. I have for many years dreamed of a way to automate multi-step if/then logic on my charts of arbitrary complexity.


I like to review all my charts in the morning, before the volume picks up with the London session. I check the news that's coming for the day. I look at any trades I have open and think about where they are likely to go, and what levels on the chart I might want to take some action (close in profit, move a SL, maybe send a notification or take a partial loss, close for a full loss, etc.). I might look at some sources of bias like the Commitment of Traders report, retail sentiment, currency strength and so on. And while I'm doing this I'm thinking things like: if price gets here then I want to do X; if RSI is extended low where I'm in this trade in drawdown then I might want to take an aggressive entry; if this trade gets to this much profit, I want to close it; and any number of variations based on what I happen to see on any given day, how many trades I'm in with how much drawdown, how much profit I've had this month, whether it's a Monday or a Friday, etc. And in that moment, when I've decided what my plan is for any given chart, THAT is the moment I want to put the plan in place, while it's all fresh in my mind. Three or 5 hours later when price hits some level I don't want to have to remember all the analysis I did in the morning and what decisions I made, especially when price may be moving fast and there's lots going on. Or I may not even be at my charts that afternoon when price reaches a level I had identified, but I still want to be able to act. Chart Logic lets me write out my plan in simple to understand statements and then run them on the chart, so I don't have to constantly monitor everything and hope I'm attentive and fast enough to act when the key moments come.


The building blocks are conditions and actions. When the conditions are true then do the actions. The condition types describe a wide range of things about your charts. Each condition evaluates as true or false based on its settings, and then moves on to the next condition. Conditions can pass their values to the next condition; or they can save their values in Variables that are more durable (they can be accessed by any other Condition or Action as long as the Condition that sets the Variable is still true). The Action types are the things you want to do: send alerts/notifications; open/modify/close trades; and draw things on your charts.


Now, anything you can describe as a sequence of Conditions and Actions can be automated, without writing a single line of code. If that weren't powerful enough, in addition to being able to refer to a number of built-in technical indicators, you can also write a Condition that obtains data from third-party indicators, and program your logic around their data as well. As long as the indicator exposes its buffers correctly (plus there is a limit on the number of input parameters supported), you can get the data and use it. Let's say you have an indicator you like but it doesn't support alerts; now you can write logic that tests its value and notifies you. Or you can incorporate the indicator into more sophisticated strategies.


Strategies that are written in Chart Logic can even be tested in the MT4 strategy tester. You can save your strategies (or just the individual pieces of logic) to disk, and share them with other Chart Logic users. You can build up a library of automation for a wide range of circumstances, and bring them out when needed. Chart Logic lets you build, test, share and run chart automation like never before.


Okay, that's enough hype. Let's get into it.


Conditions


Condition options

All Conditions start with the same basic structure. You can define how often the Condition should be checked to see if it's true; and once it tests true, how long it should be considered to still be true before it has to evaluate as true again.


Cycle - How often the Condition is evaluated


  • Timeframe

  • Frequency: Tick, Bar or Day


When you write an EA in MT4, the normal way it operates its that, when it receives a piece of data from the server, it starts a processing loop to execute all of its instructions for the given data. Some processing isn't necessary to repeat for every tick, such as testing for entries by strategies that only enter on a new candle. And some instructions only need to be processed once per day, like recalculating a daily range.


Every Condition in Chart Logic lets you independently set its Cycle for when it is evaluated. Think about how often it might be necessary to run your Condition. For example, if you're calculating an H1 Moving Average value it's not necessary to recalculate the value every tick. You can reduce the burden of processing by limiting the instructions to only when they are necessary.


Though be aware that it may be confusing if you're running a Strategy on one timeframe but it's evaluating Conditions and Actions for a different timeframe. I've had several "d'oh!" moments when I've been looking at candlestick patterns trying to figure out why the candles on the chart were clearly not following the rules in my Strategy, only to realize the rules were looking at M5 candles while I was looking at an H1 chart. It's great having complete control over what it's doing, but you also kind of have to pay attention to the details.


Expiry - How long it stays true


  • Counter

  • Period: Bars, Seconds, Ticks or Never


When a Condition evaluates as true, you can then decide how long that evaluation persists. Let's say you're writing a strategy where price crosses below a signal line for a short entry. But you only want that signal line to be valid for a certain number of bars after it formed, and then it should no longer be used for entries. When you specify "Bars" for Expiry it is using the timeframe specified by the Cycle. Once the period specified by Expiry has passed then the Condition is no longer true, until it evaluates as true again.


Note that, when a Condition has tested as true, it is still retested on its next Cycle and if it's still true, even if the Expiry has not run out yet, the Expiry is reset to the current Cycle. For instance, if you have a Condition that is tested every M5 bar (every 5 minutes) and has an Expiry of 1 hour; and after 30 minutes it is evaluated as true again, then the Expiry is reset to now. It will expire in one hour from now, not one hour from 30 minutes ago when it first evaluated as true.


For entry signals you will often want to set the Expiry to one tick. It is valid only for the single instant in which it tested true, and then it is no longer true. Otherwise you might be triggering a Trade Action on every tick for as long as the entry signal is true. Carefully consider how long each Condition should evaluate as true when constructing your trading strategies.


There is a special case with Conditions that are setting a value in a Variable. Usually a Condition is describing some logical test, but when setting a Variable the Condition is always considered to be true. In this way the data that is stored in the Variable will always be available for other Conditions or Actions that need to access it. As long as the Condition that is writing the data is able to calculate / obtain its data, it will evaluate as true. It will still only recalculate according to its Cycle. See the section on Variables below for more information.


Every condition returns the result of its evaluation as a value. If the Condition evaluates as true then the value is set; if the Condition is evaluated as false then the value is cleared. The return value is passed to the next Condition; or if this is the last Condition of a Logic Set, the value is passed to all of the Actions in the Logic Set. This value can be referenced just like a Variable, but it is not stored in the Variable space. When selecting a Variable for some parameter of a Condition or Action, the previous Condition's value is the "Input" variable. The type of this variable is determined by the previous Condition that set it. If you need this "Input" variable to be available to any other Conditions besides the next one, then save it as its own Variable. If you're only going to use some value one time it can be more efficient and easier to manage without saving it as a Variable, which then shows up in every Variable selection dialog (depending on its scope).


Conditions


A Condition can either perform a test or (in some cases) set a Variable.


Most conditions have the option to store the result of their evaluation as a Variable. If it does then it will always return true as soon as it calculates its value and no further test is performed. If it needs some other data to calculate its value that is not available (e.g., a parameter value that it needs to get from another Variable), then it evaluates as false.


If the Condition is not storing its value as a Variable, then it would be performing some kind of test using its value, and returning the result of the evaluation.


There are currently 9 conditions available. The "Type" relates to Threads in Chart Logic; see below for more details (but it's not important to understand this for just starting out).

Condition

Type

Description

Account Condition

UNPAIRED

​Obtains data about your account: balance, equity, margin, drawdown, etc.

Candle Condition

MIXED

High/Low/Open/Close/Volume/Time

Top Wick, Bottom Wick, Body, Size, Mid

Bull, Bear

Indicator Condition

MIXED

Calculates a value from a technical indicator

Key Level Condition

MIXED

Yesterday/Today/LastWeek/LastMonth High/Low values

Price Condition

FIXED

A specific price on a given chart

Set Condition

MIXED

A set of Conditions joined by AND/OR/NOT/FOR

Time Condition

MIXED

Days of the week and time of day

Trade Condition

MIXED or FIXED

Information about current trades/positions

Variable Condition

MIXED

Selection and mathematical operations on variables, with access to some built-in functions for working with datetime variables

Account Condition

Return type: double


Account Condition

Returns account information. Select from the following options:


  • Balance: Your account balance as reported by the Terminal

  • Equity: Balance +/- the value of any open trades, as reported by the Terminal

  • Drawdown $: Equity - Balance

  • Drawdown %: ((Equity - Balance) / Balance) * 100

  • Free Margin: Your account free margin as reported by the Terminal

  • Margin Level %: Your margin level percent as reported by the Terminal


For each of these Account values you can compare to a given amount. For instance you can write an Account Condition for when your Account Drawdown % is < -2.0%, which would evaluate as true when you're in 2% of drawdown.


There is no Variable to set from the Account Condition. All of the values that can be tested with this Condition are also available as Variable substitutions, so no Variable is needed. See the list of substitutions under Alert Action below.


Candle Condition

Return type: int, time, or double


Candle Condition

The Candle Condition lets you access various data about a candle or a range of candles.


  • High

  • Low

  • Open

  • Close

  • Volume

  • Time = The open time of the candle/range

  • Top = Max(Open, Close)

  • Mid = Top - (Top-Bottom)/2

  • Bottom = Min(Open, Close)

  • Top Wick Size = High - (Max(Open, Close))

  • Bottom Wick Size = (Min(Open,Close) - Low)

  • Body Size = Abs(Open-Close)

  • Candle Size = High-Low

  • BULL = (Close > Open)

  • BEAR = (Close < Open)


The "shift" is the number of bars to count back from now. The current candle has a shift of 0. The previous candle has a shift of 1, and so on. When you're in range mode the shift is the candle that starts the range, and you set the range size.


Candle Condition in Range mode

When in range mode, you can effectively think of the range as a single candle. You can get the Open/Close/High/Low prices and work with them just like with a candle. Be aware that the Top and Bottom values ignore the intermediate candles in the range. You might expect "Top" to be aligned with the top of the highest candle open/close in the range or "Bottom" to be aligned with the lowest candle open/close in the range, but that's not what it means. Top is the higher price comparing the tops of the range's opening and closing candles; and Bottom is the lower price comparing the bottoms of the range's opening and closing candles. Think of the range as a single bar of arbitrary size and ignore the candles within.


Also, in range mode, Volume is the sum of volume from all candles in the range.


Starting with version 1.4, there is a special case when getting the candle time and setting the shift to a negative value (i.e., some number of bars in the future). The condition will return the time value for this number of bars in the future.  A shift of -1 is one bar ahead; -2 is two bars and so on.  This is useful when placing some object on the chart to the right of the current time by some distance, without having to manually calculate the time for how far ahead you want to place the object.  Just set a number of bars from current time and refer to that variable.  I was calculating time variables in the future over and over, and decided to add this shortcut to make it easier!


[NOTE: The ability to return data from the future is limited to the Time value. If you set the shift to a negative value and select some data other than Time, it will not work. I know, shocking.]


Be aware if you're using Candle/Range values for comparisons of the difference between prices and sizes. The High/Low/Open/Low values are prices, but the wicks, body and size values are sizes, the difference between two prices. If you compared, say, High[2] > Top_Wick[2] it would always return true, because the top wick size is just a few points, the difference between High[2] and either Open[2] or Close[2], whichever is greater (i.e., Top).


If you're setting the Candle/Range value to a Variable, then the test and value selection fields are not displayed, as you're not performing a test. You can then use these Variables in other Conditions.


For the test (not available for the BULL/BEAR types), you can compare the selected Candle/Range value either to a specific value, or to the value from a Variable that you select. For instance, you might use the Key Level Condition to set a Variable representing Yesterday High, and then a Candle Condition to test for a candle that has a Close above Yesterday High.


Indicator Condition

Return type: double


Indicator Condition

The Indicator Condition lets you select and configure a number of built-in technical indicators available in MT4. When you select the Indicator from the list, the parameters for that indicator are populated in the dialog for you to configure. For parameter values that are based on select lists of options, you can choose the value from a drop-down list of options. See the MT4 documentation for the provided technical indicators for more information on their parameters.


Custom Indicator

There is also the option to specify the "Custom" indicator type, in which case you must provide the correct parameters to configure the indicator. Many third-party indicators are written in such a way that their data can be used by other EAs and Indicators, but before now there was no way to use values from a third-party indicator in your own trading logic without writing your own custom EA code in MQL4. Now with Chart Logic you can program any compliant third-party indicator into your Strategy with relative ease. (I mean, you still have to know the parameters and get everything setup correctly, which can be challenging depending on how well documented the indicator is.)


The "Name" field must be the full name of the compiled file under <MQL4\Indicators>. For instance, if you purchased an indicator from the market it will be under <MQL4\Indicators\Market>, and you would put "Market\\filename.ex4" in the "Name." All custom indicators are configured with the timeframe, shift and mode. Shift is which candle to obtain the value for, starting at 0 for now and increasing with each previous candle on the selected timeframe. Mode is the number of the buffer to read the data from. Check the Data window in MT4 to see the buffers that are exposed by an indicator (put the indicator on the chart first). You can use the "Test" button to confirm the connection to the custom indicator.

The inputs for the indicator that you configure when you add it to a chart can be added to the Custom Indicator configuration as well. For each custom parameter you specify a data type and a value; these must correspond to the inputs for the indicator. Currently only the first 6 inputs are supported. If you do not provide an input then the indicator's default value is used.


Key Level

Return type: double


Key Level Condition

Information about important levels on the chart:


  • Yesterday High/Low

  • Today High/Low

  • Last Week High/Low

  • Last Month High/Low


When used as a test, the Key Level Condition reports whether price is currently above or below the selected Level. When setting a Variable the Key Level Condition stores the price of the selected Level in the Variable.


Price Condition

Return type: double


Price Condition

Specify a price on a given chart, and the Price Condition will test for when the chart price crosses the target price. When you configure the Price Condition it takes note of where price is currently relative to the target price, and will evaluate as true when price crosses to the other side of target price.


Should the Price Condition evaluate as true when price simply ticks above the target price, or when the candle closes above/below the target price? That is controlled by the Cycle, of course.


If current price is below the target price, then the BID value must exceed the target price; and if current price is above the target price then the ASK value must exceed the target price.


The Price Condition does not take any Input; you cannot set the Target Price of a Price Condition to a Variable.  [NOTE: Actually, starting with 1.3, you can now set the target price from a variable.] If you want to have a Condition that evaluates as true when price crosses some price set in a Variable, then use a Candle Condition.


If you’re setting a Variable, the value that is set is the Target Price from the Condition.  Unlike other Conditions, the Variable is set when the Price Condition evaluates as false (meaning the target price hasn’t been hit yet).  Once the Price Condition reaches its Target Price, then the Variable is cleared.  You can use this to refer to the Target Price of the Price Condition in other Conditions and Actions when waiting for it to reach its target.  Its return value is also set to the Target Price when it evaluates as false.  In most cases this is useless, since having a Condition evaluate as false would normally mean that any conditions that come after would not be evaluated; but there are circumstances when this is not the case, such as when used in a NOT Set or a FOR Set.


Set Condition

Return type: the datatype of the last Condition that passed


Set Condition

A Set Condition is simply a container for other conditions, joined by AND, OR, NOT or FOR. You can add Conditions of any type to a Set Condition. And yes, because a Set Condition is a type of Condition, you can nest Set Conditions to any level of complexity you like. A Set Condition is similar in many ways to a Logic Set, except that it does not contain Actions. And a Logic Set only joins Conditions with AND (though of course a Logic Set can contain Set Conditions that join Conditions with its own AND/OR/NOT/FOR logic). The entire set returns the value of the last Condition that passed.


The "FOR" conjunction is an iterator. You set the variable name, start value, step value and count. If Step is a positive number, then the iterator will step up from Start to Start + Count in increments of Step.  If Step is a negative number then the iterator will step down from Start to Start - Count in increments of Step. When the FOR Set is evaluated it will step through the values in the FOR loop, binding the value of the iterator to the FOR variable each time. This variable can be accessed just like any variable by all conditions in the FOR set. The set behaves like an "AND" set; all Conditions in the set must be true for an iteration to be true.


There are three different “modes” for a FOR set: Each, While and Until.  In Each mode, the “count” number of loops will be run regardless of whether all of the Conditions are true in any given iteration.  The last iteration where all Conditions were true has its value returned by the FOR Set.  In While mode, the loops will run as long as all of the Conditions in the loop evaluate as true.  If any iteration has a Condition that evaluates as false, the Set returns the value of the last iteration that had all Conditions pass.  And finally the Until mode means that the iterations will execute until all Conditions in the Set are true, and then it will return the value from that iteration.


So to summarize: For EACH means all loops will run regardless of how the Conditions evaluate.  For WHILE will run while all Conditions are true, and then exit when any Condition fails.  And For UNTIL will run until all Conditions are true, and then exit.  Conditions behave as normally, in particular be aware of the setting of variables in FOR Sets, which occurs according to each individual Condition’s logic, not depending on what type of loop it’s in, whether that loop passes or fails based on the FOR Set mode and so on.


Be aware of a potentially confusing situation with any Conditions that are setting Variable values.  Let’s say you have a FOR Set defined with a loop that will execute 5 times.  There are two conditions, the first sets a Variable and the second performs some test.  On the first loop both conditions pass, so the Variable is set, the 2nd Condition’s test passes and the loop starts again.  The second time through the first Condition passes and so its Variable is set; but the 2nd Condition fails.  This causes the FOR Set to exit the loop, and the return value for the last iteration where all Conditions passed is returned; that is, the result from the first pass through the loop.  But the Variable is still set from the 2nd pass through the loop.  Once a variable is set, the only way it gets unset is if a Condition that is trying to set that Variable fails (or you explicitly unassign the value in a Variable condition).  But in this case the Condition that is setting the Variable passed, and so the Variable value remains, even though this loop ultimately failed.


Going back to Set Conditions in general, there is an interesting difference with Set Conditions in terms of how they are evaluated, because of the OR conjunction. Normally when processing conditions with AND, if you find a Condition that fails its test then you can stop processing Conditions immediately. There would be no reason to keep evaluating Conditions once one of them has failed. Try again next Cycle.


But with OR, this means that if any of the Conditions evaluated as true then the entire Set is considered to be true. Which means that all of the Conditions in the Set have to be evaluated, even if some of them evaluate as false. All Conditions in an OR Set are always evaluated (according to their Cycle).


Here's why this matters. If you have two conditions in a Logic Set, the first performing a test and the second setting a variable, then the second one will not be able to set its variable if the first one does not evaluate as true. You can use this dependency as part of your trading logic, for instance in setting a signal price when an indicator condition evaluates as true.


  • H1 RSI(21) > 50

  • Candle H1 Close[1] sets variable "BULL SIGNAL"


The 2nd Condition will not have a chance to set its signal price variable until after the first Condition has evaluated as true. If A, then B. But if A is not true, then B is not run.


However in a Set with an OR condition the signal variable would be set even if the RSI condition failed.


If the set is a NOT conjunction, this means that all of the Conditions must fail their evaluations in order for the Set to be true. In this case, if a single Condition evaluates as true then the processing of Conditions stops. Similarly if the conjunction is AND and a single Condition evaluates as false then the processing of Conditions stops. It is only in the case of the OR conjunction that processing all Conditions.


You can easily adjust the order of Conditions in the Set Condition dialog. The first column in the list of Conditions is showing the sequence number. If you click the sequence number of one of the rows, it will move that row up and update the sequence numbers. This is the same behavior for re-sequencing that is available in the Logic Set dialog. New with version 1.5: You can now use the UP/DOWN arrow keys on the numeric keyboard to adjust the order as well. Select a row (click the name, the row will be come shaded), and then use the arrow keys to move the row up and down. If the selected row is the first row and you click the up arrow, it will move to the bottom; and if the selected row is the last row and you click the down arrow, it will move to the top.


Time Condition

Return type: datetime


Select days of the week and an optional time.


Time Condition

  • Select the days of the week: Mon, Tue, Wed, Thu, Fri

  • Optionally select a time (hour and minutes)


Why not specify a 2nd time to be able to program a duration, like from 9:30am-noon daily (for trading opening range breakouts at the start of sessions, for instance)? The reason is that we already have a way of specifying the duration, it's the Expiry.


With a Time Condition, if you just select days but no time, then the Condition is true when the current day matches a selected day. If you also set the Time then it must match both Day and Time. If you do not select any days then the Time Condition will always evaluate as false. The return value is the current time (i.e., the time at the most recent Cycle).


If you're looking for more complex things to do with dates and times, look into the Variable Condition. There is advanced processing there for datetime Variables. You can also get a Time value from a candle using the Candle Condition, including some number of candles in the future.


Trade Condition

Return type: double


Trade Condition

Test or select values from trades. The Trade Condition will only be able to "see" trades that match the Thread's symbol and magic number. If you set the Symbol name here then the Trade Condition becomes FIXED to this symbol, and will only apply for this symbol. Otherwise it takes its symbol from the chart it's running on. If you set the magic number in the Strategy to zero, then the magic number will be ignored, and this Condition will look at all trades with the same symbol, regardless of magic number. If you're selecting trades for trade operations it is highly recommended to use magic numbers.


There are two modes for the Trade Condition, Trade and Position.


  • Trade Mode - Select (data from) individual trades

  • Position Mode - Select (data from) all trades for this symbol and a direction


Trade Mode


First, identify the data that is used to select a trade. You can specify values for any number of the following fields. They are cumulative; if you specify multiple values then they must all be true for the Trade Condition to select the trade. If you do not select any data, then the presence of any trade is sufficient for the Condition to evaluate as true.


  • Order Type: Market or Pending

  • Order Direction: LONG or SHORT

  • Trade Amount - The profit or loss of the trade, as an amount

  • Trade Percent - The profit or loss of the trade, as a percent of account balance

  • Trade Swap - The current amount of any swap costs for the trade

  • Trade Pips - The distance from the trade's opening price to the current price, in pips

  • Trade ADR - The distance from the trade's opening price to the current price, in ADR

  • Stop Loss - The stop loss of the trade, in the selected unit

  • Take Profit - The take profit of the trade, in the selected unit

  • Open Price - The open price of the trade


For the numeric fields you specify the value for comparison and a test (>, <, >=, <=, ==, !=). First the Trade Condition identifies the matching trade. If no trade matches all of the tests then the Condition evaluates as false and exits. If more than one trade matches, then the Trade Condition will try to return the farthest trade, according to the test. For instance, if you say "Amount > $20.00" then it will first select all the trades with profit > $20.00, and then return the one with the highest value. If you say "Percent < -2.0" then it will find the trade with the highest drawdown (the lowest percent < -2.0). If you have selected more than one field to test, or are testing with "==" or "!=", then it simply returns the first matching trade.


Once the matching trade is identified, a piece of data from that trade is returned (or the total number of matching trades). If you have a Variable set then this field (and its type) are set to the Variable. Each field's type is displayed next to the field selection button for your reference. The return field is also shown in the Trade Condition name.


Select the field from the matched trade that you want to return:


  • Count (int) - the number of matching trades

  • Order number (int) - Used to identify matching trades for a Trade Action

  • Amount (double) - The profit or loss of the trade, as an amount

  • Percent (double) - The profit or loss of the trade, as a percent of account balance

  • Color (color) - The Bull color if the trade is in profit; the Bear color in drawdown

  • Swap (double) - The current amount of swap costs for the trade

  • Pips (double) - The distance from the trade's opening price, in pips

  • ADR (double) - The distance from the trade's opening price, in ADR

  • Stop Loss (double) - The stop loss price for the trade

  • Take Profit (double) - The take profit price for the trade

  • Open Price (double) - The opening price of the trade

  • Open Time (datetime) - The time and date the trade was opened

  • Close Time (datetime) - The time and date the trade was closed, or 0 if the trade is open


The selected field is stored in the Variable and the Condition returns true. If you want to store multiple fields, then create multiple instances of the Trade Condition, one for each field to store as a Variable.


Position Mode


Use the Trade Condition in Position mode in conjunction with the "Close Position" action in the Trade Action, to close all trades in the position. You will be passing the Direction field to the Trade Action.


Trade Condition for a Position

Position mode is similar to Trade mode, the main difference being that you must select a Direction. The Direction button has moved up next to the "Position Mode" button.


The Position Parameters apply to the position in aggregate, not to any individual trades in the position. "Amount" is the sum of the amount for all trades, and so on. Instead of "Open Price" for a trade you have the "Average" price for the position (the price at which the position would break even). Pips and ADR reflect the distance that price is currently from the position average. (The "Order" number is still in the list, and it will be populated with the order number of the last trade found in the position, but it is not used directly by CL for anything. The important field for CL is the position direction. It is not recommended to use the order number from here, because there are no guarantees about which order will the last one returned by the terminal.)


Variable Condition

Return type: any


Perform comparisons or calculations on values and stored Variables.


Variable Condition

The behavior of the Variable Condition changes depending first on its data type. If you specify a Boolean type (a true/false test), then you will be selecting two values/variables and performing a comparison (>, <, >=, <=, ==, !=). For both sides of this comparison you can either provide a specific value, or select a Variable that has been set by another Condition (or the "Input" value from the previous Condition). You can optionally set the results of this comparison (either "true" or "false") in a Variable. If you're not storing the results in a Variable then a "false" result means the Condition fails the evaluation.


For data types other than Boolean you will be performing a calculation. You can store the result of the calculation in a Variable, or simply pass the value to the next Condition.

In addition to the normal mathematical calculations that are available in the list of operators, there is also an operator called “Market” (“mkt” for short).  When this “operator” is selected, then the right-hand side list of Variables is populated with a selection of data that can be returned from the terminal.  This includes:


  • Ask (double) - The most recent ask price

  • Bid (double) - The most recent bid price

  • Digits (int) The number of zeros to the right of the decimal in prices

  • High (double) - The current day’s High price

  • Lot Size (double) - Lot size in the base currency

  • Lot Step (double) - Step size for changing lots

  • Low (double) - The current day’s low price

  • Margin Required (double) - Fee margin required to open one lot

  • Max Lot (double) - The maximum lot size

  • Min Lot (double) - The minimum lot size

  • Point (double) - Point size in the quote currency

  • Spread (int) - The spread value in points (as an integer)

  • Stop Level (double) - Stop level in points

  • Swap Long (double) - Swap costs long

  • Swap Short (double) - Swap costs short

  • Tick Size (double) - Tick size in points

  • Tick Value (double) - Tick value in the deposit currency

  • Time (datetime) - The time of the most recent tick price


Variable Precision

If the datatype is "double" then you can specify the precision, i.e. the number of digits to display after the decimal. If we're displaying price data though, we don't know how many decimals to display until the strategy gets attached to a chart. In that case (and by default) set the precision to -1, and it will get replaced by the correct number at runtime. Otherwise, if you know the precision independent of what chart you'll be on, then set it here. For instance, when talking about amounts, percents, distance in ADR etc., we're usually using a precision of 2: $20.00, 0.25%, 0.25 ADR.


Variable Condition - Color

When the datatype is "color" then the select list for the right-hand side Variable is a color selection menu.


Datetimes


When the datatype is "datetime," then you have some additional options. The right-hand side select list is populated with a number of time functions from MT4, for instance you can assign the value of "TimeCurrent" to a variable and then reference this variable in other Conditions and Actions. Many Object Actions, for instance, include a "time" parameter and we often display objects at specific times on the chart. This is one way we can get this value in Chart Logic.


Variable Condition - Time Integers

When the datatype is "int" (an integer) but you select a Variable for the right-hand side that is of type "datetime," then the select list for the left-hand side is populated with functions for extracting integer values from the datetime structure. Datetimes have the following configuration:


YYYY.MM.DD hour:minute:seconds


Given a datetime Variable you can get the Year, Month, Day, Day of Week, Day of Month, Hour, Minute and Seconds from this time and store it as an integer value in the Variable. This is how, for instance, you can write a Condition that will evaluate as true only on the first Friday of the month, for strategies that should not trade during NFP (or that only trade during NFP!).


Finally, if you have a Variable Condition with a datetime data type, and instead of selecting a function from the right-side select list you provide a value, you can compose a string for this value that complies with the datetime string described above. But furthermore, you can perform variable substitution on this string. For example, let's say you wanted to figure out the datetime for "yesterday at noon". You can build this Variable like this:


  • TYPE [datetime] = TimeCurrent -> "now"

  • TYPE [int] = Year("now") -> "year"

  • TYPE [int] = Month("now") -> "month"

  • TYPE [int] = Day("now") -> "day"

  • TYPE [datetime] = "%year%.%month%.%day% 12:00:00" -> "today_noon"

  • TYPE [datetime] = 1 x D1 -> "one_day"

  • TYPE [datetime] = "today_noon" - "one_day" -> "yesterday_noon"


Store all of these Variable Conditions inside a single Set Condition (with AND), and then you can keep them collapsed in the Strategy Viewer as a single row; and you can save the entire construction to a file to easily load it into other strategies as needed.


A note about type checking. All Variables are stored with their data type. However, when you are selecting Variables to use in a Variable Condition (or anywhere, really), there is nothing to prevent you from comparing, say, a double and a bool, or a datetime and a color. These operations and comparisons don't make any sense, but there's nothing stopping you from doing it. In most cases where non-compatible types are operated on we will convert them to strings (for comparison) or double (for math operations). But the results are not guaranteed to be meaningful. In fact it's nearly certain that the results will not be meaningful. (What would it mean to calculate 2 x clrRed, or "yesterday" + $20?) Be aware of types and choose comparisons/operations that are valid.


Actions

Action Configuration

Actions describe the things you want to have happen on your charts when all of the Conditions evaluate as true. For all Alert types (except Disable), you can set a Delay timer, a number of seconds that must pass before the Action can be fired again. This is useful to prevent some actions from triggering over and over when the conditions are true, such as an alert when an indicator exceeds some value.


Actions can refer to the value returned from the last Condition in the Logic Set where they are run. Unlike Conditions, where each Condition gets the value from the previous Condition, Actions do not get the value from the previous Action; all Actions get the same value from the last Condition in the Logic Set.


The following Action types are available:

Action

Description

Alert Action

Show a popup alert or send a push notification

Object Action

Draw chart objects (lines, squares, circles, text, arrows, etc.)

Trade Action

Open/Modify/Close trades

Disable Action

Disable the Logic Set when the Actions fire

Alert Action


Alert Action

Show a popup alert and/or send a push notification. (You must configure push notifications in your MT4 settings, of course). Provide the text of the message that will be sent. The symbol name will automatically be added before this string. [NOTE: Starting with version 1.4 there is also a "Log" type of alert, which will just print the alert to the log without also sending a notification. This is useful for backtesting when you want to see log messages, because MT4 does not process alerts or notifications in the tester.]


There are also variable substitutions available for the alert message. Variable substitutions are identified by enclosing the keyword in % delimiters. The following built-in substitutions are available:


  • %balance% - Your account balance

  • %trades% - The number of open trades

  • %dd_amount% - The difference between equity and balance, as an amount

  • %dd_percent% - The difference between equity and balance, as a percent

  • %equity% - Your account equity

  • %margin% - Your free margin

  • %margin_level% - Your margin level percent

  • %symbol% - The current chart symbol

  • %timeframe% - The current chart timeframe


In addition, any Variables set by a Condition that are available in the running Thread can be substituted in this string, including the "Input" variable received from the final Condition of the Logic Set.


Object Action


Object Action

Select the object type (arrow, ellipse, label, line, rectangle, rectangle label, text, trend line, vertical line) and the parameters needed to configure that object are populated in the dialog. For any parameter values that are not select lists, you can choose from Variables that are available in the Thread. For instance, for the Text object type you have parameters for the time and price that indicate where on the chart the text object should be drawn. You can store some relevant time and price data in variables from other Conditions, and then reference them in the Object condition parameters, to have the objects displayed at those values.


You need to provide a unique name for each object on the chart.  This name is used by MT4 to refer to the object.  This is what you see in the Objects dialog in MT4.  If you have multiple objects with the same name, then each Action that creates/updates the object will be attempting to set a value for the same object on the chart, and they will likely be overwriting each others’ values.  You can get some strange results when your object names are not unique.


All object types also have the same common properties, which you can adjust by expanding the "Common Properties" section.


For the Time 1/Time 2 parameters (objects that set their coordinates based on chart time/price), if you leave the value at 0 then it will automatically use the current time. Otherwise, set a [datetime] Variable, e.g. using the Candle Condition to get a candle's time. Similarly, for the Price 1/Price 2 parameters if these are 0.0 then the price value will be set to the current price (i.e., the Bid price). If you need the Ask price then you can get it from the Market data of a Variable Condition.


For any parameter values for color, if you click the "color" header in the dialog then you will get a color select dialog to choose a color, similar to the color data type in the Variable Condition dialog. If you type in a color name or RGB value ("0, 0, 0") in the input box then the "color" header cell will change its color to match the color you typed in, to verify it is a valid color. See the list of colors in the MQL4 documentation here.


Similarly, for any parameters for a font, click the "string" header in the dialog to get a pick list of font names. This is by no means comprehensive, just a list of the most common font names. You can still type any font name in the edit box you like, just be sure it matches the name of a font that is available on your system.


There are two different methods that MT4 uses for deciding where to put objects on charts, either using datetime and price; or by using X/Y coordinates (in pixels). If the object relates to chart price, like a bar high/low price, then use objects with Time/Price coordinates. If you want an object that has a fixed location on the chart and doesn't move over time, use objects with X/Y coordinates. The type of object you're adding to the chart determines which method it uses.

Time, Price

X, Y Coordinates

Arrow


Ellipse

Lines (horizontal, vertical, trend)

Text

Label

Rectangle

Rectangle Label

The Object Action will only display its objects on the current chart when it matches the current chart's symbol. If the current chart is for a different symbol then the Object Action will still store all of its data about any needed objects in the Thread, but nothing will be displayed. If you later change the chart to one where there are objects stored in the Thread they will be displayed on the chart.


Any text that is displayed by an Object also gets the same Variable substitution described in the Alert Action above. You can, for example, put a Label on the chart showing the current chart symbol and timeframe, or show text with a line giving its price or a trade value, etc. The options are nearly limitless.


Singular / Plural Objects


Sometimes you want to put an object on a chart and have a single instance of the object. You can update information about the object in response to changing Variables or state information. For instance, if you put a line on the chart representing a price, you can move that line as price changes, and you can attach a text object to that line to show information about whatever it is you're tracking.


But sometimes you want to put something on the chart to record that something occurred, and you want to keep adding new versions of the object to the chart each time that situation occurs again. For instance you might want to put an arrow above a candle to identify a candlestick pattern, and you want to do this for every candle where this pattern is detected. In this case you don't want to update the one instance of the object when there is new information; you want to create a new instance of the object to document the new occurrence, while leaving the older versions unchanged.


In the Object Action dialog you can specify whether the object is Singular or Plural. A Singular object exists once on the chart. If the data used for this object changes (for example, if some other Condition has set a Variable used by this Object and that Variable value changes), then the Object Action updates the object with the new value. For a Plural object, each time the Object Action is triggered it will create a new object on the chart, rather than updating the Singular version. Each new object will have a number appended to the name to make it unique. You cannot update Plural objects with new information; once they are created they will exist on the chart until the Strategy is stopped.


When a Strategy is activated, if it contains any Plural Object Actions, then all of the visible bars on the chart are processed to see if they should have the objects displayed. However there are some limitations. It can only process historical information per bar, not per tick. Some Conditions may be unable to set their Variables, or will have slightly different behaviors, such as comparing price against a candle close rather than a Bid/Ask value. Expiry based on ticks will behave as if each bar == 1 tick. Expiry based on time will be looking at candle open times. A Variable Condition that is setting a [datetime] value based on a time function will use the bar open time rather than the time function. Trade and Disable actions are not checked while processing bars. In most cases the Object Actions are able to display historical objects, but if your objects are not displaying correctly this is probably why.


Trade Action


Trade Action

Select a Trade Action Type (Open Trade, Modify Trade, Close Trade, Partial Close or Close Position) and then configure the parameters for the operation. For the Open action you configure the trade as you would expect: order type, lot size, stop loss, take profit, order comment, slippage. If it's a pending order type then you must also specify the open price. Each of these can be given a specific value, or can select from a Variable.


For the "Order Size" row select between "Lots" or "Risk." If you select Lots then type in the number of fixed lots to open (or select a Variable with a fixed lot size). For Risk provide a value (or Variable) for the amount to risk as a percent of account balance (e.g., 0.25), and the number of lots will be calculated based on the risk % and value of the Stop Loss field. If you select the Risk sizing method and do not provide a Stop Loss the Trade Action will always fail.


For the SL and TP fields, you can select the unit to provide the SL/TP values. You can provide these values as pips, points, ADR, or a set price.  You can set a Variable for a number of pips (e.g., “20.0”) and then set the Trade Action to set the SL based on this number of pips and it will perform the calculation for you to determine the correct price for the SL.  New with Version 1.4: With the Take Profit field, you can set the TP value to an R value rather than to a specific price.  What does this mean?  The idea is that this is a “risk:reward” calculation.  If the SL distance is 10.0 pips and you set the TP to an R value of 2.0, then the TP will be set at 20 pips.  If you’re setting TP based on R then you must also specify the SL in the Trade Action, or else it won’t be able to calculate the R value.


When modifying a trade there is an option to set the SL to whatever the break even price is for the trade, which will take into account the trade’s commissions and swap costs (that is, it will be the actual price at which the trade breaks even, not just the profit value reported by the terminal, which does not included these costs).  If you want to move a SL to BE after some distance or profit value, this is now a breeze. 


To close a trade you can choose between the Close Trade action or the Close Position action. For a trade you must either type in an order number, or select a Variable that contains an Order Number, which would be stored by a Trade Condition. For a position you can select a variable that contains the position direction (LONG or SHORT), which would also be set by a Trade Condition but for a Position. Or you can specify the direction to close in the Trade action itself and depend on the logic in the Condition section of the Logic Set to control when the Trade Action fires.


The "Comment" field of a new trade also gets Variable substitutions, so you can refer to any Variable as part of the comment, including the Input variable from the last Condition of the Logic Set.


Disable Action


There is no UI for configuring a Disable Action, and it has no Delay. Once a Disable Action has been triggered, the entire Logic Set is disabled and no further processing takes place.


Logic Sets


Whew, that was a lot to get through! Hopefully you have a good idea of the kinds of things you can say about a chart, the Conditions that must be true and the Actions that can be performed.


Logic Set

The Conditions and Actions are grouped together into a container called a Logic Set. Conditions in the Logic Set are evaluated in order of their sequence number, which is displayed in the Logic Set Dialog. When all of the Conditions in the Logic Set are true, then all of the Actions in the Logic Set are triggered. When processing Conditions, if one Condition fails its test, then the processing of further Conditions is stopped until the next Cycle.


The order of Conditions in the Logic Set is important. If you have Conditions that you want to update on every Cycle then put them earlier in the Logic Set. Once a Condition fails, then no further Conditions are processed on this Cycle. The first number in the Condition section of the Logic Set dialog shows the sequence number of conditions, and they are always shown in order. If you remove a Condition from the list, the remaining Conditions are re-sequenced. You can easily change a Condition's sequence by clicking the sequence number; this will move it up one row in the list of Conditions and update the sequence numbers. The same behavior applies for the list of Conditions in the Set Condition dialog. New with version 1.5: You can now use the UP/DOWN arrow keys on the numeric keyboard to adjust the order as well. Select a row (click the name, the row will be come shaded), and then use the arrow keys to move the row up and down. If the selected row is the first row and you click the up arrow, it will move to the bottom; and if the selected row is the last row and you click the down arrow, it will move to the top.


In the Logic Set Dialog, there is an option to save a Logic Set as a Set Condition. This will bring up the File Save dialog, and if you provide a filename, it will save all of the Conditions in this Logic Set to a Set Condition file, which can then be opened in the Logic Set Dialog or Set Condition Dialog. A Set Condition is basically a Logic Set that doesn't have any Actions.


There is also an option to Import Logic Set. This will open a Logic Set file and add all of the Conditions and Actions from that file to this Logic Set. In terms of sequencing of the imported Conditions, they will be added after any Conditions already in the current Logic Set, but they will maintain their order from the imported Logic Set.


There is also the ability to move a Condition to a parent or child container. A Set Condition can contain other Conditions. Sometimes you may want to move a Condition down into a lower Set Condition, or up to the parent Set Condition or Logic Set. When I'm creating my Logic Sets sometimes I realize after I have started that I want a different organization. It would be inconvenient to have to delete everything and start over.


Move Conditions

You can also save Conditions to their own files, or "clone" a Condition to make an exact duplicate to work with.


Strategies


Standard Strategy

Logic Sets are combined into a container called a Strategy. A Strategy has the following properties:


  • Strategy Name - Your description for this Strategy

  • Symbols - Market Watch, Majors, Current Chart, or a List that you provide

  • Magic Number - All trades managed by this Strategy will use this magic number


A "magic number" is a convention for how all EAs work in MT4. An EA sets a magic number on any trades that it opens, and it can only "see" and operate on trades that have the same magic number. In this way two different EAs can operate on the same instance of MT4 without interfering with each other. You can have multiple Strategies running in the same instance of Chart Logic and they will not interfere with each other's trades, as long as each Strategy has a different magic number.


When you define a Strategy you can also specify which symbols it will run on. If you select Market Watch then it will run for all symbols you have loaded in Market Watch. You can also select from just the majors (the USD crosses AUDUSD, EURUSD, GBPUSD, USDCAD, USDCHF, USDJPY). Or select a list of symbols provided in the Chart Logic inputs.


New with version 1.5: Just like with the Logic Set Dialog and Set Condition Dialog, you can use the UP/DOWN arrows on the keyboard to change the order of Logic Sets in the Strategy Dialog.


Threads


When you activate a strategy, it creates an instance of the strategy for each symbol that it is configured for. Back when we first introduced the Conditions I mentioned that there were three different broad types. Let's look at these in more detail now:


  • UNPAIRED - This condition makes no reference to any symbol. For example an Account Condition that gets information about your account, not for any symbol

  • FIXED - A condition that is specific to a single symbol, such as Price condition

  • MIXED - A condition that can be defined generically, such as a Key Level Condition that says "Yesterday High". When you write the Condition it doesn't matter what the symbol is; it only become relevant when the strategy is attached to a chart.


When activated a Strategy will create a separate, independent instance of itself for each symbol that it is configured to run for. If you have 28 pairs available in Market Watch and you start a Strategy that is configured to use Market Watch, then this strategy will have 28 or 29 Threads when it runs. Here's what it it's doing.


The Strategy will examine every Logic Set to determine if it is UNPAIRED, FIXED or MIXED. This is determined by the types of all Conditions in the Logic Set. If the entire Logic Set contains only UNPAIRED Conditions, then the Logic Set is UNPAIRED, and it is added to the UNPAIRED Thread. If a Logic Set contains at least one MIXED Condition and does not contain any FIXED Conditions, then this Logic Set is MIXED and it is added to a Thread for every symbol (but not the UNPAIRED Thread). And if the Logic Set contains even one FIXED Condition then the Logic set is also FIXED and is only added to the Thread for that symbol. It wouldn't make any sense to add a Condition that is FIXED on EURUSD into a Thread that is running on some other pair.


If a Logic Set contains multiple FIXED Conditions but they're for different symbols, this Logic Set is "incoherent" and cannot be activated. The Strategy will fail to activate with a message to the log.


Logic Sets can also be independently enabled/disabled in a Strategy. In the Strategy Dialog, the first column labeled with the "E" header shows whether a Logic Set is enabled or disabled. Simply click the y/n value in the row to toggle the enabled status of each Logic Set. You can also quickly enable all Logic Sets by clicking the "E" cell in the header row. When you activate a Strategy, only enabled Logic Sets will be included. This gives you selective control over which logic is running from your strategy at any time. There is similar functionality to enable/disable Actions in a Logic Set, so you could for instance disable just the Trade Action of a Logic Set while testing all of the Object Actions.


Variables


We talked a lot about Variables while going over the Conditions. Many Condition types can store their results in Variables, and then we can refer to these Variables in Condition and Action parameters. It is a powerful way of sharing information across Conditions and Actions.


Variables can be Global or Local. A Global Variable is available to any Condition or Action in the Thread. A Local Variable is only available within its containing Logic Set.


The way that this works is, the Variables are actually stored as part of the Thread (which is why I put off this discussion of Variables until now). This means that all of the values being stored and read by Conditions and Actions are only for the symbol that these Conditions and Actions are running for. This is how we ensure that, say, an Indicator value for H1 RSI(21) on EURUSD isn't being ready by some other Condition running on a different symbol like GBPUSD. There can be no communication of Variable values from one Thread to another.


Be aware of the implication of this for UNPAIRED Logic Sets. Normally a Variable is available to all Conditions and Actions in the Thread (subject to its Scope), regardless of which Logic Set they're a part of. This is convenient for the planning, organization and running of our Strategies. We can put all of our Conditions that are setting global Thread variables into a separate Logic Set to keep them out of the way, and because they will always evaluate as true and thus don't have any meaningful impact on Condition execution within a Logic Set, other than their presence/absence in the Variable space.


However, if you have an UNPAIRED Logic Set, then it's running in its own Thread, and any Conditions in this Logic Set will be setting Variables that are NOT available to other Threads. This can be useful for Logic Sets that apply to your account generally, such as an alert when account drawdown % exceeds a certain value. If you put these Conditions/Actions into a FIXED (bad) or MIXED (worse) Logic Set, then you'd get 2-28 alerts every time the Conditions occurred (or however many symbols you have loaded in Market Watch). By putting them in an UNPAIRED Logic Set, you ensure they will only be triggered ONCE.


If you have UNPAIRED Conditions that are setting Variables that are needed by other MIXED or FIXED Conditions, then be sure to include these UNPAIRED Conditions directly within those FIXED/MIXED Logic Sets, so the Variables can be available to all FIXED/MIXED Threads.


Also, be careful with Global Variables. If you have two Logic Sets and they both create a Local Variable with the same name, then there will be two different Variables, one for each Logic Set, and they will have their own distinct values. However, if both Logic Sets create a Global Variable with the same name, then there will only be one copy of this Variable and both Logic Sets will be writing to the same Variable. (And of course I mean a Condition in a Logic Set, just abbreviating for simplicity.)


Strategy Viewer


When we're building our Strategies we're using UI dialogs to configure all of the different building blocks, setting parameters, selecting Variables and so on. However, to get a "big picture" view of what's in our Strategy that is not a very convenient approach. There is a higher-level view of a Strategy available. Simply click the name of the Strategy in the main Chart Logic window and the Strategy Viewer is displayed.


Strategy Viewer

Each Logic Set can be expanded/collapsed to show/hide its contents. If there are multiple Conditions in the Logic Set then there is a header row for Conditions which can also be expanded/collapsed. Same for Actions. And if you have any Set Conditions, these can also be expanded/collapsed independently (Set Conditions are collapsed by default). This gives you a great deal of flexibility in navigating larger Strategies and focusing on individual segments at a time. Click the "Exp" column header to toggle between expanded/collapsed for all Logic Sets in the Strategy.


For any Conditions that are setting a Variable, the Variable name is shown. Global Variables are identified with an asterisk.


Click the name of a condition or action to open the Condition/Action dialog for that item, in a read-only mode.  This way you can quickly review all of the details for any row without having to close the Strategy Viewer and navigate through the dialogs to find this specific row.  Click the row again to close the dialog, or click the “Close” button.  You cannot modify any information about the Condition or Action here, it is for display only.


When you display the Strategy Viewer for a Strategy that is running, then you can also monitor the running state of the Strategy for a specific Thread. If the Strategy Viewer is displayed on a chart that has an active Thread then that Thread is automatically selected when the Viewer is displayed. You can change Threads by selecting from the list; click the Thread name in the upper right-hand corner.


Thread Viewer

When displaying the Strategy Viewer for an active Thread you also see the values of any variables that have been set in that Thread, and the pass/fail state of all Conditions, Set Conditions and Logic Sets. For Actions you can display the value of any parameters configured for that Action; step through the Action's parameters by clicking the value in either the Name or Value column, or the first cell in the row (in the strategy tester). If the parameter value is a Variable then the Variable value is shown; if the Variable's value cannot be obtained (i.e, the Condition that sets the value is not evaluating as true) then the name of the Variable is shown instead. It's an excellent way to monitor your running Strategies in real time and understand what they're doing.


Keep in mind how data is processed in the Conditions. If a Condition passes it will be set as "passed" until its next Cycle. If previous Conditions fail then subsequent Conditions will not get re-evaluated, not until the next time that all previous Conditions have passed. This looks a little odd in the Viewer, though, to see a Condition displayed as "Passed" when earlier Conditions have failed. This just means that the last time this Condition was evaluated it passed, and it hasn't been updated since.


Strategy Tester


One of the most mind-blowing features of Chart Logic is that you can run Strategies in the MT4 Strategy Tester. You can write a Strategy, test it to see how it performs and watch it on the chart, and then revise and re-test. All without writing a single line of EA code.


There are a couple of differences between running Chart Logic in the Strategy Tester versus running on a live chart. The main Chart Logic window is not displayed. The main purpose of that window is for authoring of Strategies, which we're not doing in the tester. Plus, it is a limitation of the strategy tester that it cannot process events, and many of the behaviors in UI controls depends on events, so they simply don't work in the tester.


Instead, you specify the name of a Strategy file in the Chart Logic inputs, and this one Strategy file is loaded for testing. The Strategy is automatically activated for a single Thread. Any UNPAIRED Logic Sets are added to this Thread, as well as any MIXED Logic Sets or FIXED Logic Sets that are FIXED to the symbol being tested. If you have a FIXED Logic Set that is for a different symbol then it is not included.


The Strategy Viewer is automatically displayed for the Thread that is running in the Tester. In this way you can monitor the running of this Thread. You can also minimize the Strategy Viewer window if you prefer not to monitor things, which can help with performance.


Persistance


Chart Logic includes the ability to save and load files for Strategies, Logic Sets, Conditions and Actions. You can work on different pieces of logic and store them, try variations, share them with other Chart Logic users, etc.


All Chart Logic files are stored in the common file location on your computer. This makes it easier to share Chart Logic files across different instances of MT4 in the same environment. MT4 strictly limits access to the file system by EAs, so it is not possible to write an EA that can load files from outside of these locations. If you're downloading a Chart Logic file then you must move it to <terminal>\Common\MQL4\Files\ChartLogic. Personally I use a number of folders in this location to organize my Chart Logic files: Strategies, Logic Sets, Conditions and Actions. You will also find a "temp" folder in this location, which is used by Chart Logic for short-term persistence of Strategy and Thread information when changing charts where Chart Logic is running. You can safely change a chart's symbol and timeframe with Chart Logic running on it. Chart Logic does not care about what chart symbol or timeframe it's running on. The one exception is if you have a Strategy set to "Current Chart" for its symbols then it will use the current chart's symbol when the Strategy is activated, but once the Strategy is running you can change the chart without negatively impacting the running Strategy. The Thread becomes FIXED to the chart when the Strategy is activated. You may want to keep the chart on that Strategy's symbol to see any Object Actions (lines, text etc. being drawn on the chart), but it's not necessary. Just be sure Chart Logic is still running!


One handy trick is to combine a number of Conditions that are coordinating to answer a single question into a Set Condition, and then save this Set Condition to disk. For instance, you can define a number of Conditions that describe a candlestick pattern, and store them as a single Condition. You can, in effect, treat a complex Set Condition as a single Condition, and hide complex logic inside.


These Chart Logic files are all text files which can be opened and examined. Be careful not to modify anything, because even small differences can have unintended consequences and make a file unreadable by Chart Logic. I recommend making a backup if you are going to muck around with these files. Also, if you open a file with some other program and then Chart Logic tries to read or write the file then it will throw an error, as the other program will put a "lock" on the file and Chart Logic won't be able to access it. Be sure to close these files before attempting to read them in Chart Logic.

Hozzászólások

0 csillagot kapott az 5-ből.
Még nincsenek értékelések

Értékelés hozzáadása
  • MultiMAX Telegram Group
  • YouTube

Trading CFDs and FX is high risk and not suitable for all investors. Losses can exceed your initial investment. Any Information or advice contained on this website is general in nature and has been prepared without taking into account your objectives, financial situation, or needs. You should never trade any capital that you cannot afford to lose.  The author of this website is not responsible for any losses you incur, even if you're using tools obtained from this author, or trading based on information provided from this website, related websites and accounts (e.g. YouTube) or from the author directly.

The information on this website is not intended to be an inducement, offer, or solicitation to any person in any country or jurisdiction where such distribution or use would be contrary to local law or regulation.

 

Copyright © 2024 by ChartLogic EA.

bottom of page