# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.from cmath import isclosefrom AlgorithmImports import *### <summary>### Demonstration of how to use custom security properties.### In this algorithm we trade a security based on the values of a slow and fast EMAs which are stored in the security itself.### </summary>class SecurityCustomPropertiesAlgorithm(QCAlgorithm):'''Demonstration of how to use custom security properties.In this algorithm we trade a security based on the values of a slow and fast EMAs which are stored in the security itself.'''def initialize(self):self.set_start_date(2013,10, 7)self.set_end_date(2013,10,11)self.set_cash(100000)self.spy = self.add_equity("SPY", Resolution.MINUTE)# Using the dynamic interface to store our indicator as a custom property.self.spy.slow_ema = self.ema(self.spy.symbol, 30, Resolution.MINUTE)# Using the generic interface to store our indicator as a custom property.self.spy.add("fast_ema", self.ema(self.spy.symbol, 60, Resolution.MINUTE))# Using the indexer to store our indicator as a custom propertyself.spy["bb"] = self.bb(self.spy.symbol, 20, 1, MovingAverageType.SIMPLE, Resolution.MINUTE)# Fee factor to be used by the custom fee modelself.spy.fee_factor = 0.00002self.spy.set_fee_model(CustomFeeModel())# This property will be used to store the prices used to calculate the fees in order to assert the correct fee factor is used.self.spy.orders_fees_prices = {}def on_data(self, data):if not self.spy.fast_ema.is_ready:returnif not self.portfolio.invested:# Using the property and the generic interface to access our indicatorif self.spy.slow_ema > self.spy.fast_ema:self.set_holdings(self.spy.symbol, 1)else:if self.spy.get[ExponentialMovingAverage]("slow_ema") < self.spy.get[ExponentialMovingAverage]("fast_ema"):self.liquidate(self.spy.symbol)# Using the indexer to access our indicatorbb: BollingerBands = self.spy["bb"]self.plot("bb", bb.upper_band, bb.middle_band, bb.lower_band)def on_order_event(self, order_event):if order_event.status == OrderStatus.FILLED:fee = order_event.order_feeexpected_fee = self.spy.orders_fees_prices[order_event.order_id] * order_event.absolute_fill_quantity * self.spy.fee_factorif not isclose(fee.value.amount, expected_fee, rel_tol=1e-15):raise AssertionError(f"Custom fee model failed to set the correct fee. Expected: {expected_fee}. Actual: {fee.value.amount}")def on_end_of_algorithm(self):if self.transactions.orders_count == 0:raise AssertionError("No orders executed")class CustomFeeModel(FeeModel):'''This custom fee is implemented for demonstration purposes only.'''def get_order_fee(self, parameters):security = parameters.security# custom fee math using the fee factor stored in security instancefee_factor = security.fee_factorif fee_factor is None:fee_factor = 0.00001# Store the price used to calculate the fee for this ordersecurity["orders_fees_prices"][parameters.order.id] = security.pricefee = max(1.0, security.price * parameters.order.absolute_quantity * fee_factor)return OrderFee(CashAmount(fee, "USD"))
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。