策略源码
#define MIN(a, b)((a) < (b) ? (a) : (b))
#define MAX(a, b)((a) > (b) ? (a) : (b))
bool do_action(string cmd, string symbol, double lot, double * hold_ret) {
bool isFirst = true;
double preHold = 0;
bool coverAll = lot == 0;
if (exchange.GetName() == "Futures_CTP" && symbol.size() > 0) {
auto ct = exchange.SetContractType(symbol);
if (ct == false) {
return false;
}
symbol = (string)ct["InstrumentID"];
}
while (true) {
if (!isFirst) {
Sleep(500);
}
auto orders = exchange.GetOrders();
if (!orders.Valid) {
return false;
}
if (orders.size() > 0) {
for (auto & item: orders) {
exchange.CancelOrder(item.Id);
}
Sleep(500);
continue;
}
auto positions = exchange.GetPosition();
if (!positions.Valid) {
return false;
}
double hold = 0;
double realHold = 0;
for (auto & item: positions) {
if (symbol != item.ContractType ||
(cmd == "buy" && item.Type != PD_LONG && item.Type != PD_LONG_YD) ||
(cmd == "sell" && item.Type != PD_SHORT && item.Type != PD_SHORT_YD)) {
continue;
}
if (symbol.size() == 0) {
realHold += item.Amount;
} else {
realHold += (item.Type == PD_LONG || item.Type == PD_LONG_YD) ? item.Amount : -item.Amount;
}
hold += item.Amount;
}
if (isFirst) {
preHold = hold;
isFirst = false;
}
if (hold_ret != NULL) {
*hold_ret = realHold;
}
if (cmd == "cover") {
auto count = 0;
double remain = lot - (preHold - hold);
for (auto & item: positions) {
if (symbol.size() > 0 && symbol != item.ContractType) {
continue;
}
if (item.Type == PD_LONG || item.Type == PD_LONG_YD) {
double doAmount = coverAll ? item.Amount : MIN(remain, item.Amount);
if (doAmount > 0) {
exchange.SetDirection(item.Type == PD_LONG ? "closebuy_today" : "closebuy");
auto ct = exchange.SetContractType(item.ContractType);
if (ct == false) {
return false;
}
auto ticker = exchange.GetTicker();
if (!ticker.Valid) {
return false;
}
exchange.Sell(ticker.Buy, doAmount);
count++;
remain -= doAmount;
}
} else {
double doAmount = coverAll ? item.Amount : MIN(remain, item.Amount);
if (doAmount > 0) {
exchange.SetDirection(item.Type == PD_SHORT ? "closesell_today" : "closesell");
auto ct = exchange.SetContractType(item.ContractType);
if (ct == false) {
return false;
}
auto ticker = exchange.GetTicker();
if (!ticker.Valid) {
return false;
}
exchange.Buy(ticker.Sell, doAmount);
count++;
remain -= doAmount;
}
}
}
if (count == 0) {
return true;
}
} else {
double remain = lot - (hold - preHold);
if (remain <= 0) {
return true;
}
auto ct = exchange.SetContractType(symbol);
if (ct == false) {
return false;
}
auto ticker = exchange.GetTicker();
if (!ticker.Valid) {
return false;
}
if (cmd == "buy") {
exchange.SetDirection("buy");
exchange.Buy(ticker.Sell, remain);
} else {
exchange.SetDirection("sell");
exchange.Sell(ticker.Buy, remain);
}
}
}
return false;
}
double GetPosition(string symbol) {
if (exchange.GetName().find("Futures_") != 0) {
Panic("only support Futures exchange");
}
bool isFirst = true;
double preHold = 0;
if (exchange.GetName() == "Futures_CTP" && symbol.size() > 0) {
symbol = (string)_C(exchange.SetContractType, symbol)["InstrumentID"];
}
while (true) {
auto orders = _C(exchange.GetOrders);
if (orders.size() == 0) {
break;
}
for (auto & item: orders) {
exchange.CancelOrder(item.Id);
}
Sleep(500);
}
auto positions = _C(exchange.GetPosition);
double hold = 0;
for (auto & item: positions) {
if (symbol.size() > 0 && symbol != item.ContractType) {
continue;
}
hold += (item.Type == PD_LONG || item.Type == PD_LONG_YD) ? item.Amount : -item.Amount;
}
return hold;
}
static bool _init = false;
void init() {
_init = true;
SetErrorFilter("not login|not ready");
}
double Trade(string cmd, string symbol = "", double lot = 0) {
if (!_init) {
init();
}
if (cmd != "buy" && cmd != "sell" && cmd != "cover") {
Panic("ext::Trade not support " + cmd);
}
if (exchange.GetName().find("Futures_") != 0) {
Panic("only support Futures exchange");
}
exchange.IO("mode", 0);
double position = 0;
while (!do_action(cmd, symbol, lot, & position)) {
Sleep(1000);
}
exchange.IO("mode", 1);
Log(cmd, symbol, "position:", position);
return position;
}
void main() {
Trade("buy", "MA888", 3);
Log(exchange.GetPosition());
Log(Trade("buy", "MA888", 2));
Log(exchange.GetPosition());
Log(Trade("cover"));
Log(Trade("sell", "MA888", 3));
Log(Trade("cover", "MA888", 2));
Log(exchange.GetPosition());
Log(Trade("cover"));
Log(exchange.GetPosition());
}