Hi! I’m still on travel - and won’t return to my desk till next week, but I just wanted to give a short demo on how you can use the different components of quantpylib to run, say, a formulaic alpha on live.
As promised, it will be incredibly easy. We make some imports, set up our keys:
import os
import pytz
import asyncio
from decimal import Decimal
from dotenv import load_dotenv
load_dotenv()
from datetime import datetime
import quantpylib.standards.markets as markets
from quantpylib.standards import Period
from quantpylib.gateway.master import Gateway
from quantpylib.datapoller.master import DataPoller
from quantpylib.simulator.gene import GeneticAlpha
exc = "hyperliquid"
config_keys = {
exc: {
"alias" : exc,
"address" : os.getenv("HYP_DEMO"),
"hyp_key" : os.getenv("HYP_KEY"),
}
}
datapoller = DataPoller(config_keys=config_keys)
gateway = Gateway(config_keys=config_keys)
interval = Period.DAILY
if __name__ == "__main__":
asyncio.run(main())
Now let’s write the main method - we retrieve our capital, get the contracts available. and get OHLCV:
async def main():
capital = (await gateway.account.account_balance(exc=exc))[markets.ACCOUNT_EQUITY]
contracts = await gateway.exchange.contract_specifications(exc=exc)
tickers = list(contracts.keys())[:20]
period_start = datetime(2016,1,1, tzinfo=pytz.utc)
period_end = datetime.now(pytz.utc)
ticker_dfs = [datapoller.crypto.get_trade_bars(
ticker=ticker,
start=period_start,
end=period_end,
granularity=interval,
kline_close=True,
src=exc
) for ticker in tickers]
dfs = {ticker:df for ticker,df in zip(tickers,ticker_dfs)}
As usual, we set up our genetic alpha, write the fee parameters, inertia, volatility target and so on…then we run the backtest on say, the bollinger score momentum:
strat_configs = {
"dfs":dfs,
"granularity":interval,
"instruments":tickers,
"execrates": [0.0005] * len(tickers),
"longswps": [0.1] * len(tickers),
"shortswps": [-0.1] * len(tickers),
"weekend_trading":True,
"positional_inertia": 0.1
}
alpha = GeneticAlpha(genome="tszscre_12(close)",portfolio_vol=0.25,**strat_configs)
df = await alpha.run_simulation()
Last but not least we obtain held positions from the gateway, and compute the contracts difference between target and held - then we use the gateway to submit orders:
held = await gateway.positions.positions_get(exc=exc)
take = alpha.get_positions_for_capital(capital=capital,held={k:v[markets.AMOUNT] for k,v in held.items()})
trade = {inst : Decimal(str(take[inst])) - (Decimal('0') if inst not in held else held[inst][markets.AMOUNT]) for inst in tickers}
trade = {inst : round(amount,int(contracts[inst][markets.SYMBOL_QUANTITY_PRECISION])) for inst,amount in trade.items()}
for inst,amount in trade.items():
res = await gateway.executor.market_order(exc=exc,ticker=inst,amount=amount)
And just by changing the formulaic string - you can just about run about any trading strategy encoded formulaically….
Say you want to run this every day, on a new candle, we can schedule it on cron:
TZ=UTC
1 0 * * * python3 /path/alpha.py
This runs it at 00:00:01 UTC every day. Get access to quantpylib here:
Will be back next week to superboost quantpylib again…so get ready!
Absolutely love this!