Python Forum
While Loop Variable Freezing?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
While Loop Variable Freezing?
#1
Hey guys, I'm a newb. I'm trying to get this software to run on my computer but I seem to keep getting stuck in my while loop.

This is for trading, I am returning a set of information (variable?) to unrealizedPnL in my function pnl.

It updates every second.

def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
        print("UnrealizedPnL:", round(unrealizedPnL))
        if unrealizedPnL < -100:
            print("Step 1", unrealizedPnL)
            while unrealizedPnL < -50:
                time.sleep(1)
                print("Step 1.5", unrealizedPnL)
            else:
                print("Step 2, Worked", unrealizedPnL)
The numbers in step 1 (line 3), -100 and the -50 in step 2 (line 5) are just because its almost impossible to make a profit for the test every time. So I just open a trading position, let it lose money then adjust the numbers to run the test. I'm just trying to get the steps to work.

Once my account goes past -100, we goto step 1.5, the while loop. And it just loops infinitly (I know it does that) BUT.. if I close out my positions and my unrealizedPnL goes back to 0, or even moves around to any number, the while loop stays LOCKED on what ever number initiated it. It doesnt keep updating.

I've got time.sleep(1) in (line 6) while I try and figure this out and I'm not 100000x spammed by the while loop. Atleast I'm 5000x spammed hahah Big Grin

The end goal logically is, if I make over $100, we trigger a new set of conditions, if we stay above $50, all good. If we drop under $50, execute a command.

Let me know what you guys think!! Where am I messing up with this logical flow?

BTW Everything is working as intended.

There is a call
app.reqPnL(1000, "account", "")
that pulls the pnl into the pnl function so that I can manipulate it. It works as intended. But once the while loop triggers, thats when it freezes.

Heart
Reply
#2
Nothing in the function appears to modify unrealizedPnL. So to start the loop it must already be < -100 and will remain so. The loop cannot exit since the value it is checking is static.
Reply
#3
I thought the function itself is modfying unrealizedpnlfrom the call? Because if I delete everything and just have this

    def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
        print("UnrealizedPnL:", round(unrealizedPnL))
I get an endless stream of pnl updates
Reply
#4
Let me just get this out of the way

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.order import *

import threading
import time

class Program (EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self,self)

    def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
        print("UnrealizedPnL:", round(unrealizedPnL))

def run_program():
    app.run()

app = Program()
app.connect("127.0.0.1", 7497, 0)

time.sleep(1)

api_thread = threading.Thread(target=run_program, daemon=True)
api_thread.start()

app.reqPnL(1000, "account", "")
Thats the entire program, it gives me an endless stream of of pnl updates being printed.

So what do I need to change to get the logic explained above to work? Big Grin Heart
Reply
#5
(Feb-20-2021, 12:04 AM)stylingpat Wrote: I thought the function itself is modfying unrealizedpnlfrom the call? Because if I delete everything and just have this

    def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
        print("UnrealizedPnL:", round(unrealizedPnL))
I get an endless stream of pnl updates

That means the function is being called multiple times. Each time it is called, unrealizedPnL might be given a new value. It changes between calls, not within a single run of the function.
Reply
#6
Ok, so what do you think I need to do? I'm still kinda new to hooking this all together. I kinda understand what you mean, but dont know how to implement it off the top of my head. I still cant write Python off the top of my head, I'm copying and pasting all of this from the API source book.

I was just experimenting and trying all sorts of random stuff and I thought I tried putting the app.reqPnL inside the while function, but I remember it not working. I prob didnt put it in correctly tho.
Reply
#7
It looks like you're using the Interactive Brokers' api. I happen to know, from previously working with it, that the IB client pushes constant streams of data to you. So try to think of what you want to do at that specific point in time.

def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
        print("UnrealizedPnL:", round(unrealizedPnL))
        if unrealizedPnL < -100:
            print("Step 1", unrealizedPnL)
            if unrealizedPnL < -50:
                print("Step 1.5", unrealizedPnL)
            else:
                print("Step 2, Worked", unrealizedPnL)
Looks like you're trying to do something as the p&l increases over time. In that case, maybe you should keep track of the values as you see them, and compare them with new values as you see them.

Maybe like this?
def __init__(self):
    self.unrealized_pnl = []

def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
    if not self.unrealized_pnl:
        # this is the first time we've received data
        pass
    else:
        min_value = min(self.unrealized_pnl)
        if min_value < -100:
            print("Step 1", unrealizedPnL)
            if unrealizedPnL < -50:
                print("Step 1.5", unrealizedPnL)
    self.unrealized_pnl.append(unrealizedPnL)
Reply
#8
Hey Nilamo! Could I ask you a few questions since you've worked with the API? Maybe email would be better then here?

I ran the above code:

def __init__(self):
    self.unrealized_pnl = []
 
def pnl(self, reqId, dailyPnL, unrealizedPnL, realizedPnL):
    if not self.unrealized_pnl:
        # this is the first time we've received data
        pass
    else:
        min_value = min(self.unrealized_pnl)
        if min_value > 100:
            print("Step 1", unrealizedPnL)
            if unrealizedPnL < 50:
                print("Step 1.5", unrealizedPnL)
    self.unrealized_pnl.append(unrealizedPnL)
And I didnt get a Step 1.5 back after my PL went above 100+ and then under 50.. does image posting here not work? So I can show you my terminal?

[Image: JPL23kb.png]

Imagine above is showing me its broken in preview? Whatever. Thats a photo of it not working hehe LOL

I keep running into this "coding" scenario with TWS API.. like its not taking normal python code.. maybe I'm such an idiot at python that I am not seeing it.. but the above code doesnt work and it looks fine to me..

And stuff like this, does not work. Everything works fine coming up to this.

def __init__(self):
        EClient.__init__(self,self)
        self.pnl_summary = {}   
        self.profit_target = False
        self.trigger = False
        self.once = True


def main(app):
    app.reqPnL(1000, "DU3420572", "")
    time.sleep(0.25)
    if app.pnl_summary["UnrealizedPnL"] < 0 and app.once:
        app.trigger = True
        app.once = False
    elif app.pnl_summary["UnrealizedPnL"] > 100:
        app.profit_target = True
    if app.pnl_summary["UnrealizedPnL"] < 50 and app.profit_target and app.once:
        app.trigger = True
        app.once = False
        print("Step 2 Achieved")
    if app.trigger:
        print("Stopping Out")
Even with the "once" lock outs, I stil get an endless stream of "stopping out prints". Is that right? Or am I just being a newb thinking its right and going crazy. Wall

Its been such a headache to try and code the easiest thing, a global stop out / profit take based on my unrealized pnl. I can get the system to each section.. but the function just loops endlessly for each successive tick of the unrealized pnl sending out endless orders
Reply
#9
Can it have intermediate values between 100 and 50?

If so, imagine the function is called 3 times with these values: 110, 75, 40

First time no data present so doesn't run the else and 110 is appended.

Second time through min_value = 110. Line 10 is true and "Step 1" should print. 75 is appended.

Third time min_value will be 75. Line 10 is false and line 12 is never reached. You're checking if the current value is under 50, but only if the previous minimum was over 100. If the previous minimum was less than 100, nothing is checked.
Reply
#10
"Not working" is different from not doing what you expected. What is it you're trying to do? What is an app, what's calling main(), etc? The code we're giving might not be helpful, since we're mostly guessing what's going on lol.

Based on the last code you shared, here's what I think you're trying to do:
1) if the UnrealizedPnL is ever negative, close the position.
2) if the UnrealizedPnL is less than 50, but was over 100 at any point today, close the position.

If you only want "Stopping out" to be printed once, then turn off the toggle there:
    if app.trigger:
        print("Stopping Out")
        app.trigger = False
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Variable definitions inside loop / could be better? gugarciap 2 435 Jan-09-2024, 11:11 PM
Last Post: deanhystad
  How to create a variable only for use inside the scope of a while loop? Radical 10 1,690 Nov-07-2023, 09:49 AM
Last Post: buran
  Nested for loops - help with iterating a variable outside of the main loop dm222 4 1,579 Aug-17-2022, 10:17 PM
Last Post: deanhystad
  loop (create variable where name is dependent on another variable) brianhclo 1 1,137 Aug-05-2022, 07:46 AM
Last Post: bowlofred
  Multiple Loop Statements in a Variable Dexty 1 1,203 May-23-2022, 08:53 AM
Last Post: bowlofred
Big Grin Variable flag vs code outside of for loop?(Disregard) cubangt 2 1,169 Mar-16-2022, 08:54 PM
Last Post: cubangt
  How to save specific variable in for loop in to the database? ilknurg 1 1,145 Mar-09-2022, 10:32 PM
Last Post: cubangt
  How to add for loop values in variable paulo79 1 1,442 Mar-09-2022, 07:20 PM
Last Post: deanhystad
  Using Excel Cell As A Variable In A Loop knight2000 7 4,108 Aug-25-2021, 12:43 PM
Last Post: snippsat
  Using Excel Cell As A Variable In A Loop knight2000 7 5,003 Jul-18-2021, 10:52 AM
Last Post: knight2000

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020