[Mod]reformat code
This commit is contained in:
parent
a9f652607c
commit
e6f8060e99
@ -0,0 +1 @@
|
|||||||
|
__version__ == "2.0"
|
@ -201,10 +201,10 @@ class BacktestingEngine:
|
|||||||
s = (
|
s = (
|
||||||
DbBarData.select()
|
DbBarData.select()
|
||||||
.where(
|
.where(
|
||||||
(DbBarData.vt_symbol == self.vt_symbol) &
|
(DbBarData.vt_symbol == self.vt_symbol)
|
||||||
(DbBarData.interval == self.interval) &
|
& (DbBarData.interval == self.interval)
|
||||||
(DbBarData.datetime >= self.start) &
|
& (DbBarData.datetime >= self.start)
|
||||||
(DbBarData.datetime <= self.end)
|
& (DbBarData.datetime <= self.end)
|
||||||
)
|
)
|
||||||
.order_by(DbBarData.datetime)
|
.order_by(DbBarData.datetime)
|
||||||
)
|
)
|
||||||
@ -213,9 +213,9 @@ class BacktestingEngine:
|
|||||||
s = (
|
s = (
|
||||||
DbTickData.select()
|
DbTickData.select()
|
||||||
.where(
|
.where(
|
||||||
(DbTickData.vt_symbol == self.vt_symbol) &
|
(DbTickData.vt_symbol == self.vt_symbol)
|
||||||
(DbTickData.datetime >= self.start) &
|
& (DbTickData.datetime >= self.start)
|
||||||
(DbTickData.datetime <= self.end)
|
& (DbTickData.datetime <= self.end)
|
||||||
)
|
)
|
||||||
.order_by(DbTickData.datetime)
|
.order_by(DbTickData.datetime)
|
||||||
)
|
)
|
||||||
@ -567,15 +567,15 @@ class BacktestingEngine:
|
|||||||
|
|
||||||
# Check whether limit orders can be filled.
|
# Check whether limit orders can be filled.
|
||||||
long_cross = (
|
long_cross = (
|
||||||
order.direction == Direction.LONG and
|
order.direction == Direction.LONG
|
||||||
order.price >= long_cross_price and
|
and order.price >= long_cross_price
|
||||||
long_cross_price > 0
|
and long_cross_price > 0
|
||||||
)
|
)
|
||||||
|
|
||||||
short_cross = (
|
short_cross = (
|
||||||
order.direction == Direction.SHORT and
|
order.direction == Direction.SHORT
|
||||||
order.price <= short_cross_price and
|
and order.price <= short_cross_price
|
||||||
short_cross_price > 0
|
and short_cross_price > 0
|
||||||
)
|
)
|
||||||
|
|
||||||
if not long_cross and not short_cross:
|
if not long_cross and not short_cross:
|
||||||
@ -635,13 +635,13 @@ class BacktestingEngine:
|
|||||||
for stop_order in list(self.active_stop_orders.values()):
|
for stop_order in list(self.active_stop_orders.values()):
|
||||||
# Check whether stop order can be triggered.
|
# Check whether stop order can be triggered.
|
||||||
long_cross = (
|
long_cross = (
|
||||||
stop_order.direction == Direction.LONG and
|
stop_order.direction == Direction.LONG
|
||||||
stop_order.price <= long_cross_price
|
and stop_order.price <= long_cross_price
|
||||||
)
|
)
|
||||||
|
|
||||||
short_cross = (
|
short_cross = (
|
||||||
stop_order.direction == Direction.SHORT and
|
stop_order.direction == Direction.SHORT
|
||||||
stop_order.price >= short_cross_price
|
and stop_order.price >= short_cross_price
|
||||||
)
|
)
|
||||||
|
|
||||||
if not long_cross and not short_cross:
|
if not long_cross and not short_cross:
|
||||||
|
@ -405,10 +405,10 @@ class CtaEngine(BaseEngine):
|
|||||||
s = (
|
s = (
|
||||||
DbBarData.select()
|
DbBarData.select()
|
||||||
.where(
|
.where(
|
||||||
(DbBarData.vt_symbol == vt_symbol) &
|
(DbBarData.vt_symbol == vt_symbol)
|
||||||
(DbBarData.interval == interval) &
|
& (DbBarData.interval == interval)
|
||||||
(DbBarData.datetime >= start) &
|
& (DbBarData.datetime >= start)
|
||||||
(DbBarData.datetime <= end)
|
& (DbBarData.datetime <= end)
|
||||||
)
|
)
|
||||||
.order_by(DbBarData.datetime)
|
.order_by(DbBarData.datetime)
|
||||||
)
|
)
|
||||||
@ -425,9 +425,9 @@ class CtaEngine(BaseEngine):
|
|||||||
s = (
|
s = (
|
||||||
DbTickData.select()
|
DbTickData.select()
|
||||||
.where(
|
.where(
|
||||||
(DbBarData.vt_symbol == vt_symbol) &
|
(DbBarData.vt_symbol == vt_symbol)
|
||||||
(DbBarData.datetime >= start) &
|
& (DbBarData.datetime >= start)
|
||||||
(DbBarData.datetime <= end)
|
& (DbBarData.datetime <= end)
|
||||||
)
|
)
|
||||||
.order_by(DbBarData.datetime)
|
.order_by(DbBarData.datetime)
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
from vnpy.app.cta_strategy import (
|
from vnpy.app.cta_strategy import (
|
||||||
CtaTemplate,
|
CtaTemplate,
|
||||||
StopOrder,
|
StopOrder,
|
||||||
Direction,
|
|
||||||
TickData,
|
TickData,
|
||||||
BarData,
|
BarData,
|
||||||
TradeData,
|
TradeData,
|
||||||
OrderData,
|
OrderData,
|
||||||
BarGenerator,
|
BarGenerator,
|
||||||
ArrayManager,
|
ArrayManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -16,33 +15,33 @@ class AtrRsiStrategy(CtaTemplate):
|
|||||||
|
|
||||||
author = '用Python的交易员'
|
author = '用Python的交易员'
|
||||||
|
|
||||||
atr_length = 22
|
atr_length = 22
|
||||||
atr_ma_length = 10
|
atr_ma_length = 10
|
||||||
rsi_length = 5
|
rsi_length = 5
|
||||||
rsi_entry = 16
|
rsi_entry = 16
|
||||||
trailing_percent = 0.8
|
trailing_percent = 0.8
|
||||||
fixed_size = 1
|
fixed_size = 1
|
||||||
|
|
||||||
atr_value = 0
|
atr_value = 0
|
||||||
atr_ma = 0
|
atr_ma = 0
|
||||||
rsi_value = 0
|
rsi_value = 0
|
||||||
rsi_buy = 0
|
rsi_buy = 0
|
||||||
rsi_sell = 0
|
rsi_sell = 0
|
||||||
intra_trade_high = 0
|
intra_trade_high = 0
|
||||||
intra_trade_low = 0
|
intra_trade_low = 0
|
||||||
|
|
||||||
parameters= [ 'atr_length', 'atr_ma_length', 'rsi_length', 'rsi_entry', 'trailing_percent','fixed_size']
|
parameters = ['atr_length', 'atr_ma_length', 'rsi_length',
|
||||||
variables= ['atr_value','atr_ma','rsi_value','rsi_buy','rsi_sell']
|
'rsi_entry', 'trailing_percent', 'fixed_size']
|
||||||
|
variables = ['atr_value', 'atr_ma', 'rsi_value', 'rsi_buy', 'rsi_sell']
|
||||||
|
|
||||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||||
""""""
|
""""""
|
||||||
super(AtrRsiStrategy, self).__init__(
|
super(AtrRsiStrategy, self).__init__(
|
||||||
cta_engine, strategy_name, vt_symbol, setting
|
cta_engine, strategy_name, vt_symbol, setting
|
||||||
)
|
)
|
||||||
self.bg = BarGenerator(self.on_bar)
|
self.bg = BarGenerator(self.on_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
def on_init(self):
|
def on_init(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is inited.
|
Callback when strategy is inited.
|
||||||
@ -59,7 +58,7 @@ class AtrRsiStrategy(CtaTemplate):
|
|||||||
Callback when strategy is started.
|
Callback when strategy is started.
|
||||||
"""
|
"""
|
||||||
self.write_log("策略启动")
|
self.write_log("策略启动")
|
||||||
|
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is stopped.
|
Callback when strategy is stopped.
|
||||||
@ -85,7 +84,7 @@ class AtrRsiStrategy(CtaTemplate):
|
|||||||
|
|
||||||
atr_array = am.atr(self.atr_length, array=True)
|
atr_array = am.atr(self.atr_length, array=True)
|
||||||
self.atr_value = atr_array[-1]
|
self.atr_value = atr_array[-1]
|
||||||
self.atr_ma = atr_array[-self.atr_ma_length:].mean()
|
self.atr_ma = atr_array[-self.atr_ma_length:].mean()
|
||||||
self.rsi_value = am.rsi(self.rsi_length)
|
self.rsi_value = am.rsi(self.rsi_length)
|
||||||
|
|
||||||
if self.pos == 0:
|
if self.pos == 0:
|
||||||
@ -94,26 +93,28 @@ class AtrRsiStrategy(CtaTemplate):
|
|||||||
|
|
||||||
if self.atr_value > self.atr_ma:
|
if self.atr_value > self.atr_ma:
|
||||||
if self.rsi_value > self.rsi_buy:
|
if self.rsi_value > self.rsi_buy:
|
||||||
self.buy(bar.close_price+5, self.fixed_size)
|
self.buy(bar.close_price + 5, self.fixed_size)
|
||||||
elif self.rsi_value < self.rsi_sell:
|
elif self.rsi_value < self.rsi_sell:
|
||||||
self.short(bar.close_price-5, self.fixed_size)
|
self.short(bar.close_price - 5, self.fixed_size)
|
||||||
|
|
||||||
elif self.pos > 0:
|
elif self.pos > 0:
|
||||||
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
|
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
|
||||||
self.intra_trade_low = bar.low_price
|
self.intra_trade_low = bar.low_price
|
||||||
|
|
||||||
long_stop = self.intra_trade_high * (1-self.trailing_percent/100)
|
long_stop = self.intra_trade_high * \
|
||||||
|
(1 - self.trailing_percent / 100)
|
||||||
self.sell(long_stop, abs(self.pos), stop=True)
|
self.sell(long_stop, abs(self.pos), stop=True)
|
||||||
|
|
||||||
elif self.pos < 0:
|
elif self.pos < 0:
|
||||||
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
|
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
|
||||||
self.intra_trade_high = bar.high_price
|
self.intra_trade_high = bar.high_price
|
||||||
|
|
||||||
short_stop = self.intra_trade_low * (1+self.trailing_percent/100)
|
short_stop = self.intra_trade_low * \
|
||||||
|
(1 + self.trailing_percent / 100)
|
||||||
self.cover(short_stop, abs(self.pos), stop=True)
|
self.cover(short_stop, abs(self.pos), stop=True)
|
||||||
|
|
||||||
self.put_event()
|
self.put_event()
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
Callback of new order data update.
|
Callback of new order data update.
|
||||||
@ -130,4 +131,4 @@ class AtrRsiStrategy(CtaTemplate):
|
|||||||
"""
|
"""
|
||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from vnpy.app.cta_strategy import (
|
from vnpy.app.cta_strategy import (
|
||||||
CtaTemplate,
|
CtaTemplate,
|
||||||
StopOrder,
|
StopOrder,
|
||||||
Direction,
|
|
||||||
TickData,
|
TickData,
|
||||||
BarData,
|
BarData,
|
||||||
TradeData,
|
TradeData,
|
||||||
@ -13,38 +12,40 @@ from vnpy.app.cta_strategy import (
|
|||||||
|
|
||||||
class BollChannelStrategy(CtaTemplate):
|
class BollChannelStrategy(CtaTemplate):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
author = '用Python的交易员'
|
author = '用Python的交易员'
|
||||||
|
|
||||||
boll_window = 18
|
boll_window = 18
|
||||||
boll_dev = 3.4
|
boll_dev = 3.4
|
||||||
cci_window = 10
|
cci_window = 10
|
||||||
atr_window = 30
|
atr_window = 30
|
||||||
sl_multiplier = 5.2
|
sl_multiplier = 5.2
|
||||||
fixed_size = 1
|
fixed_size = 1
|
||||||
|
|
||||||
boll_up = 0
|
boll_up = 0
|
||||||
boll_down = 0
|
boll_down = 0
|
||||||
cci_value = 0
|
cci_value = 0
|
||||||
atr_value = 0
|
atr_value = 0
|
||||||
|
|
||||||
intra_trade_high = 0
|
intra_trade_high = 0
|
||||||
intra_trade_low = 0
|
intra_trade_low = 0
|
||||||
long_stop = 0
|
long_stop = 0
|
||||||
short_stop = 0
|
short_stop = 0
|
||||||
|
|
||||||
parameters = [ 'boll_window', 'boll_dev', 'cci_window', 'atr_window', 'sl_multiplier', 'fixed_size']
|
parameters = ['boll_window', 'boll_dev', 'cci_window',
|
||||||
variables = ['boll_up', 'boll_down', 'cci_value', 'atr_value', 'intra_trade_high', 'intra_trade_low', 'long_stop', 'short_stop']
|
'atr_window', 'sl_multiplier', 'fixed_size']
|
||||||
|
variables = ['boll_up', 'boll_down', 'cci_value', 'atr_value',
|
||||||
|
'intra_trade_high', 'intra_trade_low', 'long_stop', 'short_stop']
|
||||||
|
|
||||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||||
""""""
|
""""""
|
||||||
super(BollChannelStrategy, self).__init__(
|
super(BollChannelStrategy, self).__init__(
|
||||||
cta_engine, strategy_name, vt_symbol, setting
|
cta_engine, strategy_name, vt_symbol, setting
|
||||||
)
|
)
|
||||||
|
|
||||||
self.bg = BarGenerator(self.on_bar,15, self.on_15min_bar)
|
self.bg = BarGenerator(self.on_bar, 15, self.on_15min_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
def on_init(self):
|
def on_init(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is inited.
|
Callback when strategy is inited.
|
||||||
@ -70,49 +71,49 @@ class BollChannelStrategy(CtaTemplate):
|
|||||||
"""
|
"""
|
||||||
self.bg.update_tick(tick)
|
self.bg.update_tick(tick)
|
||||||
|
|
||||||
def on_bar(self, bar:BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.bg.update_bar(bar)
|
self.bg.update_bar(bar)
|
||||||
|
|
||||||
def on_15min_bar(self, bar:BarData):
|
def on_15min_bar(self, bar: BarData):
|
||||||
""""""
|
""""""
|
||||||
self.cancel_all()
|
self.cancel_all()
|
||||||
|
|
||||||
am = self.am
|
am = self.am
|
||||||
am.update_bar(bar)
|
am.update_bar(bar)
|
||||||
if not am.inited:
|
if not am.inited:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.boll_up, self.boll_down = am.boll(self.boll_window, self.boll_dev)
|
self.boll_up, self.boll_down = am.boll(self.boll_window, self.boll_dev)
|
||||||
self.cci_value = am.cci(self.cci_window)
|
self.cci_value = am.cci(self.cci_window)
|
||||||
self.atr_value = am.atr(self.atr_window)
|
self.atr_value = am.atr(self.atr_window)
|
||||||
|
|
||||||
if self.pos == 0:
|
if self.pos == 0:
|
||||||
self.intra_trade_high = bar.high_price
|
self.intra_trade_high = bar.high_price
|
||||||
self.intra_trade_low = bar.low_price
|
self.intra_trade_low = bar.low_price
|
||||||
|
|
||||||
if self.cci_value > 0:
|
if self.cci_value > 0:
|
||||||
self.buy(self.boll_up, self.fixed_size, True)
|
self.buy(self.boll_up, self.fixed_size, True)
|
||||||
elif self.cci_value < 0:
|
elif self.cci_value < 0:
|
||||||
self.short(self.boll_down, self.fixed_size, True)
|
self.short(self.boll_down, self.fixed_size, True)
|
||||||
|
|
||||||
elif self.pos > 0:
|
elif self.pos > 0:
|
||||||
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
|
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
|
||||||
self.intra_trade_low = bar.low_price
|
self.intra_trade_low = bar.low_price
|
||||||
|
|
||||||
self.long_stop = self.intra_trade_high - self.atr_value * self.sl_multiplier
|
self.long_stop = self.intra_trade_high - self.atr_value * self.sl_multiplier
|
||||||
self.sell(self.long_stop, abs(self.pos), True)
|
self.sell(self.long_stop, abs(self.pos), True)
|
||||||
|
|
||||||
elif self.pos < 0:
|
elif self.pos < 0:
|
||||||
self.intra_trade_high = bar.high_price
|
self.intra_trade_high = bar.high_price
|
||||||
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
|
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
|
||||||
|
|
||||||
self.short_stop = self.intra_trade_low + self.atr_value * self.sl_multiplier
|
self.short_stop = self.intra_trade_low + self.atr_value * self.sl_multiplier
|
||||||
self.cover(self.short_stop, abs(self.pos), True)
|
self.cover(self.short_stop, abs(self.pos), True)
|
||||||
|
|
||||||
self.put_event()
|
self.put_event()
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
@ -131,4 +132,3 @@ class BollChannelStrategy(CtaTemplate):
|
|||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from vnpy.app.cta_strategy import (
|
from vnpy.app.cta_strategy import (
|
||||||
CtaTemplate,
|
CtaTemplate,
|
||||||
StopOrder,
|
StopOrder,
|
||||||
Direction,
|
|
||||||
TickData,
|
TickData,
|
||||||
BarData,
|
BarData,
|
||||||
TradeData,
|
TradeData,
|
||||||
@ -13,19 +12,19 @@ from vnpy.app.cta_strategy import (
|
|||||||
|
|
||||||
class DoubleMaStrategy(CtaTemplate):
|
class DoubleMaStrategy(CtaTemplate):
|
||||||
author = '用Python的交易员'
|
author = '用Python的交易员'
|
||||||
|
|
||||||
fast_window = 10
|
|
||||||
slow_window = 20
|
|
||||||
|
|
||||||
fast_ma0 = 0.0
|
fast_window = 10
|
||||||
fast_ma1 = 0.0
|
slow_window = 20
|
||||||
|
|
||||||
|
fast_ma0 = 0.0
|
||||||
|
fast_ma1 = 0.0
|
||||||
|
|
||||||
slow_ma0 = 0.0
|
slow_ma0 = 0.0
|
||||||
slow_ma1 = 0.0
|
slow_ma1 = 0.0
|
||||||
|
|
||||||
parameters = [ 'fast_window', 'slow_window']
|
parameters = ['fast_window', 'slow_window']
|
||||||
variables = ['fast_ma0','fast_ma1','slow_ma0','slow_ma1']
|
variables = ['fast_ma0', 'fast_ma1', 'slow_ma0', 'slow_ma1']
|
||||||
|
|
||||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||||
""""""
|
""""""
|
||||||
super(DoubleMaStrategy, self).__init__(
|
super(DoubleMaStrategy, self).__init__(
|
||||||
@ -34,7 +33,7 @@ class DoubleMaStrategy(CtaTemplate):
|
|||||||
|
|
||||||
self.bg = BarGenerator(self.on_bar)
|
self.bg = BarGenerator(self.on_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
def on_init(self):
|
def on_init(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is inited.
|
Callback when strategy is inited.
|
||||||
@ -62,28 +61,28 @@ class DoubleMaStrategy(CtaTemplate):
|
|||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
"""
|
"""
|
||||||
self.bg.update_tick(tick)
|
self.bg.update_tick(tick)
|
||||||
|
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
am = self.am
|
am = self.am
|
||||||
am.update_bar(bar)
|
am.update_bar(bar)
|
||||||
if not am.inited:
|
if not am.inited:
|
||||||
return
|
return
|
||||||
|
|
||||||
fast_ma = am.sma(self.fast_window, array=True)
|
fast_ma = am.sma(self.fast_window, array=True)
|
||||||
self.fast_ma0 = fast_ma[-1]
|
self.fast_ma0 = fast_ma[-1]
|
||||||
self.fast_ma1 = fast_ma[-2]
|
self.fast_ma1 = fast_ma[-2]
|
||||||
|
|
||||||
slow_ma = am.sma(self.slow_window, array=True)
|
slow_ma = am.sma(self.slow_window, array=True)
|
||||||
self.slow_ma0 = slow_ma[-1]
|
self.slow_ma0 = slow_ma[-1]
|
||||||
self.slow_ma1 = slow_ma[-2]
|
self.slow_ma1 = slow_ma[-2]
|
||||||
|
|
||||||
cross_over = self.fast_ma0>self.slow_ma0 and self.fast_ma1<self.slow_ma1
|
cross_over = self.fast_ma0 > self.slow_ma0 and self.fast_ma1 < self.slow_ma1
|
||||||
cross_below = self.fast_ma0<self.slow_ma0 and self.fast_ma1>self.slow_ma1
|
cross_below = self.fast_ma0 < self.slow_ma0 and self.fast_ma1 > self.slow_ma1
|
||||||
|
|
||||||
if cross_over:
|
if cross_over:
|
||||||
if self.pos == 0:
|
if self.pos == 0:
|
||||||
self.buy(bar.close_price, 1)
|
self.buy(bar.close_price, 1)
|
||||||
@ -97,7 +96,7 @@ class DoubleMaStrategy(CtaTemplate):
|
|||||||
elif self.pos > 0:
|
elif self.pos > 0:
|
||||||
self.sell(bar.close_price, 1)
|
self.sell(bar.close_price, 1)
|
||||||
self.short(bar.close_price, 1)
|
self.short(bar.close_price, 1)
|
||||||
|
|
||||||
self.put_event()
|
self.put_event()
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
@ -116,4 +115,4 @@ class DoubleMaStrategy(CtaTemplate):
|
|||||||
"""
|
"""
|
||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -2,7 +2,6 @@ from datetime import time
|
|||||||
from vnpy.app.cta_strategy import (
|
from vnpy.app.cta_strategy import (
|
||||||
CtaTemplate,
|
CtaTemplate,
|
||||||
StopOrder,
|
StopOrder,
|
||||||
Direction,
|
|
||||||
TickData,
|
TickData,
|
||||||
BarData,
|
BarData,
|
||||||
TradeData,
|
TradeData,
|
||||||
@ -14,19 +13,19 @@ from vnpy.app.cta_strategy import (
|
|||||||
|
|
||||||
class DualThrustStrategy(CtaTemplate):
|
class DualThrustStrategy(CtaTemplate):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
author = u'用Python的交易员'
|
author = u'用Python的交易员'
|
||||||
|
|
||||||
fixed_size = 1
|
fixed_size = 1
|
||||||
k1 = 0.4
|
k1 = 0.4
|
||||||
k2 = 0.6
|
k2 = 0.6
|
||||||
|
|
||||||
barList = []
|
barList = []
|
||||||
|
|
||||||
day_open = 0
|
day_open = 0
|
||||||
day_high = 0
|
day_high = 0
|
||||||
day_low = 0
|
day_low = 0
|
||||||
|
|
||||||
range = 0
|
range = 0
|
||||||
long_entry = 0
|
long_entry = 0
|
||||||
short_entry = 0
|
short_entry = 0
|
||||||
@ -35,10 +34,9 @@ class DualThrustStrategy(CtaTemplate):
|
|||||||
long_entered = False
|
long_entered = False
|
||||||
short_entered = False
|
short_entered = False
|
||||||
|
|
||||||
|
parameters = ['k1', 'k2', "fixed_size"]
|
||||||
|
variables = ['range', 'long_entry', 'short_entry', 'exit_time']
|
||||||
|
|
||||||
parameters = [ 'k1', 'k2', "fixed_size"]
|
|
||||||
variables = ['range','long_entry','short_entry','exit_time']
|
|
||||||
|
|
||||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||||
""""""
|
""""""
|
||||||
super(DualThrustStrategy, self).__init__(
|
super(DualThrustStrategy, self).__init__(
|
||||||
@ -61,7 +59,7 @@ class DualThrustStrategy(CtaTemplate):
|
|||||||
Callback when strategy is started.
|
Callback when strategy is started.
|
||||||
"""
|
"""
|
||||||
self.write_log("策略启动")
|
self.write_log("策略启动")
|
||||||
|
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is stopped.
|
Callback when strategy is stopped.
|
||||||
@ -73,26 +71,26 @@ class DualThrustStrategy(CtaTemplate):
|
|||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
"""
|
"""
|
||||||
self.bg.update_tick(tick)
|
self.bg.update_tick(tick)
|
||||||
|
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.cancel_all()
|
self.cancel_all()
|
||||||
|
|
||||||
self.barList.append(bar)
|
self.barList.append(bar)
|
||||||
if len(self.barList) <= 2:
|
if len(self.barList) <= 2:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.barList.pop(0)
|
self.barList.pop(0)
|
||||||
last_bar = self.barList[-2]
|
last_bar = self.barList[-2]
|
||||||
|
|
||||||
if last_bar.datetime.date() != bar.datetime.date():
|
if last_bar.datetime.date() != bar.datetime.date():
|
||||||
if self.day_high:
|
if self.day_high:
|
||||||
self.range = self.day_high - self.day_low
|
self.range = self.day_high - self.day_low
|
||||||
self.long_entry = bar.open_price + self.k1 * self.range
|
self.long_entry = bar.open_price + self.k1 * self.range
|
||||||
self.short_entry = bar.open_price - self.k2 * self.range
|
self.short_entry = bar.open_price - self.k2 * self.range
|
||||||
|
|
||||||
self.day_open = bar.open_price
|
self.day_open = bar.open_price
|
||||||
self.day_high = bar.high_price
|
self.day_high = bar.high_price
|
||||||
self.day_low = bar.low_price
|
self.day_low = bar.low_price
|
||||||
@ -113,30 +111,31 @@ class DualThrustStrategy(CtaTemplate):
|
|||||||
self.buy(self.long_entry, self.fixed_size, stop=True)
|
self.buy(self.long_entry, self.fixed_size, stop=True)
|
||||||
else:
|
else:
|
||||||
if not self.short_entered:
|
if not self.short_entered:
|
||||||
self.short(self.short_entry, self.fixed_size, stop=True)
|
self.short(self.short_entry,
|
||||||
|
self.fixed_size, stop=True)
|
||||||
|
|
||||||
elif self.pos > 0:
|
elif self.pos > 0:
|
||||||
self.long_entered = True
|
self.long_entered = True
|
||||||
|
|
||||||
self.sell(self.short_entry, self.fixed_size, stop=True)
|
self.sell(self.short_entry, self.fixed_size, stop=True)
|
||||||
|
|
||||||
if not self.short_entered:
|
if not self.short_entered:
|
||||||
self.short(self.short_entry, self.fixed_size, stop=True)
|
self.short(self.short_entry, self.fixed_size, stop=True)
|
||||||
|
|
||||||
elif self.pos < 0:
|
elif self.pos < 0:
|
||||||
self.short_entered = True
|
self.short_entered = True
|
||||||
|
|
||||||
self.cover(self.long_entry, self.fixed_size, stop=True)
|
self.cover(self.long_entry, self.fixed_size, stop=True)
|
||||||
|
|
||||||
if not self.long_entered:
|
if not self.long_entered:
|
||||||
self.buy(self.long_entry, self.fixed_size, stop=True)
|
self.buy(self.long_entry, self.fixed_size, stop=True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if self.pos > 0:
|
if self.pos > 0:
|
||||||
self.sell(bar.close_price * 0.99, abs(self.pos))
|
self.sell(bar.close_price * 0.99, abs(self.pos))
|
||||||
elif self.pos < 0:
|
elif self.pos < 0:
|
||||||
self.cover(bar.close_price * 1.01, abs(self.pos))
|
self.cover(bar.close_price * 1.01, abs(self.pos))
|
||||||
|
|
||||||
self.put_event()
|
self.put_event()
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
@ -155,4 +154,4 @@ class DualThrustStrategy(CtaTemplate):
|
|||||||
"""
|
"""
|
||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from vnpy.app.cta_strategy import (
|
from vnpy.app.cta_strategy import (
|
||||||
CtaTemplate,
|
CtaTemplate,
|
||||||
StopOrder,
|
StopOrder,
|
||||||
Direction,
|
|
||||||
TickData,
|
TickData,
|
||||||
BarData,
|
BarData,
|
||||||
TradeData,
|
TradeData,
|
||||||
@ -10,41 +9,38 @@ from vnpy.app.cta_strategy import (
|
|||||||
ArrayManager,
|
ArrayManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class KingKeltnerStrategy(CtaTemplate):
|
class KingKeltnerStrategy(CtaTemplate):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
author = '用Python的交易员'
|
author = '用Python的交易员'
|
||||||
|
|
||||||
kk_length = 11
|
kk_length = 11
|
||||||
kk_dev = 1.6
|
kk_dev = 1.6
|
||||||
trailing_percent = 0.8
|
trailing_percent = 0.8
|
||||||
fixed_size = 1
|
fixed_size = 1
|
||||||
|
|
||||||
kk_up = 0
|
kk_up = 0
|
||||||
kk_down = 0
|
kk_down = 0
|
||||||
intra_trade_high = 0
|
intra_trade_high = 0
|
||||||
intra_trade_low = 0
|
intra_trade_low = 0
|
||||||
|
|
||||||
buy_orderidList = []
|
buy_orderidList = []
|
||||||
short_orderidList = []
|
short_orderidList = []
|
||||||
orderList = []
|
orderList = []
|
||||||
|
|
||||||
|
parameters = ['kk_length', 'kk_dev', 'fixed_size']
|
||||||
|
variables = ['kk_up', 'kk_down']
|
||||||
|
|
||||||
parameters = [ 'kk_length', 'kk_dev','fixed_size']
|
|
||||||
variables = ['kk_up','kk_down']
|
|
||||||
|
|
||||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||||
""""""
|
""""""
|
||||||
super(KingKeltnerStrategy, self).__init__(
|
super(KingKeltnerStrategy, self).__init__(
|
||||||
cta_engine, strategy_name, vt_symbol, setting
|
cta_engine, strategy_name, vt_symbol, setting
|
||||||
)
|
)
|
||||||
|
|
||||||
self.bg = BarGenerator(self.on_bar,5 ,self.on_5min_bar)
|
self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
buy_orderidList = []
|
|
||||||
short_orderidList = []
|
|
||||||
orderList = []
|
|
||||||
|
|
||||||
def on_init(self):
|
def on_init(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is inited.
|
Callback when strategy is inited.
|
||||||
@ -57,7 +53,7 @@ class KingKeltnerStrategy(CtaTemplate):
|
|||||||
Callback when strategy is started.
|
Callback when strategy is started.
|
||||||
"""
|
"""
|
||||||
self.write_log("策略启动")
|
self.write_log("策略启动")
|
||||||
|
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is stopped.
|
Callback when strategy is stopped.
|
||||||
@ -75,42 +71,42 @@ class KingKeltnerStrategy(CtaTemplate):
|
|||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.bg.update_bar(bar)
|
self.bg.update_bar(bar)
|
||||||
|
|
||||||
def on_5min_bar(self, bar:BarData):
|
def on_5min_bar(self, bar: BarData):
|
||||||
""""""
|
""""""
|
||||||
for orderid in self.orderList:
|
for orderid in self.orderList:
|
||||||
self.cancel_order(orderid)
|
self.cancel_order(orderid)
|
||||||
self.orderList = []
|
self.orderList = []
|
||||||
|
|
||||||
am = self.am
|
am = self.am
|
||||||
am.update_bar(bar)
|
am.update_bar(bar)
|
||||||
if not am.inited:
|
if not am.inited:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.kk_up, self.kk_down = am.keltner(self.kk_length, self.kk_dev)
|
self.kk_up, self.kk_down = am.keltner(self.kk_length, self.kk_dev)
|
||||||
|
|
||||||
if self.pos == 0:
|
if self.pos == 0:
|
||||||
self.intra_trade_high = bar.high_price
|
self.intra_trade_high = bar.high_price
|
||||||
self.intra_trade_low = bar.low_price
|
self.intra_trade_low = bar.low_price
|
||||||
self.send_oco_order(self.kk_up, self.kk_down, self.fixed_size)
|
self.send_oco_order(self.kk_up, self.kk_down, self.fixed_size)
|
||||||
|
|
||||||
elif self.pos > 0:
|
elif self.pos > 0:
|
||||||
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
|
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
|
||||||
self.intra_trade_low = bar.low_price
|
self.intra_trade_low = bar.low_price
|
||||||
|
|
||||||
vt_orderid = self.sell(self.intra_trade_high*(1-self.trailing_percent/100),
|
vt_orderid = self.sell(self.intra_trade_high * (1 - self.trailing_percent / 100),
|
||||||
abs(self.pos), True)
|
abs(self.pos), True)
|
||||||
self.orderList.append(vt_orderid)
|
self.orderList.append(vt_orderid)
|
||||||
|
|
||||||
elif self.pos < 0:
|
elif self.pos < 0:
|
||||||
self.intra_trade_high = bar.high_price
|
self.intra_trade_high = bar.high_price
|
||||||
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
|
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
|
||||||
|
|
||||||
vt_orderid = self.cover(self.intra_trade_low*(1+self.trailing_percent/100),
|
vt_orderid = self.cover(self.intra_trade_low * (1 + self.trailing_percent / 100),
|
||||||
abs(self.pos), True)
|
abs(self.pos), True)
|
||||||
self.orderList.append(vt_orderid)
|
self.orderList.append(vt_orderid)
|
||||||
|
|
||||||
self.put_event()
|
self.put_event()
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
@ -130,18 +126,18 @@ class KingKeltnerStrategy(CtaTemplate):
|
|||||||
elif self.pos < 0:
|
elif self.pos < 0:
|
||||||
for buy_orderid in self.buy_orderidList:
|
for buy_orderid in self.buy_orderidList:
|
||||||
self.cancel_order(buy_orderid)
|
self.cancel_order(buy_orderid)
|
||||||
|
|
||||||
for orderid in (self.buy_orderidList + self.short_orderidList):
|
for orderid in (self.buy_orderidList + self.short_orderidList):
|
||||||
if orderid in self.orderList:
|
if orderid in self.orderList:
|
||||||
self.orderList.remove(orderid)
|
self.orderList.remove(orderid)
|
||||||
|
|
||||||
self.put_event()
|
self.put_event()
|
||||||
|
|
||||||
def send_oco_order(self, buy_price, short_price, volume):
|
def send_oco_order(self, buy_price, short_price, volume):
|
||||||
""""""
|
""""""
|
||||||
self.buy_orderidList = self.buy(buy_price, volume, True)
|
self.buy_orderidList = self.buy(buy_price, volume, True)
|
||||||
self.short_orderidList = self.short(short_price, volume, True)
|
self.short_orderidList = self.short(short_price, volume, True)
|
||||||
|
|
||||||
self.orderList.append(self.buy_orderidList)
|
self.orderList.append(self.buy_orderidList)
|
||||||
self.orderList.append(self.short_orderidList)
|
self.orderList.append(self.short_orderidList)
|
||||||
|
|
||||||
@ -149,4 +145,4 @@ class KingKeltnerStrategy(CtaTemplate):
|
|||||||
"""
|
"""
|
||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
from vnpy.app.cta_strategy import (
|
from vnpy.app.cta_strategy import (
|
||||||
CtaTemplate,
|
|
||||||
StopOrder,
|
StopOrder,
|
||||||
Direction,
|
|
||||||
TickData,
|
TickData,
|
||||||
BarData,
|
BarData,
|
||||||
TradeData,
|
TradeData,
|
||||||
@ -16,7 +14,7 @@ from vnpy.app.cta_strategy import (
|
|||||||
class RsiSignal(CtaSignal):
|
class RsiSignal(CtaSignal):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
def __init__(self, rsi_window , rsi_level):
|
def __init__(self, rsi_window: int, rsi_level: float):
|
||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
super(RsiSignal, self).__init__()
|
super(RsiSignal, self).__init__()
|
||||||
|
|
||||||
@ -27,7 +25,7 @@ class RsiSignal(CtaSignal):
|
|||||||
|
|
||||||
self.bg = BarGenerator(self.on_bar)
|
self.bg = BarGenerator(self.on_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
@ -38,12 +36,12 @@ class RsiSignal(CtaSignal):
|
|||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.am.update_bar(bar)
|
self.am.update_bar(bar)
|
||||||
if not self.am.inited:
|
if not self.am.inited:
|
||||||
self.set_signal_pos(0)
|
self.set_signal_pos(0)
|
||||||
|
|
||||||
rsi_value = self.am.rsi(self.rsi_window)
|
rsi_value = self.am.rsi(self.rsi_window)
|
||||||
|
|
||||||
if rsi_value >= self.rsi_long:
|
if rsi_value >= self.rsi_long:
|
||||||
self.set_signal_pos(1)
|
self.set_signal_pos(1)
|
||||||
elif rsi_value <= self.rsi_short:
|
elif rsi_value <= self.rsi_short:
|
||||||
@ -51,10 +49,11 @@ class RsiSignal(CtaSignal):
|
|||||||
else:
|
else:
|
||||||
self.set_signal_pos(0)
|
self.set_signal_pos(0)
|
||||||
|
|
||||||
|
|
||||||
class CciSignal(CtaSignal):
|
class CciSignal(CtaSignal):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
def __init__(self, cci_window, cci_level):
|
def __init__(self, cci_window: int, cci_level: float):
|
||||||
""""""
|
""""""
|
||||||
super(CciSignal, self).__init__()
|
super(CciSignal, self).__init__()
|
||||||
|
|
||||||
@ -64,8 +63,8 @@ class CciSignal(CtaSignal):
|
|||||||
self.cci_short = -self.cci_level
|
self.cci_short = -self.cci_level
|
||||||
|
|
||||||
self.bg = BarGenerator(self.on_bar)
|
self.bg = BarGenerator(self.on_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
@ -76,32 +75,33 @@ class CciSignal(CtaSignal):
|
|||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.am.update_bar(bar)
|
self.am.update_bar(bar)
|
||||||
if not self.am.inited:
|
if not self.am.inited:
|
||||||
self.set_signal_pos(0)
|
self.set_signal_pos(0)
|
||||||
|
|
||||||
cci_value = self.am.cci(self.cci_window)
|
cci_value = self.am.cci(self.cci_window)
|
||||||
|
|
||||||
if cci_value >= self.cci_long:
|
if cci_value >= self.cci_long:
|
||||||
self.set_signal_pos(1)
|
self.set_signal_pos(1)
|
||||||
elif cci_value<= self.cci_short:
|
elif cci_value <= self.cci_short:
|
||||||
self.set_signal_pos(-1)
|
self.set_signal_pos(-1)
|
||||||
else:
|
else:
|
||||||
self.set_signal_pos(0)
|
self.set_signal_pos(0)
|
||||||
|
|
||||||
|
|
||||||
class MaSignal(CtaSignal):
|
class MaSignal(CtaSignal):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
def __init__(self, fast_window, slow_window):
|
def __init__(self, fast_window: int, slow_window: int):
|
||||||
""""""
|
""""""
|
||||||
super(MaSignal, self).__init__()
|
super(MaSignal, self).__init__()
|
||||||
|
|
||||||
self.fast_window = fast_window
|
self.fast_window = fast_window
|
||||||
self.slow_window = slow_window
|
self.slow_window = slow_window
|
||||||
|
|
||||||
self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
|
self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
|
||||||
self.am = ArrayManager()
|
self.am = ArrayManager()
|
||||||
|
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
@ -113,16 +113,16 @@ class MaSignal(CtaSignal):
|
|||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.bg.update_bar(bar)
|
self.bg.update_bar(bar)
|
||||||
|
|
||||||
def on_5min_bar(self, bar:BarData):
|
def on_5min_bar(self, bar: BarData):
|
||||||
""""""
|
""""""
|
||||||
self.am.update_bar(bar)
|
self.am.update_bar(bar)
|
||||||
if not self.am.inited:
|
if not self.am.inited:
|
||||||
self.set_signal_pos(0)
|
self.set_signal_pos(0)
|
||||||
|
|
||||||
fast_ma = self.am.sma(self.fast_window)
|
fast_ma = self.am.sma(self.fast_window)
|
||||||
slow_ma = self.am.sma(self.slow_window)
|
slow_ma = self.am.sma(self.slow_window)
|
||||||
|
|
||||||
if fast_ma > slow_ma:
|
if fast_ma > slow_ma:
|
||||||
self.set_signal_pos(1)
|
self.set_signal_pos(1)
|
||||||
elif fast_ma < slow_ma:
|
elif fast_ma < slow_ma:
|
||||||
@ -133,20 +133,21 @@ class MaSignal(CtaSignal):
|
|||||||
|
|
||||||
class MultiSignalStrategy(TargetPosTemplate):
|
class MultiSignalStrategy(TargetPosTemplate):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
author ='用Python的交易员'
|
|
||||||
|
|
||||||
rsi_window= 14
|
author = '用Python的交易员'
|
||||||
|
|
||||||
|
rsi_window = 14
|
||||||
rsi_level = 20
|
rsi_level = 20
|
||||||
cci_window = 30
|
cci_window = 30
|
||||||
cci_level = 10
|
cci_level = 10
|
||||||
fast_window = 5
|
fast_window = 5
|
||||||
slow_window = 20
|
slow_window = 20
|
||||||
|
|
||||||
signal_pos = {}
|
signal_pos = {}
|
||||||
|
|
||||||
parameters = ['rsi_window','rsi_level','cci_window','cci_level','fast_window','slow_window']
|
parameters = ['rsi_window', 'rsi_level', 'cci_window',
|
||||||
variables = ['signal_pos','target_pos']
|
'cci_level', 'fast_window', 'slow_window']
|
||||||
|
variables = ['signal_pos', 'target_pos']
|
||||||
|
|
||||||
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
|
||||||
""""""
|
""""""
|
||||||
@ -157,13 +158,13 @@ class MultiSignalStrategy(TargetPosTemplate):
|
|||||||
self.rsi_signal = RsiSignal(self.rsi_window, self.rsi_level)
|
self.rsi_signal = RsiSignal(self.rsi_window, self.rsi_level)
|
||||||
self.cci_signal = CciSignal(self.cci_window, self.cci_level)
|
self.cci_signal = CciSignal(self.cci_window, self.cci_level)
|
||||||
self.ma_signal = MaSignal(self.fast_window, self.slow_window)
|
self.ma_signal = MaSignal(self.fast_window, self.slow_window)
|
||||||
|
|
||||||
self.signal_pos = {
|
self.signal_pos = {
|
||||||
"rsi": 0,
|
"rsi": 0,
|
||||||
"cci": 0,
|
"cci": 0,
|
||||||
"ma": 0
|
"ma": 0
|
||||||
}
|
}
|
||||||
|
|
||||||
def on_init(self):
|
def on_init(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is inited.
|
Callback when strategy is inited.
|
||||||
@ -176,7 +177,7 @@ class MultiSignalStrategy(TargetPosTemplate):
|
|||||||
Callback when strategy is started.
|
Callback when strategy is started.
|
||||||
"""
|
"""
|
||||||
self.write_log("策略启动")
|
self.write_log("策略启动")
|
||||||
|
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is stopped.
|
Callback when strategy is stopped.
|
||||||
@ -188,37 +189,37 @@ class MultiSignalStrategy(TargetPosTemplate):
|
|||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
"""
|
"""
|
||||||
super(MultiSignalStrategy, self).on_tick(tick)
|
super(MultiSignalStrategy, self).on_tick(tick)
|
||||||
|
|
||||||
self.rsi_signal.on_tick(tick)
|
self.rsi_signal.on_tick(tick)
|
||||||
self.cci_signal.on_tick(tick)
|
self.cci_signal.on_tick(tick)
|
||||||
self.ma_signal.on_tick(tick)
|
self.ma_signal.on_tick(tick)
|
||||||
|
|
||||||
self.calculate_target_pos()
|
self.calculate_target_pos()
|
||||||
|
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
super(MultiSignalStrategy, self).on_bar(bar)
|
super(MultiSignalStrategy, self).on_bar(bar)
|
||||||
|
|
||||||
self.rsi_signal.on_bar(bar)
|
self.rsi_signal.on_bar(bar)
|
||||||
self.cci_signal.on_bar(bar)
|
self.cci_signal.on_bar(bar)
|
||||||
self.ma_signal.on_bar(bar)
|
self.ma_signal.on_bar(bar)
|
||||||
|
|
||||||
self.calculate_target_pos()
|
self.calculate_target_pos()
|
||||||
|
|
||||||
def calculate_target_pos(self):
|
def calculate_target_pos(self):
|
||||||
""""""
|
""""""
|
||||||
self.signal_pos['rsi'] = self.rsi_signal.get_signal_pos()
|
self.signal_pos['rsi'] = self.rsi_signal.get_signal_pos()
|
||||||
self.signal_pos['cci'] = self.cci_signal.get_signal_pos()
|
self.signal_pos['cci'] = self.cci_signal.get_signal_pos()
|
||||||
self.signal_pos['ma'] = self.ma_signal.get_signal_pos()
|
self.signal_pos['ma'] = self.ma_signal.get_signal_pos()
|
||||||
|
|
||||||
target_pos = 0
|
target_pos = 0
|
||||||
for v in self.signal_pos.values():
|
for v in self.signal_pos.values():
|
||||||
target_pos += v
|
target_pos += v
|
||||||
|
|
||||||
self.set_target_pos(target_pos)
|
self.set_target_pos(target_pos)
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
Callback of new order data update.
|
Callback of new order data update.
|
||||||
@ -235,4 +236,4 @@ class MultiSignalStrategy(TargetPosTemplate):
|
|||||||
"""
|
"""
|
||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
from abc import ABC
|
from abc import ABC
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
from vnpy.trader.constant import Interval
|
from vnpy.trader.constant import Interval, Status
|
||||||
from vnpy.trader.object import BarData, TickData, OrderData, TradeData
|
from vnpy.trader.object import BarData, TickData, OrderData, TradeData
|
||||||
|
|
||||||
from .base import CtaOrderType, StopOrder
|
from .base import CtaOrderType, StopOrder, EngineType
|
||||||
|
|
||||||
|
|
||||||
class CtaTemplate(ABC):
|
class CtaTemplate(ABC):
|
||||||
@ -246,8 +246,8 @@ class CtaSignal(ABC):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
""""""
|
""""""
|
||||||
self.signal_pos = 0
|
self.signal_pos = 0
|
||||||
|
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
@ -260,26 +260,25 @@ class CtaSignal(ABC):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def set_signal_pos(self, pos):
|
def set_signal_pos(self, pos):
|
||||||
""""""
|
""""""
|
||||||
self.signal_pos = pos
|
self.signal_pos = pos
|
||||||
|
|
||||||
def get_signal_pos(self):
|
def get_signal_pos(self):
|
||||||
""""""
|
""""""
|
||||||
return self.signal_pos
|
return self.signal_pos
|
||||||
|
|
||||||
|
|
||||||
class TargetPosTemplate(CtaTemplate):
|
class TargetPosTemplate(CtaTemplate):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
author = '量衍投资'
|
author = '量衍投资'
|
||||||
|
|
||||||
tick_add = 1
|
tick_add = 1
|
||||||
last_tick = None
|
last_tick = None
|
||||||
last_bar = None
|
last_bar = None
|
||||||
target_pos = 0
|
target_pos = 0
|
||||||
orderList = []
|
orderList = []
|
||||||
|
|
||||||
variables = ['target_pos']
|
variables = ['target_pos']
|
||||||
|
|
||||||
@ -287,74 +286,74 @@ class TargetPosTemplate(CtaTemplate):
|
|||||||
""""""
|
""""""
|
||||||
super(TargetPosTemplate, self).__init__(
|
super(TargetPosTemplate, self).__init__(
|
||||||
cta_engine, strategy_name, vt_symbol, setting
|
cta_engine, strategy_name, vt_symbol, setting
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_tick(self, tick:TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
"""
|
"""
|
||||||
self.last_tick = tick
|
self.last_tick = tick
|
||||||
|
|
||||||
if self.trading:
|
if self.trading:
|
||||||
self.trade()
|
self.trade()
|
||||||
|
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.last_bar = bar
|
self.last_bar = bar
|
||||||
|
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
Callback of new order data update.
|
Callback of new order data update.
|
||||||
"""
|
"""
|
||||||
if order.status == Status.ALLTRADED or order.status == Status.CANCELLED:
|
if order.status == Status.ALLTRADED or order.status == Status.CANCELLED:
|
||||||
if order.vt_orderid in self.orderList:
|
if order.vt_orderid in self.orderList:
|
||||||
self.orderList.remove(order.vt_orderid)
|
self.orderList.remove(order.vt_orderid)
|
||||||
|
|
||||||
def set_target_pos(self, target_pos):
|
def set_target_pos(self, target_pos):
|
||||||
""""""
|
""""""
|
||||||
self.target_pos = target_pos
|
self.target_pos = target_pos
|
||||||
self.trade()
|
self.trade()
|
||||||
|
|
||||||
def trade(self):
|
def trade(self):
|
||||||
""""""
|
""""""
|
||||||
self.cancel_all()
|
self.cancel_all()
|
||||||
|
|
||||||
pos_change = self.target_pos - self.pos
|
pos_change = self.target_pos - self.pos
|
||||||
if not pos_change:
|
if not pos_change:
|
||||||
return
|
return
|
||||||
|
|
||||||
long_price = 0
|
long_price = 0
|
||||||
short_price = 0
|
short_price = 0
|
||||||
|
|
||||||
if self.last_tick:
|
if self.last_tick:
|
||||||
if pos_change > 0:
|
if pos_change > 0:
|
||||||
long_price = self.last_tick.ask_price_1 + self.tick_add
|
long_price = self.last_tick.ask_price_1 + self.tick_add
|
||||||
if self.last_tick.limit_up:
|
if self.last_tick.limit_up:
|
||||||
long_price = min(long_price, self.last_tick.limit_up)
|
long_price = min(long_price, self.last_tick.limit_up)
|
||||||
else:
|
else:
|
||||||
short_price = self.last_tick.bid_price_1 - self.tick_add
|
short_price = self.last_tick.bid_price_1 - self.tick_add
|
||||||
if self.last_tick.limit_down:
|
if self.last_tick.limit_down:
|
||||||
short_price = max(short_price, self.last_tick.limit_down)
|
short_price = max(short_price, self.last_tick.limit_down)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if pos_change > 0:
|
if pos_change > 0:
|
||||||
long_price = self.last_bar.close_price + self.tick_add
|
long_price = self.last_bar.close_price + self.tick_add
|
||||||
else:
|
else:
|
||||||
short_price = self.last_bar.close_price - self.tick_add
|
short_price = self.last_bar.close_price - self.tick_add
|
||||||
|
|
||||||
if self.get_engine_type() == EngineType.BACKTESTING:
|
if self.get_engine_type() == EngineType.BACKTESTING:
|
||||||
if pos_change > 0:
|
if pos_change > 0:
|
||||||
vt_orderid = self.buy(long_price, abs(pos_change))
|
vt_orderid = self.buy(long_price, abs(pos_change))
|
||||||
else:
|
else:
|
||||||
vt_orderid = self.short(short_price, abs(pos_change))
|
vt_orderid = self.short(short_price, abs(pos_change))
|
||||||
self.orderList.append(vt_orderid)
|
self.orderList.append(vt_orderid)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if self.orderList:
|
if self.orderList:
|
||||||
return
|
return
|
||||||
|
|
||||||
if pos_change > 0:
|
if pos_change > 0:
|
||||||
if self.pos < 0:
|
if self.pos < 0:
|
||||||
if pos_change < abs(self.pos):
|
if pos_change < abs(self.pos):
|
||||||
@ -371,4 +370,4 @@ class TargetPosTemplate(CtaTemplate):
|
|||||||
vt_orderid = self.sell(short_price, abs(self.pos))
|
vt_orderid = self.sell(short_price, abs(self.pos))
|
||||||
else:
|
else:
|
||||||
vt_orderid = self.short(short_price, abs(pos_change))
|
vt_orderid = self.short(short_price, abs(pos_change))
|
||||||
self.orderList.append(vt_orderid)
|
self.orderList.append(vt_orderid)
|
||||||
|
@ -4,7 +4,39 @@
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from vnpy.api.ctp import *
|
from vnpy.api.ctp import (
|
||||||
|
MdApi,
|
||||||
|
TdApi,
|
||||||
|
THOST_FTDC_OAS_Submitted,
|
||||||
|
THOST_FTDC_OAS_Accepted,
|
||||||
|
THOST_FTDC_OAS_Rejected,
|
||||||
|
THOST_FTDC_OST_NoTradeQueueing,
|
||||||
|
THOST_FTDC_OST_PartTradedQueueing,
|
||||||
|
THOST_FTDC_OST_AllTraded,
|
||||||
|
THOST_FTDC_OST_Canceled,
|
||||||
|
THOST_FTDC_D_Buy,
|
||||||
|
THOST_FTDC_D_Sell,
|
||||||
|
THOST_FTDC_PD_Long,
|
||||||
|
THOST_FTDC_PD_Short,
|
||||||
|
THOST_FTDC_OPT_LimitPrice,
|
||||||
|
THOST_FTDC_OPT_AnyPrice,
|
||||||
|
THOST_FTDC_OF_Open,
|
||||||
|
THOST_FTDC_OFEN_Close,
|
||||||
|
THOST_FTDC_OFEN_CloseYesterday,
|
||||||
|
THOST_FTDC_OFEN_CloseToday,
|
||||||
|
THOST_FTDC_PC_Futures,
|
||||||
|
THOST_FTDC_PC_Options,
|
||||||
|
THOST_FTDC_CP_CallOptions,
|
||||||
|
THOST_FTDC_CP_PutOptions,
|
||||||
|
THOST_FTDC_HF_Speculation,
|
||||||
|
THOST_FTDC_CC_Immediately,
|
||||||
|
THOST_FTDC_FCC_NotForceClose,
|
||||||
|
THOST_FTDC_TC_GFD,
|
||||||
|
THOST_FTDC_VC_AV,
|
||||||
|
THOST_FTDC_TC_IOC,
|
||||||
|
THOST_FTDC_VC_CV,
|
||||||
|
THOST_FTDC_AF_Delete
|
||||||
|
)
|
||||||
from vnpy.trader.constant import (
|
from vnpy.trader.constant import (
|
||||||
Direction,
|
Direction,
|
||||||
Offset,
|
Offset,
|
||||||
@ -84,6 +116,7 @@ symbol_exchange_map = {}
|
|||||||
symbol_name_map = {}
|
symbol_name_map = {}
|
||||||
symbol_size_map = {}
|
symbol_size_map = {}
|
||||||
|
|
||||||
|
|
||||||
class CtpGateway(BaseGateway):
|
class CtpGateway(BaseGateway):
|
||||||
"""
|
"""
|
||||||
VN Trader Gateway for CTP .
|
VN Trader Gateway for CTP .
|
||||||
@ -489,7 +522,7 @@ class CtpTdApi(TdApi):
|
|||||||
account = AccountData(
|
account = AccountData(
|
||||||
accountid=data["AccountID"],
|
accountid=data["AccountID"],
|
||||||
balance=data["Balance"],
|
balance=data["Balance"],
|
||||||
frozen=data["FrozenMargin"]+data["FrozenCash"]+data["FrozenCommission"],
|
frozen=data["FrozenMargin"] + data["FrozenCash"] + data["FrozenCommission"],
|
||||||
gateway_name=self.gateway_name
|
gateway_name=self.gateway_name
|
||||||
)
|
)
|
||||||
account.available = data["Available"]
|
account.available = data["Available"]
|
||||||
@ -734,7 +767,4 @@ class CtpTdApi(TdApi):
|
|||||||
def close(self):
|
def close(self):
|
||||||
""""""
|
""""""
|
||||||
if self.connect_status:
|
if self.connect_status:
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -322,8 +322,7 @@ class FutuGateway(BaseGateway):
|
|||||||
account = AccountData(
|
account = AccountData(
|
||||||
accountid=f"{self.gateway_name}_{self.market}",
|
accountid=f"{self.gateway_name}_{self.market}",
|
||||||
balance=float(row["total_assets"]),
|
balance=float(row["total_assets"]),
|
||||||
frozen=(float(row["total_assets"]) -
|
frozen=(float(row["total_assets"]) - float(row["avl_withdrawal_cash"])),
|
||||||
float(row["avl_withdrawal_cash"])),
|
|
||||||
gateway_name=self.gateway_name,
|
gateway_name=self.gateway_name,
|
||||||
)
|
)
|
||||||
self.on_account(account)
|
self.on_account(account)
|
||||||
|
Loading…
Reference in New Issue
Block a user