General Approach
Trading strategies on MachinaTrader follow a systematic approach to analyze market data and generate buy and sell signals. Strategies can incorporate a wide range of technical indicators, mathematical calculations, and custom rules to identify potential entry and exit points in the market.
Code Structure and Purpose
Global Methods: These methods are not specific to any market and are used for internal purposes. They can include functions for parameter setup, configuration, or any other global tasks required by the strategy.
Per Market Methods: These methods are executed per market as per the MachinaTrader configuration. They include methods like onInit and onTick. The onInit method is called during the initialization of the strategy and can be used to perform setup tasks or log information. The onTick method is triggered for each tick of market data and is responsible for analyzing the data and generating trading signals.
Indicator Calculation: Strategies often involve the calculation of various technical indicators or mathematical formulas. These calculations are typically performed within a separate class or set of functions. Common libraries such as Talib or custom functions can be used to calculate indicators like moving averages, Bollinger Bands, or any other desired technical indicators.
Trading Logic: The trading logic is implemented in the onTick method or other relevant methods. It involves analyzing the market data, such as price, volume, or other relevant indicators, and generating buy, sell, or hold signals based on predefined conditions. The logic can be based on simple or complex rules and can incorporate multiple indicators or market factors.
Charting and Indicator Integration: MachinaTrader provides charting functionality that allows traders to visualize market data and indicators. Strategies can utilize the onSendIndicatorModels method to add indicators to the chart. Indicators can be displayed as lines, shapes, or any other visual representation. Traders can customize the appearance and behavior of the indicators to suit their preferences.
Charting and Indicator Integration
MachinaTrader’s charting functionality enables traders to visualize market data and indicators, providing valuable insights into the strategy’s performance. Traders can use the onSendIndicatorModels method to add various indicators to the chart, such as moving averages, Bollinger Bands, or custom indicators. Indicators can be plotted as lines, shapes, or any other visual representation.
The platform offers extensive customization options for indicators, including color, line style, thickness, and shape properties. Traders can adjust these parameters to enhance visibility and interpret the indicators more effectively.
# Strategy Name: SMA (S) # Author: MachinaLabs Ltd. # Update Date: 2022-06-19 # Importing required libraries import sys, talib, requests, json, numpy, base64, json, enum, datetime, array, math, mtCommon # Define strategy parameters and constants STRAT_NAME = 'SMA (S)' VERSION = '1.0' STRAT_TYPE = mtCommon.SimpleStrategy NUM_CANDLES = 25 SMA_FAST = 'SMA Fast' SMA_SLOW = 'SMA Slow' X_OVER = 'X-Over' X_UNDER = 'X-Under' # ------------------------------------------------------------------- # Global methods - Not specific to any market, the config is for internal use only # ------------------------------------------------------------------- def onSendParams(): # Build up parameters to send to MT _mt.addNumericParameter(SMA_FAST, 12, True) # This parameter will override the NUM_CANDLES value if it is higher _mt.addNumericParameter(SMA_SLOW, 18, True) # This parameter will override the NUM_CANDLES value if it is higher # ------------------------------------------------------------------- # Per market methods - Execution triggered per market (as per machina configuration) # ------------------------------------------------------------------- def onInit(): _mt.logInfoP('onInit called [' + STRAT_NAME + ', v' + VERSION + ']') def onTick(currentDate, candles, config): # Create an instance of the Calcs class to perform calculations calcs = Calcs(candles) # Check if candles data is available if len(candles.C) == 0: _mt.logError('No candles returned for ' + config.MARKET) return # Implement the trading logic based on the calculated indicators if calcs.hasCrossedOver(): _mt.buy(config.MARKET) elif calcs.hasCrossedUnder(): _mt.sell(config.MARKET) else: _mt.hold(config.MARKET) def onSendIndicatorModels(candles): # Create an instance of the Calcs class to perform calculations calcs = Calcs(candles) # Add simple moving average indicators to the chart _mt.addSimpleIndicator(SMA_FAST, calcs.smaFast, 'orange', mtCommon.Line, mtCommon.Solid, 3) _mt.addSimpleIndicator(SMA_SLOW, calcs.smaSlow, 'purple', mtCommon.Line, mtCommon.Solid, 3) # Draw the cross overs if they are switched on xovers = _mt.createIndicatorModel('Cross Overs') xovers.addShapeIndicator(X_OVER, calcs.crossOver, 'rgba(45, 188, 32, 0.5)', mtCommon.TriangleUp, mtCommon.AboveBar, mtCommon.Small) xovers.addShapeIndicator(X_UNDER, calcs.crossUnder, 'rgba(188, 32, 32, 0.5)', mtCommon.TriangleDown, mtCommon.BelowBar, mtCommon.Small) _mt.addIndicatorModel(xovers) class Calcs: def __init__(self, candles): self.onCalculate(candles) def onCalculate(self, candles): self.IDX = len(candles.T) - 1 # Calculate Simple Moving Averages (SMAs) based on user-defined parameters self.smaFast = talib.func.SMA(candles.C, _mt.getParameter(SMA_FAST)) self.smaSlow = talib.func.SMA(candles.C, _mt.getParameter(SMA_SLOW)) # Check for cross over and cross under events between SMAs self.crossOver = _mt.crossOver(self.smaFast, self.smaSlow) self.crossUnder = _mt.crossUnder(self.smaFast, self.smaSlow) def hasCrossedOver(self): # Return the most recent cross over event return self.crossOver[len(self.crossOver) - 1] def hasCrossedUnder(self): # Return the most recent cross under event return self.crossUnder[len(self.crossUnder) - 1]