MCP and AI tooling
Integrate your trading data with AI assistants like Claude Desktop or Cursor IDE using Model Context Protocol (MCP) servers.
MCP server example
Create a custom MCP server that exposes your trading data to AI tools:
import { McpServer } from '@modelcontextprotocol/sdk';
const API_KEY = process.env.MPJ_API_KEY;
const BASE_URL = 'https://app.mypropjournal.com/api/v1';
const server = new McpServer({
name: 'my-prop-journal',
version: '1.0.0'
});
// Tool: Get recent trades
server.tool('get-recent-trades', {
description: 'Fetch the most recent trades',
parameters: {
limit: {
type: 'number',
description: 'Number of trades to fetch (default 10)',
default: 10
}
},
async handler({ limit = 10 }) {
const response = await fetch(
`${BASE_URL}/trades?limit=${limit}&page=1`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
return {
content: [{
type: 'text',
text: JSON.stringify(data.data, null, 2)
}]
};
}
});
// Tool: Get performance stats
server.tool('get-performance', {
description: 'Get trading performance statistics',
parameters: {
start_date: {
type: 'string',
description: 'Start date (YYYY-MM-DD)',
optional: true
},
end_date: {
type: 'string',
description: 'End date (YYYY-MM-DD)',
optional: true
}
},
async handler({ start_date, end_date }) {
const params = new URLSearchParams();
if (start_date) params.append('start_date', start_date);
if (end_date) params.append('end_date', end_date);
const response = await fetch(
`${BASE_URL}/performance/overview?${params}`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
// Format performance data for AI consumption
const summary = `
Performance Summary:
- Total Trades: ${data.data.total_trades}
- Win Rate: ${data.data.win_rate.toFixed(2)}%
- Total P&L: $${data.data.total_pnl.toFixed(2)}
- Profit Factor: ${data.data.profit_factor.toFixed(2)}
- Average Win: $${data.data.average_win.toFixed(2)}
- Average Loss: $${data.data.average_loss.toFixed(2)}
`;
return {
content: [{
type: 'text',
text: summary
}]
};
}
});
server.start();
Using the MCP server
Once configured, you can interact with your trading data in Claude Desktop:
User: Show me my last 5 trades
Claude: [Calls get-recent-trades tool with limit=5]
Here are your last 5 trades:
1. NQ Short - Entry: 29298, Exit: 29290, P&L: $158
2. TSLA Long - Entry: 245.00, Exit: 250.00, P&L: $250
...
User: What's my win rate this month?
Claude: [Calls get-performance tool with current month dates]
Your win rate for this month is 62.5% across 24 trades...
Analytics and export
Build custom analytics dashboards or export data to external tools.
Python analytics script
import requests
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
API_KEY = 'mpj_your_api_key_here'
BASE_URL = 'https://app.mypropjournal.com/api/v1'
def get_all_trades():
"""Fetch all trades using pagination"""
all_trades = []
page = 1
has_more = True
while has_more:
response = requests.get(
f'{BASE_URL}/trades',
headers={'Authorization': f'Bearer {API_KEY}'},
params={'page': page, 'limit': 100}
)
data = response.json()
all_trades.extend(data['data'])
has_more = data['pagination']['has_more']
page += 1
return all_trades
def analyze_trades(trades):
"""Convert trades to DataFrame and analyze"""
df = pd.DataFrame(trades)
# Convert dates
df['entry_date'] = pd.to_datetime(df['entry_date'])
df['exit_date'] = pd.to_datetime(df['exit_date'])
# Calculate metrics
df['hold_time'] = (df['exit_date'] - df['entry_date']).dt.days
df['win'] = df['status'] == 'win'
# Daily P&L
daily_pnl = df.groupby('exit_date')['net_pnl'].sum()
# Cumulative P&L
cumulative_pnl = daily_pnl.cumsum()
return df, cumulative_pnl
def plot_equity_curve(cumulative_pnl):
"""Plot equity curve"""
plt.figure(figsize=(12, 6))
plt.plot(cumulative_pnl.index, cumulative_pnl.values, linewidth=2)
plt.title('Equity Curve', fontsize=16)
plt.xlabel('Date')
plt.ylabel('Cumulative P&L ($)')
plt.grid(True, alpha=0.3)
plt.savefig('equity_curve.png', dpi=300, bbox_inches='tight')
print('Equity curve saved to equity_curve.png')
# Main analysis
trades = get_all_trades()
df, cumulative_pnl = analyze_trades(trades)
print(f"\nTotal trades: {len(trades)}")
print(f"Win rate: {(df['win'].sum() / len(df) * 100):.2f}%")
print(f"Total P&L: ${df['net_pnl'].sum():.2f}")
print(f"Average hold time: {df['hold_time'].mean():.1f} days")
# Generate equity curve
plot_equity_curve(cumulative_pnl)
Export to CSV
def export_to_csv(trades, filename='trades_export.csv'):
"""Export trades to CSV"""
df = pd.DataFrame(trades)
# Flatten executions
df['num_executions'] = df['executions'].apply(len)
df = df.drop('executions', axis=1)
df.to_csv(filename, index=False)
print(f'Exported {len(df)} trades to {filename}')
trades = get_all_trades()
export_to_csv(trades)
Google Sheets integration
function importTradesToSheet() {
const API_KEY = PropertiesService.getScriptProperties()
.getProperty('MPJ_API_KEY');
const url = 'https://app.mypropjournal.com/api/v1/trades?limit=100';
const options = {
'method': 'get',
'headers': {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
};
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText());
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Trades');
// Clear existing data
sheet.clear();
// Add headers
sheet.appendRow([
'Date', 'Symbol', 'Side', 'Entry', 'Exit',
'Quantity', 'P&L', 'Status'
]);
// Add trade data
data.data.forEach(trade => {
sheet.appendRow([
trade.entry_date,
trade.symbol,
trade.side,
trade.entry_price,
trade.exit_price,
trade.quantity,
trade.net_pnl,
trade.status
]);
});
Logger.log(`Imported ${data.data.length} trades`);
}
Mobile and wearables
Build mobile applications or widgets using the API.
React Native example
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
const API_KEY = 'mpj_your_api_key_here';
const BASE_URL = 'https://app.mypropjournal.com/api/v1';
function TradesScreen() {
const [trades, setTrades] = useState([]);
const [performance, setPerformance] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchData();
}, []);
async function fetchData() {
try {
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
// Fetch recent trades and performance
const [tradesRes, perfRes] = await Promise.all([
fetch(`${BASE_URL}/trades?limit=10`, { headers }),
fetch(`${BASE_URL}/performance/overview`, { headers })
]);
const tradesData = await tradesRes.json();
const perfData = await perfRes.json();
setTrades(tradesData.data);
setPerformance(perfData.data);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
}
if (loading) {
return <Text>Loading...</Text>;
}
return (
<View style={styles.container}>
{/* Performance summary */}
<View style={styles.performanceCard}>
<Text style={styles.cardTitle}>Performance Overview</Text>
<Text style={styles.stat}>
Win Rate: {performance.win_rate.toFixed(1)}%
</Text>
<Text style={[
styles.stat,
{ color: performance.total_pnl >= 0 ? '#00ff00' : '#ff0000' }
]}>
Total P&L: ${performance.total_pnl.toFixed(2)}
</Text>
</View>
{/* Recent trades list */}
<Text style={styles.sectionTitle}>Recent Trades</Text>
<FlatList
data={trades}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<View style={styles.tradeCard}>
<Text style={styles.tradeSymbol}>{item.symbol}</Text>
<Text>{item.side.toUpperCase()}</Text>
<Text style={[
styles.tradePnl,
{ color: item.net_pnl >= 0 ? '#00ff00' : '#ff0000' }
]}>
${item.net_pnl.toFixed(2)}
</Text>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
backgroundColor: '#000'
},
performanceCard: {
backgroundColor: '#1a1a1a',
padding: 16,
borderRadius: 8,
marginBottom: 16
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#fff',
marginBottom: 8
},
stat: {
fontSize: 16,
color: '#ccc',
marginVertical: 4
},
sectionTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#fff',
marginVertical: 8
},
tradeCard: {
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#1a1a1a',
padding: 12,
borderRadius: 6,
marginVertical: 4
},
tradeSymbol: {
fontSize: 16,
fontWeight: 'bold',
color: '#fff'
},
tradePnl: {
fontSize: 16,
fontWeight: 'bold'
}
});
export default TradesScreen;
iOS Shortcuts integration
Create iOS Shortcuts that fetch your trading stats:
// Shortcut: "My Trading Stats"
// Action: Get Contents of URL
// URL
https://app.mypropjournal.com/api/v1/performance/overview
// Headers
Authorization: Bearer mpj_your_api_key_here
Content-Type: application/json
// Parse JSON and display
Show Notification:
Title: "Trading Stats"
Body: "Win Rate: [win_rate]% | P&L: $[total_pnl]"
Automation
Automate trade logging, backups, and notifications.
Automated trade sync
# Run daily via cron
import requests
from datetime import datetime, timedelta
API_KEY = 'mpj_your_api_key_here'
BASE_URL = 'https://app.mypropjournal.com/api/v1'
def sync_trades_from_broker():
"""Fetch trades from broker and sync to My Prop Journal"""
# Get yesterday's trades from your broker's API
yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
broker_trades = fetch_broker_trades(yesterday) # Your broker API
for trade in broker_trades:
# Convert to MPJ format
mpj_trade = {
'account_id': 'your-account-id',
'symbol': trade['symbol'],
'side': trade['side'],
'entry_date': trade['entry_date'],
'entry_price': trade['entry_price'],
'exit_price': trade['exit_price'],
'exit_date': trade['exit_date'],
'quantity': trade['quantity'],
'executions': trade['fills']
}
# Create trade in MPJ
response = requests.post(
f'{BASE_URL}/trades',
headers={
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
},
json=mpj_trade
)
if response.status_code == 201:
print(f"β Synced {trade['symbol']}")
else:
print(f"β Failed to sync {trade['symbol']}: {response.text}")
sync_trades_from_broker()
Discord/Slack notifications
// Send daily performance summary to Discord
async function sendDailyReport() {
const API_KEY = process.env.MPJ_API_KEY;
const DISCORD_WEBHOOK = process.env.DISCORD_WEBHOOK_URL;
// Get today's performance
const today = new Date().toISOString().split('T')[0];
const response = await fetch(
`https://app.mypropjournal.com/api/v1/performance/overview?start_date=${today}&end_date=${today}`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
const perf = data.data;
// Format Discord message
const embed = {
title: `π Daily Trading Report - ${today}`,
color: perf.total_pnl >= 0 ? 0x00ff00 : 0xff0000,
fields: [
{ name: 'Total Trades', value: perf.total_trades.toString(), inline: true },
{ name: 'Win Rate', value: `${perf.win_rate.toFixed(1)}%`, inline: true },
{ name: 'P&L', value: `$${perf.total_pnl.toFixed(2)}`, inline: true },
{ name: 'Profit Factor', value: perf.profit_factor.toFixed(2), inline: true }
],
timestamp: new Date().toISOString()
};
// Send to Discord
await fetch(DISCORD_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ embeds: [embed] })
});
console.log('Daily report sent to Discord');
}
// Run daily at 5 PM
sendDailyReport();
Migration and backups
Automated daily backup
#!/bin/bash
# Run daily via cron
API_KEY="mpj_your_api_key_here"
BACKUP_DIR="$HOME/mpj_backups"
DATE=$(date +%Y-%m-%d)
mkdir -p "$BACKUP_DIR"
# Fetch all trades
curl "https://app.mypropjournal.com/api/v1/trades?limit=100&page=1" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-o "$BACKUP_DIR/trades_$DATE.json"
# Fetch performance data
curl "https://app.mypropjournal.com/api/v1/performance/overview" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-o "$BACKUP_DIR/performance_$DATE.json"
echo "Backup completed: $DATE"
# Keep only last 30 days
find "$BACKUP_DIR" -name "*.json" -mtime +30 -delete
Migration script
def migrate_to_another_platform():
"""Export MPJ data and import to another platform"""
# Export from MPJ
trades = get_all_trades()
accounts = get_all_accounts()
playbooks = get_all_playbooks()
# Transform to target platform format
target_data = {
'trades': [transform_trade(t) for t in trades],
'accounts': [transform_account(a) for a in accounts],
'strategies': [transform_playbook(p) for p in playbooks]
}
# Import to target platform
import_to_target_platform(target_data)
print(f"Migrated {len(trades)} trades to target platform")