Add files via upload

This commit is contained in:
Immanuel Edunsin
2025-07-23 14:44:57 +01:00
committed by GitHub
parent a030b61f4f
commit 7d02222da7
14 changed files with 1036 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
import pandas as pd
# 1) Load the CSV
df = pd.read_csv("optimization_results.csv")
# 2) Sort by total_pnl descending
top = df.sort_values("total_pnl", ascending=False).head(10)
# 3) Print to console
print("Top 10 parameter sets by Total PnL:\n", top.to_string(index=False))
+220
View File
@@ -0,0 +1,220 @@
import os
import requests
import random
import streamlit as st
import numpy as np
import pandas as pd
from dateutil import parser
from oandapyV20 import API
from oandapyV20.endpoints.pricing import PricingInfo
from cip import theoretical_forward, deviation_bps
from streamlit_autorefresh import st_autorefresh
# Auto-refresh every 5 seconds
st_autorefresh(interval=5_000, key="refresh")
# Page configuration
st.set_page_config(page_title="FX Arbitrage Dashboard", layout="wide")
# --- Credentials via Streamlit secrets & Endpoints ---
# Create a file at ~/.streamlit/secrets.toml (or ./fx_arbitrage/.streamlit/secrets.toml) with:
#
# [oanda]
# token = "<YOUR_OANDA_TOKEN>"
# account_id = "<YOUR_OANDA_ACCOUNT_ID>"
#
# [slack]
# webhook = "<YOUR_SLACK_WEBHOOK_URL>"
#
# Streamlit will auto-load this file into st.secrets
OANDA_TOKEN = st.secrets["oanda"]["token"]
OANDA_ACCOUNT_ID = st.secrets["oanda"]["account_id"]
SLACK_WEBHOOK = st.secrets.get("slack", {}).get("webhook", "")
PRACTICE_SWAP_API = "https://api-fxpractice.oanda.com"
# Initialize OANDA client for spot data
client = API(access_token=OANDA_TOKEN, environment="practice")
# --- Sidebar controls ---
st.sidebar.header("Settings")
override_provider = st.sidebar.selectbox(
"Forward-Rate Provider", ["Manual", "Swap-Points"]
)
manual_bps = st.sidebar.slider(
"Manual forward offset (bps)", -10.0, 10.0, 0.0, step=0.1
)
threshold_bps = st.sidebar.number_input(
"Deviation threshold (bps)", 0.5, 10.0, 1.0, step=0.5
)
stop_loss_bps = st.sidebar.number_input(
"Stop-loss threshold (bps)", 0.0, 20.0, 2.0, step=0.5
)
spread_bps = st.sidebar.number_input(
"Spread cost per trade (bps)", 0.0, 5.0, 0.1, step=0.1
)
tenor_days = st.sidebar.number_input(
"Tenor days", 1, 90, 30
)
pairs = st.sidebar.multiselect(
"Currency pairs", ["EUR_USD", "GBP_USD", "USD_JPY"], default=["EUR_USD", "GBP_USD", "USD_JPY"]
)
# Initialize histories
if 'history' not in st.session_state:
st.session_state.history = {pair: [] for pair in pairs}
if 'fwd_history' not in st.session_state:
st.session_state.fwd_history = {pair: [] for pair in pairs}
# --- Utility functions ---
def fetch_spot(pair):
pricing = client.request(
PricingInfo(accountID=OANDA_ACCOUNT_ID, params={"instruments": pair})
)
bid = float(pricing["prices"][0]["bids"][0]["price"])
ask = float(pricing["prices"][0]["asks"][0]["price"])
return (bid + ask) / 2
def fetch_swap_point(pair):
"""Fetch the daily swap-point for the given tenor."""
url = f"{PRACTICE_SWAP_API}/v3/accounts/{OANDA_ACCOUNT_ID}/instruments/{pair}/swap_rates"
headers = {"Authorization": f"Bearer {OANDA_TOKEN}"}
resp = requests.get(url, headers=headers)
if resp.status_code != 200:
return 0.0
for r in resp.json().get("swapRates", []):
if r.get('tenor').endswith('D') and int(r.get('tenor')[:-1]) == tenor_days:
lr = float(r.get("longRate", 0))
sr = float(r.get("shortRate", 0))
return lr - sr
return 0.0
def simulate_pnl(spot0, obs_fwd, days, sims=500):
pnls = []
for _ in range(sims):
path = spot0
daily = []
for _ in range(days):
shock = random.uniform(-0.005, 0.005)
path *= (1 + shock)
daily.append(1e6 * (path - obs_fwd))
pnls.append(daily)
return np.array(pnls)
# --- Data collection & metrics ---
data_rows = []
for pair in pairs:
spot_mid = fetch_spot(pair)
# Determine observed forward
if override_provider == "Manual":
theo_fwd = theoretical_forward(spot_mid, 0.025, 0.005, tenor_days)
obs_fwd = theo_fwd * (1 + manual_bps / 10_000)
else:
swap_pts = fetch_swap_point(pair)
obs_fwd = spot_mid + swap_pts * tenor_days / 360
theo_fwd = theoretical_forward(spot_mid, 0.025, 0.005, tenor_days)
dev_bps = deviation_bps(obs_fwd, theo_fwd)
# update histories
hist = st.session_state.history[pair]
hist.append(dev_bps)
if len(hist) > 50:
hist.pop(0)
st.session_state.history[pair] = hist
fh = st.session_state.fwd_history[pair]
fh.append(obs_fwd)
if len(fh) > 50:
fh.pop(0)
st.session_state.fwd_history[pair] = fh
# signal
if dev_bps > threshold_bps:
sig = "Rich → Sell forward"
elif dev_bps < -threshold_bps:
sig = "Cheap → Buy forward"
else:
sig = "No arbitrage"
# PnL calculation
cost = spread_bps / 10_000 * 1_000_000
raw_pnl = (obs_fwd - theo_fwd) * 1_000_000
pnl = raw_pnl - cost
stop_amt = stop_loss_bps / 10_000 * 1_000_000
if pnl < -stop_amt:
pnl = -stop_amt
data_rows.append({
"Pair": pair,
"Spot Mid": f"{spot_mid:.6f}",
"Observed Forward": f"{obs_fwd:.6f}",
"Theoretical Fwd": f"{theo_fwd:.6f}",
"Deviation (bps)": f"{dev_bps:+.2f}",
"Signal": sig,
"PnL ($)": f"{pnl:,.0f}"
})
if SLACK_WEBHOOK and sig != "No arbitrage":
requests.post(SLACK_WEBHOOK, json={"text": f"Arb alert: {pair} {dev_bps:+.2f}bps → {sig}"})
# --- Summary Metrics ---
col1, col2, col3, col4 = st.columns(4)
# parse PnL values from data_rows
pnls = [float(r["PnL ($)"].replace("$","").replace(",","") ) for r in data_rows]
total_pnl = sum(pnls)
win_rate = np.mean([1 if v>0 else 0 for v in pnls]) * 100
max_dd = min(pnls)
current_dev= data_rows[0]["Deviation (bps)"]
col1.metric("Total PnL", f"${total_pnl:,.0f}")
col2.metric("Win Rate", f"{win_rate:.1f}%")
col3.metric("Max Drawdown", f"${max_dd:,.0f}")
col4.metric("Current Dev", f"{current_dev} bps")
# --- Display dashboard ---
st.title("FX Arbitrage Dashboard — Live")
st.dataframe(pd.DataFrame(data_rows), use_container_width=True)
st.markdown("**Auto-refreshes every 5s**")
# Deviation & Forward History
st.subheader("Deviation History (bps)")
for pair in pairs:
st.line_chart(pd.DataFrame({pair: st.session_state.history[pair]}))
st.subheader("Observed Forward History")
for pair in pairs:
st.line_chart(pd.DataFrame({pair: st.session_state.fwd_history[pair]}))
# PnL Distribution
st.subheader(f"PnL Distribution at Day {tenor_days}")
for pair in pairs:
spot_mid = fetch_spot(pair)
if override_provider == "Manual":
theo_fwd = theoretical_forward(spot_mid, 0.025, 0.005, tenor_days)
obs_fwd = theo_fwd * (1 + manual_bps / 10_000)
else:
swap_pts = fetch_swap_point(pair)
obs_fwd = spot_mid + swap_pts * tenor_days / 360
sims = simulate_pnl(spot_mid, obs_fwd, tenor_days, sims=1000)
st.write(f"{pair} PnL Histogram")
st.bar_chart(pd.Series(sims[:, -1], name=pair))
# --- Equity Curve ---
st.subheader("Equity Curve (last 50 bars)")
for pair in pairs:
# compute per-bar PnL from history and forward history
pnl_series = []
for obs, dev in zip(st.session_state.fwd_history[pair], st.session_state.history[pair]):
spot_val = fetch_spot(pair)
theo_val = theoretical_forward(spot_val, 0.025, 0.005, tenor_days)
raw = (obs - theo_val) * 1_000_000
cost = spread_bps/10_000 * 1_000_000
pnl_val = raw - cost
stop_amt = stop_loss_bps/10_000 * 1_000_000
pnl_series.append(max(pnl_val, -stop_amt))
equity = np.cumsum(pnl_series)
st.line_chart(pd.DataFrame({pair: equity}))
+144
View File
@@ -0,0 +1,144 @@
import os
import requests
import pandas as pd
import matplotlib.pyplot as plt
from dateutil import parser
from oandapyV20 import API
from oandapyV20.endpoints.instruments import InstrumentsCandles
from cip import theoretical_forward, deviation_bps
# === Configuration ===
OANDA_TOKEN = os.getenv("OANDA_TOKEN")
OANDA_ACCOUNT_ID = os.getenv("OANDA_ACCOUNT_ID")
BASE_URL = "https://api-fxtrade.oanda.com" # production for swap rates
if not OANDA_TOKEN or not OANDA_ACCOUNT_ID:
raise RuntimeError("Please set OANDA_TOKEN and OANDA_ACCOUNT_ID environment variables")
# Initialize OANDA API client (practice for spot data)
api = API(access_token=OANDA_TOKEN, environment="practice")
# === Data Fetching ===
def fetch_spot_history(pair: str, days: int = 365) -> pd.Series:
"""
Fetch daily historical spot mid-prices for the FX pair.
Returns a pandas Series indexed by date.
"""
req = InstrumentsCandles(
instrument=pair,
params={"granularity": "D", "count": days, "price": "M"}
)
data = api.request(req)["candles"]
records = []
for c in data:
dt = parser.isoparse(c["time"]) # full timestamp
o = float(c["mid"]["o"])
c_ = float(c["mid"]["c"])
records.append((dt.date(), (o + c_) / 2))
series = pd.Series({d: s for d, s in records}).sort_index()
return series
def fetch_swap_history(pair: str, days: int = 365) -> pd.Series:
"""
Fetch daily historical swap-rates (forward-points) for the FX pair.
Returns a pandas Series of daily forward-points (decimal) indexed by date.
Falls back to zeros if endpoint unavailable (e.g., practice account).
"""
url = f"{BASE_URL}/v3/accounts/{OANDA_ACCOUNT_ID}/instruments/{pair}/swap_rates"
headers = {"Authorization": f"Bearer {OANDA_TOKEN}"}
params = {"count": days, "granularity": "D"}
try:
resp = requests.get(url, headers=headers, params=params)
resp.raise_for_status()
data = resp.json().get("swapRates", [])
records = []
for r in data:
dt = parser.isoparse(r["time"]).date()
long_rate = float(r.get("longRate", 0))
short_rate = float(r.get("shortRate", 0))
records.append((dt, long_rate - short_rate))
series = pd.Series({d: p for d, p in records}).sort_index()
except Exception:
# Practice environment may not support swap_rates; fallback to zeros
print("Warning: swap_rates endpoint unavailable, falling back to zeros.")
# Build zero series over requested date range
df_spot = fetch_spot_history(pair, days=days)
series = pd.Series(0.0, index=df_spot.index)
return series
# === Backtest ===
def backtest(
pair: str,
tenor_days: int = 30,
r_dom: float = 0.025,
r_for: float = 0.005,
notional: float = 1_000_000,
spread_bps: float = 0.5,
stop_loss_bps: float = 5.0,
history_days: int = 365
) -> None:
"""
Back-test FX CIP arbitrage using real swap-points.
"""
# Fetch data
spot = fetch_spot_history(pair, days=history_days)
swap_pts = fetch_swap_history(pair, days=history_days)
# Build DataFrame
df = pd.DataFrame({"spot": spot})
# theoretical forward
df["theo_fwd"] = df["spot"].apply(lambda s: theoretical_forward(s, r_dom, r_for, tenor_days))
# observed forward = spot + tenor * swap_pts/360
df["swap_pts"] = swap_pts.reindex(df.index).fillna(method="ffill")
df["obs_fwd"] = df["spot"] + df["swap_pts"] * tenor_days / 360
# deviation and signal
df["dev_bps"] = (df["obs_fwd"] - df["theo_fwd"]) / df["theo_fwd"] * 10_000
df["signal"] = 0
df.loc[df["dev_bps"] > 0, "signal"] = -1 # sell forward if rich
df.loc[df["dev_bps"] < 0, "signal"] = +1 # buy forward if cheap
# PnL with spread cost & stop-loss
cost = spread_bps / 10_000 * notional
df["exit_spot"] = df["spot"].shift(-tenor_days)
df["raw_pnl"] = df["signal"] * (df["exit_spot"] - df["obs_fwd"]) * notional
df["pnl"] = df["raw_pnl"] - df["signal"].abs() * cost
stop_amt = stop_loss_bps / 10_000 * notional
df.loc[df["pnl"] < -stop_amt, "pnl"] = -stop_amt
# drop incomplete
trades = df.dropna(subset=["pnl"])
# metrics
total_pnl = trades["pnl"].sum()
num_trades = (trades["signal"] != 0).sum()
win_rate = trades["pnl"].gt(0).mean() * 100 if num_trades else 0
avg_pnl = trades["pnl"].mean() if num_trades else 0
equity = trades["pnl"].cumsum()
max_dd = (equity.cummax() - equity).max() if not equity.empty else 0
# output
print(f"=== Backtest Results for {pair} ({tenor_days}d tenor) ===")
print(f"Total PnL : ${total_pnl:,.0f}")
print(f"Number of trades : {num_trades}")
print(f"Win rate : {win_rate:.1f}%")
print(f"Average PnL/trade : ${avg_pnl:,.0f}")
print(f"Max Drawdown : ${max_dd:,.0f}")
# plot equity
plt.figure(figsize=(10, 4))
plt.plot(equity.index, equity.values)
plt.title(f"Equity Curve ({pair}, {tenor_days}d)")
plt.xlabel("Date")
plt.ylabel("Cumulative PnL ($)")
plt.grid(True)
plt.tight_layout()
plt.show()
# === Main ===
if __name__ == "__main__":
backtest("EUR_USD")
+27
View File
@@ -0,0 +1,27 @@
def theoretical_forward(spot: float, r_dom: float, r_for: float, tenor_days: int) -> float:
"""
Calculate the theoretical forward rate:
F = S * (1 + r_dom * (tenor_days/360)) / (1 + r_for * (tenor_days/360))
"""
return spot * (1 + r_dom * tenor_days / 360) / (1 + r_for * tenor_days / 360)
def deviation_bps(obs_fwd: float, theo_fwd: float) -> float:
"""
Compute the deviation between observed and theoretical forward,
expressed in basis points.
"""
return (obs_fwd - theo_fwd) / theo_fwd * 10_000
if __name__ == "__main__":
# Example inputs (replace these with your real data)
spot_rate = 1.16910 # from PricingInfo closeout or mid
observed_fwd = 1.16930 # placeholder forward outright
r_domestic = 0.025 # e.g., 2.5% annual domestic interest
r_foreign = 0.005 # e.g., 0.5% annual foreign interest
tenor_in_days = 30 # for 1M tenor, approx 30 days
theo = theoretical_forward(spot_rate, r_domestic, r_foreign, tenor_in_days)
dev = deviation_bps(observed_fwd, theo)
print(f"Theoretical 1M Forward: {theo:.6f}")
print(f"Deviation: {dev:.2f} bps")
+74
View File
@@ -0,0 +1,74 @@
{
"time": "2025-07-22T10:40:15.470477032Z",
"prices": [
{
"type": "PRICE",
"time": "2025-07-22T10:40:10.297022351Z",
"bids": [
{
"price": "1.17025",
"liquidity": 500000
},
{
"price": "1.17024",
"liquidity": 500000
},
{
"price": "1.17023",
"liquidity": 2000000
},
{
"price": "1.17022",
"liquidity": 2000000
},
{
"price": "1.17021",
"liquidity": 5000000
},
{
"price": "1.17019",
"liquidity": 10000000
},
{
"price": "1.17016",
"liquidity": 10000000
}
],
"asks": [
{
"price": "1.17032",
"liquidity": 500000
},
{
"price": "1.17034",
"liquidity": 2500000
},
{
"price": "1.17035",
"liquidity": 2000000
},
{
"price": "1.17036",
"liquidity": 5000000
},
{
"price": "1.17039",
"liquidity": 10000000
},
{
"price": "1.17042",
"liquidity": 10000000
}
],
"closeoutBid": "1.17016",
"closeoutAsk": "1.17042",
"status": "tradeable",
"tradeable": true,
"quoteHomeConversionFactors": {
"positiveUnits": "0.74144374",
"negativeUnits": "0.74155370"
},
"instrument": "EUR_USD"
}
]
}
+17
View File
@@ -0,0 +1,17 @@
import os, json
from oandapyV20 import API
from oandapyV20.endpoints.accounts import AccountList
# 1. Read your practice token from env
token = os.getenv("OANDA_TOKEN")
# 2. Initialize the client in practice mode
client = API(access_token=token, environment="practice")
# 3. Create and send the AccountList request
req = AccountList()
resp = client.request(req)
# 4. Pretty-print the JSON so you can see your account IDs
print(json.dumps(resp, indent=2))
+92
View File
@@ -0,0 +1,92 @@
import warnings
from urllib3.exceptions import NotOpenSSLWarning
# Silence the LibreSSL/OpenSSL warning
warnings.filterwarnings("ignore", category=NotOpenSSLWarning)
import os
import json
import requests
from oandapyV20 import API
from oandapyV20.endpoints.pricing import PricingInfo
from cip import theoretical_forward, deviation_bps
# 1. Read credentials from environment variables
# Ensure OANDA_TOKEN and OANDA_ACCOUNT_ID are exported in the same shell
token = os.getenv("OANDA_TOKEN")
account_id = os.getenv("OANDA_ACCOUNT_ID")
# Debug: verify credentials are loaded (remove after confirming)
print("DEBUG: token →", token)
print("DEBUG: account_id →", account_id)
# 2. Initialize OANDA client (practice environment)
client = API(access_token=token, environment="practice")
# 3. Fetch spot pricing for EUR/USD
pricing_req = PricingInfo(accountID=account_id, params={"instruments": "EUR_USD"})
pricing_resp = client.request(pricing_req)
print("\nSPOT PRICING:")
print(json.dumps(pricing_resp, indent=2))
# 4. Compute spot mid price
bid = float(pricing_resp["prices"][0]["bids"][0]["price"])
ask = float(pricing_resp["prices"][0]["asks"][0]["price"])
spot_mid = (bid + ask) / 2
print(f"Spot mid: {spot_mid:.6f}")
# 5. Fetch all swap rates for EUR/USD via correct endpoint
swap_url = "https://api-fxpractice.oanda.com/v3/instruments/EUR_USD/swap_rates"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
swap_resp = requests.get(swap_url, headers=headers)
swap_data = swap_resp.json()
print("\nSWAP RATES RESPONSE:")
print(json.dumps(swap_data, indent=2))
# 6. Extract 1M swap-rate if available
days = 30 # tenor in days for 1M
swap_rates = swap_data.get("swapRates", [])
if swap_rates:
rate_1m = next((r for r in swap_rates if r.get("tenor") == "1M"), None)
if rate_1m:
print("\nObserved market 1M swap-rate object:")
print(json.dumps(rate_1m, indent=2))
# Compute observed forward outright: spot_mid + swap points
fwd_pts = (rate_1m["longRate"] - rate_1m["shortRate"]) * days / 360
obs_fwd = spot_mid + fwd_pts
print(f"Observed 1M forward (spot + swap points): {obs_fwd:.6f}")
else:
print("\n⚠️ 1M tenor not found in swapRates; falling back to theoretical CIP")
# placeholder interest rates
r_domestic = 0.025 # e.g., USD OIS
r_foreign = 0.005 # e.g., EUR OIS
obs_fwd = theoretical_forward(spot_mid, r_domestic, r_foreign, days)
print(f"Fallback observed forward: {obs_fwd:.6f}")
else:
print("\n⚠️ No swapRates data; using theoretical CIP as observed forward")
# placeholder interest rates
r_domestic = 0.025
r_foreign = 0.005
obs_fwd = theoretical_forward(spot_mid, r_domestic, r_foreign, days)
print(f"Fallback observed forward: {obs_fwd:.6f}")
# 7. Compute theoretical forward and deviation
# placeholder interest rates (update with live data when available)
r_domestic = 0.025
r_foreign = 0.005
theo_fwd = theoretical_forward(spot_mid, r_domestic, r_foreign, days)
dev_bps = deviation_bps(obs_fwd, theo_fwd)
print(f"\nTheoretical 1M Forward: {theo_fwd:.6f}")
print(f"Deviation : {dev_bps:.2f} bps")
# 8. Flag arbitrage signal if deviation exceeds threshold
threshold = 2.0 # bps
if abs(dev_bps) > threshold:
direction = "Sell forward / Buy spot" if dev_bps > 0 else "Buy forward / Sell spot"
print(f"⚠️ Arbitrage signal: {dev_bps:.2f} bps → {direction}")
else:
print("✅ No actionable arbitrage (deviation within threshold).")
+226
View File
@@ -0,0 +1,226 @@
threshold_bps,offset_bps,stop_loss_bps,spread_bps,total_pnl,num_trades,win_rate,avg_pnl,max_drawdown
0.5,1.0,2.0,0.1,3035914.489215958,335,44.47761194029851,9062.431311092412,14800.0
0.5,1.0,2.0,0.5,3029914.489215958,335,44.47761194029851,9044.520863331218,14800.0
0.5,1.0,2.0,1.0,3022414.489215958,335,44.47761194029851,9022.132803629725,14800.0
0.5,1.0,5.0,0.1,2980414.489215958,335,44.47761194029851,8896.759669301367,37000.0
0.5,1.0,5.0,0.5,2974414.489215958,335,44.47761194029851,8878.849221540173,37000.0
0.5,1.0,5.0,1.0,2966914.489215958,335,44.47761194029851,8856.46116183868,37000.0
0.5,1.0,10.0,0.1,2888282.456922122,335,44.47761194029851,8621.738677379468,75079.10061016213
0.5,1.0,10.0,0.5,2882242.456922122,335,44.47761194029851,8603.7088266332,75399.10061016213
0.5,1.0,10.0,1.0,2874692.456922122,335,44.47761194029851,8581.171513200363,75799.10061016213
0.5,2.0,2.0,0.1,3052218.607753026,335,44.776119402985074,9111.100321650823,14800.0
0.5,2.0,2.0,0.5,3046218.607753026,335,44.47761194029851,9093.189873889629,14800.0
0.5,2.0,2.0,1.0,3038718.607753026,335,44.47761194029851,9070.801814188137,14800.0
0.5,2.0,5.0,0.1,2996718.607753026,335,44.776119402985074,8945.428679859779,37000.0
0.5,2.0,5.0,0.5,2990718.607753026,335,44.47761194029851,8927.518232098584,37000.0
0.5,2.0,5.0,1.0,2983218.607753026,335,44.47761194029851,8905.130172397092,37000.0
0.5,2.0,10.0,0.1,2904773.3181278696,335,44.776119402985074,8670.96512873991,74165.65436484851
0.5,2.0,10.0,0.5,2898693.3181278696,335,44.47761194029851,8652.815875008566,74485.65436484851
0.5,2.0,10.0,1.0,2891110.4573677694,335,44.47761194029851,8630.180469754536,74885.65436484851
0.5,3.0,2.0,0.1,3068522.72629009,335,44.776119402985074,9159.769332209224,14800.0
0.5,3.0,2.0,0.5,3062522.72629009,335,44.776119402985074,9141.85888444803,14800.0
0.5,3.0,2.0,1.0,3055022.72629009,335,44.776119402985074,9119.470824746537,14800.0
0.5,3.0,5.0,0.1,3013118.457813414,335,44.776119402985074,8994.383456159445,37000.0
0.5,3.0,5.0,0.5,3007078.457813414,335,44.776119402985074,8976.353605413176,37000.0
0.5,3.0,5.0,1.0,2999528.457813414,335,44.776119402985074,8953.81629198034,37000.0
0.5,3.0,10.0,0.1,2921299.887645775,335,44.776119402985074,8720.29817207694,74000.0
0.5,3.0,10.0,0.5,2915219.887645775,335,44.776119402985074,8702.148918345598,74000.0
0.5,3.0,10.0,1.0,2907619.887645775,335,44.776119402985074,8679.462351181417,74000.0
0.5,4.0,2.0,0.1,3084826.8448271556,335,44.776119402985074,9208.43834276763,14800.0
0.5,4.0,2.0,0.5,3078826.8448271556,335,44.776119402985074,9190.527895006435,14800.0
0.5,4.0,2.0,1.0,3071326.8448271556,335,44.776119402985074,9168.139835304943,14800.0
0.5,4.0,5.0,0.1,3029536.458259059,335,44.776119402985074,9043.392412713609,37000.0
0.5,4.0,5.0,0.5,3023496.458259059,335,44.776119402985074,9025.36256196734,37000.0
0.5,4.0,5.0,1.0,3015946.458259059,335,44.776119402985074,9002.825248534506,37000.0
0.5,4.0,10.0,0.1,2937917.0644606417,335,44.776119402985074,8769.90168495714,74000.0
0.5,4.0,10.0,0.5,2931797.0644606417,335,44.776119402985074,8751.633028240722,74000.0
0.5,4.0,10.0,1.0,2924147.0644606417,335,44.776119402985074,8728.797207345198,74000.0
0.5,5.0,2.0,0.1,3101154.4587047044,335,44.776119402985074,9257.177488670759,14800.0
0.5,5.0,2.0,0.5,3095130.963364221,335,44.776119402985074,9239.196905564839,14800.0
0.5,5.0,2.0,1.0,3087630.963364221,335,44.776119402985074,9216.808845863347,14800.0
0.5,5.0,5.0,0.1,3045954.4587047044,335,44.776119402985074,9092.401369267774,37000.0
0.5,5.0,5.0,0.5,3039914.4587047044,335,44.776119402985074,9074.371518521506,37000.0
0.5,5.0,5.0,1.0,3032364.4587047044,335,44.776119402985074,9051.83420508867,37000.0
0.5,5.0,10.0,0.1,2954551.9901967905,335,44.776119402985074,8819.558179691912,74000.0
0.5,5.0,10.0,0.5,2948431.9901967905,335,44.776119402985074,8801.289522975494,74000.0
0.5,5.0,10.0,1.0,2940781.9901967905,335,44.776119402985074,8778.453702079973,74000.0
1.0,1.0,2.0,0.1,1233700.1759173332,160,19.1044776119403,3682.687092290547,7200.0
1.0,1.0,2.0,0.5,1231100.1759173332,160,19.1044776119403,3674.925898260696,7200.0
1.0,1.0,2.0,1.0,1227850.1759173332,160,19.1044776119403,3665.224405723383,7200.0
1.0,1.0,5.0,0.1,1205200.1759173332,160,19.1044776119403,3597.612465424875,18000.0
1.0,1.0,5.0,0.5,1202600.1759173332,160,19.1044776119403,3589.8512713950245,18000.0
1.0,1.0,5.0,1.0,1199350.1759173332,160,19.1044776119403,3580.149778857711,18000.0
1.0,1.0,10.0,0.1,1157700.1759173332,160,19.1044776119403,3455.821420648756,42775.720814244356
1.0,1.0,10.0,0.5,1155100.1759173332,160,19.1044776119403,3448.0602266189053,42895.720814244356
1.0,1.0,10.0,1.0,1151850.1759173332,160,19.1044776119403,3438.3587340815916,43045.720814244356
1.0,2.0,2.0,0.1,3052218.607753026,335,44.776119402985074,9111.100321650823,14800.0
1.0,2.0,2.0,0.5,3046218.607753026,335,44.47761194029851,9093.189873889629,14800.0
1.0,2.0,2.0,1.0,3038718.607753026,335,44.47761194029851,9070.801814188137,14800.0
1.0,2.0,5.0,0.1,2996718.607753026,335,44.776119402985074,8945.428679859779,37000.0
1.0,2.0,5.0,0.5,2990718.607753026,335,44.47761194029851,8927.518232098584,37000.0
1.0,2.0,5.0,1.0,2983218.607753026,335,44.47761194029851,8905.130172397092,37000.0
1.0,2.0,10.0,0.1,2904773.3181278696,335,44.776119402985074,8670.96512873991,74165.65436484851
1.0,2.0,10.0,0.5,2898693.3181278696,335,44.47761194029851,8652.815875008566,74485.65436484851
1.0,2.0,10.0,1.0,2891110.4573677694,335,44.47761194029851,8630.180469754536,74885.65436484851
1.0,3.0,2.0,0.1,3068522.72629009,335,44.776119402985074,9159.769332209224,14800.0
1.0,3.0,2.0,0.5,3062522.72629009,335,44.776119402985074,9141.85888444803,14800.0
1.0,3.0,2.0,1.0,3055022.72629009,335,44.776119402985074,9119.470824746537,14800.0
1.0,3.0,5.0,0.1,3013118.457813414,335,44.776119402985074,8994.383456159445,37000.0
1.0,3.0,5.0,0.5,3007078.457813414,335,44.776119402985074,8976.353605413176,37000.0
1.0,3.0,5.0,1.0,2999528.457813414,335,44.776119402985074,8953.81629198034,37000.0
1.0,3.0,10.0,0.1,2921299.887645775,335,44.776119402985074,8720.29817207694,74000.0
1.0,3.0,10.0,0.5,2915219.887645775,335,44.776119402985074,8702.148918345598,74000.0
1.0,3.0,10.0,1.0,2907619.887645775,335,44.776119402985074,8679.462351181417,74000.0
1.0,4.0,2.0,0.1,3084826.8448271556,335,44.776119402985074,9208.43834276763,14800.0
1.0,4.0,2.0,0.5,3078826.8448271556,335,44.776119402985074,9190.527895006435,14800.0
1.0,4.0,2.0,1.0,3071326.8448271556,335,44.776119402985074,9168.139835304943,14800.0
1.0,4.0,5.0,0.1,3029536.458259059,335,44.776119402985074,9043.392412713609,37000.0
1.0,4.0,5.0,0.5,3023496.458259059,335,44.776119402985074,9025.36256196734,37000.0
1.0,4.0,5.0,1.0,3015946.458259059,335,44.776119402985074,9002.825248534506,37000.0
1.0,4.0,10.0,0.1,2937917.0644606417,335,44.776119402985074,8769.90168495714,74000.0
1.0,4.0,10.0,0.5,2931797.0644606417,335,44.776119402985074,8751.633028240722,74000.0
1.0,4.0,10.0,1.0,2924147.0644606417,335,44.776119402985074,8728.797207345198,74000.0
1.0,5.0,2.0,0.1,3101154.4587047044,335,44.776119402985074,9257.177488670759,14800.0
1.0,5.0,2.0,0.5,3095130.963364221,335,44.776119402985074,9239.196905564839,14800.0
1.0,5.0,2.0,1.0,3087630.963364221,335,44.776119402985074,9216.808845863347,14800.0
1.0,5.0,5.0,0.1,3045954.4587047044,335,44.776119402985074,9092.401369267774,37000.0
1.0,5.0,5.0,0.5,3039914.4587047044,335,44.776119402985074,9074.371518521506,37000.0
1.0,5.0,5.0,1.0,3032364.4587047044,335,44.776119402985074,9051.83420508867,37000.0
1.0,5.0,10.0,0.1,2954551.9901967905,335,44.776119402985074,8819.558179691912,74000.0
1.0,5.0,10.0,0.5,2948431.9901967905,335,44.776119402985074,8801.289522975494,74000.0
1.0,5.0,10.0,1.0,2940781.9901967905,335,44.776119402985074,8778.453702079973,74000.0
2.0,1.0,2.0,0.1,0.0,0,0.0,0.0,0.0
2.0,1.0,2.0,0.5,0.0,0,0.0,0.0,0.0
2.0,1.0,2.0,1.0,0.0,0,0.0,0.0,0.0
2.0,1.0,5.0,0.1,0.0,0,0.0,0.0,0.0
2.0,1.0,5.0,0.5,0.0,0,0.0,0.0,0.0
2.0,1.0,5.0,1.0,0.0,0,0.0,0.0,0.0
2.0,1.0,10.0,0.1,0.0,0,0.0,0.0,0.0
2.0,1.0,10.0,0.5,0.0,0,0.0,0.0,0.0
2.0,1.0,10.0,1.0,0.0,0,0.0,0.0,0.0
2.0,2.0,2.0,0.1,1234607.5833340343,130,18.507462686567163,3685.395771146371,5800.0
2.0,2.0,2.0,0.5,1232127.5833340343,130,18.507462686567163,3677.9927860717444,5800.0
2.0,2.0,2.0,1.0,1229027.5833340343,130,18.507462686567163,3668.739054728461,5800.0
2.0,2.0,5.0,0.1,1214207.5833340343,130,18.507462686567163,3624.5002487583115,14500.0
2.0,2.0,5.0,0.5,1211727.5833340343,130,18.507462686567163,3617.0972636836846,14500.0
2.0,2.0,5.0,1.0,1208627.5833340343,130,18.507462686567163,3607.843532340401,14500.0
2.0,2.0,10.0,0.1,1180207.5833340343,130,18.507462686567163,3523.0077114448786,29000.0
2.0,2.0,10.0,0.5,1177727.5833340343,130,18.507462686567163,3515.6047263702517,29000.0
2.0,2.0,10.0,1.0,1174627.5833340343,130,18.507462686567163,3506.350995026968,29000.0
2.0,3.0,2.0,0.1,3068522.72629009,335,44.776119402985074,9159.769332209224,14800.0
2.0,3.0,2.0,0.5,3062522.72629009,335,44.776119402985074,9141.85888444803,14800.0
2.0,3.0,2.0,1.0,3055022.72629009,335,44.776119402985074,9119.470824746537,14800.0
2.0,3.0,5.0,0.1,3013118.457813414,335,44.776119402985074,8994.383456159445,37000.0
2.0,3.0,5.0,0.5,3007078.457813414,335,44.776119402985074,8976.353605413176,37000.0
2.0,3.0,5.0,1.0,2999528.457813414,335,44.776119402985074,8953.81629198034,37000.0
2.0,3.0,10.0,0.1,2921299.887645775,335,44.776119402985074,8720.29817207694,74000.0
2.0,3.0,10.0,0.5,2915219.887645775,335,44.776119402985074,8702.148918345598,74000.0
2.0,3.0,10.0,1.0,2907619.887645775,335,44.776119402985074,8679.462351181417,74000.0
2.0,4.0,2.0,0.1,3084826.8448271556,335,44.776119402985074,9208.43834276763,14800.0
2.0,4.0,2.0,0.5,3078826.8448271556,335,44.776119402985074,9190.527895006435,14800.0
2.0,4.0,2.0,1.0,3071326.8448271556,335,44.776119402985074,9168.139835304943,14800.0
2.0,4.0,5.0,0.1,3029536.458259059,335,44.776119402985074,9043.392412713609,37000.0
2.0,4.0,5.0,0.5,3023496.458259059,335,44.776119402985074,9025.36256196734,37000.0
2.0,4.0,5.0,1.0,3015946.458259059,335,44.776119402985074,9002.825248534506,37000.0
2.0,4.0,10.0,0.1,2937917.0644606417,335,44.776119402985074,8769.90168495714,74000.0
2.0,4.0,10.0,0.5,2931797.0644606417,335,44.776119402985074,8751.633028240722,74000.0
2.0,4.0,10.0,1.0,2924147.0644606417,335,44.776119402985074,8728.797207345198,74000.0
2.0,5.0,2.0,0.1,3101154.4587047044,335,44.776119402985074,9257.177488670759,14800.0
2.0,5.0,2.0,0.5,3095130.963364221,335,44.776119402985074,9239.196905564839,14800.0
2.0,5.0,2.0,1.0,3087630.963364221,335,44.776119402985074,9216.808845863347,14800.0
2.0,5.0,5.0,0.1,3045954.4587047044,335,44.776119402985074,9092.401369267774,37000.0
2.0,5.0,5.0,0.5,3039914.4587047044,335,44.776119402985074,9074.371518521506,37000.0
2.0,5.0,5.0,1.0,3032364.4587047044,335,44.776119402985074,9051.83420508867,37000.0
2.0,5.0,10.0,0.1,2954551.9901967905,335,44.776119402985074,8819.558179691912,74000.0
2.0,5.0,10.0,0.5,2948431.9901967905,335,44.776119402985074,8801.289522975494,74000.0
2.0,5.0,10.0,1.0,2940781.9901967905,335,44.776119402985074,8778.453702079973,74000.0
3.0,1.0,2.0,0.1,0.0,0,0.0,0.0,0.0
3.0,1.0,2.0,0.5,0.0,0,0.0,0.0,0.0
3.0,1.0,2.0,1.0,0.0,0,0.0,0.0,0.0
3.0,1.0,5.0,0.1,0.0,0,0.0,0.0,0.0
3.0,1.0,5.0,0.5,0.0,0,0.0,0.0,0.0
3.0,1.0,5.0,1.0,0.0,0,0.0,0.0,0.0
3.0,1.0,10.0,0.1,0.0,0,0.0,0.0,0.0
3.0,1.0,10.0,0.5,0.0,0,0.0,0.0,0.0
3.0,1.0,10.0,1.0,0.0,0,0.0,0.0,0.0
3.0,2.0,2.0,0.1,0.0,0,0.0,0.0,0.0
3.0,2.0,2.0,0.5,0.0,0,0.0,0.0,0.0
3.0,2.0,2.0,1.0,0.0,0,0.0,0.0,0.0
3.0,2.0,5.0,0.1,0.0,0,0.0,0.0,0.0
3.0,2.0,5.0,0.5,0.0,0,0.0,0.0,0.0
3.0,2.0,5.0,1.0,0.0,0,0.0,0.0,0.0
3.0,2.0,10.0,0.1,0.0,0,0.0,0.0,0.0
3.0,2.0,10.0,0.5,0.0,0,0.0,0.0,0.0
3.0,2.0,10.0,1.0,0.0,0,0.0,0.0,0.0
3.0,3.0,2.0,0.1,1136323.1076457775,116,16.119402985074625,3392.0092765545596,5000.0
3.0,3.0,2.0,0.5,1134163.1076457775,116,16.119402985074625,3385.56151536053,5000.0
3.0,3.0,2.0,1.0,1131463.1076457775,116,16.119402985074625,3377.5018138679925,5000.0
3.0,3.0,5.0,0.1,1117723.1076457775,116,16.119402985074625,3336.4868884948582,12500.0
3.0,3.0,5.0,0.5,1115563.1076457775,116,16.119402985074625,3330.0391273008286,12500.0
3.0,3.0,5.0,1.0,1112863.1076457775,116,16.119402985074625,3321.979425808291,12500.0
3.0,3.0,10.0,0.1,1086723.1076457775,116,16.119402985074625,3243.9495750620226,25000.0
3.0,3.0,10.0,0.5,1084563.1076457775,116,16.119402985074625,3237.5018138679925,25000.0
3.0,3.0,10.0,1.0,1081863.1076457775,116,16.119402985074625,3229.4421123754555,25000.0
3.0,4.0,2.0,0.1,3084826.8448271556,335,44.776119402985074,9208.43834276763,14800.0
3.0,4.0,2.0,0.5,3078826.8448271556,335,44.776119402985074,9190.527895006435,14800.0
3.0,4.0,2.0,1.0,3071326.8448271556,335,44.776119402985074,9168.139835304943,14800.0
3.0,4.0,5.0,0.1,3029536.458259059,335,44.776119402985074,9043.392412713609,37000.0
3.0,4.0,5.0,0.5,3023496.458259059,335,44.776119402985074,9025.36256196734,37000.0
3.0,4.0,5.0,1.0,3015946.458259059,335,44.776119402985074,9002.825248534506,37000.0
3.0,4.0,10.0,0.1,2937917.0644606417,335,44.776119402985074,8769.90168495714,74000.0
3.0,4.0,10.0,0.5,2931797.0644606417,335,44.776119402985074,8751.633028240722,74000.0
3.0,4.0,10.0,1.0,2924147.0644606417,335,44.776119402985074,8728.797207345198,74000.0
3.0,5.0,2.0,0.1,3101154.4587047044,335,44.776119402985074,9257.177488670759,14800.0
3.0,5.0,2.0,0.5,3095130.963364221,335,44.776119402985074,9239.196905564839,14800.0
3.0,5.0,2.0,1.0,3087630.963364221,335,44.776119402985074,9216.808845863347,14800.0
3.0,5.0,5.0,0.1,3045954.4587047044,335,44.776119402985074,9092.401369267774,37000.0
3.0,5.0,5.0,0.5,3039914.4587047044,335,44.776119402985074,9074.371518521506,37000.0
3.0,5.0,5.0,1.0,3032364.4587047044,335,44.776119402985074,9051.83420508867,37000.0
3.0,5.0,10.0,0.1,2954551.9901967905,335,44.776119402985074,8819.558179691912,74000.0
3.0,5.0,10.0,0.5,2948431.9901967905,335,44.776119402985074,8801.289522975494,74000.0
3.0,5.0,10.0,1.0,2940781.9901967905,335,44.776119402985074,8778.453702079973,74000.0
4.0,1.0,2.0,0.1,0.0,0,0.0,0.0,0.0
4.0,1.0,2.0,0.5,0.0,0,0.0,0.0,0.0
4.0,1.0,2.0,1.0,0.0,0,0.0,0.0,0.0
4.0,1.0,5.0,0.1,0.0,0,0.0,0.0,0.0
4.0,1.0,5.0,0.5,0.0,0,0.0,0.0,0.0
4.0,1.0,5.0,1.0,0.0,0,0.0,0.0,0.0
4.0,1.0,10.0,0.1,0.0,0,0.0,0.0,0.0
4.0,1.0,10.0,0.5,0.0,0,0.0,0.0,0.0
4.0,1.0,10.0,1.0,0.0,0,0.0,0.0,0.0
4.0,2.0,2.0,0.1,0.0,0,0.0,0.0,0.0
4.0,2.0,2.0,0.5,0.0,0,0.0,0.0,0.0
4.0,2.0,2.0,1.0,0.0,0,0.0,0.0,0.0
4.0,2.0,5.0,0.1,0.0,0,0.0,0.0,0.0
4.0,2.0,5.0,0.5,0.0,0,0.0,0.0,0.0
4.0,2.0,5.0,1.0,0.0,0,0.0,0.0,0.0
4.0,2.0,10.0,0.1,0.0,0,0.0,0.0,0.0
4.0,2.0,10.0,0.5,0.0,0,0.0,0.0,0.0
4.0,2.0,10.0,1.0,0.0,0,0.0,0.0,0.0
4.0,3.0,2.0,0.1,0.0,0,0.0,0.0,0.0
4.0,3.0,2.0,0.5,0.0,0,0.0,0.0,0.0
4.0,3.0,2.0,1.0,0.0,0,0.0,0.0,0.0
4.0,3.0,5.0,0.1,0.0,0,0.0,0.0,0.0
4.0,3.0,5.0,0.5,0.0,0,0.0,0.0,0.0
4.0,3.0,5.0,1.0,0.0,0,0.0,0.0,0.0
4.0,3.0,10.0,0.1,0.0,0,0.0,0.0,0.0
4.0,3.0,10.0,0.5,0.0,0,0.0,0.0,0.0
4.0,3.0,10.0,1.0,0.0,0,0.0,0.0,0.0
4.0,4.0,2.0,0.1,744222.7130903826,90,11.343283582089553,2221.5603375832316,6948.339329446317
4.0,4.0,2.0,0.5,742702.7130903827,90,11.343283582089553,2217.0230241503964,6988.339329446317
4.0,4.0,2.0,1.0,740802.7130903827,90,11.343283582089553,2211.3513823593516,7038.339329446317
4.0,4.0,5.0,0.1,728622.7130903827,90,11.343283582089553,2174.9931734041274,17748.339329446317
4.0,4.0,5.0,0.5,727102.7130903827,90,11.343283582089553,2170.455859971292,17788.339329446317
4.0,4.0,5.0,1.0,725202.7130903827,90,11.343283582089553,2164.784218180247,17838.339329446317
4.0,4.0,10.0,0.1,702713.3203873425,90,11.343283582089553,2097.6517026487836,35748.33932944632
4.0,4.0,10.0,0.5,701153.3203873425,90,11.343283582089553,2092.994986230873,35788.33932944632
4.0,4.0,10.0,1.0,699203.3203873425,90,11.343283582089553,2087.174090708485,35838.33932944632
4.0,5.0,2.0,0.1,3101154.4587047044,335,44.776119402985074,9257.177488670759,14800.0
4.0,5.0,2.0,0.5,3095130.963364221,335,44.776119402985074,9239.196905564839,14800.0
4.0,5.0,2.0,1.0,3087630.963364221,335,44.776119402985074,9216.808845863347,14800.0
4.0,5.0,5.0,0.1,3045954.4587047044,335,44.776119402985074,9092.401369267774,37000.0
4.0,5.0,5.0,0.5,3039914.4587047044,335,44.776119402985074,9074.371518521506,37000.0
4.0,5.0,5.0,1.0,3032364.4587047044,335,44.776119402985074,9051.83420508867,37000.0
4.0,5.0,10.0,0.1,2954551.9901967905,335,44.776119402985074,8819.558179691912,74000.0
4.0,5.0,10.0,0.5,2948431.9901967905,335,44.776119402985074,8801.289522975494,74000.0
4.0,5.0,10.0,1.0,2940781.9901967905,335,44.776119402985074,8778.453702079973,74000.0
1 threshold_bps offset_bps stop_loss_bps spread_bps total_pnl num_trades win_rate avg_pnl max_drawdown
2 0.5 1.0 2.0 0.1 3035914.489215958 335 44.47761194029851 9062.431311092412 14800.0
3 0.5 1.0 2.0 0.5 3029914.489215958 335 44.47761194029851 9044.520863331218 14800.0
4 0.5 1.0 2.0 1.0 3022414.489215958 335 44.47761194029851 9022.132803629725 14800.0
5 0.5 1.0 5.0 0.1 2980414.489215958 335 44.47761194029851 8896.759669301367 37000.0
6 0.5 1.0 5.0 0.5 2974414.489215958 335 44.47761194029851 8878.849221540173 37000.0
7 0.5 1.0 5.0 1.0 2966914.489215958 335 44.47761194029851 8856.46116183868 37000.0
8 0.5 1.0 10.0 0.1 2888282.456922122 335 44.47761194029851 8621.738677379468 75079.10061016213
9 0.5 1.0 10.0 0.5 2882242.456922122 335 44.47761194029851 8603.7088266332 75399.10061016213
10 0.5 1.0 10.0 1.0 2874692.456922122 335 44.47761194029851 8581.171513200363 75799.10061016213
11 0.5 2.0 2.0 0.1 3052218.607753026 335 44.776119402985074 9111.100321650823 14800.0
12 0.5 2.0 2.0 0.5 3046218.607753026 335 44.47761194029851 9093.189873889629 14800.0
13 0.5 2.0 2.0 1.0 3038718.607753026 335 44.47761194029851 9070.801814188137 14800.0
14 0.5 2.0 5.0 0.1 2996718.607753026 335 44.776119402985074 8945.428679859779 37000.0
15 0.5 2.0 5.0 0.5 2990718.607753026 335 44.47761194029851 8927.518232098584 37000.0
16 0.5 2.0 5.0 1.0 2983218.607753026 335 44.47761194029851 8905.130172397092 37000.0
17 0.5 2.0 10.0 0.1 2904773.3181278696 335 44.776119402985074 8670.96512873991 74165.65436484851
18 0.5 2.0 10.0 0.5 2898693.3181278696 335 44.47761194029851 8652.815875008566 74485.65436484851
19 0.5 2.0 10.0 1.0 2891110.4573677694 335 44.47761194029851 8630.180469754536 74885.65436484851
20 0.5 3.0 2.0 0.1 3068522.72629009 335 44.776119402985074 9159.769332209224 14800.0
21 0.5 3.0 2.0 0.5 3062522.72629009 335 44.776119402985074 9141.85888444803 14800.0
22 0.5 3.0 2.0 1.0 3055022.72629009 335 44.776119402985074 9119.470824746537 14800.0
23 0.5 3.0 5.0 0.1 3013118.457813414 335 44.776119402985074 8994.383456159445 37000.0
24 0.5 3.0 5.0 0.5 3007078.457813414 335 44.776119402985074 8976.353605413176 37000.0
25 0.5 3.0 5.0 1.0 2999528.457813414 335 44.776119402985074 8953.81629198034 37000.0
26 0.5 3.0 10.0 0.1 2921299.887645775 335 44.776119402985074 8720.29817207694 74000.0
27 0.5 3.0 10.0 0.5 2915219.887645775 335 44.776119402985074 8702.148918345598 74000.0
28 0.5 3.0 10.0 1.0 2907619.887645775 335 44.776119402985074 8679.462351181417 74000.0
29 0.5 4.0 2.0 0.1 3084826.8448271556 335 44.776119402985074 9208.43834276763 14800.0
30 0.5 4.0 2.0 0.5 3078826.8448271556 335 44.776119402985074 9190.527895006435 14800.0
31 0.5 4.0 2.0 1.0 3071326.8448271556 335 44.776119402985074 9168.139835304943 14800.0
32 0.5 4.0 5.0 0.1 3029536.458259059 335 44.776119402985074 9043.392412713609 37000.0
33 0.5 4.0 5.0 0.5 3023496.458259059 335 44.776119402985074 9025.36256196734 37000.0
34 0.5 4.0 5.0 1.0 3015946.458259059 335 44.776119402985074 9002.825248534506 37000.0
35 0.5 4.0 10.0 0.1 2937917.0644606417 335 44.776119402985074 8769.90168495714 74000.0
36 0.5 4.0 10.0 0.5 2931797.0644606417 335 44.776119402985074 8751.633028240722 74000.0
37 0.5 4.0 10.0 1.0 2924147.0644606417 335 44.776119402985074 8728.797207345198 74000.0
38 0.5 5.0 2.0 0.1 3101154.4587047044 335 44.776119402985074 9257.177488670759 14800.0
39 0.5 5.0 2.0 0.5 3095130.963364221 335 44.776119402985074 9239.196905564839 14800.0
40 0.5 5.0 2.0 1.0 3087630.963364221 335 44.776119402985074 9216.808845863347 14800.0
41 0.5 5.0 5.0 0.1 3045954.4587047044 335 44.776119402985074 9092.401369267774 37000.0
42 0.5 5.0 5.0 0.5 3039914.4587047044 335 44.776119402985074 9074.371518521506 37000.0
43 0.5 5.0 5.0 1.0 3032364.4587047044 335 44.776119402985074 9051.83420508867 37000.0
44 0.5 5.0 10.0 0.1 2954551.9901967905 335 44.776119402985074 8819.558179691912 74000.0
45 0.5 5.0 10.0 0.5 2948431.9901967905 335 44.776119402985074 8801.289522975494 74000.0
46 0.5 5.0 10.0 1.0 2940781.9901967905 335 44.776119402985074 8778.453702079973 74000.0
47 1.0 1.0 2.0 0.1 1233700.1759173332 160 19.1044776119403 3682.687092290547 7200.0
48 1.0 1.0 2.0 0.5 1231100.1759173332 160 19.1044776119403 3674.925898260696 7200.0
49 1.0 1.0 2.0 1.0 1227850.1759173332 160 19.1044776119403 3665.224405723383 7200.0
50 1.0 1.0 5.0 0.1 1205200.1759173332 160 19.1044776119403 3597.612465424875 18000.0
51 1.0 1.0 5.0 0.5 1202600.1759173332 160 19.1044776119403 3589.8512713950245 18000.0
52 1.0 1.0 5.0 1.0 1199350.1759173332 160 19.1044776119403 3580.149778857711 18000.0
53 1.0 1.0 10.0 0.1 1157700.1759173332 160 19.1044776119403 3455.821420648756 42775.720814244356
54 1.0 1.0 10.0 0.5 1155100.1759173332 160 19.1044776119403 3448.0602266189053 42895.720814244356
55 1.0 1.0 10.0 1.0 1151850.1759173332 160 19.1044776119403 3438.3587340815916 43045.720814244356
56 1.0 2.0 2.0 0.1 3052218.607753026 335 44.776119402985074 9111.100321650823 14800.0
57 1.0 2.0 2.0 0.5 3046218.607753026 335 44.47761194029851 9093.189873889629 14800.0
58 1.0 2.0 2.0 1.0 3038718.607753026 335 44.47761194029851 9070.801814188137 14800.0
59 1.0 2.0 5.0 0.1 2996718.607753026 335 44.776119402985074 8945.428679859779 37000.0
60 1.0 2.0 5.0 0.5 2990718.607753026 335 44.47761194029851 8927.518232098584 37000.0
61 1.0 2.0 5.0 1.0 2983218.607753026 335 44.47761194029851 8905.130172397092 37000.0
62 1.0 2.0 10.0 0.1 2904773.3181278696 335 44.776119402985074 8670.96512873991 74165.65436484851
63 1.0 2.0 10.0 0.5 2898693.3181278696 335 44.47761194029851 8652.815875008566 74485.65436484851
64 1.0 2.0 10.0 1.0 2891110.4573677694 335 44.47761194029851 8630.180469754536 74885.65436484851
65 1.0 3.0 2.0 0.1 3068522.72629009 335 44.776119402985074 9159.769332209224 14800.0
66 1.0 3.0 2.0 0.5 3062522.72629009 335 44.776119402985074 9141.85888444803 14800.0
67 1.0 3.0 2.0 1.0 3055022.72629009 335 44.776119402985074 9119.470824746537 14800.0
68 1.0 3.0 5.0 0.1 3013118.457813414 335 44.776119402985074 8994.383456159445 37000.0
69 1.0 3.0 5.0 0.5 3007078.457813414 335 44.776119402985074 8976.353605413176 37000.0
70 1.0 3.0 5.0 1.0 2999528.457813414 335 44.776119402985074 8953.81629198034 37000.0
71 1.0 3.0 10.0 0.1 2921299.887645775 335 44.776119402985074 8720.29817207694 74000.0
72 1.0 3.0 10.0 0.5 2915219.887645775 335 44.776119402985074 8702.148918345598 74000.0
73 1.0 3.0 10.0 1.0 2907619.887645775 335 44.776119402985074 8679.462351181417 74000.0
74 1.0 4.0 2.0 0.1 3084826.8448271556 335 44.776119402985074 9208.43834276763 14800.0
75 1.0 4.0 2.0 0.5 3078826.8448271556 335 44.776119402985074 9190.527895006435 14800.0
76 1.0 4.0 2.0 1.0 3071326.8448271556 335 44.776119402985074 9168.139835304943 14800.0
77 1.0 4.0 5.0 0.1 3029536.458259059 335 44.776119402985074 9043.392412713609 37000.0
78 1.0 4.0 5.0 0.5 3023496.458259059 335 44.776119402985074 9025.36256196734 37000.0
79 1.0 4.0 5.0 1.0 3015946.458259059 335 44.776119402985074 9002.825248534506 37000.0
80 1.0 4.0 10.0 0.1 2937917.0644606417 335 44.776119402985074 8769.90168495714 74000.0
81 1.0 4.0 10.0 0.5 2931797.0644606417 335 44.776119402985074 8751.633028240722 74000.0
82 1.0 4.0 10.0 1.0 2924147.0644606417 335 44.776119402985074 8728.797207345198 74000.0
83 1.0 5.0 2.0 0.1 3101154.4587047044 335 44.776119402985074 9257.177488670759 14800.0
84 1.0 5.0 2.0 0.5 3095130.963364221 335 44.776119402985074 9239.196905564839 14800.0
85 1.0 5.0 2.0 1.0 3087630.963364221 335 44.776119402985074 9216.808845863347 14800.0
86 1.0 5.0 5.0 0.1 3045954.4587047044 335 44.776119402985074 9092.401369267774 37000.0
87 1.0 5.0 5.0 0.5 3039914.4587047044 335 44.776119402985074 9074.371518521506 37000.0
88 1.0 5.0 5.0 1.0 3032364.4587047044 335 44.776119402985074 9051.83420508867 37000.0
89 1.0 5.0 10.0 0.1 2954551.9901967905 335 44.776119402985074 8819.558179691912 74000.0
90 1.0 5.0 10.0 0.5 2948431.9901967905 335 44.776119402985074 8801.289522975494 74000.0
91 1.0 5.0 10.0 1.0 2940781.9901967905 335 44.776119402985074 8778.453702079973 74000.0
92 2.0 1.0 2.0 0.1 0.0 0 0.0 0.0 0.0
93 2.0 1.0 2.0 0.5 0.0 0 0.0 0.0 0.0
94 2.0 1.0 2.0 1.0 0.0 0 0.0 0.0 0.0
95 2.0 1.0 5.0 0.1 0.0 0 0.0 0.0 0.0
96 2.0 1.0 5.0 0.5 0.0 0 0.0 0.0 0.0
97 2.0 1.0 5.0 1.0 0.0 0 0.0 0.0 0.0
98 2.0 1.0 10.0 0.1 0.0 0 0.0 0.0 0.0
99 2.0 1.0 10.0 0.5 0.0 0 0.0 0.0 0.0
100 2.0 1.0 10.0 1.0 0.0 0 0.0 0.0 0.0
101 2.0 2.0 2.0 0.1 1234607.5833340343 130 18.507462686567163 3685.395771146371 5800.0
102 2.0 2.0 2.0 0.5 1232127.5833340343 130 18.507462686567163 3677.9927860717444 5800.0
103 2.0 2.0 2.0 1.0 1229027.5833340343 130 18.507462686567163 3668.739054728461 5800.0
104 2.0 2.0 5.0 0.1 1214207.5833340343 130 18.507462686567163 3624.5002487583115 14500.0
105 2.0 2.0 5.0 0.5 1211727.5833340343 130 18.507462686567163 3617.0972636836846 14500.0
106 2.0 2.0 5.0 1.0 1208627.5833340343 130 18.507462686567163 3607.843532340401 14500.0
107 2.0 2.0 10.0 0.1 1180207.5833340343 130 18.507462686567163 3523.0077114448786 29000.0
108 2.0 2.0 10.0 0.5 1177727.5833340343 130 18.507462686567163 3515.6047263702517 29000.0
109 2.0 2.0 10.0 1.0 1174627.5833340343 130 18.507462686567163 3506.350995026968 29000.0
110 2.0 3.0 2.0 0.1 3068522.72629009 335 44.776119402985074 9159.769332209224 14800.0
111 2.0 3.0 2.0 0.5 3062522.72629009 335 44.776119402985074 9141.85888444803 14800.0
112 2.0 3.0 2.0 1.0 3055022.72629009 335 44.776119402985074 9119.470824746537 14800.0
113 2.0 3.0 5.0 0.1 3013118.457813414 335 44.776119402985074 8994.383456159445 37000.0
114 2.0 3.0 5.0 0.5 3007078.457813414 335 44.776119402985074 8976.353605413176 37000.0
115 2.0 3.0 5.0 1.0 2999528.457813414 335 44.776119402985074 8953.81629198034 37000.0
116 2.0 3.0 10.0 0.1 2921299.887645775 335 44.776119402985074 8720.29817207694 74000.0
117 2.0 3.0 10.0 0.5 2915219.887645775 335 44.776119402985074 8702.148918345598 74000.0
118 2.0 3.0 10.0 1.0 2907619.887645775 335 44.776119402985074 8679.462351181417 74000.0
119 2.0 4.0 2.0 0.1 3084826.8448271556 335 44.776119402985074 9208.43834276763 14800.0
120 2.0 4.0 2.0 0.5 3078826.8448271556 335 44.776119402985074 9190.527895006435 14800.0
121 2.0 4.0 2.0 1.0 3071326.8448271556 335 44.776119402985074 9168.139835304943 14800.0
122 2.0 4.0 5.0 0.1 3029536.458259059 335 44.776119402985074 9043.392412713609 37000.0
123 2.0 4.0 5.0 0.5 3023496.458259059 335 44.776119402985074 9025.36256196734 37000.0
124 2.0 4.0 5.0 1.0 3015946.458259059 335 44.776119402985074 9002.825248534506 37000.0
125 2.0 4.0 10.0 0.1 2937917.0644606417 335 44.776119402985074 8769.90168495714 74000.0
126 2.0 4.0 10.0 0.5 2931797.0644606417 335 44.776119402985074 8751.633028240722 74000.0
127 2.0 4.0 10.0 1.0 2924147.0644606417 335 44.776119402985074 8728.797207345198 74000.0
128 2.0 5.0 2.0 0.1 3101154.4587047044 335 44.776119402985074 9257.177488670759 14800.0
129 2.0 5.0 2.0 0.5 3095130.963364221 335 44.776119402985074 9239.196905564839 14800.0
130 2.0 5.0 2.0 1.0 3087630.963364221 335 44.776119402985074 9216.808845863347 14800.0
131 2.0 5.0 5.0 0.1 3045954.4587047044 335 44.776119402985074 9092.401369267774 37000.0
132 2.0 5.0 5.0 0.5 3039914.4587047044 335 44.776119402985074 9074.371518521506 37000.0
133 2.0 5.0 5.0 1.0 3032364.4587047044 335 44.776119402985074 9051.83420508867 37000.0
134 2.0 5.0 10.0 0.1 2954551.9901967905 335 44.776119402985074 8819.558179691912 74000.0
135 2.0 5.0 10.0 0.5 2948431.9901967905 335 44.776119402985074 8801.289522975494 74000.0
136 2.0 5.0 10.0 1.0 2940781.9901967905 335 44.776119402985074 8778.453702079973 74000.0
137 3.0 1.0 2.0 0.1 0.0 0 0.0 0.0 0.0
138 3.0 1.0 2.0 0.5 0.0 0 0.0 0.0 0.0
139 3.0 1.0 2.0 1.0 0.0 0 0.0 0.0 0.0
140 3.0 1.0 5.0 0.1 0.0 0 0.0 0.0 0.0
141 3.0 1.0 5.0 0.5 0.0 0 0.0 0.0 0.0
142 3.0 1.0 5.0 1.0 0.0 0 0.0 0.0 0.0
143 3.0 1.0 10.0 0.1 0.0 0 0.0 0.0 0.0
144 3.0 1.0 10.0 0.5 0.0 0 0.0 0.0 0.0
145 3.0 1.0 10.0 1.0 0.0 0 0.0 0.0 0.0
146 3.0 2.0 2.0 0.1 0.0 0 0.0 0.0 0.0
147 3.0 2.0 2.0 0.5 0.0 0 0.0 0.0 0.0
148 3.0 2.0 2.0 1.0 0.0 0 0.0 0.0 0.0
149 3.0 2.0 5.0 0.1 0.0 0 0.0 0.0 0.0
150 3.0 2.0 5.0 0.5 0.0 0 0.0 0.0 0.0
151 3.0 2.0 5.0 1.0 0.0 0 0.0 0.0 0.0
152 3.0 2.0 10.0 0.1 0.0 0 0.0 0.0 0.0
153 3.0 2.0 10.0 0.5 0.0 0 0.0 0.0 0.0
154 3.0 2.0 10.0 1.0 0.0 0 0.0 0.0 0.0
155 3.0 3.0 2.0 0.1 1136323.1076457775 116 16.119402985074625 3392.0092765545596 5000.0
156 3.0 3.0 2.0 0.5 1134163.1076457775 116 16.119402985074625 3385.56151536053 5000.0
157 3.0 3.0 2.0 1.0 1131463.1076457775 116 16.119402985074625 3377.5018138679925 5000.0
158 3.0 3.0 5.0 0.1 1117723.1076457775 116 16.119402985074625 3336.4868884948582 12500.0
159 3.0 3.0 5.0 0.5 1115563.1076457775 116 16.119402985074625 3330.0391273008286 12500.0
160 3.0 3.0 5.0 1.0 1112863.1076457775 116 16.119402985074625 3321.979425808291 12500.0
161 3.0 3.0 10.0 0.1 1086723.1076457775 116 16.119402985074625 3243.9495750620226 25000.0
162 3.0 3.0 10.0 0.5 1084563.1076457775 116 16.119402985074625 3237.5018138679925 25000.0
163 3.0 3.0 10.0 1.0 1081863.1076457775 116 16.119402985074625 3229.4421123754555 25000.0
164 3.0 4.0 2.0 0.1 3084826.8448271556 335 44.776119402985074 9208.43834276763 14800.0
165 3.0 4.0 2.0 0.5 3078826.8448271556 335 44.776119402985074 9190.527895006435 14800.0
166 3.0 4.0 2.0 1.0 3071326.8448271556 335 44.776119402985074 9168.139835304943 14800.0
167 3.0 4.0 5.0 0.1 3029536.458259059 335 44.776119402985074 9043.392412713609 37000.0
168 3.0 4.0 5.0 0.5 3023496.458259059 335 44.776119402985074 9025.36256196734 37000.0
169 3.0 4.0 5.0 1.0 3015946.458259059 335 44.776119402985074 9002.825248534506 37000.0
170 3.0 4.0 10.0 0.1 2937917.0644606417 335 44.776119402985074 8769.90168495714 74000.0
171 3.0 4.0 10.0 0.5 2931797.0644606417 335 44.776119402985074 8751.633028240722 74000.0
172 3.0 4.0 10.0 1.0 2924147.0644606417 335 44.776119402985074 8728.797207345198 74000.0
173 3.0 5.0 2.0 0.1 3101154.4587047044 335 44.776119402985074 9257.177488670759 14800.0
174 3.0 5.0 2.0 0.5 3095130.963364221 335 44.776119402985074 9239.196905564839 14800.0
175 3.0 5.0 2.0 1.0 3087630.963364221 335 44.776119402985074 9216.808845863347 14800.0
176 3.0 5.0 5.0 0.1 3045954.4587047044 335 44.776119402985074 9092.401369267774 37000.0
177 3.0 5.0 5.0 0.5 3039914.4587047044 335 44.776119402985074 9074.371518521506 37000.0
178 3.0 5.0 5.0 1.0 3032364.4587047044 335 44.776119402985074 9051.83420508867 37000.0
179 3.0 5.0 10.0 0.1 2954551.9901967905 335 44.776119402985074 8819.558179691912 74000.0
180 3.0 5.0 10.0 0.5 2948431.9901967905 335 44.776119402985074 8801.289522975494 74000.0
181 3.0 5.0 10.0 1.0 2940781.9901967905 335 44.776119402985074 8778.453702079973 74000.0
182 4.0 1.0 2.0 0.1 0.0 0 0.0 0.0 0.0
183 4.0 1.0 2.0 0.5 0.0 0 0.0 0.0 0.0
184 4.0 1.0 2.0 1.0 0.0 0 0.0 0.0 0.0
185 4.0 1.0 5.0 0.1 0.0 0 0.0 0.0 0.0
186 4.0 1.0 5.0 0.5 0.0 0 0.0 0.0 0.0
187 4.0 1.0 5.0 1.0 0.0 0 0.0 0.0 0.0
188 4.0 1.0 10.0 0.1 0.0 0 0.0 0.0 0.0
189 4.0 1.0 10.0 0.5 0.0 0 0.0 0.0 0.0
190 4.0 1.0 10.0 1.0 0.0 0 0.0 0.0 0.0
191 4.0 2.0 2.0 0.1 0.0 0 0.0 0.0 0.0
192 4.0 2.0 2.0 0.5 0.0 0 0.0 0.0 0.0
193 4.0 2.0 2.0 1.0 0.0 0 0.0 0.0 0.0
194 4.0 2.0 5.0 0.1 0.0 0 0.0 0.0 0.0
195 4.0 2.0 5.0 0.5 0.0 0 0.0 0.0 0.0
196 4.0 2.0 5.0 1.0 0.0 0 0.0 0.0 0.0
197 4.0 2.0 10.0 0.1 0.0 0 0.0 0.0 0.0
198 4.0 2.0 10.0 0.5 0.0 0 0.0 0.0 0.0
199 4.0 2.0 10.0 1.0 0.0 0 0.0 0.0 0.0
200 4.0 3.0 2.0 0.1 0.0 0 0.0 0.0 0.0
201 4.0 3.0 2.0 0.5 0.0 0 0.0 0.0 0.0
202 4.0 3.0 2.0 1.0 0.0 0 0.0 0.0 0.0
203 4.0 3.0 5.0 0.1 0.0 0 0.0 0.0 0.0
204 4.0 3.0 5.0 0.5 0.0 0 0.0 0.0 0.0
205 4.0 3.0 5.0 1.0 0.0 0 0.0 0.0 0.0
206 4.0 3.0 10.0 0.1 0.0 0 0.0 0.0 0.0
207 4.0 3.0 10.0 0.5 0.0 0 0.0 0.0 0.0
208 4.0 3.0 10.0 1.0 0.0 0 0.0 0.0 0.0
209 4.0 4.0 2.0 0.1 744222.7130903826 90 11.343283582089553 2221.5603375832316 6948.339329446317
210 4.0 4.0 2.0 0.5 742702.7130903827 90 11.343283582089553 2217.0230241503964 6988.339329446317
211 4.0 4.0 2.0 1.0 740802.7130903827 90 11.343283582089553 2211.3513823593516 7038.339329446317
212 4.0 4.0 5.0 0.1 728622.7130903827 90 11.343283582089553 2174.9931734041274 17748.339329446317
213 4.0 4.0 5.0 0.5 727102.7130903827 90 11.343283582089553 2170.455859971292 17788.339329446317
214 4.0 4.0 5.0 1.0 725202.7130903827 90 11.343283582089553 2164.784218180247 17838.339329446317
215 4.0 4.0 10.0 0.1 702713.3203873425 90 11.343283582089553 2097.6517026487836 35748.33932944632
216 4.0 4.0 10.0 0.5 701153.3203873425 90 11.343283582089553 2092.994986230873 35788.33932944632
217 4.0 4.0 10.0 1.0 699203.3203873425 90 11.343283582089553 2087.174090708485 35838.33932944632
218 4.0 5.0 2.0 0.1 3101154.4587047044 335 44.776119402985074 9257.177488670759 14800.0
219 4.0 5.0 2.0 0.5 3095130.963364221 335 44.776119402985074 9239.196905564839 14800.0
220 4.0 5.0 2.0 1.0 3087630.963364221 335 44.776119402985074 9216.808845863347 14800.0
221 4.0 5.0 5.0 0.1 3045954.4587047044 335 44.776119402985074 9092.401369267774 37000.0
222 4.0 5.0 5.0 0.5 3039914.4587047044 335 44.776119402985074 9074.371518521506 37000.0
223 4.0 5.0 5.0 1.0 3032364.4587047044 335 44.776119402985074 9051.83420508867 37000.0
224 4.0 5.0 10.0 0.1 2954551.9901967905 335 44.776119402985074 8819.558179691912 74000.0
225 4.0 5.0 10.0 0.5 2948431.9901967905 335 44.776119402985074 8801.289522975494 74000.0
226 4.0 5.0 10.0 1.0 2940781.9901967905 335 44.776119402985074 8778.453702079973 74000.0
+37
View File
@@ -0,0 +1,37 @@
threshold_bps,stop_loss_bps,spread_bps,total_pnl,num_trades,win_rate,avg_pnl,max_drawdown
0.5,2.0,0.1,5153890.000000001,335,57.611940298507456,15384.74626865672,18295.0
0.5,2.0,0.5,5146160.000000002,335,57.611940298507456,15361.67164179105,18335.0
0.5,2.0,1.0,5136510.000000002,335,57.611940298507456,15332.865671641797,18385.0
0.5,5.0,0.1,5111590.000000001,335,57.611940298507456,15258.477611940301,46495.0
0.5,5.0,0.5,5103830.000000001,335,57.611940298507456,15235.313432835823,46535.0
0.5,5.0,1.0,5094130.000000001,335,57.611940298507456,15206.358208955227,46585.0
0.5,10.0,0.1,5042665.0,335,57.611940298507456,15052.731343283582,92680.00000000047
0.5,10.0,0.5,5034665.0,335,57.611940298507456,15028.850746268658,92840.00000000047
0.5,10.0,1.0,5024730.000000001,335,57.611940298507456,14999.194029850749,93025.00000000023
1.0,2.0,0.1,5153890.000000001,335,57.611940298507456,15384.74626865672,18295.0
1.0,2.0,0.5,5146160.000000002,335,57.611940298507456,15361.67164179105,18335.0
1.0,2.0,1.0,5136510.000000002,335,57.611940298507456,15332.865671641797,18385.0
1.0,5.0,0.1,5111590.000000001,335,57.611940298507456,15258.477611940301,46495.0
1.0,5.0,0.5,5103830.000000001,335,57.611940298507456,15235.313432835823,46535.0
1.0,5.0,1.0,5094130.000000001,335,57.611940298507456,15206.358208955227,46585.0
1.0,10.0,0.1,5042665.0,335,57.611940298507456,15052.731343283582,92680.00000000047
1.0,10.0,0.5,5034665.0,335,57.611940298507456,15028.850746268658,92840.00000000047
1.0,10.0,1.0,5024730.000000001,335,57.611940298507456,14999.194029850749,93025.00000000023
2.0,2.0,0.1,5153890.000000001,335,57.611940298507456,15384.74626865672,18295.0
2.0,2.0,0.5,5146160.000000002,335,57.611940298507456,15361.67164179105,18335.0
2.0,2.0,1.0,5136510.000000002,335,57.611940298507456,15332.865671641797,18385.0
2.0,5.0,0.1,5111590.000000001,335,57.611940298507456,15258.477611940301,46495.0
2.0,5.0,0.5,5103830.000000001,335,57.611940298507456,15235.313432835823,46535.0
2.0,5.0,1.0,5094130.000000001,335,57.611940298507456,15206.358208955227,46585.0
2.0,10.0,0.1,5042665.0,335,57.611940298507456,15052.731343283582,92680.00000000047
2.0,10.0,0.5,5034665.0,335,57.611940298507456,15028.850746268658,92840.00000000047
2.0,10.0,1.0,5024730.000000001,335,57.611940298507456,14999.194029850749,93025.00000000023
3.0,2.0,0.1,5153890.000000001,335,57.611940298507456,15384.74626865672,18295.0
3.0,2.0,0.5,5146160.000000002,335,57.611940298507456,15361.67164179105,18335.0
3.0,2.0,1.0,5136510.000000002,335,57.611940298507456,15332.865671641797,18385.0
3.0,5.0,0.1,5111590.000000001,335,57.611940298507456,15258.477611940301,46495.0
3.0,5.0,0.5,5103830.000000001,335,57.611940298507456,15235.313432835823,46535.0
3.0,5.0,1.0,5094130.000000001,335,57.611940298507456,15206.358208955227,46585.0
3.0,10.0,0.1,5042665.0,335,57.611940298507456,15052.731343283582,92680.00000000047
3.0,10.0,0.5,5034665.0,335,57.611940298507456,15028.850746268658,92840.00000000047
3.0,10.0,1.0,5024730.000000001,335,57.611940298507456,14999.194029850749,93025.00000000023
1 threshold_bps stop_loss_bps spread_bps total_pnl num_trades win_rate avg_pnl max_drawdown
2 0.5 2.0 0.1 5153890.000000001 335 57.611940298507456 15384.74626865672 18295.0
3 0.5 2.0 0.5 5146160.000000002 335 57.611940298507456 15361.67164179105 18335.0
4 0.5 2.0 1.0 5136510.000000002 335 57.611940298507456 15332.865671641797 18385.0
5 0.5 5.0 0.1 5111590.000000001 335 57.611940298507456 15258.477611940301 46495.0
6 0.5 5.0 0.5 5103830.000000001 335 57.611940298507456 15235.313432835823 46535.0
7 0.5 5.0 1.0 5094130.000000001 335 57.611940298507456 15206.358208955227 46585.0
8 0.5 10.0 0.1 5042665.0 335 57.611940298507456 15052.731343283582 92680.00000000047
9 0.5 10.0 0.5 5034665.0 335 57.611940298507456 15028.850746268658 92840.00000000047
10 0.5 10.0 1.0 5024730.000000001 335 57.611940298507456 14999.194029850749 93025.00000000023
11 1.0 2.0 0.1 5153890.000000001 335 57.611940298507456 15384.74626865672 18295.0
12 1.0 2.0 0.5 5146160.000000002 335 57.611940298507456 15361.67164179105 18335.0
13 1.0 2.0 1.0 5136510.000000002 335 57.611940298507456 15332.865671641797 18385.0
14 1.0 5.0 0.1 5111590.000000001 335 57.611940298507456 15258.477611940301 46495.0
15 1.0 5.0 0.5 5103830.000000001 335 57.611940298507456 15235.313432835823 46535.0
16 1.0 5.0 1.0 5094130.000000001 335 57.611940298507456 15206.358208955227 46585.0
17 1.0 10.0 0.1 5042665.0 335 57.611940298507456 15052.731343283582 92680.00000000047
18 1.0 10.0 0.5 5034665.0 335 57.611940298507456 15028.850746268658 92840.00000000047
19 1.0 10.0 1.0 5024730.000000001 335 57.611940298507456 14999.194029850749 93025.00000000023
20 2.0 2.0 0.1 5153890.000000001 335 57.611940298507456 15384.74626865672 18295.0
21 2.0 2.0 0.5 5146160.000000002 335 57.611940298507456 15361.67164179105 18335.0
22 2.0 2.0 1.0 5136510.000000002 335 57.611940298507456 15332.865671641797 18385.0
23 2.0 5.0 0.1 5111590.000000001 335 57.611940298507456 15258.477611940301 46495.0
24 2.0 5.0 0.5 5103830.000000001 335 57.611940298507456 15235.313432835823 46535.0
25 2.0 5.0 1.0 5094130.000000001 335 57.611940298507456 15206.358208955227 46585.0
26 2.0 10.0 0.1 5042665.0 335 57.611940298507456 15052.731343283582 92680.00000000047
27 2.0 10.0 0.5 5034665.0 335 57.611940298507456 15028.850746268658 92840.00000000047
28 2.0 10.0 1.0 5024730.000000001 335 57.611940298507456 14999.194029850749 93025.00000000023
29 3.0 2.0 0.1 5153890.000000001 335 57.611940298507456 15384.74626865672 18295.0
30 3.0 2.0 0.5 5146160.000000002 335 57.611940298507456 15361.67164179105 18335.0
31 3.0 2.0 1.0 5136510.000000002 335 57.611940298507456 15332.865671641797 18385.0
32 3.0 5.0 0.1 5111590.000000001 335 57.611940298507456 15258.477611940301 46495.0
33 3.0 5.0 0.5 5103830.000000001 335 57.611940298507456 15235.313432835823 46535.0
34 3.0 5.0 1.0 5094130.000000001 335 57.611940298507456 15206.358208955227 46585.0
35 3.0 10.0 0.1 5042665.0 335 57.611940298507456 15052.731343283582 92680.00000000047
36 3.0 10.0 0.5 5034665.0 335 57.611940298507456 15028.850746268658 92840.00000000047
37 3.0 10.0 1.0 5024730.000000001 335 57.611940298507456 14999.194029850749 93025.00000000023
+114
View File
@@ -0,0 +1,114 @@
import os
import itertools
import pandas as pd
import matplotlib.pyplot as plt
import requests
from dateutil import parser
from oandapyV20 import API
from oandapyV20.endpoints.instruments import InstrumentsCandles
from cip import theoretical_forward, deviation_bps
# === Configuration ===
OANDA_TOKEN = os.getenv("OANDA_TOKEN")
OANDA_ACCOUNT_ID = os.getenv("OANDA_ACCOUNT_ID")
BASE_URL_SWAP = "https://api-fxpractice.oanda.com" # practice swap endpoint
if not OANDA_TOKEN or not OANDA_ACCOUNT_ID:
raise RuntimeError("Please set OANDA_TOKEN and OANDA_ACCOUNT_ID environment variables")
# Initialize OANDA API client for spot
api = API(access_token=OANDA_TOKEN, environment="practice")
# === Data fetching ===
def fetch_spot_history(pair: str, days: int = 365) -> pd.Series:
req = InstrumentsCandles(
instrument=pair,
params={"granularity": "D", "count": days, "price": "M"}
)
data = api.request(req)["candles"]
records = [(parser.isoparse(c["time"]).date(), (float(c["mid"]["o"]) + float(c["mid"]["c"]))/2)
for c in data]
return pd.Series({d: s for d, s in records}).sort_index()
def fetch_swap_history(pair: str, days: int = 365) -> pd.Series:
url = f"{BASE_URL_SWAP}/v3/accounts/{OANDA_ACCOUNT_ID}/instruments/{pair}/swap_rates"
headers = {"Authorization": f"Bearer {OANDA_TOKEN}"}
params = {"count": days, "granularity": "D"}
try:
resp = requests.get(url, headers=headers, params=params)
resp.raise_for_status()
data = resp.json().get("swapRates", [])
records = []
for r in data:
dt = parser.isoparse(r["time"]).date()
lr = float(r.get("longRate", 0))
sr = float(r.get("shortRate", 0))
records.append((dt, lr - sr))
return pd.Series({d: p for d, p in records}).sort_index()
except Exception:
# fallback zeros
spot = fetch_spot_history(pair, days)
return pd.Series(0.0, index=spot.index)
# === Backtest using real forward ===
def run_backtest(
spot: pd.Series,
swap_pts: pd.Series,
threshold_bps: float,
stop_loss_bps: float,
spread_bps: float,
tenor_days: int = 30,
r_dom: float = 0.025,
r_for: float = 0.005,
notional: float = 1_000_000
) -> dict:
df = pd.DataFrame({"spot": spot})
df["swap_pts"] = swap_pts.reindex(df.index).fillna(method="ffill")
df["theo_fwd"] = df["spot"].apply(lambda s: theoretical_forward(s, r_dom, r_for, tenor_days))
df["obs_fwd"] = df["spot"] + df["swap_pts"] * tenor_days / 360
df["dev_bps"] = (df["obs_fwd"] - df["theo_fwd"]) / df["theo_fwd"] * 10_000
df["signal"] = 0
df.loc[df["dev_bps"] > threshold_bps, "signal"] = -1
df.loc[df["dev_bps"] < -threshold_bps, "signal"] = +1
cost = spread_bps / 10_000 * notional
df["exit_spot"] = df["spot"].shift(-tenor_days)
df["raw_pnl"] = df["signal"] * (df["exit_spot"] - df["obs_fwd"]) * notional
df["pnl"] = df["raw_pnl"] - df["signal"].abs() * cost
stop_amt = stop_loss_bps / 10_000 * notional
df.loc[df["pnl"] < -stop_amt, "pnl"] = -stop_amt
trades = df.dropna(subset=["pnl"])
total_pnl = trades["pnl"].sum()
num_trades = (trades["signal"] != 0).sum()
win_rate = trades["pnl"].gt(0).mean() * 100 if num_trades else 0
avg_pnl = trades["pnl"].mean() if num_trades else 0
equity = trades["pnl"].cumsum()
max_dd = (equity.cummax() - equity).max() if not equity.empty else 0
return {"total_pnl": total_pnl,
"num_trades": num_trades,
"win_rate": win_rate,
"avg_pnl": avg_pnl,
"max_drawdown": max_dd}
# === Optimization sweep ===
if __name__ == "__main__":
pair = "EUR_USD"
spot = fetch_spot_history(pair, days=365)
swap_pts= fetch_swap_history(pair, days=365)
thresholds = [0.5, 1.0, 2.0, 3.0]
stop_losses = [2.0, 5.0, 10.0]
spreads = [0.1, 0.5, 1.0]
tenor_days = 30
results = []
for th, sl, sp in itertools.product(thresholds, stop_losses, spreads):
m = run_backtest(spot, swap_pts, th, sl, sp, tenor_days)
results.append({"threshold_bps": th,
"stop_loss_bps": sl,
"spread_bps": sp,
**m})
df = pd.DataFrame(results)
df.to_csv("optimization_results_real.csv", index=False)
top = df.sort_values("total_pnl", ascending=False).head(10)
print("Top 10 real-forward parameter sets:")
print(top.to_string(index=False))
+3
View File
@@ -0,0 +1,3 @@
home = /Library/Developer/CommandLineTools/usr/bin
include-system-site-packages = false
version = 3.9.6
+6
View File
@@ -0,0 +1,6 @@
certifi==2025.7.14
charset-normalizer==3.4.2
idna==3.10
oandapyV20==0.7.2
requests==2.32.4
urllib3==2.5.0
+32
View File
@@ -0,0 +1,32 @@
def pnl_path(spot_series, obs_forward, notional=1_000_000):
"""
Given a time series of spot prices (list of floats) and a
locked-in forward price (obs_forward), returns a list of
PnL values under a +1 lot trade.
PnL_t = notional * (spot_t - obs_forward)
"""
return [notional * (s - obs_forward) for s in spot_series]
import random
# e.g. 10 days of spot returns ±0.5%
base = 1.16987
path = []
for _ in range(10):
shock = random.uniform(-0.005, 0.005)
base = base * (1 + shock)
path.append(round(base, 6))
from risk import pnl_path
# assume obs_forward from your engine, e.g. 1.17105
obs_forward = 1.17105
pnls = pnl_path(path, obs_forward)
print("Day-by-day PnL:", pnls)
import numpy as np
# compute daily PnL changes
diffs = np.diff(pnls)
# find the 5th percentile loss
var95 = -np.percentile(diffs, 5)
print(f"1-day 95% VaR: ${var95:,.2f}")
+33
View File
@@ -0,0 +1,33 @@
# simulate_forward.py
import random
from cip import theoretical_forward, deviation_bps
# === Simulation parameters ===
spot_mid = 1.16987 # last known spot mid
r_domestic = 0.025 # e.g. USD OIS annual rate
r_foreign = 0.005 # e.g. EUR OIS annual rate
days = 30 # tenor in days for 1M
threshold_bps = 2.0 # alert threshold in bps
# 1) Compute the “fair” 1M forward via CIP
theo_fwd = theoretical_forward(spot_mid, r_domestic, r_foreign, days)
print(f"Theoretical 1M forward: {theo_fwd:.6f}\n")
# 2) Run 10 simulated “observed” forwards with noise ±5 bps
for i in range(1, 11):
noise_bps = random.uniform(-5, 5)
obs_fwd = theo_fwd * (1 + noise_bps / 10_000)
dev = deviation_bps(obs_fwd, theo_fwd)
# 3) Determine if it breaches your threshold
signal = ""
if abs(dev) > threshold_bps:
direction = "Sell forward / Buy spot" if dev > 0 else "Buy forward / Sell spot"
signal = f" ⚠️ ARB SIGNAL: {dev:.2f} bps → {direction}"
# 4) Print the result for this trial
print(
f"Sim #{i:2d}: noise={noise_bps:+.2f} bps → "
f"observed={obs_fwd:.6f} → dev={dev:+.2f} bps{signal}"
)