0% found this document useful (0 votes)
53 views9 pages

Agent Reflection Code Execution LangChain

The document discusses a Python code generator for algorithmic trading strategies. It includes sample Python code to calculate the relative strength index (RSI) technical indicator and tests the code for valid imports and execution. When the initial code fails due to import errors, a reflection agent is called to propose new Python code to calculate RSI using different import libraries.

Uploaded by

titoahadopus2022
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
53 views9 pages

Agent Reflection Code Execution LangChain

The document discusses a Python code generator for algorithmic trading strategies. It includes sample Python code to calculate the relative strength index (RSI) technical indicator and tests the code for valid imports and execution. When the initial code fails due to import errors, a reflection agent is called to propose new Python code to calculate RSI using different import libraries.

Uploaded by

titoahadopus2022
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Agent_Reflection_code_execution

April 25, 2024

[1]: !pip install -U --quiet langchain


!pip install --quiet langchain_openai

���������������������������������������� 817.7/817.7
kB 11.8 MB/s eta 0:00:00
���������������������������������������� 1.9/1.9 MB
25.3 MB/s eta 0:00:00
���������������������������������������� 291.3/291.3
kB 23.3 MB/s eta 0:00:00
���������������������������������������� 115.5/115.5
kB 12.1 MB/s eta 0:00:00
���������������������������������������� 49.4/49.4 kB
5.6 MB/s eta 0:00:00
���������������������������������������� 53.0/53.0 kB
5.6 MB/s eta 0:00:00
���������������������������������������� 141.1/141.1
kB 14.5 MB/s eta 0:00:00
���������������������������������������� 311.6/311.6
kB 9.1 MB/s eta 0:00:00
���������������������������������������� 1.8/1.8 MB
16.5 MB/s eta 0:00:00
���������������������������������������� 75.6/75.6 kB
6.9 MB/s eta 0:00:00
���������������������������������������� 77.9/77.9 kB
7.3 MB/s eta 0:00:00
���������������������������������������� 58.3/58.3 kB
5.5 MB/s eta 0:00:00

[2]: from langchain_core.messages import AIMessage, BaseMessage, HumanMessage


from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.pydantic_v1 import BaseModel, Field

1
[3]: from langchain_openai import ChatOpenAI

from google.colab import userdata


OPENAI_API_KEY = userdata.get('OPENAI_API_KEY')

llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0,␣


↪api_key=OPENAI_API_KEY)

1 Data model of the outputed Python implemention code


[4]: # Data model
class code(BaseModel):
"""Code output"""
prefix: str = Field(description="Description of the trading strategy")
imports: str = Field(description="Code block import statements")
code: str = Field(description="Code block not including import statements")
name: str = Field(description="Name of the method")
parameters: str = Field(description="list of the parameters")
description = "Schema for code solutions to questions about algorithmic␣
↪trading strategies Python implementation."

2 Call the Generator Agent


[5]: prompt_generate = """You are a Python code generator specializing in␣
↪algorithmic trading. Your main role is to provide Python code solutions that␣

↪are straightforward, efficient, and strictly follow Pythonic principles.␣

↪Your responses should strictly consist of executable Python code tailored to␣

↪algorithmic trading strategies.

Please adhere to these protocols:


- Generate a code that is simple, efficient, optimized and the most␣
↪understandable possible.

- Augment your code by inline comments and docstrings, when it's necessary, to␣
↪clarify the functionality and the structure of the code.

- Make sure all code conforms to Python best practices and conventions.
- This code will be used as it is by the user, so make sure to generate an␣
↪executable code in prodution environment.

- Only produce executable Python code. Omit any explanatory text, descriptions,␣
↪or elements that are not code from your responses.

- Avoid using non-existent built-in methods, such as np.rolling or pd.rolling,␣


↪in well-known libraries.

- Be specific on the type of the prices you are implementing in the code.␣
↪Specify if it's a close, open, low, or high prices in each of your␣

↪implementation.

2
Answer only with Pyton code without any explanatory text, descriptions, or␣
↪elements that are not code from your responses.

"""

[ ]: prompt = ChatPromptTemplate.from_messages(
[
(
"system",
prompt_generate,
),
MessagesPlaceholder(variable_name="messages"),
]
)

generator = prompt | llm.with_structured_output(code)

#In this query I put "talib" library in purpose because it's not built-in␣
↪method which will generate an exec code error. It's an example to go␣

↪throught the whole process of reflection

query = "Propose a Python code for RSI, and be specific on the type of the␣
↪prices you are implementing in the code: close, open, high or low. Use talib␣

↪library"

request = HumanMessage(
content = query
)
resp = generator.invoke({"messages": [request]})

[100]: print(resp.code)

def calculate_rsi(close_prices, period=14):


rsi = talib.RSI(close_prices, timeperiod=period)
return rsi

3 Check if the code is executable


[65]: def exec_import(resp):
error_message=""
print("IMPORTS FOR THE STRATEGY\n")
print(resp.imports)
try:
exec(resp.imports)
print("---CODE IMPORT EXEC: SUCCEDDED---")
return None
except Exception as e:
print("---CODE IMPORT EXEC: FAILED---")

3
print(e)
message_e = f"The proposed code failed the import test: `{e}`"
error_message = HumanMessage(content= f"The import code is: '{resp.
↪imports}'. Message error: {message_e}")

return error_message

def exec_code(resp):
error_message=""
print("\nCODE STRATEGY\n")
print(resp.code)
try:
exec(resp.code)
print("---CODE IMPLEMNTATION EXEC: SUCCEDDED---")
return None
except Exception as e:
print("---CODE IMPLEMNTATION EXEC: FAILED---")
print(e)
message_e = f"The proposed code failed : `{e}`"
# error_message = HumanMessage(content=resp.code+ ". Message error:" +␣
↪message_e)

error_message = HumanMessage(content= f"The main code of the strategy is:


↪'{resp.code}'. Message error: {message_e}")

return error_message

[93]: messages = []
if exec_import(resp) !=None:
messages.append(exec_import(resp))

if exec_code(resp) !=None:
messages.append(exec_code(resp))

IMPORTS FOR THE STRATEGY

import talib
---CODE IMPORT EXEC: FAILED---
No module named 'talib'
IMPORTS FOR THE STRATEGY

import talib
---CODE IMPORT EXEC: FAILED---
No module named 'talib'

CODE STRATEGY

def calculate_rsi(close_prices, period=14):


rsi = talib.RSI(close_prices, timeperiod=period)
return rsi

4
---CODE IMPLEMNTATION EXEC: SUCCEDDED---

[68]: messages

[68]: [HumanMessage(content="The import code is: 'import talib'. Message error: The
proposed code failed the import test: `No module named 'talib'`")]

[59]: print(resp.prefix)
print(resp.imports)
print(resp.code)
print(resp.name)
print(resp.parameters)

Calculate Relative Strength Index (RSI) using close prices with talib library
import talib
def calculate_rsi(close_prices, period=14):
rsi = talib.RSI(close_prices, timeperiod=period)
return rsi
calculate_rsi
close_prices: List[float], period: int = 14

4 Reflection Agent
[94]: prompt_reflection = """
- The code execution has failed. It could be at the import libraries level or␣
↪at the code level.

- Reflect on this failure given the message error and propose a new Python code␣
↪implementation of the strategy requested by the user, for both the import␣

↪level and the code level.

- Avoid using the same code than the one failed. Propose another one.
- Generate a code that is simple, efficient, optimized and the most␣
↪understandable possible.

- Augment your code by inline comments and docstrings, when it's necessary, to␣
↪clarify the functionality and the structure of the code.

- Make sure all code conforms to Python best practices and conventions.
- Refrain from using non-existent built-in methods in well-known libraries.
"""

reflection_prompt = ChatPromptTemplate.from_messages(
[
(
"system",
prompt_reflection,
),
MessagesPlaceholder(variable_name="messages"),
]
)

5
reflect = reflection_prompt | llm.with_structured_output(code)

query = "Propose a Python code for RSI, and be specific on the type of the␣
↪prices you are implementing in the code: close, open, high or low"

request = HumanMessage(
content = query
)

#If there is any error in the exec code: call the reflection agent
if messages != []:
print("MESSAGE TO ADD TO REFLECTION\n")
print(messages)
print("REFLECTION\n")
reflection = reflect.invoke({"messages": [request, messages[0]]})
print(reflection)

MESSAGE TO ADD TO REFLECTION

[HumanMessage(content="The import code is: 'import talib'. Message error: The


proposed code failed the import test: `No module named 'talib'`")]
REFLECTION

prefix='Calculating Relative Strength Index (RSI) using close prices'


imports='import numpy as np\nimport pandas as pd' code='def
calculate_rsi(close_prices, period=14):\n delta = close_prices.diff()\n
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()\n loss =
(-delta.where(delta < 0, 0)).rolling(window=period).mean()\n rs = gain /
loss\n rsi = 100 - (100 / (1 + rs))\n return rsi' name='calculate_rsi'
parameters='close_prices: pd.Series, period: int = 14' description='Function to
calculate the Relative Strength Index (RSI) using close prices'

4.0.1 The reflection agent replaces talib with buyilt-in methods and the test checking
if the code is executable is OK.
[95]: # messages = []
if exec_import(reflection) !=None:
messages.append(exec_import(reflection))

if exec_code(reflection) !=None:
messages.append(exec_code(reflection))

IMPORTS FOR THE STRATEGY

import numpy as np
import pandas as pd
---CODE IMPORT EXEC: SUCCEDDED---

6
CODE STRATEGY

def calculate_rsi(close_prices, period=14):


delta = close_prices.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
---CODE IMPLEMNTATION EXEC: SUCCEDDED---

5 If still a FAILED EXEC ==> add to the content “messages”


list the new erros and send it back to the reflection agent:
[85]: message_content =""
for mess in messages:
message_content += mess.content+"\n"

[96]: messages

[96]: [HumanMessage(content="The import code is: 'import talib'. Message error: The
proposed code failed the import test: `No module named 'talib'`")]

[ ]: mess_hum = HumanMessage(content=message_content)

5.1 Call the reflection agent with the new error messages
[88]: if messages != []:
print("MESSAGE TO ADD TO REFLECTION\n")
print(messages)
print("REFLECTION\n")
reflection = reflect.invoke({"messages": [request, mess_hum]})
print(reflection)

MESSAGE TO ADD TO REFLECTION

[HumanMessage(content="The import code is: 'import talib'. Message error: The


proposed code failed the import test: `No module named 'talib'`"),
HumanMessage(content="The import code is: 'import numpy as np\nimport pandas as
pd\nfrom talib.abstract import *'. Message error: The proposed code failed the
import test: `No module named 'talib'`"), HumanMessage(content="The import code
is: 'import numpy as np\nimport pandas as pd\nimport talib'. Message error: The
proposed code failed the import test: `No module named 'talib'`")]
REFLECTION

prefix='Calculate the Relative Strength Index (RSI) using closing prices'

7
imports='import numpy as np\nimport pandas as pd\nimport talib' code="# Define a
function to calculate RSI\n\ndef calculate_rsi(data, period=14):\n rsi =
talib.RSI(data['close'], timeperiod=period)\n return rsi"
name='calculate_rsi' parameters='data: pandas DataFrame, period: int = 14'
description='Function to calculate the Relative Strength Index (RSI) using
closing prices'

5.2 Then Check if any FAILED EXEC


[84]: # messages = []
if exec_import(reflection) !=None:
messages.append(exec_import(reflection))

if exec_code(reflection) !=None:
messages.append(exec_code(reflection))

IMPORTS FOR THE STRATEGY

import numpy as np
import pandas as pd
import talib
---CODE IMPORT EXEC: FAILED---
No module named 'talib'
IMPORTS FOR THE STRATEGY

import numpy as np
import pandas as pd
import talib
---CODE IMPORT EXEC: FAILED---
No module named 'talib'

CODE STRATEGY

def calculate_rsi(data, period=14):


data['RSI'] = talib.RSI(data['Close'], timeperiod=period)
return data
---CODE IMPLEMNTATION EXEC: SUCCEDDED---

[99]: # If both == None ==> no error from the execution of the proposed code ==>␣
↪messages = []

if exec_import(reflection) ==None and exec_code(reflection) ==None:


messages = []

IMPORTS FOR THE STRATEGY

import numpy as np
import pandas as pd
---CODE IMPORT EXEC: SUCCEDDED---

8
CODE STRATEGY

def calculate_rsi(close_prices, period=14):


delta = close_prices.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
---CODE IMPLEMNTATION EXEC: SUCCEDDED---

[98]: messages

[98]: []

And start again, adding it to the list of the messages and sending it back to the reflection agent.

You might also like