Skip to content
No description, website, or topics provided.
CSS
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
image
README.org
worg.css

README.org

Introduction

GradientFlows is an advanced real time trading system on top of InteractiveBrokders. It enhances many functions of IB terminal and provide additional features to facilitate various type of tradings(algorithm trading, scalping, etc). It was originally developed in an attempt to research and deploy quantitative trading strategies. Currently, I use it mainly for facilitating day trading, i.e. reading price actions. Below is a non-exhaustive list of the features:

  • Price action trading
    • a simplistic approach for price action trading. It only includes necessary indicators and information for success trading
    • lines(trend, support/resistence, etc) can be draw at high precision
    • orders(bracket, limit, stop, etc) can be placed with one click to reduce latency
    • charts can be saved for later study
    • an easy and powerful window management system
  • Advanced option analytics
    • view all the available contracts in a matrix form, i.e. for each symbol, each row corresponds to one expiry and each column corresponds to one strike/moneyness.
    • calculate in real time various greeks, including delta, gamma, theta, and vega.
    • calculate in real time the implied volatility.
    • submit orders of popular option strategies with one click. For example, covered call, bull/bear spread, calendar spread, strangle, straddle, butterfly spread
    • calculate historical volatilities of contracts using different methods, including close to close, Parkinson, GarmanKlauss, RogersSatchell, YangZhang
  • Algorithmic trading
    • load and execute list of trades from csv files. These trades may be generated from algorithmic trading signals
    • execute statistical arbitrage or pairs trading strategies automatically by providing the pairs and other parameters
    • other trading strategies such as gamma scalping, rule based futures scalping.

Screenshots

Price Action on Forex    Four trades in one screen


Market Watch    Option Trading


Option Historical Vol    Screen Setup


Structure of the Code

There are two main components in the code, MathLab and Terminal. Mathlab started when I was a quant at an Investment Bank. It includes

  • MathLab. This is a fully functional option pricing library. It has common utilities that can be found in mature IB quant library, such as linear algebra, integration, root finding, optimization and some option pricing functions. These functions were originally developed to benchmark production models.
  • TWS. This is the API from Interactive Brokers.
  • Trading. This folder includes trading utilities and trading strategies.

Matlab can be run independently without GUI.

Terminal is the GUI of GradientFlows. The GUI is developed using QT.

License

Due to QT licensing, I’m not able to provide the software without open sourcing the entire project, which is the direction I’m not going to take, at least for now. If you are interested in the project in any way, drop an email to gradientflows@icloud.com

Examples of Quantitative Strategies

Statistical arbitrage

StratArb finds two or a set of stocks or ETFs that are cointegrated. When the supposed mean reversion portfolio deviates from the historical mean, positions are open and otherwise closed.

The parameters are specified in json files. An example is

{
    "strategy":"statisticalArbitrage",
    "symbols":["DOD","AOA"],
    "nLookback":20,
    "entryScore":2,
    "exitScore":0.05,
    "nPosition":100,
    "initialization":1,
    "histDataPath":"DOD_AOA.csv"
}

Factor models

Factor models use machine learning algorithms, mostly regressions, to estimate equity returns and their covariances. Based on these estimations, optimal weights of the equities in the portfolio are calculated and the portfolio is submited for execution.

The portfolio is rebalanced weekly. The portfolio is constructed using MATLAB and then read into GradientFlows for execution. An example is

SymbolAVYCOLDGXDTEEDEQRKOMSFTNEEPPLRAIROPSWKSYKUTXVRSNXELXL
Quantity7972624756981828534138119274644686799197

Gamma Scalping

Gamma scalping establishes a long position in straddle and long or short position in the underlying. The stragegy shorts the underlying when it moves higher and longs the underlying when it moves lower. Profits are made from mean reversion. Below are the code used for real trading.

class StratGammaScalping : public Strategy
{
	std::string    m_symbol;                    //underlying symbol
	double         m_strike;                    //strike                
	Date           m_expiry;                    //expiry
	Contract       m_contract;                  //option contract of symbol
	Order          m_buyOrder;                  //buy order
	Order          m_sellOrder;                 //sell order
	int            m_currentTotalPosition;      //current total number of contracts
	StratOptionPtr m_stratOpt;                  //option trading module
	std::string    m_jsonFilename;              //strategy setting file
public:
	StratGammaScalping
	(
		const std::string& id,                                 //strategy id
		const std::string& filename,                           //strategy setting file
		OrderExecutionEnginePtr orderExecutionEngine,          //order execution engine
		MarketDataEnginePtr mktDataEngine,                     //market data engine
        StratOptionPtr m_stratOpt                              //option trading module
	)
	:Strategy(id, "StratGammaScalping", orderExecutionEngine, mktDataEngine), m_stratOpt(stratOpt), m_jsonFilename(filename)
	{
		
		CELLDictPtr dict = jsonFromFile(filename);
		m_symbol = dict->toString("symbol");
		m_strike = dict->toDouble("strike");
		m_expiry = str::toDate(dict->toString("expiry"),"");
		m_currentTotalPosition = dict->toDouble("currentTotalPosition");

		m_contract = TradingUtility::strToContract(m_symbol);

		m_buyOrder.action = "BUY";
		m_buyOrder.totalQuantity = 1;
		m_buyOrder.orderType = "MKT";
		m_buyOrder.lmtPrice = 0;

		m_sellOrder.action = "SELL";
		m_sellOrder.totalQuantity = 1;
		m_sellOrder.orderType = "MKT";
		m_sellOrder.lmtPrice = 0;


		m_stratOpt->reqMktData(m_strike, m_expiry);
	}

    //apply function will be called everytime market data updates. This function
    //is to determine if the updates concerns the symbol
	bool symbolInPortfolio(const std::string& symbol)
	{ 
		if (symbol == m_symbol)
			return true;
		return false; 
	};

	
    //calculate delta of the straddle
    double calcDelta()
	{
		double impliedVolCall, deltaCall, gammaCall, thetaCall, vegaCall;
		double impliedVolPut, deltaPut, gammaPut, thetaPut, vegaPut;

		m_stratOpt->calculate(m_strike, m_expiry, OptionStrategyType::CALL, impliedVolCall, deltaCall, gammaCall, thetaCall, vegaCall);
		m_stratOpt->calculate(m_strike, m_expiry, OptionStrategyType::PUT, impliedVolPut, deltaPut, gammaPut, thetaPut, vegaPut);

		double delta = deltaCall + deltaPut + m_currentTotalPosition / 100.0;
		return delta;
	}

    //hedge the straddle
	void deltaHedge()
	{
		double delta = calcDelta();
		if (delta > 0.2)
		{
			m_sellOrder.totalQuantity = (int)(delta * 100);
			m_currentTotalPosition -= m_sellOrder.totalQuantity;
			getOrderExecutionEngine()->addOrder(m_contract, m_sellOrder, "StratGammaScalping " + m_id);
			writeFile(m_currentTotalPosition);
		}
		else if (delta < -0.2)
		{
			m_buyOrder.totalQuantity = (int)(-delta * 100);
			m_currentTotalPosition += m_buyOrder.totalQuantity;
			getOrderExecutionEngine()->addOrder(m_contract, m_buyOrder, "StratGammaScalping " + m_id);
			writeFile(m_currentTotalPosition);
		}		
	}
    
    //display the status of the current position
	const std::string status() 
	{ 
		double delta = calcDelta();
		return str::fromNumber(delta); 
	}

    //save position to file at end of day
	void writeFile(int currentTotalPosition)
	{
		CELLDictPtr dict = jsonFromFile(m_jsonFilename);
		dict->set("currentTotalPosition", (double)currentTotalPosition);
		std::ofstream file(m_jsonFilename, 'w');
		if (file.is_open())
		{
			file << *dict;
			file.close();
		}
	}

    //the entry point. This function gets called every time market data updates
	void apply(const std::string& symbol) 
	{       
        if (isRunning() && symbolInPortfolio(symbol))
		{			
			utl::Log("StratGammaScalping::apply") << m_symbol << " deltaHedge Called\n";
			deltaHedge();
		}

	}

    //manually call delta hedge
	void applyOnce(const std::string& parameters) 
	{
		deltaHedge();
	}
};

The settings are read from json files. Below is an example

{
    "currentTotalPosition" : -65,
    "expiry" : "20170324",
    "strategy" : "gammaScalping",
    "strike" : 139,
    "symbol" : "AAPL"
}
You can’t perform that action at this time.