TradeStation: PositionProvider – Tracking Position in Studies using OOEL

A lot of time when we use OOEL to do automatic trading we will be using indicators or studies instead of Strategy. Problem with Indicators File is you cant track your position using MarketPosition. So here is the sample working code to track your position and know how many times you have traded and know whether you last trade is a loss trade or a profit trade.

// OOEL Position Tracker using PositionsProvider
// This indicator tracks positions using PositionsProvider object

using elsystem;
using elsystem.collections;
using tsdata.trading;
using tsdata.common;

inputs:
    string iAccount("");  // Leave empty to use default account

variables:
    PositionsProvider oPositionsProvider(null),
    Position oPosition(null),
    
    // Trade tracking variables
    intrabarpersist double LastPositionSize(0.0),
    intrabarpersist double CurrentPositionSize(0.0),
    intrabarpersist double LastEntryPrice(0.0),
    intrabarpersist double LastExitPrice(0.0),
    intrabarpersist double LastTradeProfit(0.0),
    intrabarpersist bool TradeJustClosed(false),
    
    // Statistics
    intrabarpersist int TotalTradeCount(0),
    intrabarpersist int WinningTradeCount(0),
    intrabarpersist int LosingTradeCount(0),
    intrabarpersist double WinRatePercent(0.0),
    
    // Helpers
    intrabarpersist double TempPrice(0.0),
    intrabarpersist double TempSize(0.0),
    intrabarpersist string CurrentSymbol(""),
    intrabarpersist string AccountToUse("");

// Initialize PositionsProvider once
once begin
    CurrentSymbol = GetSymbolName;
    
    // Use provided account or default
    if iAccount <> "" then
        AccountToUse = iAccount
    else
        AccountToUse = GetAccountID;  // Get current account
    
    oPositionsProvider = PositionsProvider.Create();
    
    if oPositionsProvider <> null then begin
        oPositionsProvider.Realtime = true;
        oPositionsProvider.TimeZone = TimeZone.local;
        oPositionsProvider.Name = "PositionTracker";
        oPositionsProvider.Load = true;
        
        // Force loading of provider
        Value99 = oPositionsProvider.Count;
        
        Print("PositionsProvider initialized successfully");
        Print("Tracking Symbol: ", CurrentSymbol);
        Print("Account: ", AccountToUse);
    end
    else begin
        Print("ERROR: Failed to initialize PositionsProvider");
    end;
end;

// Main position tracking logic
if oPositionsProvider <> null then begin
  
    // Check if we have a position for this symbol and account
    if oPositionsProvider.Contains(CurrentSymbol, AccountToUse) then begin
        oPosition = oPositionsProvider.Position[CurrentSymbol, AccountToUse];
        
        if oPosition <> null then begin
            CurrentPositionSize = oPosition.Quantity;
            
            // Display position details when position changes
            if CurrentPositionSize <> LastPositionSize then begin
                if CurrentPositionSize <> 0 then begin
                    Print("=== POSITION UPDATE ===");
                    Print("Symbol: ", oPosition.Symbol);
                    //Print("Account: ", oPosition.Account);
                    Print("Position Type: ", oPosition.Type.ToString());
                    Print("Quantity: ", oPosition.Quantity:0:0);
                    Print("Avg Entry Price: ", oPosition.AveragePrice:4:2);
                    Print("Current Price: ", Close:4:2);
                    //Print("Open P/L: ", oPosition.OpenPL:4:2);
                    Print("Market Value: ", oPosition.MarketValue:4:2);
                    Print("=====================");
                    
                    // Store entry price for new positions
                    if LastPositionSize = 0 then
                        LastEntryPrice = oPosition.AveragePrice;
                end;
            end;
            
            // Check for position closure
            TradeJustClosed = (LastPositionSize <> 0 and CurrentPositionSize = 0);
            
            if TradeJustClosed then begin
                // Calculate trade profit/loss
                LastExitPrice = Close;
                
                if LastPositionSize > 0 then begin
                    // Long position closed
                    LastTradeProfit = (LastExitPrice - LastEntryPrice) * LastPositionSize;
                    Print("");
                    Print(">>> LONG POSITION CLOSED <<<");
                end
                else begin
                    // Short position closed
                    LastTradeProfit = (LastEntryPrice - LastExitPrice) * AbsValue(LastPositionSize);
                    Print("");
                    Print(">>> SHORT POSITION CLOSED <<<");
                end;
                
                Print("Entry Price: ", LastEntryPrice:4:2);
                Print("Exit Price: ", LastExitPrice:4:2);
                Print("Position Size: ", LastPositionSize:0:0);
                Print("Trade P&L: $", LastTradeProfit:4:2);
                
                // Update statistics
                TotalTradeCount = TotalTradeCount + 1;
                
                if LastTradeProfit > 0 then begin
                    WinningTradeCount = WinningTradeCount + 1;
                    Print("Result: WINNER! ✓");
                end
                else if LastTradeProfit < 0 then begin
                    LosingTradeCount = LosingTradeCount + 1;
                    Print("Result: LOSER! ✗");
                end
                else begin
                    Print("Result: BREAKEVEN");
                end;
                
                // Calculate win rate
                if TotalTradeCount > 0 then
                    WinRatePercent = (WinningTradeCount / TotalTradeCount) * 100;
                
                Print("");
                Print("=== TRADE SUMMARY ===");
                Print("Total Trades: ", TotalTradeCount);
                Print("Winners: ", WinningTradeCount);
                Print("Losers: ", LosingTradeCount);
                Print("Win Rate: ", WinRatePercent:4:1, "%");
                Print("====================");
                Print("");
            end;
            
            // Track new position entries
            if LastPositionSize = 0 and CurrentPositionSize <> 0 then begin
                if CurrentPositionSize > 0 then
                    Print(">>> NEW LONG POSITION: Size=", CurrentPositionSize:0:0, " Entry=", LastEntryPrice:4:2)
                else
                    Print(">>> NEW SHORT POSITION: Size=", CurrentPositionSize:0:0, " Entry=", LastEntryPrice:4:2);
            end;
            
            // Update for next bar
            LastPositionSize = CurrentPositionSize;
            
            // Display current status in commentary
            if CurrentPositionSize > 0 then begin
                TempPrice = oPosition.OpenPL;
                Commentary("LONG: Size=" + NumToStr(CurrentPositionSize,0) + 
                          " | Entry=" + NumToStr(oPosition.AveragePrice,2) +
                          " | Open P&L: $" + NumToStr(TempPrice,2));
            end
            else if CurrentPositionSize < 0 then begin
                TempPrice = oPosition.OpenPL;
                Commentary("SHORT: Size=" + NumToStr(AbsValue(CurrentPositionSize),0) + 
                          " | Entry=" + NumToStr(oPosition.AveragePrice,2) +
                          " | Open P&L: $" + NumToStr(TempPrice,2));
            end;
        end;
    end
    else begin
        // No position for this symbol/account
        if LastPositionSize <> 0 then begin
            // Position was just closed
            CurrentPositionSize = 0;
            TradeJustClosed = true;
            
            // Handle the closure logic (same as above)
            LastExitPrice = Close;
            
            if LastPositionSize > 0 then begin
                LastTradeProfit = (LastExitPrice - LastEntryPrice) * LastPositionSize;
                Print("");
                Print(">>> LONG POSITION CLOSED <<<");
            end
            else begin
                LastTradeProfit = (LastEntryPrice - LastExitPrice) * AbsValue(LastPositionSize);
                Print("");
                Print(">>> SHORT POSITION CLOSED <<<");
            end;
            
            Print("Entry Price: ", LastEntryPrice:4:2);
            Print("Exit Price: ", LastExitPrice:4:2);
            Print("Position Size: ", LastPositionSize:0:0);
            Print("Trade P&L: $", LastTradeProfit:4:2);
            
            TotalTradeCount = TotalTradeCount + 1;
            
            if LastTradeProfit > 0 then begin
                WinningTradeCount = WinningTradeCount + 1;
                Print("Result: WINNER! ✓");
            end
            else if LastTradeProfit < 0 then begin
                LosingTradeCount = LosingTradeCount + 1;
                Print("Result: LOSER! ✗");
            end
            else begin
                Print("Result: BREAKEVEN");
            end;
            
            if TotalTradeCount > 0 then
                WinRatePercent = (WinningTradeCount / TotalTradeCount) * 100;
            
            Print("");
            Print("=== TRADE SUMMARY ===");
            Print("Total Trades: ", TotalTradeCount);
            Print("Winners: ", WinningTradeCount);
            Print("Losers: ", LosingTradeCount);
            Print("Win Rate: ", WinRatePercent:4:1, "%");
            Print("====================");
            Print("");
        end;
        
        CurrentPositionSize = 0;
        LastPositionSize = 0;
        
        Commentary("FLAT | Trades: " + NumToStr(TotalTradeCount,0) + 
                  " | Win Rate: " + NumToStr(WinRatePercent,1) + "%");
    end;
end;

If you think this code is useful for your algorithmic trading. You should buy me a coffee.

Nik Izwan Kamel is an Entrepreneur who venture in multiple businesses in different industries including IT, Blockchain, E-Commerce, Security, Retail and F&B. A cryptocurrency enthusiast and cooking computer codes at night.

Leave a reply:

Your email address will not be published.

Site Footer

css.php