Overall Statistics
Total Trades
9980
Average Win
0.01%
Average Loss
-0.01%
Compounding Annual Return
33.481%
Drawdown
5.800%
Expectancy
0.442
Net Profit
16.233%
Sharpe Ratio
1.994
Probabilistic Sharpe Ratio
81.522%
Loss Rate
35%
Win Rate
65%
Profit-Loss Ratio
1.21
Alpha
0.213
Beta
-0.082
Annual Standard Deviation
0.103
Annual Variance
0.011
Information Ratio
0.665
Tracking Error
0.181
Treynor Ratio
-2.5
Total Fees
$0.00
### <summary>
### In this example, implementing simple algo
### </summary>

import clr
clr.AddReference("System")
clr.AddReference("QuantConnect.Algorithm")
clr.AddReference("QuantConnect.Indicators")
clr.AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
#from QuantConnect.Algorithm import *
#from QuantConnect.Indicators import *
import numpy as np
import json 

class CurrPairs:
    def __init__(self, cpName0, FxData0, PendingBuy0 = 0, PendingSell0 = 0, DefaultUnit0 = 1000, 
            OrderDiffPip0 = 6, LastTradeId0 = 0, LastTradePrice0 = 0.0, LastTradeUnit0 = 0, 
            LastBuyTradeId0 = 0, LastOpenBuyOrderId0 = 0, LastCloseBuyOrderId0 = 0, LastSellTradeId0 = 0, 
            LastOpenSellOrderId0 = 0,LastCloseSellOrderId0 = 0,
            AvgBuyCount0 = 0.0, AvgBuyDist0 = 0.0, MaxBuyCount0 = 0, MaxBuyDist0 = 0.0, BuyCount0 = 0, 
            AvgSellCount0 = 0.0, AvgSellDist0 = 0.0, MaxSellCount0 = 0, MaxSellDist0 = 0.0, 
            SellCount0 = 0, ChngCount0 = 0, AvgChngDist0 = 0.0, MaxChngDist0 = 0.0, PlusOverride0 = 1.05, 
            MinusOverride0 = 1.05, TakeProfitCount0 = 100.0, HoldingUnit0 = 0, DefaultLong0 = True, 
            OnePip0 = 0.0001, MinProfitPip0 = 9, MaxHolding0 = 50000, MinHolding0 = 500 ):
        self.cpName = cpName0
        self.FxData = FxData0 
        self.PendingBuy = PendingBuy0 
        self.PendingSell = PendingSell0  
        self.DefaultUnit = DefaultUnit0 
        self.OrderDiffPip = OrderDiffPip0
        self.OrderDiff = OrderDiffPip0 * OnePip0
        self.LastTradeId = LastTradeId0  
        self.LastTradePrice = LastTradePrice0 
        self.LastTradeUnit = LastTradeUnit0  
        self.LastBuyTradeId = LastBuyTradeId0 
        self.LastOpenBuyOrderId = LastOpenBuyOrderId0 
        self.LastCloseBuyOrderId = LastCloseBuyOrderId0 
        self.LastSellTradeId = LastSellTradeId0 
        self.LastOpenSellOrderId = LastOpenSellOrderId0 
        self.LastCloseSellOrderId = LastCloseSellOrderId0 
        self.Price = 0.0
        self.PrevPrice = 0.0
        self.PriceMove = 0
        self.AvgBuyCount = AvgBuyCount0 
        self.AvgBuyDist = AvgBuyDist0
        self.MaxBuyCount = MaxBuyCount0
        self.MaxBuyDist = MaxBuyDist0
        self.BuyCount = BuyCount0
        self.AvgSellCount = AvgSellCount0
        self.AvgSellDist = AvgSellDist0
        self.MaxSellCount = MaxSellCount0
        self.MaxSellDist = MaxSellDist0
        self.SellCount = SellCount0
        self.ChngCount = ChngCount0
        self.AvgChngDist = AvgChngDist0
        self.MaxChngDist = MaxChngDist0
        self.PlusOverride = PlusOverride0  
        self.MinusOverride = MinusOverride0
        self.TakeProfitCount = TakeProfitCount0
        self.HoldingUnit = HoldingUnit0
        self.DefaultLong = DefaultLong0
        self.OnePip = OnePip0 
        self.MinProfitPip = MinProfitPip0  
        self.MinProfit = MinProfitPip0 * OnePip0
        self.MaxHolding = MaxHolding0 
        self.MinHolding = MinHolding0
        
class  GenericCounters:

    def __init__(self):
        self.CounterValues = {}
        
    def new (self, CounterName, StartValue = 0):
        self.CounterValues[CounterName] = StartValue
        return self.CounterValues[CounterName]
    
    def inc (self, CounterName, increment = 1):
        self.CounterValues[CounterName] += increment
        return self.CounterValues[CounterName]
    
    def dec (self, CounterName, decrement = 1):
        self.CounterValues[CounterName] -= decrement
        return self.CounterValues[CounterName]

### <meta name="tag" content="strategy example" />
class SR000100(QCAlgorithm):

    def mylog (self, MsgLevel, strObj = "", *argv ):
        if  MsgLevel > self.DebugLevel:
            LineOut = strObj + ">"
            cntr = 0
            for arg in argv:
                cntr += 1
                LineOut += "|{0}:{1} :".format(cntr , arg)
            LineOut += "<# "
            self.Log(LineOut) 
    # End of mylog()
    
    def updateCounters(self, OrderEvent, OT, CallerID):

        NewTag = OT.Tag + CallerID + ":OiD-{0}:".format(OT.OrderId)
        self.mylog( 5, CallerID+"FO Tag-update:", OT.OrderId, OT.Symbol, OT.Quantity, OT.Time, OT.Status, OT.Tag, NewTag)

        CP = self.fxPairs[OrderEvent.Symbol.Value]
        CP.HoldingUnit = CP.HoldingUnit + OrderEvent.FillQuantity
        CP.LastTradeId = OrderEvent.OrderId  
        CP.LastTradePrice = OrderEvent.FillPrice 
        CP.LastTradeUnit = OrderEvent.FillQuantity  
        if OrderEvent.FillQuantity > 0 :  # Buy Fill 
            CP.LastBuyTradeId = OrderEvent.OrderId  
        elif OrderEvent.FillQuantity < 0 : # Sell Fill
            CP.LastSellTradeId = OrderEvent.OrderId  
            
        self.mylog( 5, CallerID+"updateCounters:", CP.cpName, CP.Price, CP.PendingBuy, CP.PendingSell,  
                CP.LastTradeId, CP.LastTradePrice, CP.LastTradeUnit, 
                CP.LastBuyTradeId, CP.LastOpenBuyOrderId, CP.LastCloseBuyOrderId, CP.LastSellTradeId, 
                CP.LastOpenSellOrderId, CP.LastCloseSellOrderId,
                CP.AvgBuyCount, CP.AvgBuyDist, CP.MaxBuyCount, CP.MaxBuyDist, CP.BuyCount, 
                CP.AvgSellCount, CP.AvgSellDist, CP.MaxSellCount, CP.MaxSellDist, 
                CP.SellCount, CP.ChngCount, CP.AvgChngDist, CP.MaxChngDist, CP.PlusOverride, 
                CP.MinusOverride, CP.TakeProfitCount, CP.HoldingUnit, self.Portfolio[OrderEvent.Symbol].Quantity  )


    def formatBuyPrice(self, Price, DiffPip, OnePip):
        return (Price - Price %(DiffPip * OnePip)) 

    def formatSellPrice(self, Price, DiffPip, OnePip):
        HalfDiff = DiffPip * OnePip / 2.0
        return (Price + ((-Price - HalfDiff) %(DiffPip * OnePip))) 
    
    def GetOrder(self, OrderId, CallerId = ""):
        Order = self.Transactions.GetOrderById(OrderId)
        if Order is None:
            self.mylog( 10, CallerID+"GetOrder param:", OrderId)
        return Order

    def GetOrderTicket(self, OrderId, CallerId = ""):
        OrderTicket = self.Transactions.GetOrderTicket(OrderId)
        if Order is None:
            self.mylog( 10, CallerID+"GetOrderTicket param:", OrderId)
        return OrderTicket

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.OpenTag = "open"
        self.CloseTag = "close"
        self.DebugLevel = 6   #messages with less level do not print
        
        self.FCC = GenericCounters()
        self.FCC.new("DP")   # DataPoint
        self.FCC.new("OE")  # OrderEvent
        self.FCC.new("OC")  # OrderCount
        self.FCC.new("OBO") # OpenBuyOrder
        self.FCC.new("CBO") # CloseBuyOrder
        self.FCC.new("OSO") # OpenSellOrder
        self.FCC.new("CSO") # CloseSellOrder
        
        self.DefaultOrderProperties.TimeInForce = TimeInForce.GoodTilCanceled
        self.symbols = ["EURUSD", "EURGBP", "GBPUSD"]
        self.ShortPairs = ["EURUSD", "EURGBP", "GBPUSD"]
#        self.symbols = ["EURUSD"]
#        self.ShortPairs = ["EURUSD"]
        PairsCount30 = len(self.symbols)

        self.SetStartDate(2018, 12, 3)    #Set Start Date
        self.SetEndDate(2019, 12, 26)      #Set End Date
        self.SetCash(PairsCount30 * 10000)    #Set Strategy Cash
        self.fxPairs = {}

        # Initialize status data set 
        for symbol in self.symbols:
            fxData = self.AddForex(symbol, Resolution.Hour, Market.Oanda, True, 50.0 )
#            CP = CurrPairs(symbol, fxData )
            self.fxPairs[symbol] = CurrPairs(symbol, fxData )
            if symbol in self.ShortPairs :
                self.fxPairs[symbol].DefaultLong = False

    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
        DP = "DP:{0}:".format(self.FCC.inc("DP"))
        for key in data.Keys:
            CP = self.fxPairs[key.Value]
            CP.Price = self.Securities[key.Value].Price
            PrevPrice =  CP.PrevPrice
            CP.PriceMove = (CP.Price - CP.PrevPrice) 
            if abs(CP.PriceMove) > CP.OrderDiff:
                CP.PrevPrice = CP.Price
            self.mylog( 5, DP, data.Time, key.Value, PrevPrice, CP.Price, CP.PriceMove, data[key].Price, 
                    self.Securities[key.Value].Price, self.Portfolio[key.Value].Quantity )

            OT = 0
            if abs(CP.PriceMove) < CP.OrderDiff:
                pass
            elif abs(self.Portfolio[key.Value].Quantity) < CP.DefaultUnit:
                OC = "OC:{0}:".format(self.FCC.inc("OC"))
                if CP.DefaultLong == True and CP.LastOpenBuyOrderId == 0: 
                    OrderQty = CP.DefaultUnit
                    OrderPrice = self.formatBuyPrice(CP.Price, CP.OrderDiffPip, CP.OnePip)
                    OrderTag = DP + OC + "OBO:{0}:".format(self.FCC.inc("OBO")) + self.OpenTag + ":F"
                    OT = self.LimitOrder(key.Value, OrderQty, OrderPrice, OrderTag)
                    self.mylog( 5, DP+"HLess OBO OT" , OT.OrderId, OT.Symbol, OT.Quantity, OrderPrice, OT.Time, OT.Status, OT.Tag)
                    CP.LastOpenBuyOrderId = OT.OrderId
                elif CP.DefaultLong == False and CP.LastOpenSellOrderId == 0:
                    OrderQty = - CP.DefaultUnit
                    OrderPrice = self.formatSellPrice(CP.Price, CP.OrderDiffPip, CP.OnePip)
                    OrderTag = DP + OC + "OSO:{0}:".format(self.FCC.inc("OSO")) + self.OpenTag + ":F"
                    OT = self.LimitOrder(key.Value, OrderQty, OrderPrice, OrderTag)
                    self.mylog( 5, DP+"HLess OSO OT" , OT.OrderId, OT.Symbol, OT.Quantity, OrderPrice, OT.Time, OT.Status, OT.Tag)
                    CP.LastOpenSellOrderId = OT.OrderId
#                OT = self.MarketOrder(key.Value, OrderQty, False, OrderTag)
            elif abs(CP.PendingBuy) < CP.MinHolding and abs(CP.PendingSell) > CP.MinHolding and CP.LastOpenSellOrderId == 0:
                # place Open Sell Order
                NextSellPrice = CP.Price + CP.MinProfit
                OrderPrice = self.formatSellPrice(NextSellPrice, CP.OrderDiffPip, CP.OnePip)
                OrderQty = - CP.DefaultUnit
                OC = "OC:{0}:".format(self.FCC.inc("OC"))
                OrderTag = DP + OC + "OSO:{0}:".format(self.FCC.inc("OSO")) + self.OpenTag + ":F"
                OT = self.LimitOrder(key.Value, OrderQty, OrderPrice, OrderTag)
                self.mylog( 5, DP+"PendingBuy Less OT" , OT.OrderId, OT.Symbol, OT.Quantity, OrderPrice, OT.Time, OT.Status, OT.Tag)
                CP.LastOpenSellOrderId = OT.OrderId
            elif abs(CP.PendingSell) < CP.MinHolding and abs(CP.PendingBuy) > CP.MinHolding and CP.LastOpenBuyOrderId == 0:  
                # place Open Buy Order
                NextBuyPrice = CP.Price - CP.MinProfit
                OrderPrice = self.formatBuyPrice(NextBuyPrice, CP.OrderDiffPip, CP.OnePip)
                OrderQty = CP.DefaultUnit
                OC = "OC:{0}:".format(self.FCC.inc("OC"))
                OrderTag = DP + OC + "OBO:{0}:".format(self.FCC.inc("OBO")) + self.OpenTag + ":F"
                OT = self.LimitOrder(key.Value, OrderQty, OrderPrice, OrderTag)
                self.mylog( 5, DP+"PendingSell Less OT" , OT.OrderId, OT.Symbol, OT.Quantity, OrderPrice, OT.Time, OT.Status, OT.Tag)
                CP.LastOpenBuyOrderId = OT.OrderId
            
            self.mylog( 0, DP+key.Value, CP.cpName, CP.PrevPrice, CP.Price, CP.PriceMove, CP.PendingBuy, CP.PendingSell,  
                    CP.LastTradeId, CP.LastTradePrice, CP.LastTradeUnit, 
                    CP.LastBuyTradeId, CP.LastOpenBuyOrderId, CP.LastCloseBuyOrderId, CP.LastSellTradeId, 
                    CP.LastOpenSellOrderId, CP.LastCloseSellOrderId,
                    CP.AvgBuyCount, CP.AvgBuyDist, CP.MaxBuyCount, CP.MaxBuyDist, CP.BuyCount, 
                    CP.AvgSellCount, CP.AvgSellDist, CP.MaxSellCount, CP.MaxSellDist, 
                    CP.SellCount, CP.ChngCount, CP.AvgChngDist, CP.MaxChngDist, CP.PlusOverride, 
                    CP.MinusOverride, CP.TakeProfitCount, CP.HoldingUnit, self.Portfolio[key.Value].Quantity  )
#            self.Plot('FX Price', CP.cpName, CP.Price )
#            self.Plot('PendingBuySell', 'PendingBuy' , CP.PendingBuy )
#            self.Plot('PendingBuySell', 'PendingSell' , CP.PendingSell )
#            self.Plot('PendingBuySell', 'Holding' , CP.HoldingUnit )
#        self.mylog( 5, DP+"end of onData()")

    def OnOrderEvent(self, OrderEvent):
        if OrderEvent.Status != OrderStatus.Filled :
            return

        OE = "OE:{0}:".format(self.FCC.inc("OE"))
        self.mylog( 5, OE+"param: ", OrderEvent.OrderId, OrderEvent.Symbol, OrderEvent.Status, 
                OrderEvent.FillPrice, OrderEvent.FillQuantity, OrderEvent.Direction, OrderEvent.Message )
        Order = self.GetOrder(OrderEvent.OrderId, OE)
        OrderTicket = self.GetOrderTicket(OrderEvent.OrderId, OE+"param")
        self.mylog( 5, OE+"Order/OTicket: ", OrderTicket.OrderId, Order.BrokerId, Order.Symbol, Order.Price,
                 Order.Quantity, Order.Type, Order.Status, Order.Tag, Order.Direction, Order.Value )

        otFilter = lambda ot: ( ot.Symbol == OrderEvent.Symbol and self.OpenTag in Order.Tag )
        OOList = self.Transactions.GetOpenOrders(filter = otFilter)
        x = 0
        for OO in OOList:
            x += 1
            self.mylog( 5, OE+"OOList: ", x, OOList[x-1], OO, OO.Id, OO.BrokerId, OO.Symbol, OO.Price, OO.Quantity,
                    OO.Type, OO.Status, OO.Tag, OO.Direction, OO.Value ) 

        if OrderEvent.Symbol.Value in self.fxPairs:
            CP = self.fxPairs[OrderEvent.Symbol.Value]
        else:
            self.mylog( 5, OE+"fxPairs[] not found", OrderEvent.Symbol.Value, OrderEvent.OrderId , Order.Id)

        if OrderEvent.Status == OrderStatus.Filled :
            self.updateCounters(OrderEvent, OrderTicket, OE)

            if OrderEvent.FillQuantity > 0 :  # Buy Fill 
                NextBuyPrice = OrderEvent.FillPrice - CP.OrderDiff
                while NextBuyPrice >= self.Securities[OrderEvent.Symbol].Price :
                    NextBuyPrice -=  CP.OrderDiff

                NextSellPrice = OrderEvent.FillPrice + CP.MinProfit
                while NextSellPrice <= self.Securities[OrderEvent.Symbol].Price :
                    NextSellPrice +=  CP.OrderDiff

                NextBuyPrice = self.formatBuyPrice(NextBuyPrice, CP.OrderDiffPip, CP.OnePip)
                NextSellPrice = self.formatSellPrice(NextSellPrice, CP.OrderDiffPip, CP.OnePip)
                
                self.mylog( 5, OE+"BOF Prices" , OrderEvent.FillPrice, self.Securities[OrderEvent.Symbol].Price, 
                            NextBuyPrice, NextSellPrice)

                if  self.OpenTag  in Order.Tag:   #Buy - Open - Fill
                    CP.PendingSell -= OrderEvent.FillQuantity    #increase PendingSell
                    CloseSellQuantity = CP.PendingSell / CP.TakeProfitCount
                    OpenBuyQuantity = CP.DefaultUnit
                    NextBuyPrice -= CP.OnePip - CP.OnePip
                    if CP.LastOpenBuyOrderId != OrderEvent.OrderId and CP.LastOpenBuyOrderId != 0:
                        LastOpenBuyOrder = self.GetOrderTicket(CP.LastOpenBuyOrderId, OE+"BOF-OBO")
                        if LastOpenBuyOrder is not None:
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextBuyPrice
                            updateSettings.Quantity = OpenBuyQuantity
                            response = LastOpenBuyOrder.Update(updateSettings)
                            self.mylog( 5, OE+"BOF-update OBO:", updateSettings.LimitPrice, updateSettings.Quantity, response.ToString() )
                            if response.IsSuccess:
                                OT = LastOpenBuyOrder
                                self.mylog( 5, OE+"BOF-OBO:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                         updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                    else:
                        CP.LastOpenBuyOrderId = 0
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "OBO:{0}:".format(self.FCC.inc("OBO")) + self.OpenTag + ":F"    
                        self.mylog( 5, OE+"BOF-OBO price:" , NextBuyPrice , Order.Symbol , OpenBuyQuantity )
                        OT2 = self.LimitOrder(Order.Symbol, OpenBuyQuantity, NextBuyPrice, OrderTag)
                        self.mylog( 5, OE+"BOF-OBO-OT2:" , 
                                OT2.OrderId, OT2.Symbol, OT2.Quantity, NextBuyPrice, OT2.Time, OT2.Status, OT2.Tag)
                        CP.LastOpenBuyOrderId = OT2.OrderId

                    if CP.LastCloseSellOrderId != 0:
                        LastCloseSellOrder = self.GetOrderTicket(CP.LastCloseSellOrderId, OE+"BOF-CSO")
                        if LastCloseSellOrder is not None and LastCloseSellOrder.Status == OrderStatus.Submitted :
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextSellPrice
                            updateSettings.Quantity = CloseSellQuantity
                            response = LastCloseSellOrder.Update(updateSettings)
                            self.mylog( 5, OE+"BOF-update CSO:", updateSettings.LimitPrice, updateSettings.Quantity, response.ToString() )
                            if response.IsSuccess:
                                OT = LastCloseSellOrder
                                self.mylog( 5, OE+"BOF-CSO:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                             updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                        else:
                            OC = "OC:{0}:".format(self.FCC.inc("OC"))
                            OrderTag = OE + OC + "CSO:{0}:".format(self.FCC.inc("CSO")) + self.CloseTag + ":F"
                            self.mylog( 5, OE+"BOF-CSO price:" , NextSellPrice , Order.Symbol , CloseSellQuantity, OrderTag )
                            OT1 = self.LimitOrder(Order.Symbol, CloseSellQuantity, NextSellPrice, OrderTag)
                            self.mylog( 5, OE+"BOF-CSO-OT1:" , 
                                    OT1.OrderId, OT1.Symbol, OT1.Quantity, NextSellPrice, OT1.Time, OT1.Status, OT1.Tag)
                            CP.LastCloseSellOrderId = OT1.OrderId
                    else:
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "CSO:{0}:".format(self.FCC.inc("CSO")) + self.CloseTag + ":F"
                        self.mylog( 5, OE+"BOF-CSO price:" , NextSellPrice , Order.Symbol , CloseSellQuantity )
                        OT1 = self.LimitOrder(Order.Symbol, CloseSellQuantity, NextSellPrice, OrderTag)
                        self.mylog( 5, OE+"BOF-CSO-OT1:" , 
                                OT1.OrderId, OT1.Symbol, OT1.Quantity, NextSellPrice, OT1.Time, OT1.Status, OT1.Tag)
                        CP.LastCloseSellOrderId = OT1.OrderId

                elif self.CloseTag  in Order.Tag:        #buy Close
                    CP.PendingBuy -= OrderEvent.FillQuantity      #decrease PendingBuy
                    CloseBuyQuantity = CP.PendingBuy / CP.TakeProfitCount
                    OpenSellQuantity = - CP.DefaultUnit
                    NextSellPrice += CP.OnePip + CP.OnePip
                    if CP.LastCloseBuyOrderId != OrderEvent.OrderId and CP.LastCloseBuyOrderId != 0:
                        LastCloseBuyOrder = self.GetOrderTicket(CP.LastCloseBuyOrderId, OE+"BOF-CBO")
                        if LastCloseBuyOrder is not None:
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextBuyPrice
                            updateSettings.Quantity = CloseBuyQuantity
                            response = LastCloseBuyOrder.Update(updateSettings)
                            self.mylog( 5, OE+"BOF-update CBO:", updateSettings.LimitPrice, updateSettings.Quantity, response.ToString() )
                            if response.IsSuccess:
                                OT = LastCloseBuyOrder
                                self.mylog( 5, OE+"BOF-CBO:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                         updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                    else:
                        CP.LastCloseBuyOrderId = 0
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "CBO:{0}:".format(self.FCC.inc("CBO")) + self.CloseTag + ":F"    
                        self.mylog( 5, OE+"BOF-CBO price:" , NextBuyPrice , Order.Symbol , CloseBuyQuantity )
                        OT2 = self.LimitOrder(Order.Symbol, CloseBuyQuantity, NextBuyPrice, OrderTag)
                        self.mylog( 5, OE+"BOF-CBO-OT2:" , 
                                OT2.OrderId, OT2.Symbol, OT2.Quantity, NextBuyPrice, OT2.Time, OT2.Status, OT2.Tag)
                        CP.LastCloseBuyOrderId = OT2.OrderId

                    if CP.LastOpenSellOrderId != 0:
                        LastOpenSellOrder = self.GetOrderTicket(CP.LastOpenSellOrderId, OE+"BOF-OSO")
                        if LastOpenSellOrder is not None and LastOpenSellOrder.Status == OrderStatus.Submitted :
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextSellPrice
                            updateSettings.Quantity = OpenSellQuantity
                            response = LastOpenSellOrder.Update(updateSettings)
                            self.mylog( 5, OE+"BOF-update OSO:", updateSettings.LimitPrice, updateSettings.Quantity, response.ToString() )
                            if response.IsSuccess:
                                OT = LastOpenSellOrder
                                self.mylog( 5, OE+"BOF-OSO:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                             updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                        else:
                            OC = "OC:{0}:".format(self.FCC.inc("OC"))
                            OrderTag = OE + OC + "OSO:{0}:".format(self.FCC.inc("OSO")) + self.OpenTag + ":F"
                            self.mylog( 5, OE+"BOF-OSO price:" , NextSellPrice , Order.Symbol , OpenSellQuantity )
                            OT1 = self.LimitOrder(Order.Symbol, OpenSellQuantity, NextSellPrice, OrderTag)
                            self.mylog( 5, OE+"BOF-OSO-OT1:" , 
                                    OT1.OrderId, OT1.Symbol, OT1.Quantity, NextSellPrice, OT1.Time, OT1.Status, OT1.Tag)
                            CP.LastOpenSellOrderId = OT1.OrderId
                    else:
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "OSO:{0}:".format(self.FCC.inc("OSO")) + self.OpenTag + ":F"
                        self.mylog( 5, OE+"BOF-OSO price:" , NextSellPrice ,  Order.Symbol , OpenSellQuantity )
                        OT1 = self.LimitOrder(Order.Symbol, OpenSellQuantity, NextSellPrice, OrderTag)
                        self.mylog( 5, OE+"BOF-OSO-OT1:" , 
                                OT1.OrderId, OT1.Symbol, OT1.Quantity, NextSellPrice, OT1.Time, OT1.Status, OT1.Tag)
                        CP.LastOpenSellOrderId = OT1.OrderId

            elif OrderEvent.FillQuantity < 0 : # Sell Fill
                NextBuyPrice = OrderEvent.FillPrice - CP.MinProfit
                while NextBuyPrice >= self.Securities[Order.Symbol].Price :
                    NextBuyPrice -=  CP.OrderDiff

                NextSellPrice = OrderEvent.FillPrice + CP.OrderDiff
                while NextSellPrice <= self.Securities[Order.Symbol].Price :
                    NextSellPrice +=  CP.OrderDiff

                NextBuyPrice = self.formatBuyPrice(NextBuyPrice, CP.OrderDiffPip, CP.OnePip)
                NextSellPrice = self.formatSellPrice(NextSellPrice, CP.OrderDiffPip, CP.OnePip)

                self.mylog( 5, OE+"SOF " , OrderEvent.FillPrice, self.Securities[OrderEvent.Symbol].Price, 
                            NextBuyPrice, NextSellPrice)

                if  self.OpenTag  in Order.Tag:
                    CP.PendingBuy -= OrderEvent.FillQuantity    #increase PendingBuy
                    CloseBuyQuantity = CP.PendingBuy / CP.TakeProfitCount
                    OpenSellQuantity = -CP.DefaultUnit
                    if CP.LastOpenSellOrderId != OrderEvent.OrderId and CP.LastOpenSellOrderId != 0:
                        LastOpenSellOrder = self.GetOrderTicket(CP.LastOpenSellOrderId, OE+"SOF-OSO")
                        if LastOpenSellOrder is not None:
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextSellPrice
                            updateSettings.Quantity = OpenSellQuantity
                            response = LastOpenSellOrder.Update(updateSettings)
                            self.mylog( 5, OE+"SOF-update OSO:", updateSettings.LimitPrice, updateSettings.Quantity, response.ToString() )
                            if response.IsSuccess:
                                OT = LastOpenSellOrder
                                self.mylog( 5, OE+"SOF-OSO:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                         updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                    else:
                        CP.LastOpenSellOrderId = 0
                        NextSellPrice += CP.OnePip + CP.OnePip
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "OSO:{0}:".format(self.FCC.inc("OSO")) + self.OpenTag + ":F"
                        self.mylog( 5, OE+"SOF-OSO price:" , NextSellPrice , Order.Symbol , OpenSellQuantity )
                        OT2 = self.LimitOrder(Order.Symbol, OpenSellQuantity, NextSellPrice, OrderTag)
                        self.mylog( 5, OE+"SOF-OSO-OT2:" , 
                                OT2.OrderId, OT2.Symbol, OT2.Quantity, NextSellPrice, OT2.Time, OT2.Status, OT2.Tag)
                        CP.LastOpenSellOrderId = OT2.OrderId

                    if CP.LastCloseBuyOrderId != 0:
                        LastCloseBuyOrder = self.GetOrderTicket(CP.LastCloseBuyOrderId, OE+"SOF-CBO")
                        if LastCloseBuyOrder is not None and LastCloseBuyOrder.Status == OrderStatus.Submitted :
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextBuyPrice
                            updateSettings.Quantity = CloseBuyQuantity
                            response = LastCloseBuyOrder.Update(updateSettings)
                            self.mylog( 5, OE+"SOF-CBO update:", updateSettings.LimitPrice, updateSettings.Quantity, response, response.ToString() )
                            if response.IsSuccess:
                                OT = LastCloseBuyOrder
                                self.mylog( 5, OE+"SOF-CBO updated:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                             updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                        else:
                            OC = "OC:{0}:".format(self.FCC.inc("OC"))
                            OrderTag = OE + OC + "CBO:{0}:".format(self.FCC.inc("CBO")) + self.CloseTag + ":F"    
                            self.mylog( 5, OE+"SOF-CBO price:" , NextBuyPrice , Order.Symbol , CloseBuyQuantity )
                            OT1 = self.LimitOrder(Order.Symbol, CloseBuyQuantity, NextBuyPrice, OrderTag)
                            self.mylog( 5, OE+"SOF-CBO-OT1:" , 
                                    OT1.OrderId, OT1.Symbol, OT1.Quantity, NextBuyPrice, OT1.Time, OT1.Status, OT1.Tag)
                            CP.LastCloseBuyOrderId = OT1.OrderId
                    else:
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "CBO:{0}:".format(self.FCC.inc("CBO")) + self.CloseTag + ":F"    
                        self.mylog( 5, OE+"SOF-CBO price:" , NextBuyPrice , Order.Symbol , CloseBuyQuantity )
                        OT1 = self.LimitOrder(Order.Symbol, CloseBuyQuantity, NextBuyPrice, OrderTag)
                        self.mylog( 5, OE+"SOF-CBO-OT1:" , 
                                OT1.OrderId, OT1.Symbol, OT1.Quantity, NextBuyPrice, OT1.Time, OT1.Status, OT1.Tag)
                        CP.LastCloseBuyOrderId = OT1.OrderId

                elif self.CloseTag  in Order.Tag:
                    CP.PendingSell -= OrderEvent.FillQuantity      #decrease PendingSell
                    CloseSellQuantity = CP.PendingSell / CP.TakeProfitCount
                    OpenBuyQuantity =  CP.DefaultUnit
                    NextBuyPrice -= CP.OnePip - CP.OnePip
                    if CP.LastCloseSellOrderId != OrderEvent.OrderId and CP.LastCloseSellOrderId != 0:
                        LastCloseSellOrder = self.GetOrderTicket(CP.LastCloseSellOrderId, OE+"SOF-CSO")
                        if LastCloseSellOrder is not None:
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextSellPrice
                            updateSettings.Quantity = CloseSellQuantity
                            response = LastCloseSellOrder.Update(updateSettings)
                            self.mylog( 5, OE+"SOF-update CSO:", updateSettings.LimitPrice, updateSettings.Quantity, response.ToString() )
                            if response.IsSuccess:
                                OT = LastCloseSellOrder
                                self.mylog( 5, OE+"SOF-CSO:" , OT.OrderId, OT.Symbol, OT.Quantity,
                                         updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                    else:
                        CP.LastCloseSellOrderId = 0
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "CSO:{0}:".format(self.FCC.inc("CSO")) + self.CloseTag + ":F"
                        self.mylog( 5, OE+"SOF-CSO price:" , NextSellPrice , Order.Symbol , CloseSellQuantity )
                        OT2 = self.LimitOrder(Order.Symbol, CloseSellQuantity, NextSellPrice, OrderTag)
                        self.mylog( 5, OE+"SOF-CSO-OT2: " , 
                                OT2.OrderId, OT2.Symbol, OT2.Quantity, NextSellPrice, OT2.Time, OT2.Status, OT2.Tag)
                        CP.LastCloseSellOrderId = OT2.OrderId

                    if CP.LastOpenBuyOrderId != 0:
                        LastOpenBuyOrder = self.GetOrderTicket(CP.LastOpenBuyOrderId, OE+"SOF-OBO")
                        if LastOpenBuyOrder is not None and LastOpenBuyOrder.Status == OrderStatus.Submitted :
                            updateSettings = UpdateOrderFields()
                            updateSettings.LimitPrice = NextBuyPrice
                            updateSettings.Quantity = OpenBuyQuantity
                            response = LastOpenBuyOrder.Update(updateSettings)
                            self.mylog( 5, OE+"SOF-OBO update:", updateSettings.LimitPrice, updateSettings.Quantity, response, response.ToString() )
                            if response.IsSuccess:
                                OT = LastOpenBuyOrder
                                self.mylog( 5, OE+"SOF-OBO updated:" , OT.OrderId, OT.Symbol, OT.Quantity, 
                                            updateSettings.LimitPrice, OT.Time, OT.Status, OT.Tag)
                        else:
                            OC = "OC:{0}:".format(self.FCC.inc("OC"))
                            OrderTag = OE + OC + "OBO:{0}:".format(self.FCC.inc("OBO")) + self.OpenTag + ":F"    
                            self.mylog( 5, OE+"SOF-OBO price:" , NextBuyPrice ,  Order.Symbol , OpenBuyQuantity )
                            OT1 = self.LimitOrder(Order.Symbol, OpenBuyQuantity, NextBuyPrice, OrderTag)
                            self.mylog( 5, OE+"SOF-OBO-OT1:" , 
                                    OT1.OrderId, OT1.Symbol, OT1.Quantity, NextBuyPrice, OT1.Time, OT1.Status, OT1.Tag)
                            CP.LastOpenBuyOrderId = OT1.OrderId
                    else:
                        OC = "OC:{0}:".format(self.FCC.inc("OC"))
                        OrderTag = OE + OC + "OBO:{0}:".format(self.FCC.inc("OBO")) + self.OpenTag + ":F"    
                        self.mylog( 5, OE+"SOF-OBO price:" , NextBuyPrice ,  Order.Symbol , OpenBuyQuantity )
                        OT1 = self.LimitOrder(Order.Symbol, OpenBuyQuantity, NextBuyPrice, OrderTag)
                        self.mylog( 5, OE+"SOF-OBO-OT1:" , 
                                OT1.OrderId, OT1.Symbol, OT1.Quantity, NextBuyPrice, OT1.Time, OT1.Status, OT1.Tag)
                        CP.LastOpenBuyOrderId = OT1.OrderId

            self.mylog( 5, OE+"END of onOrderEvent()--Filled")
        # end of Order.status == Filled
        self.mylog( 5, OE+CP.cpName, CP.cpName, self.Securities[OrderEvent.Symbol].Price, CP.PendingBuy, CP.PendingSell,  
                CP.LastTradeId, CP.LastTradePrice, CP.LastTradeUnit, 
                CP.LastBuyTradeId, CP.LastOpenBuyOrderId, CP.LastCloseBuyOrderId, CP.LastSellTradeId, 
                CP.LastOpenSellOrderId, CP.LastCloseSellOrderId,
                CP.AvgBuyCount, CP.AvgBuyDist, CP.MaxBuyCount, CP.MaxBuyDist, CP.BuyCount, 
                CP.AvgSellCount, CP.AvgSellDist, CP.MaxSellCount, CP.MaxSellDist, 
                CP.SellCount, CP.ChngCount, CP.AvgChngDist, CP.MaxChngDist, CP.PlusOverride, 
                CP.MinusOverride, CP.TakeProfitCount, CP.HoldingUnit )