quantstrat,我怎样才能以特定价格设置止损?

时间:2017-06-24 13:58:28

标签: r quantstrat

美好的一天!

朋友,我真的需要你的帮助!

我的问题是: 我怎么能以特定价格设置止损?

Quantstrat的工作原理如下(长仓): 止损价=入场价 - 入场价*门槛。

例如,我尝试运行我的代码。但StopLossLONG不起作用。

如何编写停止代码?

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/core/handlers/base.py" in _legacy_get_response
  249.             response = self._get_response(request)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
  83.             return self.dispatch(request, *args, **kwargs)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  483.             response = self.handle_exception(exc)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/rest_framework/views.py" in handle_exception
  443.             self.raise_uncaught_exception(exc)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  480.             response = handler(request, *args, **kwargs)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/croinc/babycroinc/bc_views/rest.py" in timeline_questions_reshuffle
  309.         queryset = child.reshuffle_timeline_questions(self.TIMELINE_QUESTIONS_COUNT)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/croinc/babycroinc/bc_models/core.py" in reshuffle_timeline_questions
  346.         self.generate_question_set(num)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/croinc/babycroinc/bc_models/core.py" in generate_question_set
  294.                 new_questions = self.generate_random_timeline_questions(count_q)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/croinc/babycroinc/bc_models/core.py" in generate_random_timeline_questions
  508.                 questions += [TimelineQuestion.objects.create(alg_type=alg_str, alg_score=0, snippet=rep, child=self)]

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/query.py" in create
  394.         obj.save(force_insert=True, using=self.db)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/base.py" in save
  806.                        force_update=force_update, update_fields=update_fields)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/base.py" in save_base
  836.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
  922.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
  961.                                using=using, raw=raw)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/query.py" in _insert
  1061.         return query.get_compiler(using=using).execute_sql(return_id)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1099.                 cursor.execute(sql, params)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  65.                 return self.cursor.execute(sql, params)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/utils.py" in __exit__
  94.                 six.reraise(dj_exc_type, dj_exc_value, traceback)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  65.                 return self.cursor.execute(sql, params)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/django/db/backends/mysql/base.py" in execute
  101.             return self.cursor.execute(query, args)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/MySQLdb/cursors.py" in execute
  205.             self.errorhandler(self, exc, value)

File "/home/www/public_html/croinc.org/baby-croinc/croinc-baby-croinc.baby-croinc/env/lib/python2.7/site-packages/MySQLdb/connections.py" in defaulterrorhandler
  36.     raise errorclass, errorvalue

谢谢!

1 个答案:

答案 0 :(得分:5)

您的代码有一些奇怪的设置,如果它是您问题的一部分,我会指出:

1)您已为带有标签enabled = FALSE的停止规则设置了StopLossLONG,因此无论如何都不会应用此规则。

2)在您的数据期间SPY似乎永远不会达到208,因此您不会获得任何长期交易。

您问是否可以按特定价格设置止损。仔细阅读你的问题后,我认为你的意思是我可以设置一个绝对水平的止损,比如这里的0.005吗?而不是一些绝对水平的“入门价 - 一些门槛金额”。是的,如果您修改ruleSignal,则可以。这就是name = 'ruleSignal函数中公开add.rule的原因...因此您可以自行调整订单的生成方式。

以下是一个示例,您的条目现在为202,允许您的示例进行一次交易。它将止损水平设置为9.999(您可以将任何绝对价格水平设置为低于您的入场价格)。我已对函数ruleSignalAbsoluteStopPrice添加了注释,该注释将替换ruleSignal。如果你有正确的预期参数(比如ruleSignal的参数),你可以使用你想要的任何函数,如果你想使用这个函数的修改版本,你可以调用addOrder(或类似addOrder之类的东西也是......但在这之前你需要了解量子来源。)

如果您想了解如何以与现有quantstrat代码的其余部分相关的正确方式修改ruleSignal,请尝试将browser()置于ruleSignal内并逐行执行以查看你需要改变以使事情正常工作。

请参阅我添加的评论,其中我调整了现有ruleSignal代码的部分内容。

library('TTR')
library('blotter')
library("quantmod")
require(quantstrat)

# Define new function to replace 'ruleSignal' for long stoplimit orders:

ruleSignalAbsoluteStopPrice <- function (mktdata = mktdata, timestamp, sigcol, sigval, orderqty = 0,
                                         ordertype, orderside = NULL, orderset = NULL, threshold = NULL,
                                         tmult = FALSE, replace = TRUE, delay = 1e-04, osFUN = "osNoOp",
                                         pricemethod = c("market", "opside", "active"), portfolio,
                                         symbol, ..., ruletype, TxnFees = 0, prefer = NULL, sethold = FALSE,
                                         label = "", order.price = NULL, chain.price = NULL, time.in.force = "",
                                         absoluteStopPrice = 9.999)
{

    if (!is.function(osFUN))
        osFUN <- match.fun(osFUN)
    if (hasArg(curIndex))
        curIndex <- eval(match.call(expand.dots = TRUE)$curIndex,
                         parent.frame())
    else curIndex <- mktdata[timestamp, which.i = TRUE]
    # Just for long orderside and stoplimit order types.
    if (curIndex > 0 && curIndex <= nrow(mktdata) && ordertype == "stoplimit" && orderside == "long" && (ruletype ==
                                                                                                         "chain" )) {
        pricemethod <- pricemethod[1]
        if (hasArg(prefer))
            prefer = match.call(expand.dots = TRUE)$prefer
        else prefer = NULL

        # chain.price is the transaction price of the long trade.
        # Handle the case where the price may be less than your absolute stop level (here we skip entering a long position):
        if (chain.price <= absoluteStopPrice)
            return()

        threshold <- chain.price - absoluteStopPrice
        # Ensure that tmult = FALSE when using this approach.

        if (is.null(orderside) & !isTRUE(orderqty == 0)) {
            curqty <- getPosQty(Portfolio = portfolio, Symbol = symbol,
                                Date = timestamp)
            if (curqty > 0) {
                orderside <- "long"
            }
            else if (curqty < 0) {
                orderside <- "short"
            }
            else {
                if (orderqty > 0)
                    orderside <- "long"
                else orderside <- "short"
            }
        }
        if (orderqty == "all") {
            if (orderside == "long") {
                tmpqty <- 1
            }
            else {
                tmpqty <- -1
            }
        }
        else {
            tmpqty <- orderqty
        }
        if (!is.null(order.price)) {
            orderprice <- order.price
        }
        else if (!is.null(chain.price)) {
            orderprice <- chain.price
        }
        else {

        }
        if (is.null(orderset))
            orderset = NA
        if (orderqty != "all") {
            orderqty <- osFUN(strategy = strategy, data = mktdata,
                              timestamp = timestamp, orderqty = orderqty, ordertype = ordertype,
                              orderside = orderside, portfolio = portfolio,
                              symbol = symbol, ... = ..., ruletype = ruletype,
                              orderprice = as.numeric(orderprice))
        }
        if (!is.null(orderqty) && orderqty != 0 && length(orderprice)) {

            # All the arguments passed to `addOrder` are reasonable, and similar to what ruleSignal expects
            addOrder(portfolio = portfolio, symbol = symbol,
                     timestamp = timestamp, qty = orderqty, price = as.numeric(orderprice),
                     ordertype = ordertype, side = orderside, orderset = orderset,
                     threshold = threshold, status = "open", replace = replace,
                     delay = delay, tmult = tmult, ... = ..., prefer = prefer,
                     TxnFees = TxnFees, label = label, time.in.force = time.in.force)
        }
    }
    if (sethold)
        hold <<- TRUE
}



from <- "2016-04-01"
to <- "2016-07-01"

SPY <- getSymbols.yahoo('SPY',
                        env = .GlobalEnv,
                        return.class = 'xts',
                        index.class = 'Date',
                        from = from,
                        to = to,
                        periodicity = "daily",
                        auto.assign = FALSE)

SPY <- SPY[, c(1, 2, 3, 4, 5)]
names(SPY) <- c('Open','High','Low','Close','Volume')

level <- function(ts, level) {
    ts$level <- level
    res <- ts$level
    names(res) <- c("")
    return(res)
}

rm(list = ls(.blotter), envir = .blotter)
symbols = "SPY"
currency('USD')
initDate = from
from = from
to = to
initEq = 100000
strName = "test"

stock(symbols, currency = "USD", tick_size = 0.001, multiplier = 1)
getInstrument(symbols, type = "instrument")

strategy.st <- strName
portfolio.st <- strName
account.st <- strName
rm.strat(portfolio.st)
rm.strat(strategy.st)

initPortf(portfolio.st, symbols = symbols, initDate = initDate, currency = 'USD')
initAcct(account.st, portfolios = portfolio.st, initDate = initDate, currency = 'USD', initEq = initEq)
initOrders(portfolio.st, initDate = initDate)

strategy(strategy.st, store = TRUE)

addPosLimit(portfolio.st, symbols, timestamp = initDate, maxpos = 1, minpos = -1)

# indicators

# Set the level to 202 to allow one entry trade at least:

add.indicator(strategy.st, name = "level",
              arguments = list(ts = quote((mktdata)), level = 202.0),
              label = "LEV202")

add.indicator(strategy.st, name = "level",
              arguments = list(ts = quote((mktdata)), level = 212.0),
              label = "LEV212")

add.indicator(strategy.st, name = "level",
              arguments = list(ts = quote((mktdata)), level = 207.0),
              label = "LEV207")

# signals

add.signal(strategy.st, name = "sigCrossover",
           arguments = list(columns = c("Close", "LEV202"),
                            relationship = "gt"),
           label = "OPEN")

add.signal(strategy.st, name = "sigCrossover",
           arguments = list(columns = c("Close", "LEV212"),
                            relationship = "gt"),
           label = "CLOSE")

# rules

add.rule(strategy.st, name = "ruleSignal",
         arguments = list(sigcol = "OPEN", sigval = TRUE,
                          orderside = "long",
                          ordertype = "market",
                          prefer = "Open",
                          orderqty = 1,
                          replace = FALSE,
                          osFUN = osMaxPos
         ),
         type = "enter",
         label = "LE"
)

add.rule(strategy.st, name = "ruleSignal",
         arguments = list(sigcol = "CLOSE", sigval = TRUE,
                          orderside = "long",
                          ordertype = "market",
                          prefer = "Open",
                          orderqty = "all",
                          replace = FALSE
         ),
         type = "exit",
         label = "LX"
)

add.rule(strategy.st,
         name = "ruleSignalAbsoluteStopPrice",
         arguments = list(sigcol = "OPEN",
                          sigval = TRUE,
                          replace = FALSE,
                          orderside = "long",
                          ordertype = "stoplimit",
                          #threshold = quote(0.005),  don't bother setting threshold argument as ruleSignalAbsoluteStopPrice won't used the passed in argument 'threshold'.
                          absoluteStopPrice = 9.999, # Demonstrat that we can use new arguments related to the `ruleSignalAbsoluteStopPrice`` function
                          tmult = FALSE, # tmult is potentially used in `addOrder`
                          orderqty = "all",
                          orderset = "ocolong"),
         type = "chain",
         parent = "LE",
         label = "StopLossLONG",
         enabled = TRUE # Enable this rule
)


applyStrategy(strategy.st, portfolio.st)
save.strategy(strategy.st)

orderbook <- getOrderBook(portfolio.st)
orderbook

现在检查你得到了什么(停止限价9.999):

> orderbook
$test
$test$SPY
           Order.Qty Order.Price Order.Type  Order.Side Order.Threshold Order.Status Order.StatusTime      Prefer Order.Set Txn.Fees Rule           Time.In.Force
2016-04-13 "1"       "201.827"   "market"    "long"     NA              "closed"     "2016-04-14 00:00:00" "Open" NA        "0"      "LE"           ""           
2016-04-14 "all"     "9.999"     "stoplimit" "long"     "-192.812707"   "open"       NA                    ""     "ocolong" "0"      "StopLossLONG" ""  

我们认为交易依旧开放:

> getTxns(portfolio.st, "SPY")
                    Txn.Qty Txn.Price Txn.Fees Txn.Value Txn.Avg.Cost Net.Txn.Realized.PL
2016-04-01 00:00:00       0      0.00        0      0.00         0.00                   0
2016-04-13 20:00:00       1    202.87        0    202.87       202.87                   0

希望这有帮助。