How to Submit and Modify an Order

#region Namespaces
# ---------- DON'T REMOVE OR EDIT THESE LINES -------------------
# These lines are required for integrating Python with our .NET platform.
import clr
clr.AddReference("Tickblaze.Model")
import ScriptCode
from TradingStrategyAPI import *
from AssemblyTradingStrategy_3008_ImportedScripts import *
# ---------------------------------------------------------------
#endregion

## <summary>
## Trading Strategy scripts are used for trading one symbol at a time such that each symbol gets its own strategy instance. 
## Common use-cases include momentum strategies, crossover strategies and overbought / oversold strategies, all of which need to evaluate only a single symbol at a time in order to make trading decisions.
## </summary>
class MyTradingStrategy(ScriptCode.TradingStrategyScriptBase):  # NEVER CHANGE THE CLASS NAME
    #region Variables
    # Variables Content
    #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>
    ## --------------------------------------------------------------------------------------------------
    ##                                 INSTRUCTIONS - PLEASE READ CAREFULLY
    ## --------------------------------------------------------------------------------------------------
    ## 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' (The 'long' data type can only be used for date/time representation)
    ## Set to "DateTimeArray" when the data type is 'long[]' (The 'long' data type can only be used for date/time representation)
    ## 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> 
    ### --------------------------------------------------------------------------------------------------
    def OnInitialize(self):
        # OnInitialize Content
        pass
    #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 for the second data series, etc. (See the DataSeriesSwitch function).</param>
    ## <param name="completedBars" type="Integer">The number of completed bars for the specified symbol since the last call to OnBarUpdate.
    ## Always 1 unless the bar type can generate multiple completed bars from a single tick/minute/day update (depending on the underlying bar source).</param>
    def OnBarUpdate(self, symbolIndex, dataSeries, completedBars):
        OutputWriteLine("")
        # The symbol Id of the underlying symbol.
        OutputWriteLine("SymbolID: " + SymbolID())
        # The symbol index of the underlying symbol.
        OutputWriteLine("SymbolIndex: " + str(symbolIndex))
        
        # Check whether the last two bars are down bars so that we have some entry conditions for creating orders.
        if (DataOpen(0) > DataClose(0) and DataOpen(1) > DataClose(1)):
            # Create a market order for the symbol
            BrokerMarket(C_ActionType.BUY, 0, C_TIF.DAY, "Market order")    
            # Create a limit order for the symbol
            orderIndex = BrokerLimit(C_ActionType.BUY, 20, C_TIF.DAY, DataClose(0), "Limit order")
            # Create a stop loss order from the requested limit price, note that the order could fill better than the limit
            # This method must be called at the same time the parent order is created, it can't be called afterwards because brokers require it to be sent with the original parent order.
            BrokerSetStopLoss(orderIndex, DataClose(0) - SymbolTickSize() * 10, "Stop loss 10 ticks below set limit price")
            # Create a take profit order from the requested limit price, note that the order could fill better than the limit
            # This method must be called at the same time the parent order is created, it can't be called afterwards because brokers require it to be sent with the original parent order.
            BrokerSetTakeProfit(orderIndex, DataClose(0) + SymbolTickSize() * 10, "Take profit 10 ticks above set limit price")
            # Create a stop order for the symbol
            BrokerStop(C_ActionType.BUY, 30, C_TIF.DAY, DataClose(0), "Stop order")
                       
        # Check whether the last two bars are up bars so that we have some entry conditions for creating orders.
        if (DataOpen(0) < DataClose(0) and DataOpen(1) < DataClose(1)):
            # Close the open position if such a position exists for the underlying symbol
            BrokerClosePosition("Close the position");
            
        # Get the pending order indexes.
        pendingOrderIndexes = OrderByStatus(C_Status.PENDING)
        # Iterate over the pending order indexes while modifying the order quantities.
        for o in pendingOrderIndexes:
            BrokerModifyOrder(o, OrderQuantity(o) + 1, -1, -1)
            
            
    #endregion

    #region OnOrderFillUpdate
    ## <summary>
    ## This function is called for each new order fill.
    ## </summary>
    ## <param name="symbolIndex" type="Integer">The symbol index</param>
    ## <param name="orderIndex" type="Integer">The order index</param>
    ## <param name="orderFillIndex" type="Integer">The order fill index</param>
    def OnOrderFillUpdate(self, symbolIndex, orderIndex, status):
        # OnOrderFillUpdate Content
        pass
    #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="C_Status">The updated status of the order</param>
    def OnOrderUpdate(self, symbolIndex, orderIndex, status):
        # OnOrderUpdate Content
        pass
    #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="C_PositionStatus">The updated status of the position</param>
    def OnPositionUpdate(self, symbolIndex, positionIndex, status):
        # OnPositionUpdate Content
        pass
    #endregion

    #region OnSessionUpdate
    ## <summary>
    ## This function is called when a session is opened or closed.
    ## </summary>
    ## <param name="symbolIndex" type="Integer">The symbol index whose session is updated</param>
    ## <param name="status" type="C_SessionStatus">The session status</param>
    def OnSessionUpdate(self, symbolIndex, status):
        # OnSessionUpdate Content
        pass
    #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="C_MessageType">The update message type</param>
    def OnNewsUpdate(self, symbolIndex, dateTime, title, message, type):
        # OnNewsUpdate Content
        # [NO_NEWS_UPDATES] - Delete this comment to enable news updates to this strategy.
        pass
    #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="C_MessageType">The message type</param>
    def OnRSSUpdate(self, symbolIndex, dateTime, title, message, type):
        # OnRSSUpdate Content
        # [NO_RSS_UPDATES] - Delete this comment to enable RSS updates to this strategy.
        pass
    #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="C_MessageType">The update message type</param>
    def OnAlertUpdate(self, symbolIndex, dateTime, message, type):
        # OnAlertUpdate Content
        # [NO_ALERT_UPDATES] - Delete this comment to enable alert updates to this strategy.
        pass
    #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="C_MessageType">The update message type</param>
    def OnJournalUpdate(self, symbolIndex, dateTime, title, message, type):
        # OnJournalUpdate Content
        # [NO_JOURNAL_UPDATES] - Delete this comment to enable journal updates to this strategy.
        pass
    #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="C_MessageType">The update message type</param>
    def OnDataConnectionUpdate(self, symbolIndex, dateTime, message, type):
        # OnDataConnectionUpdate Content
        # [NO_DATA_CONNECTION_UPDATES] - Delete this comment to enable data connection updates to this strategy.
        pass
    #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="C_MessageType">The update message type</param>
    def OnBrokerConnectionUpdate(self, dateTime, message, type):
        # OnBrokerConnectionUpdate Content
        # [NO_BROKER_CONNECTION_UPDATES] - Delete this comment to enable broker connection updates to this strategy.
        pass
    #endregion

    #region OnShutdown
    ## <summary>
    ## This function is called when the script is shutdown.
    ## </summary>
    def OnShutdown(self):
        # OnShutdown Content
        pass
    #endregion