Loading ...

选择性套利

Author: 风云, Date: 2019-01-12 13:02:13
Tags: C++ Hedge


//常量值
const int MARGIN = 10;
const string DIRECTION = "buy";
const int  THRESHOLD = -1;
const double POSITION = 100;//下单量
const double SELL_AT = 47;
const double PROFIT = 0.062 / MARGIN; //卖一半的盈利比
enum operation {
	open_buy, open_sell,  nothing
};
class Test_BM {
private:
	//账户数量
	double amount;
	//进行的操作
	operation op;
	//购买时的价格和当前的价格
	double current_price;
	double buy_price;
	//表示交点
	int cross_plus_minus;
	int cross_adx_plus;
	int cross_adx_minus;
	//表示当前的DI值
	double plus_di_now;
	double minus_di_now;
	double adx_now;
	double sub_di;//DI间差值
	//对过去的一次记录
	double plus_di_last;
	double minus_di_last;
	double adx_last;
	//私有操作
	void tick();
	int plus_order(string direction);
	int minus_order(string direction);

public:
	Test_BM();
	double get_amount()
	{
		return amount;
	}
	void bm_00() {
		//仅测试函数的正确性
		tick();
		plus_order("buy");
		Sleep(6000);
	}
	void bm_01();//套利策略

};
Test_BM::Test_BM() {
	amount = 0;
	op = nothing;
	current_price = -1;
	buy_price = -1;
	cross_plus_minus = -1;
	cross_adx_plus = -1;
	cross_adx_minus = -1;
	plus_di_now = -1;
	minus_di_now = -1;
	adx_now = -1;
}
void Test_BM::tick()
{   //获取大部分数值,用于策略
	auto ticker = _C(exchange.GetTicker);       //获取当前市场行情,_C容错处理
//    auto records = exchange.GetRecords(); //获取K线数据
	auto records = exchange.GetRecords();
//Log(records);
	auto plus_di = talib.PLUS_DI(records);  //C++11  auto自动推断类型
	auto minus_di = talib.MINUS_DI(records);
	auto adx = talib.ADX(records, 14);
	cross_plus_minus = _Cross(plus_di, minus_di);
	cross_adx_minus = _Cross(adx, minus_di);
	cross_adx_plus = _Cross(adx, plus_di);
	plus_di_now = plus_di[plus_di.size() - 1];
	minus_di_now = minus_di[minus_di.size() - 1];
	adx_now = adx[adx.size() - 1];
	sub_di = plus_di_now - minus_di_now;
	current_price = ticker.Last;   //最新价格
}
int Test_BM::plus_order(string direction)
{
	double price = current_price;
	int rv = 0;
	if (direction == "buy") {
		//操作多单时增加AMOUNT
		exchange.SetDirection("buy"); //买入开多
		auto  orderId = exchange.Buy(price, POSITION);
		if (orderId.Valid)rv = 1;
	}
	else if (direction == "sell") {
		//操作空单时增加AMOUNT
		exchange.SetDirection("sell");  //卖出开空 
		auto  orderId = exchange.Sell(price, POSITION);
		if (orderId.Valid)rv = 1;
	}
	return rv;
}
int Test_BM::minus_order(string direction)
{
	double price = current_price;
	int rv = 0;
	if (direction == "buy") {
		exchange.SetDirection("closebuy"); //卖出平多 多单减少
		auto orderId = exchange.Sell(price, get_amount());
		if (orderId.Valid)rv = 1;
	}
	else if (direction == "sell") {
		exchange.SetDirection("closesell"); //卖出Sell  开多‘sell’ 买入平空
		auto orderId = exchange.Buy(price, get_amount());
		if (orderId.Valid)rv = 1;
	}
	return rv;
}

void Test_BM::bm_01() {
	while (true) {
		//op =nothing ,采取做多或做空,测试是否有交点存在
		tick();
		if (op == nothing) {
			if (cross_plus_minus == 1 && plus_di_now < SELL_AT && sub_di<=0.618 ) {
				if (plus_order("buy") == 0) break;
				else {
					plus_di_last = plus_di_now;
					buy_price = current_price;
					amount += POSITION;
					op = open_buy;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			if (cross_plus_minus == -1 && minus_di_now < SELL_AT && sub_di >= -0.618)
			{
				if (plus_order("sell") == 0)break;
				else {
					minus_di_last = minus_di_now;
					buy_price = current_price;
					amount += POSITION;
					op = open_sell;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
		}
		//op = open_buy 做空套利
		if (op == open_buy)
		{
			
			//可以全卖
			if (plus_di_now >= SELL_AT)
			{
				if (minus_order("buy") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖止盈");
					op = nothing;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			//可以套利
			if ((current_price - buy_price) / (buy_price) > PROFIT)
			{
				if (minus_order("buy") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖套利");
					op = nothing;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			//可以止损
			if ((buy_price - current_price) / (buy_price) > PROFIT*0.375)
			{
				if (minus_order("buy") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖止损");
					op = nothing;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			//改方向,先全卖,再买空
			if (cross_plus_minus == -1 && minus_di_now < SELL_AT && sub_di >= -0.618)
			{
				if (minus_order("buy") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖改方向");
					op = nothing; //先改变op
					if (plus_order("sell") == 0)break;
					else {
						minus_di_last = minus_di_now;
						buy_price = current_price;
						amount += POSITION;
						op = open_sell;
						Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
						break;
					}
				}
			}
		}
		//op==open_sell
		if (op == open_sell)
		{
			
			//可以全卖
			if (minus_di_now >= SELL_AT)
			{
				if (minus_order("sell") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖止盈");
					op = nothing;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			//可以套利
			if ((buy_price - current_price) / (buy_price) > PROFIT)
			{
				if (minus_order("sell") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖套利");
					op = nothing;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			//可以止损
			if ((current_price - buy_price) / (buy_price) > PROFIT*0.375)
			{
				if (minus_order("sell") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖止损");
					op = nothing;
					Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
					break;
				}
			}
			//改方向,先全卖,再买多
			if (cross_plus_minus == 1 && plus_di_now < SELL_AT && sub_di <= 0.618)
			{
				if (minus_order("sell") == 0) break;
				else {
					amount = 0;//卖完,amount=0
					Log("全卖改方向");
					op = nothing; //先改变op
					if (plus_order("buy") == 0) break;
					else {
						plus_di_last = plus_di_now;
						buy_price = current_price;
						amount += POSITION;
						op = open_buy;
						Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now);
						break;
					}
				}
			}
		}
		Sleep(6180);
	}

}

void main() {
	Log("Who care the bullshit");
	Log(_C(exchange.GetAccount));
	exchange.SetContractType("XBTUSD");   //     设置交易所期货类型
	exchange.SetMarginLevel(MARGIN);      //     设置杠杆倍数
	exchange.SetDirection(DIRECTION);     //     设置期货方向  
	Test_BM *bm = new Test_BM();
	while (true) {
		bm->bm_01();
	}
}

Related

More

发明者量化 膜拜 C++ 大神~ 可以把回测设置保存到源文件中, 这样复制走就可以直接回测不用选交易所了~