C++ 期货类库


创建日期: 2019-03-28 13:34:00 最后修改: 2026-02-25 16:56:49
复制: 0 点击次数: 425
avatar of 扫地僧 扫地僧
1
关注
275
关注者
策略源码
#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());
}