Skip to content

Commit 36ee4a1

Browse files
committed
Add pnl
1 parent 1cb4def commit 36ee4a1

File tree

2 files changed

+47
-34
lines changed

2 files changed

+47
-34
lines changed

packages/client-coinbase/src/index.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export class CoinbaseClient implements Client {
9595
});
9696
}
9797

98-
private async generateTweetContent(event: WebhookEvent, amountInCurrency: number, formattedTimestamp: string, state: State): Promise<string> {
98+
private async generateTweetContent(event: WebhookEvent, amountInCurrency: number, pnlText: string, formattedTimestamp: string, state: State): Promise<string> {
9999
try {
100100
const tradeTweetTemplate = `
101101
# Task
@@ -105,6 +105,7 @@ Trade details:
105105
- ${event.event.toUpperCase()} order for ${event.ticker}
106106
- Trading amount: $${amountInCurrency.toFixed(2)}
107107
- Current price: $${Number(event.price).toFixed(2)}
108+
- Overall Unrealized PNL: $${pnlText}
108109
- Time: ${formattedTimestamp}
109110
110111
Requirements:
@@ -117,12 +118,12 @@ Requirements:
117118
7. Include the key information: action, amount, ticker, and price
118119
119120
Example variations for buys:
120-
"📈 Just added $1,000 of BTC to the portfolio at $50,000.00"
121-
"🎯 Strategic BTC purchase: $1,000 at $50,000.00"
121+
"📈 Just added $1,000 of BTC to the portfolio at $50,000.00. Overall Unrealized PNL: $${pnlText}"
122+
"🎯 Strategic BTC purchase: $1,000 at $50,000.00. Overall Unrealized PNL: $${pnlText}"
122123
123124
Example variations for sells:
124-
"💫 Executed BTC position: Sold $1,000 at $52,000.00"
125-
"📊 Strategic exit: Released $1,000 of BTC at $52,000.00"
125+
"💫 Executed BTC position: Sold $1,000 at $52,000.00. Overall Unrealized PNL: $${pnlText}"
126+
"📊 Strategic exit: Released $1,000 of BTC at $52,000.00. Overall Unrealized PNL: $${pnlText}"
126127
127128
Generate only the tweet text, no commentary or markdown.`;
128129
const context = composeContext({
@@ -133,7 +134,7 @@ Generate only the tweet text, no commentary or markdown.`;
133134
const tweetContent = await generateText({
134135
runtime: this.runtime,
135136
context,
136-
modelClass: ModelClass.SMALL,
137+
modelClass: ModelClass.LARGE,
137138
});
138139

139140
const trimmedContent = tweetContent.trim();
@@ -189,10 +190,10 @@ Generate only the tweet text, no commentary or markdown.`;
189190

190191
const pnl = await pnlProvider.get(this.runtime, memory);
191192

192-
const pnlText = pnl ? `Realized PNL: ${JSON.stringify(pnl.realizedPnl)}, Unrealized PNL: ${JSON.stringify(pnl.unrealizedPnl)}` : "";
193+
const pnlText = `Unrealized PNL: $${pnl.toFixed(2)}`;
193194

194195
try {
195-
const tweetContent = await this.generateTweetContent(event, amount, formattedTimestamp, state);
196+
const tweetContent = await this.generateTweetContent(event, amount, pnlText, formattedTimestamp, state);
196197
elizaLogger.info("Generated tweet content:", tweetContent);
197198
const response = await postTweet(tweetContent);
198199
elizaLogger.info("Tweet response:", response);

packages/plugin-coinbase/src/plugins/advancedTrade.ts

+38-26
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,40 @@ const tradeProvider: Provider = {
105105
},
106106
};
107107

108+
async function calculatePnl(client: RESTClient, amount: number): Promise<number> {
109+
const accounts = JSON.parse(await client.listAccounts({})).accounts;
110+
elizaLogger.info("Accounts:", accounts);
111+
112+
const btcAccount = accounts.find(account => account.currency === "BTC");
113+
elizaLogger.info("BTC Account:", btcAccount);
114+
const btcBalance = parseFloat(btcAccount?.available_balance?.value);
115+
elizaLogger.info("BTC Balance:", btcBalance);
116+
117+
const ethAccount = accounts.find(account => account.currency === "ETH");
118+
elizaLogger.info("ETH Account:", ethAccount);
119+
const ethBalance = parseFloat(ethAccount?.available_balance?.value);
120+
elizaLogger.info("ETH Balance:", ethBalance);
121+
122+
const usdAccount = accounts.find(account => account.currency === "USD");
123+
elizaLogger.info("USD Account:", usdAccount);
124+
const usdBalance = parseFloat(usdAccount?.available_balance?.value);
125+
elizaLogger.info("USD Balance:", usdBalance);
126+
127+
const btcPrice = await getPrice(client, "BTC-USD");
128+
elizaLogger.info("BTC Price:", btcPrice);
129+
const ethPrice = await getPrice(client, "ETH-USD");
130+
elizaLogger.info("ETH Price:", ethPrice);
131+
132+
const btcUSD = btcBalance * btcPrice;
133+
elizaLogger.info("BTC USD:", btcUSD);
134+
const ethUSD = ethBalance * ethPrice;
135+
const totalValueUSD = btcUSD + ethUSD + usdBalance;
136+
elizaLogger.info("Total Value USD:", totalValueUSD);
137+
138+
const pnl = totalValueUSD - amount;
139+
return pnl;
140+
}
141+
108142
export const pnlProvider: Provider = {
109143
get: async (runtime: IAgentRuntime, _message: Memory) => {
110144
const client = new RESTClient(
@@ -115,36 +149,14 @@ export const pnlProvider: Provider = {
115149
elizaLogger.info("Portfolios:", portfolios);
116150
const portfolioId = portfolios.portfolios[0].uuid;
117151
elizaLogger.info("Portfolio ID:", portfolioId);
118-
return { realizedPnl: 0, unrealizedPnl: 0 };
119152
if (!portfolioId) {
120153
elizaLogger.error("Portfolio ID is not set");
121154
return { realizedPnl: 0, unrealizedPnl: 0 };
122155
}
123-
124-
let btcPosition: Position, ethPosition: Position;
125-
try {
126-
btcPosition = JSON.parse(await client.getPortfolioBalances({portfolioUuid: portfolioId, symbol: "BTC-USD"})).position;
127-
ethPosition = JSON.parse(await client.getPortfolioBalances({portfolioUuid: portfolioId, symbol: "ETH-USD"})).position;
128-
elizaLogger.info("BTC Position:", btcPosition);
129-
elizaLogger.info("ETH Position:", ethPosition);
130-
} catch (error) {
131-
elizaLogger.error("Error fetching portfolio balances:", error.message);
132-
return { realizedPnl: 0, unrealizedPnl: 0 };
133-
}
134-
135-
const btcUnrealizedPnl = btcPosition?.unrealized_pnl || 0;
136-
const ethUnrealizedPnl = ethPosition?.unrealized_pnl || 0;
137-
const ethAggregatedPnl = ethPosition?.aggregated_pnl || 0;
138-
const btcAggregatedPnl = btcPosition?.aggregated_pnl || 0;
139-
elizaLogger.info("BTC Unrealized PNL:", JSON.stringify(btcUnrealizedPnl));
140-
elizaLogger.info("ETH Unrealized PNL:", JSON.stringify(ethUnrealizedPnl));
141-
elizaLogger.info("ETH Aggregated PNL:", JSON.stringify(ethAggregatedPnl));
142-
return {
143-
btcUnrealizedPnl: JSON.stringify(btcUnrealizedPnl),
144-
ethUnrealizedPnl: JSON.stringify(ethUnrealizedPnl),
145-
ethAggregatedPnl: JSON.stringify(ethAggregatedPnl),
146-
btcAggregatedPnl: JSON.stringify(btcAggregatedPnl)
147-
}
156+
// Need to manually set the amount and calculate as endpoints not accessible for portfolios
157+
const pnl = await calculatePnl(client, 1000);
158+
elizaLogger.info("Pnl:", pnl);
159+
return pnl
148160
}
149161
}
150162

0 commit comments

Comments
 (0)