Summary:
This trading system script generates orders based on the crossing of two indicators.

Rules:
1. Buy Market - When the first indicator crosses over the second indicator.
2. Sell Market - When the second indicator crosses over the first indicator.
3. Sell Short Market - When the second indicator crosses over the first indicator.
4. Buy To Cover Market - When the first indicator crosses over the second indicator.

                    
#region Namespaces using System; using System.IO; using System.Linq; #endregion namespace ScriptCode { /// <summary> /// Trading strategy scripts are used for trading one symbol at a time such that each symbol gets its own strategy instance. /// </summary> public partial class MyTradingStrategy : TradingStrategyScriptBase // NEVER CHANGE THE CLASS NAME { #region Variables // Use for the first indicator with which trading signals will be generated. private Indicator _indicator1; // Use for the second indicator with which trading signals will be generated. private Indicator _indicator2; // Use for indicating whether to enable the trading strategy to short symbols. private bool _enableShorting; // Use for the percent distance from the entry price in which to place a stop loss order. private double _stopLoss; // Use for the percent distance from the entry price in which to place a take profit order. private double _takeProfit; #endregion #region OnInitialize /// <summary> /// This function is used for accepting the script parameters and for initializing the script prior to all other function calls. /// Once the script is assigned to a desktop, its parameter values can be specified by the user and can be selected for optimization. /// </summary> /// -------------------------------------------------------------------------------------------------- /// PLEASE USE THE SCRIPT WIZARD (CTRL+W) TO ADD, EDIT AND REMOVE THE SCRIPT PARAMETERS /// -------------------------------------------------------------------------------------------------- /// YOU MUST SET A PARAM TAG FOR EACH PARAMETER ACCEPTED BY THIS FUNCTION. /// ALL PARAM TAGS SHOULD BE SET IN THE 'OnInitialize' REGION, RIGHT ABOVE THE 'OnInitialize' FUNCTION. /// THE ORDER OF THE TAGS MUST MATCH THE ORDER OF THE ACTUAL PARAMETERS. /// REQUIRED ATTRIBUTES: /// (1) name: The exact parameter name. /// (2) type: The type of data to collect from the user: /// Set to "Integer" when the data type is 'int' /// Set to "IntegerArray" when the data type is 'int[]' /// Set to "DateTime" when the data type is 'long' /// Set to "DateTimeArray" when the data type is 'long[]' /// Set to "Boolean" when the data type is 'bool' /// Set to "BooleanArray" when the data type is 'bool[]' /// Set to "Double" when the data type is 'double' /// Set to "DoubleArray" when the data type is 'double[]' /// Set to "String" when the data type is 'string' /// Set to "StringArray" when the data type is 'string[]' /// Set to "Indicator" when the data type is 'Indicator' /// Set to "Pattern" when the data type is 'Pattern' /// Set to "Signal" when the data type is 'Signal' /// Set to "Drawing" when the data type is 'Drawing' /// OPTIONAL ATTRIBUTES: /// (3) default: The default parameter value is only valid when the type is Integer, Boolean, Double, String or an API Type. /// (4) min: The minimum parameter value is only valid when the type is Integer or Double. /// (5) max: The maximum parameter value is only valid when the type is Integer or Double. /// EXAMPLE: <param name="" type="" default="" min="" max="">Enter the parameter description here.</param> /// -------------------------------------------------------------------------------------------------- /// <param name="indicator1" type="Indicator">Use for the first indicator with which trading signals will be generated.</param> /// <param name="indicator1Color" type="IQ_Color" default="ROYAL_BLUE">Use for the color of the first indicator.</param> /// <param name="indicator1PlotStyle" type="IQ_PlotStyle" default="LINE">Use for the plot style of the first indicator.</param> /// <param name="indicator2" type="Indicator">Use for the second indicator with which trading signals will be generated.</param> /// <param name="indicator2Color" type="IQ_Color" default="GREEN">Use for the color of the second indicator.</param> /// <param name="indicator2PlotStyle" type="IQ_PlotStyle" default="LINE">Use for the plot style of the second indicator.</param> /// <param name="enableShorting" type="Boolean" default="False">Use for indicating whether to enable the trading strategy to short symbols. </param> /// <param name="stopLoss" type="Double" default="0">Use for the percent distance from the entry price in which to place a stop loss order. (0 to ignore). </param> /// <param name="takeProfit" type="Double" default="0">Use for the percent distance from the entry price in which to place a take profit order. (0 to ignore). </param> public void OnInitialize( Indicator indicator1, IQ_Color indicator1Color, IQ_PlotStyle indicator1PlotStyle, Indicator indicator2, IQ_Color indicator2Color, IQ_PlotStyle indicator2PlotStyle, bool enableShorting, double stopLoss, double takeProfit) { // Set the script parameters to script variables. _enableShorting = enableShorting; _stopLoss = stopLoss; _takeProfit = takeProfit; // Keep the specified indicator. _indicator1 = indicator1; // Plot the indicator on the underlying symbol's chart. int indicator1ItemID = ChartIndicatorPlot(SymbolIndex(), _indicator1, "", - 1, 1); // Set the indicator pen. ChartIndicatorSetPen(SymbolIndex(), indicator1ItemID, 0, indicator1Color, IQ_DashStyle.SOLID, 2); // Set the indicator style. ChartIndicatorSetPlotStyle(SymbolIndex(), indicator1ItemID, indicator1PlotStyle); // Keep the specified indicator. _indicator2 = indicator2; // Plot the indicator on the underlying symbol's chart. int indicator2ItemID = ChartIndicatorPlot(SymbolIndex(), _indicator2, "", - 1, 1); // Set the indicator pen. ChartIndicatorSetPen(SymbolIndex(), indicator2ItemID, 0, indicator2Color, IQ_DashStyle.SOLID, 2); // Set the indicator style. ChartIndicatorSetPlotStyle(SymbolIndex(), indicator2ItemID, indicator2PlotStyle); } #endregion #region OnBarUpdate /// <summary> /// This function is called after each new bar of each symbol assigned to the desktop strategy. /// It should evaluate the specified symbol and its new bar in order to determine whether to generate new orders for it. /// Never create indicators, signals or patterns from OnBarUpdate, for performance reasons those should be created from OnInitialize. /// </summary> /// <param name="symbolIndex" type="Integer">The index of the symbol in the strategy symbol table</param> /// <param name="dataSeries" type="Integer">The number indicating the data series from which the symbol was updated. /// According to the desktop strategy data series settings: 0 for the main data series, 1 or 2 for the second and third, respectively</param> public override void OnBarUpdate( int symbolIndex, int dataSeries) { // Check whether only one bar has been processed so far by the script. if (SessionTotalBarCount(symbolIndex) <= 1) return ; // Check whether the first indicator crosses over the second one. if (_indicator1[0] > _indicator2[0] && _indicator1[1] <= _indicator2[1]) { // Check whether a short position exists. if (_enableShorting && PositionExists(IQ_TradeStatus.OPEN, symbolIndex, IQ_Direction.SHORT_SIDE)) { // Generate a buy to cover market order. BrokerMarket(IQ_ActionType.BUY_TO_COVER, symbolIndex, 5, IQ_TIF.DAY, "Positive crossover."); } // Check whether a long position doesn't exists. if (!PositionExists(IQ_TradeStatus.OPEN, symbolIndex, IQ_Direction.LONG_SIDE) && !OrderExists(IQ_Status.PENDING, symbolIndex)) { // Generate a buy market order. int orderIndex = BrokerMarket(IQ_ActionType.BUY, symbolIndex, 5, IQ_TIF.DAY, "Positive crossover."); // Set a stop loss on the order. BrokerSetStopLossPercent(orderIndex, _stopLoss, true, ""); // Set a take profit on the order. BrokerSetTakeProfitPercent(orderIndex, _takeProfit, true, ""); } } // Check whether the second indicator crosses over the first one. else if (_indicator1[0] < _indicator2[0] && _indicator1[1] >= _indicator2[1]) { // Check whether a long position exists. if (PositionExists(IQ_TradeStatus.OPEN, symbolIndex, IQ_Direction.LONG_SIDE)) { // Generate a sell market order. BrokerMarket(IQ_ActionType.SELL, symbolIndex, 5, IQ_TIF.DAY, "Negative crossover."); } // Check whether a short position doesn't exists. if (_enableShorting && !PositionExists(IQ_TradeStatus.OPEN, symbolIndex, IQ_Direction.SHORT_SIDE) && !OrderExists(IQ_Status.PENDING, symbolIndex)) { // Generate a sell short market order. int orderIndex = BrokerMarket(IQ_ActionType.SELL_SHORT, symbolIndex, 5, IQ_TIF.DAY, "Negative crossover."); // Set a stop loss on the order. BrokerSetStopLossPercent(orderIndex, _stopLoss, true, ""); // Set a take profit on the order. BrokerSetTakeProfitPercent(orderIndex, _takeProfit, true, ""); } } } #endregion #region OnOrderUpdate /// <summary> /// This function is called when an order is executed or cancelled. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index</param> /// <param name="orderIndex" type="Integer">The order index</param> /// <param name="status" type="IQ_Status">The updated status of the order</param> public override void OnOrderUpdate( int symbolIndex, int orderIndex, IQ_Status status) { // OnOrderUpdate Content } #endregion #region OnTradeUpdate /// <summary> /// This function is called when a trade is opened or closed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index</param> /// <param name="tradeIndex" type="Integer">The trade index</param> /// <param name="status" type="IQ_TradeStatus">The updated status of the trade</param> public override void OnTradeUpdate( int symbolIndex, int tradeIndex, IQ_TradeStatus status) { // OnTradeUpdate Content } #endregion #region OnPositionUpdate /// <summary> /// This function is called when a position is opened or closed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index</param> /// <param name="positionIndex" type="Integer">The position index</param> /// <param name="status" type="IQ_TradeStatus">The updated status of the position</param> public override void OnPositionUpdate( int symbolIndex, int positionIndex, IQ_TradeStatus status) { // OnPositionUpdate Content } #endregion #region OnNewsUpdate /// <summary> /// This function is called when a news update is received and only if the NO_NEWS_UPDATES comment is removed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index for the update</param> /// <param name="dateTime" type="DateTime">The date/time in which the update was received by the platform</param> /// <param name="title" type="String">The update title</param> /// <param name="message" type="String">The update message</param> /// <param name="type" type="IQ_MessageType">The message type</param> public override void OnNewsUpdate( int symbolIndex, long dateTime, string title, string message, IQ_MessageType type) { // OnNewsUpdate Content // [NO_NEWS_UPDATES] - Delete this comment to enable news updates to this strategy. } #endregion #region OnRSSUpdate /// <summary> /// This function is called when an RSS update is received and only if the NO_RSS_UPDATES comment is removed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index for the update</param> /// <param name="dateTime" type="DateTime">The date/time in which the update was received by the platform</param> /// <param name="title" type="String">The update title</param> /// <param name="message" type="String">The update message</param> /// <param name="type" type="IQ_MessageType">The message type</param> public override void OnRSSUpdate( int symbolIndex, long dateTime, string title, string message, IQ_MessageType type) { // OnRSSUpdate Content // [NO_RSS_UPDATES] - Delete this comment to enable RSS updates to this strategy. } #endregion #region OnAlertUpdate /// <summary> /// This function is called when an alert update is received and only if the NO_ALERT_UPDATES comment is removed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index for the update</param> /// <param name="dateTime" type="DateTime">The date/time in which the update was received by the platform</param> /// <param name="message" type="String">The update message</param> /// <param name="type" type="IQ_MessageType">The message type</param> public override void OnAlertUpdate( int symbolIndex, long dateTime, string message, IQ_MessageType type) { // OnAlertUpdate Content // [NO_ALERT_UPDATES] - Delete this comment to enable alert updates to this strategy. } #endregion #region OnJournalUpdate /// <summary> /// This function is called when a journal update is received and only if the NO_JOURNAL_UPDATES comment is removed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index for the update</param> /// <param name="dateTime" type="DateTime">The date/time in which the update was received by the platform</param> /// <param name="title" type="String">The update title</param> /// <param name="message" type="String">The update message</param> /// <param name="type" type="IQ_MessageType">The message type</param> public override void OnJournalUpdate( int symbolIndex, long dateTime, string title, string message, IQ_MessageType type) { // OnJournalUpdate Content // [NO_JOURNAL_UPDATES] - Delete this comment to enable journal updates to this strategy. } #endregion #region OnDataConnectionUpdate /// <summary> /// This function is called when a data connection update is received and only if the NO_DATA_CONNECTION_UPDATES comment is removed. /// </summary> /// <param name="symbolIndex" type="Integer">The symbol index for the update</param> /// <param name="dateTime" type="DateTime">The date/time in which the update was received by the platform</param> /// <param name="message" type="String">The update message</param> /// <param name="type" type="IQ_MessageType">The message type</param> public override void OnDataConnectionUpdate( int symbolIndex, long dateTime, string message, IQ_MessageType type) { // OnDataConnectionUpdate Content // [NO_DATA_CONNECTION_UPDATES] - Delete this comment to enable data connection updates to this strategy. } #endregion #region OnBrokerConnectionUpdate /// <summary> /// This function is called when a broker connection update is received and only if the NO_BROKER_CONNECTION_UPDATES comment is removed. /// </summary> /// <param name="dateTime" type="DateTime">The date/time in which the update was received by the platform</param> /// <param name="message" type="String">The update message</param> /// <param name="type" type="IQ_MessageType">The message type</param> public override void OnBrokerConnectionUpdate( long dateTime, string message, IQ_MessageType type) { // OnBrokerConnectionUpdate Content // [NO_BROKER_CONNECTION_UPDATES] - Delete this comment to enable broker connection updates to this strategy. } #endregion #region OnShutdown /// <summary> /// This function is called when the script is shutdown. /// </summary> public override void OnShutdown() { // OnShutdown Content } #endregion } }

The Automated Trading Software for Hedge Funds and Quants