利用pipeline提供的買賣清單與持股權重進行定期再平衡的演算法。
本文件包含以下部份:
基本設定
參數說明與範例
API Reference:參數說明。
Examples:範例。
import pandas as pd
import datetime
import tejapi
import os
# set tej_key and base
os.environ['TEJAPI_KEY'] = "your key"
os.environ['TEJAPI_BASE'] = "https://api.tej.com.tw"
# set benchmark
benchmark=['IR0001']
# set calendar
calendar_name='TEJ_XTAI'
# set bundle name
bundle_name = 'tquant'
# set date
start='2023-06-01'
end='2023-10-03'
# 由文字型態轉為Timestamp,供回測使用
tz = 'UTC'
start_dt, end_dt = pd.Timestamp(start, tz = tz), pd.Timestamp(end, tz = tz)
# 設定os.environ['mdate'] = start+' '+end,供ingest bundle使用
os.environ['mdate'] = start+' '+end
from zipline.sources.TEJ_Api_Data import get_universe
StockList = get_universe(start, end, idx_id='IX0002')
print(len(StockList))
Currently used TEJ API key call quota 67/9223372036854775807 (0.0%) Currently used TEJ API key data quota 2255014/9223372036854775807 (0.0%) 55
os.environ['ticker'] = ' '.join(StockList + benchmark)
os.environ['ticker']
'1101 1216 1301 1303 1326 1402 1590 1605 2002 2207 2301 2303 2308 2317 2327 2330 2345 2357 2379 2382 2395 2408 2412 2454 2603 2609 2615 2801 2880 2881 2882 2883 2884 2885 2886 2887 2890 2891 2892 2912 3008 3034 3037 3045 3231 3711 4904 4938 5871 5876 5880 6415 6505 6669 9910 IR0001'
# Ingest pricing bundle
!zipline ingest -b tquant
Merging daily equity files: Currently used TEJ API key call quota 72/9223372036854775807 (0.0%) Currently used TEJ API key data quota 2261479/9223372036854775807 (0.0%)
[2024-03-13 02:40:44.060855] INFO: zipline.data.bundles.core: Ingesting tquant. [2024-03-13 02:40:49.764291] INFO: zipline.data.bundles.core: Ingest tquant successfully.
from zipline.data.data_portal import get_bundle_price
df_bundle_price = get_bundle_price(bundle_name=bundle_name,
calendar_name=calendar_name,
start_dt=start_dt,
end_dt=end_dt)
import warnings
warnings.filterwarnings('ignore')
from time import time
import numpy as np
import pandas as pd
import empyrical as ep
from logbook import Logger, StderrHandler, INFO, WARNING
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from TejToolAPI.TejToolAPI import *
from zipline.api import record
from zipline.utils.calendar_utils import get_calendar
from zipline.utils.run_algo import (get_transaction_detail,
get_record_vars)
from zipline.pipeline import Pipeline, CustomFactor
from zipline.pipeline.filters import SingleAsset
from zipline.pipeline.factors import RSI
from zipline.pipeline.data import TQAltDataSet
from zipline.finance import slippage
from zipline.TQresearch.tej_pipeline import run_pipeline
# 設定log顯示方式
log_handler = StderrHandler(format_string='[{record.time:%Y-%m-%d %H:%M:%S.%f}]: ' +
'{record.level_name}: {record.func_name}: {record.message}',
level=INFO)
log_handler.push_application()
log = Logger('Algorithm')
import warnings
warnings.filterwarnings('ignore')
col = ['Market_Cap_Dollars']
fields = ''
for i in col:
fields += i
fields += ' '
os.environ['fields'] = fields
# Ingest Fundamental Bundle
!zipline ingest -b fundamentals
Currently used TEJ API key call quota 83/9223372036854775807 (0.0%) Currently used TEJ API key data quota 2298569/9223372036854775807 (0.0%)
[2024-03-13 02:40:54.272410] INFO: zipline.data.bundles.core: Ingesting fundamentals. [2024-03-13 02:41:05.038363] INFO: zipline.data.bundles.core: Ingest fundamentals successfully.
(self, bundle_name='tquant', start_session=None, end_session=None, trading_calendar=get_calendar('TEJ_XTAI'),
capital_base=1e7, data_frequency='daily', tradeday=None, rebalance_date_rule=None, stocklist=None, benchmark='IR0001',
zero_treasury_returns=True, slippage_model=slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1),
commission_model=commission.Custom_TW_Commission(min_trade_cost=20, discount = 1.0, tax = 0.003), max_leverage=0.8,
limit_buy_multiplier=None, limit_sell_multiplier=None, allow_short=False, cancel_datedelta=None, custom_weight=False,
custom_loader=None, pipeline=None, analyze=None, record_vars=None, get_record_vars=False, get_transaction_detail=False,
order_filling_policy='next_bar')
利用pipeline提供的買賣清單與持股權重進行定期再平衡的演算法。必要參數僅有pipeline
。
bundle_name (str, optional)-bundle名稱。預設是 'tquant'
。
start_session (pd.Timestamp or datetime, optional)-回測起始日期。預設是bundle中最早的資料日期。
end_session (pd.Timestamp or datetime, optional)-回測結束日期。預設是bundle中最晚的資料日期。
trading_calendar (TradingCalendar, optional)-
get_calendar('TEJ_XTAI')
。zipline.utils.calendar_utils.TradingCalendar
。capital_base (float, optional)-初始資金額度。預設是一千萬。
data_frequency ({'daily', 'minute'}, optional)-資料頻率,目前僅支援日頻率 'daily'
。
tradeday (list[str] or list[pd.Timestamp] or pd.DatetimeIndex, optional)-
rebalance_date_rule
與tradeday
請擇一設定,若兩者皆設定,則會以rebalance_date_rule
為主。rebalance_date_rule(EventRule, optional)-
rebalance_date_rule
與tradeday
請擇一設定,若兩者皆設定,則會以rebalance_date_rule
為主。zipline.utils.events.EventRule
。可使用的rebalance_date_rule
參考zipline.api.date_rules。stocklist (list[str], optional)-交易清單,限制只能交易這個清單中的股票。預設是None,代表使用所有bundle中的股票。
benchmark (str, optional)-指數名稱,用來與投資組合報酬率比較。預設是'IR0001'
,代表台灣發行量加權股價報酬指數。
zero_treasury_returns (bool, optional)-
algo.run()
產出的回測報表中,treasury_return
與treasury_period_return
皆會是0。slippage_model (SlippageModel, optional)-
slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)
。可使用的模型參考:lecture/Zipline Slippage.ipynbzipline.finance.slippage.SlippageModel
。commission_model (CommissionModel, optional)-
commission.Custom_TW_Commission(min_trade_cost=20, discount=1.0, tax = 0.003)
。可使用的模型參考:lecture/Zipline Commission Models.ipynbzipline.finance.commission.CommissionModel
max_leverage (float, optional)-槓桿限制,預設 = 0.8。
limit_buy_multiplier (float, optional)-
limit_buy_multiplier
。limit_sell_multiplier (float, optional)-
limit_sell_multiplier
。allow_short (bool, optional)-是否允許放空股票,預設為False,代表僅能做多。若設定為True,則pipeline中需要有shorts
欄位。
cancel_datedelta (int, optional)-訂單幾天內未完全成交就取消。預設是在下一次再平衡時取消。
custom_weight (bool, optional)-
long_weights
(若allow_short
=True,則也須有short_weights
)欄位。custom_loader (PipelineLoader , optional)-
TQDataSet
與TQAltDataSet
以外資料。zipline.pipeline.data.TQDataSet
zipline.pipeline.data.TQAltDataSet
PipelineLoader
:zipline.pipeline.loaders.frame.DataFrameLoader
)。pipeline (Pipeline)-
zipline.pipeline.Pipeline
analyze (callable[(context, pd.DataFrame) -> None], optional)-
analyze
函式以用於回測,函式中必須要有context
與perf
參數,預設是None。record_vars (callable[(context, BarData) -> None], optional)-
record_vars
函式以用於回測,函式中必須要有context
與data
參數,預設是None。get_record_vars (bool, optional)-
record_vars
中record
方法所記錄的變數,預設為False,代表不產出。algo.dict_record_vars
取出。get_transaction_detail (bool, optional)-
algo.positions
、algo.transactions
、algo.orders
方式取出交易結果。order_filling_policy (str, optional)-
algo
zipline.algo.pipeline_algo.TargetPercentPipeAlgo
run()
執行演算法
Returns:
- perf(回測報表)
Return type:
- pd.DataFrame
zipline.api.schedule_function
的date_rule
參數中。用來決定要以何種頻率觸發某項規則。from zipline.api import date_rules
。static every_day()
每日觸發某項規則。
Returns:
- rule
Return type:
- zipline.utils.events.EventRule
static month_end(days_offset=0)
每個月底觸發某項規則,並可以選擇性的新增一個偏移量。
Parameters:
- days_offset(int , optional):
- 在月底之前的第幾個交易日(由0開始計算)觸發某項規則。預設值是0,即在月底的最後一個交易日觸發。
- days_offset只能介於0~22之間。
Returns:
- rule
Return type:
- zipline.utils.events.EventRule
static month_start(days_offset=0)
每個月初觸發某項規則,並可以選擇性的新增一個偏移量。
Parameters:
- days_offset(int , optional):
- 在月初之後的第幾個交易日(由0開始計算)才觸發某項規則。預設值是0,即在月初的第一個交易日觸發。
- days_offset只能介於0~22之間。
Returns:
- rule
Return type:
- zipline.utils.events.EventRule
static week_end(days_offset=0)
在每周最後一個交易日觸發某項規則,並可以選擇性的新增一個偏移量。
Parameters:
- days_offset(int , optional):
- 在每周倒數第幾個交易日(由0開始計算)觸發某項規則。預設值是0,即在每周的最後一個交易日觸發。
- days_offset只能介於0~4之間。
Returns:
- rule
Return type:
- zipline.utils.events.EventRule
static week_start(days_offset=0)
在每周的第一個交易日觸發某項規則,並可以選擇性的新增一個偏移量。
Parameters:
- days_offset(int , optional):
- 在每周的第幾個交易日(由0開始計算)才觸發某項規則。預設值是0,即在每周的第一個交易日觸發。
- days_offset只能介於0~4之間。
Returns:
- rule
Return type:
- zipline.utils.events.EventRule
from zipline.utils.algo_instance import get_algo_instance, set_algo_instance
from zipline.algo.pipeline_algo import TargetPercentPipeAlgo
僅調整start_session
與end_session
。其餘保持預設值。
以下設定pipeline(make_pipeline()
),並定義longs
欄位用來判斷須持有的股票。在longs
欄位中要持有的股票標記為True,反之標記為False。
from zipline.data import bundles
bundle = bundles.load(bundle_name)
def make_pipeline():
rsi = RSI()
longs = rsi.top(2, mask = ~SingleAsset(bundle.asset_finder.lookup_symbol('IR0001', as_of_date=None)))
return Pipeline(
columns = {
"longs" : longs,
}
)
algo_start = '2023-09-21'
algo_start_dt = pd.Timestamp(algo_start, tz = tz)
result = run_pipeline(make_pipeline(), algo_start, end)
result.query('longs == True')
longs | ||
---|---|---|
2023-09-22 00:00:00+00:00 | Equity(6 [1590]) | True |
Equity(24 [2603]) | True | |
2023-09-25 00:00:00+00:00 | Equity(25 [2609]) | True |
Equity(34 [2886]) | True | |
2023-09-26 00:00:00+00:00 | Equity(33 [2885]) | True |
Equity(34 [2886]) | True | |
2023-09-27 00:00:00+00:00 | Equity(25 [2609]) | True |
Equity(34 [2886]) | True | |
2023-09-28 00:00:00+00:00 | Equity(6 [1590]) | True |
Equity(34 [2886]) | True | |
2023-10-02 00:00:00+00:00 | Equity(24 [2603]) | True |
Equity(34 [2886]) | True | |
2023-10-03 00:00:00+00:00 | Equity(6 [1590]) | True |
Equity(14 [2327]) | True |
TargetPercentPipeAlgo
並命名為algo
。set_algo_instance(algo)
stats
(pd.DataFrame):stats = algo.run()
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:05.491033]: INFO: rebalance: Cancel_order: current time: 2023-09-22 , created: 2023-09-21 , asset: Equity(46 [4904]), amount: 55478 , filled: 51900 [2024-03-13 02:41:05.499675]: INFO: rebalance: Cancel_order: current time: 2023-09-25 , created: 2023-09-25 , asset: Equity(46 [4904]), amount: -14450 , filled: 0 [2024-03-13 02:41:05.504262]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 54616.31935744 [2024-03-13 02:41:05.505924]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 4062, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:05.506228]: INFO: handle_split: returning cash: 643.94 [2024-03-13 02:41:05.549641]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
查看演算法中的參數設定
algo
TargetPercentPipeAlgo( sim_params = SimulationParameters( start_session=2023-09-21 00:00:00+00:00, end_session=2023-10-03 00:00:00+00:00, capital_base=10000000.0, data_frequency=daily, emission_rate=daily, first_open=2023-09-21 01:01:00+00:00, last_close=2023-10-03 05:30:00+00:00, trading_calendar=<exchange_calendars.exchange_calendar_tejxtai.TEJ_XTAIExchangeCalendar object at 0x0000017B415030D0> ), benchmark = IR0001, zero treasury returns or not(if "True" then treasury returns = 0)= True, max_leverage = 0.8, slippage model used = VolumeShareSlippage( volume_limit=0.025, price_impact=0.1), commission_model = Custom_TW_Commission(min_trade_cost=20.0), liquidity_risk_management_rule = None, order_filling_policy = next_bar, adjust amount or not = False, limit_buy_multiplier = None, limit_sell_multiplier = None, allow short or not(if "False" then long only)= False, use custom weight or not(if not then "equal weighted")= False, cancel_datedelta(if "None" then cancel open orders at next rebalance date)= None, stocklist = ['1101', '1216', '1301', '1303', '1326', '1402', '1590', '1605', '2002', '2207', '2301', '2303', '2308', '2317', '2327', '2330', '2345', '2357', '2379', '2382', '2395', '2408', '2412', '2454', '2603', '2609', '2615', '2801', '2880', '2881', '2882', '2883', '2884', '2885', '2886', '2887', '2890', '2891', '2892', '2912', '3008', '3034', '3037', '3045', '3231', '3711', '4904', '4938', '5871', '5876', '5880', '6415', '6505', '6669', '9910', 'IR0001'], tradeday = DatetimeIndex(['2023-09-21 00:00:00+00:00', '2023-09-22 00:00:00+00:00', '2023-09-25 00:00:00+00:00', '2023-09-26 00:00:00+00:00', '2023-09-27 00:00:00+00:00', '2023-09-28 00:00:00+00:00', '2023-10-02 00:00:00+00:00', '2023-10-03 00:00:00+00:00'], dtype='datetime64[ns, UTC]', freq='C'), rebalance_date_rule(If the "rebalance_date_rule" parameter is provided, then ignore the "tradeday" parameter.") = None, get transaction detail or not = False, blotter = SimulationBlotter( slippage_models={<class 'zipline.assets._assets.Equity'>: VolumeShareSlippage( volume_limit=0.025, price_impact=0.1), <class 'zipline.assets._assets.Future'>: VolatilityVolumeShare(volume_limit=0.05, eta=<varies>)}, commission_models={<class 'zipline.assets._assets.Equity'>: Custom_TW_Commission(min_trade_cost=20.0), <class 'zipline.assets._assets.Future'>: PerContract(cost_per_contract=0.85, exchange_fee=<varies>, min_trade_cost=0)}, open_orders=defaultdict(<class 'list'>, {Equity(24 [2603]): [Order({'id': '307a0683715641db990a5ac44c1077bf', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': -33982, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(24 [2603]), 'status': <ORDER_STATUS.OPEN: 0>})], Equity(34 [2886]): [Order({'id': 'e5f6a3c19d2d4465ad5f0592eb6578c5', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': -102579, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.OPEN: 0>})], Equity(6 [1590]): [Order({'id': '4545f498f583429d8c867307ac34f9d5', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': 3846, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(6 [1590]), 'status': <ORDER_STATUS.OPEN: 0>})], Equity(14 [2327]): [Order({'id': '11c46077c2b549c9ab4c156f697053f6', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': 7381, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(14 [2327]), 'status': <ORDER_STATUS.OPEN: 0>})]}), orders={'bdcb9758340444948f3af991c6b2478b': Order({'id': 'bdcb9758340444948f3af991c6b2478b', 'dt': Timestamp('2023-09-22 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-21 05:30:00+0000', tz='UTC'), 'amount': 106951, 'filled': 106951, 'commission': 5761, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), 'acc3c2d89f8e48c3bc42daa9e8d81560': Order({'id': 'acc3c2d89f8e48c3bc42daa9e8d81560', 'dt': Timestamp('2023-09-22 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-21 05:30:00+0000', tz='UTC'), 'amount': 55478, 'filled': 51900, 'commission': 5333, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(46 [4904]), 'status': <ORDER_STATUS.CANCELLED: 2>}), '91e9060255b8480c88251ce5ed781b49': Order({'id': '91e9060255b8480c88251ce5ed781b49', 'dt': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-22 05:30:00+0000', tz='UTC'), 'amount': -106951, 'filled': -106951, 'commission': 17985, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), '71a11f3296354834956e3a801721c806': Order({'id': '71a11f3296354834956e3a801721c806', 'dt': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-22 05:30:00+0000', tz='UTC'), 'amount': -51900, 'filled': -37450, 'commission': 12081, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(46 [4904]), 'status': <ORDER_STATUS.CANCELLED: 2>}), '2777dbff1bbd48188466187cc31e69d3': Order({'id': '2777dbff1bbd48188466187cc31e69d3', 'dt': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-22 05:30:00+0000', tz='UTC'), 'amount': 34894, 'filled': 34894, 'commission': 5768, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(24 [2603]), 'status': <ORDER_STATUS.FILLED: 1>}), '1ec8dcf092f84220a87650c5db8959fc': Order({'id': '1ec8dcf092f84220a87650c5db8959fc', 'dt': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-22 05:30:00+0000', tz='UTC'), 'amount': 4064, 'filled': 4064, 'commission': 5682, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(6 [1590]), 'status': <ORDER_STATUS.FILLED: 1>}), 'f39524a1508142c9af7306307956f8e9': Order({'id': 'f39524a1508142c9af7306307956f8e9', 'dt': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'amount': -14450, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(46 [4904]), 'status': <ORDER_STATUS.CANCELLED: 2>}), 'dc7128121a9d40d182ec3d9d4d465492': Order({'id': 'dc7128121a9d40d182ec3d9d4d465492', 'dt': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'amount': -34894, 'filled': -34894, 'commission': 17835, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(24 [2603]), 'status': <ORDER_STATUS.FILLED: 1>}), 'ceec5c24911044baba3d8c0abab96960': Order({'id': 'ceec5c24911044baba3d8c0abab96960', 'dt': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'amount': -14450, 'filled': -14450, 'commission': 4649, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(46 [4904]), 'status': <ORDER_STATUS.FILLED: 1>}), 'c55dc4e5611246698718518b5ad46860': Order({'id': 'c55dc4e5611246698718518b5ad46860', 'dt': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'amount': -4062, 'filled': -4062, 'commission': 17221, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(6 [1590]), 'status': <ORDER_STATUS.FILLED: 1>}), '5ca0608910f8443a9c2ec23de6c1ab6f': Order({'id': '5ca0608910f8443a9c2ec23de6c1ab6f', 'dt': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'amount': 87136, 'filled': 87136, 'commission': 5706, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(25 [2609]), 'status': <ORDER_STATUS.FILLED: 1>}), 'aafbcc931d8e4f87adb21686aeb0f227': Order({'id': 'aafbcc931d8e4f87adb21686aeb0f227', 'dt': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-25 05:30:00+0000', tz='UTC'), 'amount': 105366, 'filled': 105366, 'commission': 5684, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), '153b35815aa44224aebbd79d673403b2': Order({'id': '153b35815aa44224aebbd79d673403b2', 'dt': Timestamp('2023-09-27 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'amount': -87136, 'filled': -87136, 'commission': 17699, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(25 [2609]), 'status': <ORDER_STATUS.FILLED: 1>}), 'b397a24cd315420683b711b7c933abc3': Order({'id': 'b397a24cd315420683b711b7c933abc3', 'dt': Timestamp('2023-09-27 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'amount': 157495, 'filled': 157495, 'commission': 5645, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(33 [2885]), 'status': <ORDER_STATUS.FILLED: 1>}), '2f3a95e39fd840dc8aca520f0c36f6b1': Order({'id': '2f3a95e39fd840dc8aca520f0c36f6b1', 'dt': Timestamp('2023-09-27 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-26 05:30:00+0000', tz='UTC'), 'amount': -1339, 'filled': -1339, 'commission': 224, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), '1ebe571a863a415297cd8aa1bc2b07b9': Order({'id': '1ebe571a863a415297cd8aa1bc2b07b9', 'dt': Timestamp('2023-09-28 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-27 05:30:00+0000', tz='UTC'), 'amount': -157495, 'filled': -157495, 'commission': 17458, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(33 [2885]), 'status': <ORDER_STATUS.FILLED: 1>}), '432d560b9e99476d846b3675db5b2d44': Order({'id': '432d560b9e99476d846b3675db5b2d44', 'dt': Timestamp('2023-09-28 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-27 05:30:00+0000', tz='UTC'), 'amount': 85400, 'filled': 85400, 'commission': 5532, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(25 [2609]), 'status': <ORDER_STATUS.FILLED: 1>}), '9fb1d769ef504f44b2dd544653e997c2': Order({'id': '9fb1d769ef504f44b2dd544653e997c2', 'dt': Timestamp('2023-09-28 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-27 05:30:00+0000', tz='UTC'), 'amount': -51, 'filled': -51, 'commission': 26.0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), '5a76b96aecf749d683699d19b7fc687c': Order({'id': '5a76b96aecf749d683699d19b7fc687c', 'dt': Timestamp('2023-10-02 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-28 05:30:00+0000', tz='UTC'), 'amount': -85400, 'filled': -85400, 'commission': 16799, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(25 [2609]), 'status': <ORDER_STATUS.FILLED: 1>}), 'c2f1f413dea8434f9ef69b9f58c40810': Order({'id': 'c2f1f413dea8434f9ef69b9f58c40810', 'dt': Timestamp('2023-10-02 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-28 05:30:00+0000', tz='UTC'), 'amount': -412, 'filled': -412, 'commission': 70, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), 'c2c40f199a7f4f7a85e33a6f0fd9c3d7': Order({'id': 'c2c40f199a7f4f7a85e33a6f0fd9c3d7', 'dt': Timestamp('2023-10-02 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-09-28 05:30:00+0000', tz='UTC'), 'amount': 3988, 'filled': 3988, 'commission': 5712, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(6 [1590]), 'status': <ORDER_STATUS.FILLED: 1>}), '40c0549e04914d8db877272facf233f9': Order({'id': '40c0549e04914d8db877272facf233f9', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-02 05:30:00+0000', tz='UTC'), 'amount': -3988, 'filled': -3988, 'commission': 17612, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(6 [1590]), 'status': <ORDER_STATUS.FILLED: 1>}), 'b990b03de87744508a9bfcbab7e14ba6': Order({'id': 'b990b03de87744508a9bfcbab7e14ba6', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-02 05:30:00+0000', tz='UTC'), 'amount': 33982, 'filled': 33982, 'commission': 5351, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(24 [2603]), 'status': <ORDER_STATUS.FILLED: 1>}), 'fcc61389fce5448297c04514a9523155': Order({'id': 'fcc61389fce5448297c04514a9523155', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-02 05:30:00+0000', tz='UTC'), 'amount': -985, 'filled': -985, 'commission': 165, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.FILLED: 1>}), '307a0683715641db990a5ac44c1077bf': Order({'id': '307a0683715641db990a5ac44c1077bf', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': -33982, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(24 [2603]), 'status': <ORDER_STATUS.OPEN: 0>}), 'e5f6a3c19d2d4465ad5f0592eb6578c5': Order({'id': 'e5f6a3c19d2d4465ad5f0592eb6578c5', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': -102579, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(34 [2886]), 'status': <ORDER_STATUS.OPEN: 0>}), '4545f498f583429d8c867307ac34f9d5': Order({'id': '4545f498f583429d8c867307ac34f9d5', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': 3846, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(6 [1590]), 'status': <ORDER_STATUS.OPEN: 0>}), '11c46077c2b549c9ab4c156f697053f6': Order({'id': '11c46077c2b549c9ab4c156f697053f6', 'dt': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'reason': None, 'created': Timestamp('2023-10-03 05:30:00+0000', tz='UTC'), 'amount': 7381, 'filled': 0, 'commission': 0, 'stop': None, 'limit': None, 'stop_reached': False, 'limit_reached': False, 'sid': Equity(14 [2327]), 'status': <ORDER_STATUS.OPEN: 0>})}, new_orders=[], current_dt=2023-10-03 05:30:00+00:00), recorded_vars = {})
stats.T
2023-09-21 13:30:00+08:00 | 2023-09-22 13:30:00+08:00 | 2023-09-25 13:30:00+08:00 | 2023-09-26 13:30:00+08:00 | 2023-09-27 13:30:00+08:00 | 2023-09-28 13:30:00+08:00 | 2023-10-02 13:30:00+08:00 | 2023-10-03 13:30:00+08:00 | |
---|---|---|---|---|---|---|---|---|
period_open | 2023-09-21 09:01:00+08:00 | 2023-09-22 09:01:00+08:00 | 2023-09-25 09:01:00+08:00 | 2023-09-26 09:01:00+08:00 | 2023-09-27 09:01:00+08:00 | 2023-09-28 09:01:00+08:00 | 2023-10-02 09:01:00+08:00 | 2023-10-03 09:01:00+08:00 |
period_close | 2023-09-21 13:30:00+08:00 | 2023-09-22 13:30:00+08:00 | 2023-09-25 13:30:00+08:00 | 2023-09-26 13:30:00+08:00 | 2023-09-27 13:30:00+08:00 | 2023-09-28 13:30:00+08:00 | 2023-10-02 13:30:00+08:00 | 2023-10-03 13:30:00+08:00 |
starting_cash | 10000000.0 | 10000000.0 | 2203905.142427 | 921903.876036 | 1851480.446535 | 1916878.693942 | 1959492.659321 | 1740449.09152 |
ending_cash | 10000000.0 | 2203905.142427 | 921903.876036 | 1851480.446535 | 1916878.693942 | 1959492.659321 | 1740449.09152 | 1979378.550691 |
portfolio_value | 10000000.0 | 9988642.942427 | 10009796.876036 | 9843482.746535 | 9799695.843942 | 9760817.859321 | 9642395.49152 | 9596488.900691 |
transactions | [] | [{'amount': 106951, 'dt': 2023-09-22 13:30:00+... | [{'amount': -37450, 'dt': 2023-09-25 13:30:00+... | [{'amount': -14450, 'dt': 2023-09-26 13:30:00+... | [{'amount': -87136, 'dt': 2023-09-27 13:30:00+... | [{'amount': -157495, 'dt': 2023-09-28 13:30:00... | [{'amount': -85400, 'dt': 2023-10-02 13:30:00+... | [{'amount': -3988, 'dt': 2023-10-03 13:30:00+0... |
shorts_count | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
positions | [] | [{'sid': Equity(34 [2886]), 'amount': 106951, ... | [{'sid': Equity(46 [4904]), 'amount': 14450, '... | [{'sid': Equity(25 [2609]), 'amount': 87136, '... | [{'sid': Equity(34 [2886]), 'amount': 104027, ... | [{'sid': Equity(34 [2886]), 'amount': 103976, ... | [{'sid': Equity(34 [2886]), 'amount': 103564, ... | [{'sid': Equity(34 [2886]), 'amount': 102579, ... |
short_value | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
short_exposure | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
treasury_return | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
longs_count | 0 | 2 | 3 | 2 | 2 | 2 | 2 | 2 |
net_leverage | 0.0 | 0.779359 | 0.9079 | 0.811908 | 0.804394 | 0.799249 | 0.8195 | 0.793739 |
long_value | 0.0 | 7784737.8 | 9087893.0 | 7992002.3 | 7882817.15 | 7801325.2 | 7901946.4 | 7617110.35 |
ending_exposure | 0.0 | 7784737.8 | 9087893.0 | 7992002.3 | 7882817.15 | 7801325.2 | 7901946.4 | 7617110.35 |
long_exposure | 0.0 | 7784737.8 | 9087893.0 | 7992002.3 | 7882817.15 | 7801325.2 | 7901946.4 | 7617110.35 |
returns | 0.0 | -0.001136 | 0.002118 | -0.016615 | -0.004448 | -0.003967 | -0.012132 | -0.004761 |
gross_leverage | 0.0 | 0.779359 | 0.9079 | 0.811908 | 0.804394 | 0.799249 | 0.8195 | 0.793739 |
benchmark_return | -0.013189 | 0.001704 | 0.006593 | -0.010622 | 0.002108 | 0.002659 | 0.012448 | -0.006213 |
pnl | 0.0 | -11357.057573 | 21153.933609 | -166314.129501 | -43786.902594 | -38877.98462 | -118422.367801 | -45906.590829 |
orders | [{'id': 'bdcb9758340444948f3af991c6b2478b', 'd... | [{'id': 'bdcb9758340444948f3af991c6b2478b', 'd... | [{'id': '91e9060255b8480c88251ce5ed781b49', 'd... | [{'id': 'ceec5c24911044baba3d8c0abab96960', 'd... | [{'id': '153b35815aa44224aebbd79d673403b2', 'd... | [{'id': '1ebe571a863a415297cd8aa1bc2b07b9', 'd... | [{'id': '5a76b96aecf749d683699d19b7fc687c', 'd... | [{'id': '40c0549e04914d8db877272facf233f9', 'd... |
ending_value | 0.0 | 7784737.8 | 9087893.0 | 7992002.3 | 7882817.15 | 7801325.2 | 7901946.4 | 7617110.35 |
capital_used | 0.0 | -7796094.857573 | -1282001.266391 | 929576.570499 | 65398.247406 | 42613.96538 | -219043.567801 | 238929.459171 |
starting_exposure | 0.0 | 0.0 | 7784737.8 | 9087893.0 | 7992002.3 | 7882817.15 | 7801325.2 | 7901946.4 |
starting_value | 0.0 | 0.0 | 7784737.8 | 9087893.0 | 7992002.3 | 7882817.15 | 7801325.2 | 7901946.4 |
treasury_period_return | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
sharpe | NaN | -11.224972 | 3.147118 | -7.232764 | -8.577955 | -9.570898 | -12.063911 | -12.898619 |
max_drawdown | 0.0 | -0.001136 | -0.001136 | -0.016615 | -0.02099 | -0.024874 | -0.036704 | -0.04129 |
trading_days | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
algo_volatility | NaN | 0.012748 | 0.026213 | 0.136169 | 0.117989 | 0.105533 | 0.107968 | 0.099985 |
algorithm_period_return | 0.0 | -0.001136 | 0.00098 | -0.015652 | -0.02003 | -0.023918 | -0.03576 | -0.040351 |
benchmark_period_return | -0.013189 | -0.011508 | -0.004991 | -0.01556 | -0.013485 | -0.010861 | 0.001452 | -0.00477 |
excess_return | 0.013189 | 0.010372 | 0.005971 | -0.000091 | -0.006546 | -0.013057 | -0.037212 | -0.035581 |
benchmark_volatility | NaN | 0.167179 | 0.163572 | 0.151427 | 0.137856 | 0.128068 | 0.1448 | 0.138869 |
alpha | NaN | -0.223982 | 0.114994 | -0.409947 | -0.5193 | -0.56714 | -0.729949 | -0.723783 |
beta | NaN | -0.076255 | 0.064179 | 0.468458 | 0.415352 | 0.385683 | 0.052787 | 0.044894 |
sortino | NaN | -11.224972 | 7.925494 | -7.450711 | -8.270423 | -8.811025 | -10.120875 | -10.458434 |
max_leverage | 0.0 | 0.779359 | 0.9079 | 0.9079 | 0.9079 | 0.9079 | 0.9079 | 0.9079 |
period_label | 2023-09 | 2023-09 | 2023-09 | 2023-09 | 2023-09 | 2023-09 | 2023-10 | 2023-10 |
positions, transactions, orders = get_transaction_detail(stats)
transactions
sid | symbol | amount | dt | price | order_id | asset | commission | |
---|---|---|---|---|---|---|---|---|
2023-09-22 13:30:00+08:00 | 34 | 2886 | 106951 | 2023-09-22 13:30:00+08:00 | 37.800273 | bdcb9758340444948f3af991c6b2478b | Equity(34 [2886]) | None |
2023-09-22 13:30:00+08:00 | 46 | 4904 | 51900 | 2023-09-22 13:30:00+08:00 | 72.104506 | acc3c2d89f8e48c3bc42daa9e8d81560 | Equity(46 [4904]) | None |
2023-09-25 13:30:00+08:00 | 46 | 4904 | -37450 | 2023-09-25 13:30:00+08:00 | 72.895444 | 71a11f3296354834956e3a801721c806 | Equity(46 [4904]) | None |
2023-09-25 13:30:00+08:00 | 34 | 2886 | -106951 | 2023-09-25 13:30:00+08:00 | 37.999742 | 91e9060255b8480c88251ce5ed781b49 | Equity(34 [2886]) | None |
2023-09-25 13:30:00+08:00 | 24 | 2603 | 34894 | 2023-09-25 13:30:00+08:00 | 116.000161 | 2777dbff1bbd48188466187cc31e69d3 | Equity(24 [2603]) | None |
2023-09-25 13:30:00+08:00 | 6 | 1590 | 4064 | 2023-09-25 13:30:00+08:00 | 981.008970 | 1ec8dcf092f84220a87650c5db8959fc | Equity(6 [1590]) | None |
2023-09-26 13:30:00+08:00 | 46 | 4904 | -14450 | 2023-09-26 13:30:00+08:00 | 72.699787 | ceec5c24911044baba3d8c0abab96960 | Equity(46 [4904]) | None |
2023-09-26 13:30:00+08:00 | 24 | 2603 | -34894 | 2023-09-26 13:30:00+08:00 | 115.499884 | dc7128121a9d40d182ec3d9d4d465492 | Equity(24 [2603]) | None |
2023-09-26 13:30:00+08:00 | 6 | 1590 | -4062 | 2023-09-26 13:30:00+08:00 | 957.984660 | c55dc4e5611246698718518b5ad46860 | Equity(6 [1590]) | None |
2023-09-26 13:30:00+08:00 | 25 | 2609 | 87136 | 2023-09-26 13:30:00+08:00 | 45.950388 | 5ca0608910f8443a9c2ec23de6c1ab6f | Equity(25 [2609]) | None |
2023-09-26 13:30:00+08:00 | 34 | 2886 | 105366 | 2023-09-26 13:30:00+08:00 | 37.850331 | aafbcc931d8e4f87adb21686aeb0f227 | Equity(34 [2886]) | None |
2023-09-27 13:30:00+08:00 | 25 | 2609 | -87136 | 2023-09-27 13:30:00+08:00 | 45.899835 | 153b35815aa44224aebbd79d673403b2 | Equity(25 [2609]) | None |
2023-09-27 13:30:00+08:00 | 33 | 2885 | 157495 | 2023-09-27 13:30:00+08:00 | 25.150272 | b397a24cd315420683b711b7c933abc3 | Equity(33 [2885]) | None |
2023-09-27 13:30:00+08:00 | 34 | 2886 | -1339 | 2023-09-27 13:30:00+08:00 | 37.700000 | 2f3a95e39fd840dc8aca520f0c36f6b1 | Equity(34 [2886]) | None |
2023-09-28 13:30:00+08:00 | 33 | 2885 | -157495 | 2023-09-28 13:30:00+08:00 | 25.049461 | 1ebe571a863a415297cd8aa1bc2b07b9 | Equity(33 [2885]) | None |
2023-09-28 13:30:00+08:00 | 25 | 2609 | 85400 | 2023-09-28 13:30:00+08:00 | 45.450323 | 432d560b9e99476d846b3675db5b2d44 | Equity(25 [2609]) | None |
2023-09-28 13:30:00+08:00 | 34 | 2886 | -51 | 2023-09-28 13:30:00+08:00 | 37.700000 | 9fb1d769ef504f44b2dd544653e997c2 | Equity(34 [2886]) | None |
2023-10-02 13:30:00+08:00 | 25 | 2609 | -85400 | 2023-10-02 13:30:00+08:00 | 44.449880 | 5a76b96aecf749d683699d19b7fc687c | Equity(25 [2609]) | None |
2023-10-02 13:30:00+08:00 | 34 | 2886 | -412 | 2023-10-02 13:30:00+08:00 | 37.600000 | c2f1f413dea8434f9ef69b9f58c40810 | Equity(34 [2886]) | None |
2023-10-02 13:30:00+08:00 | 6 | 1590 | 3988 | 2023-10-02 13:30:00+08:00 | 1005.008408 | c2c40f199a7f4f7a85e33a6f0fd9c3d7 | Equity(6 [1590]) | None |
2023-10-03 13:30:00+08:00 | 6 | 1590 | -3988 | 2023-10-03 13:30:00+08:00 | 997.990178 | 40c0549e04914d8db877272facf233f9 | Equity(6 [1590]) | None |
2023-10-03 13:30:00+08:00 | 24 | 2603 | 33982 | 2023-10-03 13:30:00+08:00 | 110.500048 | b990b03de87744508a9bfcbab7e14ba6 | Equity(24 [2603]) | None |
2023-10-03 13:30:00+08:00 | 34 | 2886 | -985 | 2023-10-03 13:30:00+08:00 | 37.650000 | fcc61389fce5448297c04514a9523155 | Equity(34 [2886]) | None |
positions['mv'] = positions['amount'] * positions['last_sale_price']
positions
sid | symbol | asset | amount | cost_basis | last_sale_price | mv | |
---|---|---|---|---|---|---|---|
2023-09-22 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 106951 | 37.854139 | 37.80 | 4042747.80 |
2023-09-22 13:30:00+08:00 | 46 | 4904 | Equity(46 [4904]) | 51900 | 72.207262 | 72.10 | 3741990.00 |
2023-09-25 13:30:00+08:00 | 46 | 4904 | Equity(46 [4904]) | 14450 | 73.043317 | 72.90 | 1053405.00 |
2023-09-25 13:30:00+08:00 | 24 | 2603 | Equity(24 [2603]) | 34894 | 116.165462 | 116.00 | 4047704.00 |
2023-09-25 13:30:00+08:00 | 6 | 1590 | Equity(6 [1590]) | 4064 | 982.407100 | 981.00 | 3986784.00 |
2023-09-26 13:30:00+08:00 | 25 | 2609 | Equity(25 [2609]) | 87136 | 46.015872 | 45.95 | 4003899.20 |
2023-09-26 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 105366 | 37.904276 | 37.85 | 3988103.10 |
2023-09-27 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 104027 | 37.906429 | 37.70 | 3921817.90 |
2023-09-27 13:30:00+08:00 | 33 | 2885 | Equity(33 [2885]) | 157495 | 25.186114 | 25.15 | 3960999.25 |
2023-09-28 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 103976 | 37.906679 | 37.70 | 3919895.20 |
2023-09-28 13:30:00+08:00 | 25 | 2609 | Equity(25 [2609]) | 85400 | 45.515101 | 45.45 | 3881430.00 |
2023-10-02 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 103564 | 37.907355 | 37.60 | 3894006.40 |
2023-10-02 13:30:00+08:00 | 6 | 1590 | Equity(6 [1590]) | 3988 | 1006.440705 | 1005.00 | 4007940.00 |
2023-10-03 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 102579 | 37.908964 | 37.65 | 3862099.35 |
2023-10-03 13:30:00+08:00 | 24 | 2603 | Equity(24 [2603]) | 33982 | 110.657513 | 110.50 | 3755011.00 |
stats.net_leverage
2023-09-21 13:30:00+08:00 0.000000 2023-09-22 13:30:00+08:00 0.779359 2023-09-25 13:30:00+08:00 0.907900 2023-09-26 13:30:00+08:00 0.811908 2023-09-27 13:30:00+08:00 0.804394 2023-09-28 13:30:00+08:00 0.799249 2023-10-02 13:30:00+08:00 0.819500 2023-10-03 13:30:00+08:00 0.793739 Name: net_leverage, dtype: float64
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
max_leverage=0.70,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:05.749665]: INFO: rebalance: Cancel_order: current time: 2023-09-25 , created: 2023-09-25 , asset: Equity(46 [4904]), amount: -11093 , filled: 0 [2024-03-13 02:41:05.753066]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 47789.27943776 [2024-03-13 02:41:05.754062]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 3554, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:05.754062]: INFO: handle_split: returning cash: 809.13 [2024-03-13 02:41:05.795164]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
stats.net_leverage
2023-09-21 13:30:00+08:00 0.000000 2023-09-22 13:30:00+08:00 0.704456 2023-09-25 13:30:00+08:00 0.783204 2023-09-26 13:30:00+08:00 0.708862 2023-09-27 13:30:00+08:00 0.703443 2023-09-28 13:30:00+08:00 0.698989 2023-10-02 13:30:00+08:00 0.715883 2023-10-03 13:30:00+08:00 0.694088 Name: net_leverage, dtype: float64
# 設定再平衡日期
freq = 'MS' # QS-JUL MS W
_tradeday = list(pd.date_range(start=start_dt, end=end_dt, freq=freq))
tradeday = [get_calendar(calendar_name).next_open(pd.Timestamp(i)).strftime('%Y-%m-%d') if \
get_calendar(calendar_name).is_session(i)==False else i.strftime('%Y-%m-%d') for i in _tradeday]
tradeday
['2023-06-01', '2023-07-03', '2023-08-01', '2023-09-01', '2023-10-02']
algo_start_dt
Timestamp('2023-09-21 00:00:00+0000', tz='UTC')
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
tradeday=tradeday,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:05.883443]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
transactions
sid | symbol | amount | dt | price | order_id | asset | commission | |
---|---|---|---|---|---|---|---|---|
2023-10-03 13:30:00+08:00 | 24 | 2603 | 35242 | 2023-10-03 13:30:00+08:00 | 110.500051 | 35a33e935bde4439b8e113256e10f083 | Equity(24 [2603]) | None |
2023-10-03 13:30:00+08:00 | 34 | 2886 | 106382 | 2023-10-03 13:30:00+08:00 | 37.650179 | fb0b44482bc54fff9b6dec3fd649e715 | Equity(34 [2886]) | None |
接續Case 1,多新增rebalance_date_rule
,並修改start_session
為2023-09-01,其餘與Case 1相同。
from zipline.api import date_rules
algo = TargetPercentPipeAlgo(
start_session=pd.Timestamp('2023-09-01', tz='UTC'),
end_session=end_dt,
pipeline=make_pipeline,
# 每月的第四個交易日下單
rebalance_date_rule=date_rules.month_start(days_offset=3)
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:06.016104]: INFO: handle_simulation_end: Simulated 22 trading days first open: 2023-09-01 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
orders
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-06 13:30:00+08:00 | 41 | 3034 | 4706e48bb8644098b53fd9a9c90ed314 | 2023-09-06 13:30:00+08:00 | None | 2023-09-06 13:30:00+08:00 | 9411 | 0 | 0 | None | None | False | False | Equity(41 [3034]) | 0 |
2023-09-06 13:30:00+08:00 | 14 | 2327 | ca20e3e3e6554702a701388075f7b1f3 | 2023-09-06 13:30:00+08:00 | None | 2023-09-06 13:30:00+08:00 | 7920 | 0 | 0 | None | None | False | False | Equity(14 [2327]) | 0 |
2023-09-07 13:30:00+08:00 | 41 | 3034 | 4706e48bb8644098b53fd9a9c90ed314 | 2023-09-07 13:30:00+08:00 | None | 2023-09-06 13:30:00+08:00 | 9411 | 9411 | 5727 | None | None | False | False | Equity(41 [3034]) | 1 |
2023-09-07 13:30:00+08:00 | 14 | 2327 | ca20e3e3e6554702a701388075f7b1f3 | 2023-09-07 13:30:00+08:00 | None | 2023-09-06 13:30:00+08:00 | 7920 | 7920 | 5666 | None | None | False | False | Equity(14 [2327]) | 1 |
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
pipeline=make_pipeline,
slippage_model=slippage.VolumeShareSlippage(volume_limit=0.01, price_impact=0.1)
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:06.113628]: INFO: rebalance: Cancel_order: current time: 2023-09-22 , created: 2023-09-21 , asset: Equity(46 [4904]), amount: 55478 , filled: 20760 [2024-03-13 02:41:06.121367]: INFO: rebalance: Cancel_order: current time: 2023-09-25 , created: 2023-09-25 , asset: Equity(46 [4904]), amount: -5780 , filled: 0 [2024-03-13 02:41:06.121367]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 54629.7584124 [2024-03-13 02:41:06.121367]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 4063, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:06.121367]: INFO: handle_split: returning cash: 643.62 [2024-03-13 02:41:06.132990]: INFO: rebalance: Cancel_order: current time: 2023-09-26 , created: 2023-09-26 , asset: Equity(6 [1590]), amount: -853 , filled: 0 [2024-03-13 02:41:06.138066]: INFO: rebalance: Cancel_order: current time: 2023-09-27 , created: 2023-09-26 , asset: Equity(33 [2885]), amount: 157400 , filled: 151500 [2024-03-13 02:41:06.138066]: INFO: rebalance: Cancel_order: current time: 2023-09-28 , created: 2023-09-28 , asset: Equity(33 [2885]), amount: -44120 , filled: 0 [2024-03-13 02:41:06.171376]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
orders.query('(symbol == "1590") & (created.dt.strftime("%Y-%m-%d") == "2023-09-25")')
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-25 13:30:00+08:00 | 6 | 1590 | 3217f240f39a4bc88fcdce896268d7cc | 2023-09-25 13:30:00+08:00 | None | 2023-09-25 13:30:00+08:00 | -4065 | 0 | 0.0 | None | None | False | False | Equity(6 [1590]) | 0 |
2023-09-26 13:30:00+08:00 | 6 | 1590 | 3217f240f39a4bc88fcdce896268d7cc | 2023-09-26 13:30:00+08:00 | None | 2023-09-25 13:30:00+08:00 | -4063 | -3210 | 13609.0 | None | None | False | False | Equity(6 [1590]) | 2 |
# 321000 * 1% = 3210(股)
df_bundle_price.query('(symbol == "1590") & (date.dt.strftime("%Y-%m-%d") == "2023-09-26")')[['symbol','date','volume']]
symbol | date | volume | |
---|---|---|---|
4486 | 1590 | 2023-09-26 00:00:00+00:00 | 321000.0 |
orders.query('(symbol == "2885") & (created.dt.strftime("%Y-%m-%d") == "2023-09-27")')
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-27 13:30:00+08:00 | 33 | 2885 | 06063291dd4e449a8871819852919f94 | 2023-09-27 13:30:00+08:00 | None | 2023-09-27 13:30:00+08:00 | -151500 | 0 | 0.0 | None | None | False | False | Equity(33 [2885]) | 0 |
2023-09-28 13:30:00+08:00 | 33 | 2885 | 06063291dd4e449a8871819852919f94 | 2023-09-28 13:30:00+08:00 | None | 2023-09-27 13:30:00+08:00 | -151500 | -107380 | 11904.0 | None | None | False | False | Equity(33 [2885]) | 2 |
# 10738000 * 1% = 107380(股)
df_bundle_price.query('(symbol == "2885") & (date.dt.strftime("%Y-%m-%d") == "2023-09-28")')[['symbol','date','volume']]
symbol | date | volume | |
---|---|---|---|
4625 | 2885 | 2023-09-28 00:00:00+00:00 | 10738000.0 |
接續Case 1,多新增stocklist
,其餘與Case 1相同。
註1:stocklist
限制是在pipeline執行完後。
註2:也可以使用pipeline直接限制股票池。
len(StockList)
55
_StockList = [i for i in StockList if i!='2886']
len(_StockList)
54
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
stocklist=_StockList,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:06.339500]: INFO: rebalance: Cancel_order: current time: 2023-09-22 , created: 2023-09-21 , asset: Equity(46 [4904]), amount: 55478 , filled: 51900 [2024-03-13 02:41:06.346237]: INFO: rebalance: Cancel_order: current time: 2023-09-25 , created: 2023-09-25 , asset: Equity(46 [4904]), amount: -14450 , filled: 0 [2024-03-13 02:41:06.349619]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 54643.19746736 [2024-03-13 02:41:06.350619]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 4064, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:06.350619]: INFO: handle_split: returning cash: 643.29 [2024-03-13 02:41:06.385375]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
positions
sid | symbol | asset | amount | cost_basis | last_sale_price | |
---|---|---|---|---|---|---|
2023-09-22 13:30:00+08:00 | 46 | 4904 | Equity(46 [4904]) | 51900 | 72.207262 | 72.10 |
2023-09-25 13:30:00+08:00 | 46 | 4904 | Equity(46 [4904]) | 14450 | 73.043317 | 72.90 |
2023-09-25 13:30:00+08:00 | 24 | 2603 | Equity(24 [2603]) | 34915 | 116.165477 | 116.00 |
2023-09-25 13:30:00+08:00 | 6 | 1590 | Equity(6 [1590]) | 4066 | 982.407159 | 981.00 |
2023-09-26 13:30:00+08:00 | 25 | 2609 | Equity(25 [2609]) | 87157 | 46.015867 | 45.95 |
2023-09-27 13:30:00+08:00 | 33 | 2885 | Equity(33 [2885]) | 157624 | 25.186117 | 25.15 |
2023-09-28 13:30:00+08:00 | 25 | 2609 | Equity(25 [2609]) | 85610 | 45.515095 | 45.45 |
2023-10-02 13:30:00+08:00 | 6 | 1590 | Equity(6 [1590]) | 3997 | 1006.440770 | 1005.00 |
2023-10-03 13:30:00+08:00 | 24 | 2603 | Equity(24 [2603]) | 34102 | 110.657517 | 110.50 |
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
pipeline=make_pipeline,
order_filling_policy='current_bar'
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:06.476428]: INFO: rebalance: Cancel_order: current time: 2023-09-25 , created: 2023-09-25 , asset: Equity(46 [4904]), amount: -3578 , filled: 0 [2024-03-13 02:41:06.523514]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
result.loc['2023-09-22'].query('longs == True')
longs | |
---|---|
Equity(6 [1590]) | True |
Equity(24 [2603]) | True |
# 從`orders`中可以發現created=2023-09-22的單在當天就成交(status由0變為1)
orders.loc['2023-09-22']
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-22 13:30:00+08:00 | 34 | 2886 | 36e7f2eb3d37492e829558f5748560aa | 2023-09-22 13:30:00+08:00 | None | 2023-09-22 08:45:00+08:00 | -106951 | -106951 | 17890.0 | None | None | False | False | Equity(34 [2886]) | 1 |
2023-09-22 13:30:00+08:00 | 46 | 4904 | 0fc833a0c418408dae3da988454b2029 | 2023-09-22 13:30:00+08:00 | None | 2023-09-22 08:45:00+08:00 | -55478 | -51900 | 16559.0 | None | None | False | False | Equity(46 [4904]) | 0 |
2023-09-22 13:30:00+08:00 | 24 | 2603 | 737aa5d17c9c43ff814b7c09a94898fe | 2023-09-22 13:30:00+08:00 | None | 2023-09-22 08:45:00+08:00 | 35043 | 35043 | 5718.0 | None | None | False | False | Equity(24 [2603]) | 1 |
2023-09-22 13:30:00+08:00 | 6 | 1590 | 50897cf4326c46abbea7efdf8869a5af | 2023-09-22 13:30:00+08:00 | None | 2023-09-22 08:45:00+08:00 | 4081 | 4081 | 5717.0 | None | None | False | False | Equity(6 [1590]) | 1 |
接續Case 1,多新增allow_short=True
,其餘與Case 1相同。
以下設定pipeline(make_pipeline()
),並定義shorts
欄位用來判斷須放空的股票。在shorts
欄位中要放空的股票標記為True,反之標記為False。
def make_pipeline():
rsi = RSI()
longs = rsi.top(2, mask = ~SingleAsset(bundle.asset_finder.lookup_symbol('IR0001', as_of_date=None)))
shorts = rsi.bottom(2, mask = ~SingleAsset(bundle.asset_finder.lookup_symbol('IR0001', as_of_date=None)))
return Pipeline(
columns = {
"longs" : longs,
"shorts" : shorts
}
)
result = run_pipeline(make_pipeline(), algo_start, end)
result.query('(longs == True) | (shorts == True)' )
longs | shorts | ||
---|---|---|---|
2023-09-22 00:00:00+00:00 | Equity(6 [1590]) | True | False |
Equity(10 [2301]) | False | True | |
Equity(24 [2603]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-09-25 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(25 [2609]) | True | False | |
Equity(31 [2883]) | False | True | |
Equity(34 [2886]) | True | False | |
2023-09-26 00:00:00+00:00 | Equity(8 [2002]) | False | True |
Equity(10 [2301]) | False | True | |
Equity(33 [2885]) | True | False | |
Equity(34 [2886]) | True | False | |
2023-09-27 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(17 [2357]) | False | True | |
Equity(25 [2609]) | True | False | |
Equity(34 [2886]) | True | False | |
2023-09-28 00:00:00+00:00 | Equity(6 [1590]) | True | False |
Equity(10 [2301]) | False | True | |
Equity(34 [2886]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-10-02 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(24 [2603]) | True | False | |
Equity(34 [2886]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-10-03 00:00:00+00:00 | Equity(2 [1301]) | False | True |
Equity(6 [1590]) | True | False | |
Equity(14 [2327]) | True | False | |
Equity(30 [2882]) | False | True |
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
allow_short=True,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:06.669320]: INFO: rebalance: Cancel_order: current time: 2023-09-22 , created: 2023-09-21 , asset: Equity(46 [4904]), amount: 55478 , filled: 51900 [2024-03-13 02:41:06.681121]: INFO: rebalance: Cancel_order: current time: 2023-09-25 , created: 2023-09-25 , asset: Equity(46 [4904]), amount: -14450 , filled: 0 [2024-03-13 02:41:06.687058]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 54414.73353304 [2024-03-13 02:41:06.687453]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 4047, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:06.687453]: INFO: handle_split: returning cash: 648.82 [2024-03-13 02:41:06.734225]: INFO: rebalance: Cancel_order: current time: 2023-10-02 , created: 2023-09-28 , asset: Equity(39 [2912]), amount: -14669 , filled: -8575 [2024-03-13 02:41:06.747551]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
# 當天取消
orders.query('(symbol == "2912") & (created.dt.strftime("%Y-%m-%d") == "2023-09-28")')
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-28 13:30:00+08:00 | 39 | 2912 | 2ed71c04d41546fabc89536cab7b49de | 2023-09-28 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | -14669 | 0 | 0.0 | None | None | False | False | Equity(39 [2912]) | 0 |
2023-10-02 13:30:00+08:00 | 39 | 2912 | 2ed71c04d41546fabc89536cab7b49de | 2023-10-02 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | -14669 | -8575 | 9980.0 | None | None | False | False | Equity(39 [2912]) | 2 |
# 343000 * 2.5% = 8575(股)
df_bundle_price.query('(symbol == "2912") & (date.dt.strftime("%Y-%m-%d") == "2023-10-02")')[['symbol','date','volume']]
symbol | date | volume | |
---|---|---|---|
4687 | 2912 | 2023-10-02 00:00:00+00:00 | 343000.0 |
positions['mv'] = positions['amount'] * positions['last_sale_price']
positions.query('(symbol == "2912")')
sid | symbol | asset | amount | cost_basis | last_sale_price | mv | |
---|---|---|---|---|---|---|---|
2023-09-25 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -15079 | 263.315631 | 264.5 | -3988395.5 |
2023-10-02 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -8575 | 261.819714 | 263.0 | -2255225.0 |
2023-10-03 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -14152 | 261.433302 | 262.0 | -3707824.0 |
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
allow_short=True,
cancel_datedelta=2,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:06.883576]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 54414.73353304 [2024-03-13 02:41:06.883576]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 4047, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:06.883576]: INFO: handle_split: returning cash: 648.82 [2024-03-13 02:41:06.951237]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
result = run_pipeline(make_pipeline(), algo_start, end)
result.query('(longs == True) | (shorts == True)' )
longs | shorts | ||
---|---|---|---|
2023-09-22 00:00:00+00:00 | Equity(6 [1590]) | True | False |
Equity(10 [2301]) | False | True | |
Equity(24 [2603]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-09-25 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(25 [2609]) | True | False | |
Equity(31 [2883]) | False | True | |
Equity(34 [2886]) | True | False | |
2023-09-26 00:00:00+00:00 | Equity(8 [2002]) | False | True |
Equity(10 [2301]) | False | True | |
Equity(33 [2885]) | True | False | |
Equity(34 [2886]) | True | False | |
2023-09-27 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(17 [2357]) | False | True | |
Equity(25 [2609]) | True | False | |
Equity(34 [2886]) | True | False | |
2023-09-28 00:00:00+00:00 | Equity(6 [1590]) | True | False |
Equity(10 [2301]) | False | True | |
Equity(34 [2886]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-10-02 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(24 [2603]) | True | False | |
Equity(34 [2886]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-10-03 00:00:00+00:00 | Equity(2 [1301]) | False | True |
Equity(6 [1590]) | True | False | |
Equity(14 [2327]) | True | False | |
Equity(30 [2882]) | False | True |
positions, transactions, orders = get_transaction_detail(stats)
orders.query('(symbol == "2912") & (created.dt.strftime("%Y-%m-%d") == "2023-09-28")')
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-28 13:30:00+08:00 | 39 | 2912 | 05ab5284f0904f0599fce02cafe7dd93 | 2023-09-28 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | -14660 | 0 | 0.0 | None | None | False | False | Equity(39 [2912]) | 0 |
2023-10-02 13:30:00+08:00 | 39 | 2912 | 05ab5284f0904f0599fce02cafe7dd93 | 2023-10-02 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | -14660 | -8575 | 9980.0 | None | None | False | False | Equity(39 [2912]) | 0 |
2023-10-03 13:30:00+08:00 | 39 | 2912 | 05ab5284f0904f0599fce02cafe7dd93 | 2023-10-03 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | -14660 | -14660 | 17035.0 | None | None | False | False | Equity(39 [2912]) | 1 |
# 10/02:343000 * 2.5% = 8575(股)
# 10/03:808000 * 2.5% = 20200(股)
df_bundle_price.query('(symbol == "2912") & (date.dt.strftime("%Y-%m-%d")>="2023-10-02")')\
[['symbol','date','volume']]
symbol | date | volume | |
---|---|---|---|
4687 | 2912 | 2023-10-02 00:00:00+00:00 | 343000.0 |
4743 | 2912 | 2023-10-03 00:00:00+00:00 | 808000.0 |
positions['mv'] = positions['amount'] * positions['last_sale_price']
positions.query('(symbol == "2912")')
sid | symbol | asset | amount | cost_basis | last_sale_price | mv | |
---|---|---|---|---|---|---|---|
2023-09-25 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -15079 | 263.315631 | 264.5 | -3988395.5 |
2023-10-02 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -8575 | 261.819714 | 263.0 | -2255225.0 |
2023-10-03 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -14660 | 261.412688 | 262.0 | -3840920.0 |
result = run_pipeline(make_pipeline(), algo_start, end)
result.query('(longs == True) | (shorts == True)' )
longs | shorts | ||
---|---|---|---|
2023-09-22 00:00:00+00:00 | Equity(6 [1590]) | True | False |
Equity(10 [2301]) | False | True | |
Equity(24 [2603]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-09-25 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(25 [2609]) | True | False | |
Equity(31 [2883]) | False | True | |
Equity(34 [2886]) | True | False | |
2023-09-26 00:00:00+00:00 | Equity(8 [2002]) | False | True |
Equity(10 [2301]) | False | True | |
Equity(33 [2885]) | True | False | |
Equity(34 [2886]) | True | False | |
2023-09-27 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(17 [2357]) | False | True | |
Equity(25 [2609]) | True | False | |
Equity(34 [2886]) | True | False | |
2023-09-28 00:00:00+00:00 | Equity(6 [1590]) | True | False |
Equity(10 [2301]) | False | True | |
Equity(34 [2886]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-10-02 00:00:00+00:00 | Equity(10 [2301]) | False | True |
Equity(24 [2603]) | True | False | |
Equity(34 [2886]) | True | False | |
Equity(39 [2912]) | False | True | |
2023-10-03 00:00:00+00:00 | Equity(2 [1301]) | False | True |
Equity(6 [1590]) | True | False | |
Equity(14 [2327]) | True | False | |
Equity(30 [2882]) | False | True |
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
limit_buy_multiplier=1.015,
allow_short=True,
cancel_datedelta=2,
pipeline=make_pipeline,
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:07.183718]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 54414.73353304 [2024-03-13 02:41:07.183718]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 4047, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:07.183718]: INFO: handle_split: returning cash: 648.82 [2024-03-13 02:41:07.254114]: INFO: exec_cancel: Cancel_order: current time: 2023-10-03, due to : created>=current time + cancel_datedelta(2 days), created: 2023-09-28, asset: Equity(6 [1590]), amount: 3931, filled: 0' [2024-03-13 02:41:07.259895]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
positions, transactions, orders = get_transaction_detail(stats)
orders
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-21 13:30:00+08:00 | 34 | 2886 | 5e4ce9d6633d408a9389b175c652626b | 2023-09-21 13:30:00+08:00 | None | 2023-09-21 13:30:00+08:00 | 106951 | 0 | 0.0 | None | 37.96 | False | False | Equity(34 [2886]) | 0 |
2023-09-21 13:30:00+08:00 | 46 | 4904 | e0b2c8d022ff41959b6f077bccad0c43 | 2023-09-21 13:30:00+08:00 | None | 2023-09-21 13:30:00+08:00 | 55478 | 0 | 0.0 | None | 73.18 | False | False | Equity(46 [4904]) | 0 |
2023-09-21 13:30:00+08:00 | 10 | 2301 | 25b053b3403b4ec4aa3408745f592ac4 | 2023-09-21 13:30:00+08:00 | None | 2023-09-21 13:30:00+08:00 | -33613 | 0 | 0.0 | None | NaN | False | False | Equity(10 [2301]) | 0 |
2023-09-21 13:30:00+08:00 | 44 | 3231 | 7a065d9e8d604f699ec3efd6ca41d47c | 2023-09-21 13:30:00+08:00 | None | 2023-09-21 13:30:00+08:00 | -39800 | 0 | 0.0 | None | NaN | False | False | Equity(44 [3231]) | 0 |
2023-09-22 13:30:00+08:00 | 34 | 2886 | 5e4ce9d6633d408a9389b175c652626b | 2023-09-22 13:30:00+08:00 | None | 2023-09-21 13:30:00+08:00 | 106951 | 106951 | 5761.0 | None | 37.96 | False | True | Equity(34 [2886]) | 1 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2023-10-03 13:30:00+08:00 | 39 | 2912 | aaa092b0d9954807a887fab5edbed96e | 2023-10-03 13:30:00+08:00 | None | 2023-10-03 13:30:00+08:00 | 14660 | 0 | 0.0 | None | NaN | False | False | Equity(39 [2912]) | 0 |
2023-10-03 13:30:00+08:00 | 6 | 1590 | 01f05fe434e643268c1562ae1004734a | 2023-10-03 13:30:00+08:00 | None | 2023-10-03 13:30:00+08:00 | 3762 | 0 | 0.0 | None | 1012.97 | False | False | Equity(6 [1590]) | 0 |
2023-10-03 13:30:00+08:00 | 14 | 2327 | 606f2de8c38d4be484df5d6889fe5e28 | 2023-10-03 13:30:00+08:00 | None | 2023-10-03 13:30:00+08:00 | 7221 | 0 | 0.0 | None | 527.80 | False | False | Equity(14 [2327]) | 0 |
2023-10-03 13:30:00+08:00 | 2 | 1301 | d5aa6f02906f4e008bceac04ade72d21 | 2023-10-03 13:30:00+08:00 | None | 2023-10-03 13:30:00+08:00 | -47471 | 0 | 0.0 | None | NaN | False | False | Equity(2 [1301]) | 0 |
2023-10-03 13:30:00+08:00 | 30 | 2882 | 82adef75477d4095beaf6b4e02657dcb | 2023-10-03 13:30:00+08:00 | None | 2023-10-03 13:30:00+08:00 | -85340 | 0 | 0.0 | None | NaN | False | False | Equity(30 [2882]) | 0 |
92 rows × 15 columns
orders.query('(symbol == "1590") & (created.dt.strftime("%Y-%m-%d") == "2023-09-28")')
sid | symbol | id | dt | reason | created | amount | filled | commission | stop | limit | stop_reached | limit_reached | asset | status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2023-09-28 13:30:00+08:00 | 6 | 1590 | 7a1633e9d2314561bf5fc6b235784201 | 2023-09-28 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | 3931 | 0 | 0.0 | None | 993.68 | False | False | Equity(6 [1590]) | 0 |
2023-10-03 13:30:00+08:00 | 6 | 1590 | 7a1633e9d2314561bf5fc6b235784201 | 2023-10-03 13:30:00+08:00 | None | 2023-09-28 13:30:00+08:00 | 3931 | 0 | 0.0 | None | 993.68 | False | False | Equity(6 [1590]) | 2 |
# 9/28 979 * 1.015 = 993.685
df_bundle_price.query('(symbol == "1590") & (date.dt.strftime("%Y-%m-%d")>="2023-09-28")')\
[['symbol','date','close']]
symbol | date | close | |
---|---|---|---|
4598 | 1590 | 2023-09-28 00:00:00+00:00 | 979.0 |
4654 | 1590 | 2023-10-02 00:00:00+00:00 | 1005.0 |
4710 | 1590 | 2023-10-03 00:00:00+00:00 | 998.0 |
接續Case 10,多設定custom_weight
=True、analyze
、record_vars
、get_record_vars
=True與get_transaction_detail
=True,其餘與Case 10相同。
class Weight(CustomFactor):
inputs = [TQAltDataSet.Market_Cap_Dollars]
outputs = ["Market_Cap_Dollars","Sum_Market_Cap_Dollars","Weight"]
window_length = 1
def compute(self, today, assets, out, Market_Cap_Dollars):
out.Market_Cap_Dollars[:] = Market_Cap_Dollars
out.Sum_Market_Cap_Dollars[:] = np.nansum(Market_Cap_Dollars, axis=1)
out.Weight[:] = Market_Cap_Dollars / np.sum(Market_Cap_Dollars, axis=1)
def make_pipeline():
rsi = RSI()
longs = rsi.top(2, mask = ~SingleAsset(bundle.asset_finder.lookup_symbol('IR0001', as_of_date=None)))
shorts = rsi.bottom(2, mask = ~SingleAsset(bundle.asset_finder.lookup_symbol('IR0001', as_of_date=None)))
return Pipeline(
columns = {
"Market_Cap_Dollars":Weight().Market_Cap_Dollars,
"longs" : longs,
"shorts" : shorts,
"long_weights" : Weight(mask=longs).Weight,
"short_weights" : Weight(mask=shorts).Weight
}
)
def analyze(context, perf):
fig = plt.figure(figsize=(16, 24), dpi=400)
# First chart(累積報酬)
ax = fig.add_subplot(611)
ax.set_title('Strategy Results')
ax.plot(perf['algorithm_period_return'],
linestyle='-',
label='algorithm period return',
linewidth=3.0)
ax.plot(perf['benchmark_period_return'],
linestyle='-',
label='benchmark period return',
linewidth=3.0)
ax.legend()
ax.grid(False)
# Second chart(returns)
ax = fig.add_subplot(612, sharex=ax)
ax.plot(perf['returns'],
linestyle='-',
label='returns',
linewidth=3.0)
ax.legend()
ax.grid(False)
# Third chart(ending_cash) -> 觀察是否超買
ax = fig.add_subplot(613, sharex=ax)
ax.plot(perf['ending_cash'],
label='ending_cash',
linestyle='-',
linewidth=3.0)
ax.axhline(y=1, c='r', linewidth=1)
ax.legend()
ax.grid(False)
# Forth chart(shorts_count) -> 觀察是否放空
ax = fig.add_subplot(614, sharex=ax)
ax.plot(perf['shorts_count'],
label='shorts_count',
linestyle='-',
linewidth=3.0)
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
ax.axhline(y=0, c='r', linewidth=1)
ax.legend()
ax.grid(False)
# Fifth chart(longs_count)
ax = fig.add_subplot(615, sharex=ax)
ax.plot(perf['longs_count'],
label='longs_count',
linestyle='-',
linewidth=3.0)
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
ax.axhline(y=0, c='r', linewidth=1)
ax.legend()
ax.grid(False)
# Sixth chart(weights) -> 觀察每日持股權重
ax = fig.add_subplot(616, sharex=ax)
weights = pd.concat([df.to_frame(d) for d, df in perf['daily_weights'].dropna().items()],axis=1).T
for i in weights.columns:
df = weights.loc[:,i]
ax.scatter(df.index,df.values,marker='.', s=5, c='grey', label='daily_weights')
ax.axhline(y=0, c='r', linewidth=1)
ax.legend(['daily_weights'])
ax.grid(False)
fig.tight_layout()
def record_vars(context, data):
"""
Plot variables at the end of each day.
"""
record(daily_weights=context.daily_weights,
Market_Cap_Dollars=context.output.Market_Cap_Dollars
)
algo = TargetPercentPipeAlgo(
start_session=algo_start_dt,
end_session=end_dt,
limit_buy_multiplier=1.015,
allow_short=True,
custom_weight=True,
cancel_datedelta=2,
pipeline=make_pipeline,
analyze=analyze,
record_vars=record_vars,
get_record_vars=True,
get_transaction_detail=True
)
# set_algo_instance
set_algo_instance(algo)
# run
stats = algo.run()
[2024-03-13 02:41:07.483598]: INFO: earn_dividends: Equity(6 [1590]), cash_dividend amount: 13.43905496, pay_date: 2023-10-30, div_owed: 48703.13517504 [2024-03-13 02:41:07.483598]: INFO: handle_split: after split: asset: Equity(6 [1590]), amount: 3622, cost_basis: 982.73, last_sale_price: 981.0 [2024-03-13 02:41:07.483598]: INFO: handle_split: returning cash: 787.02 [2024-03-13 02:41:07.583608]: INFO: exec_cancel: Cancel_order: current time: 2023-10-03, due to : created>=current time + cancel_datedelta(2 days), created: 2023-09-28, asset: Equity(6 [1590]), amount: 2145, filled: 0' [2024-03-13 02:41:07.600275]: INFO: handle_simulation_end: Simulated 8 trading days first open: 2023-09-21 01:01:00+00:00 last close: 2023-10-03 05:30:00+00:00
result = run_pipeline(make_pipeline(), algo_start, end)
result.query('(longs == True) | (shorts == True)' )
Market_Cap_Dollars | longs | shorts | long_weights | short_weights | ||
---|---|---|---|---|---|---|
2023-09-22 00:00:00+00:00 | Equity(6 [1590]) | 1.980000e+11 | True | False | 0.447512 | NaN |
Equity(10 [2301]) | 2.818339e+11 | False | True | NaN | 0.507101 | |
Equity(24 [2603]) | 2.444465e+11 | True | False | 0.552488 | NaN | |
Equity(39 [2912]) | 2.739405e+11 | False | True | NaN | 0.492899 | |
2023-09-25 00:00:00+00:00 | Equity(10 [2301]) | 2.842023e+11 | False | True | NaN | 0.590585 |
Equity(25 [2609]) | 1.599384e+11 | True | False | 0.231433 | NaN | |
Equity(31 [2883]) | 1.970197e+11 | False | True | NaN | 0.409415 | |
Equity(34 [2886]) | 5.311406e+11 | True | False | 0.768567 | NaN | |
2023-09-26 00:00:00+00:00 | Equity(8 [2002]) | 4.122534e+11 | False | True | NaN | 0.591931 |
Equity(10 [2301]) | 2.842023e+11 | False | True | NaN | 0.408069 | |
Equity(33 [2885]) | 3.197649e+11 | True | False | 0.374557 | NaN | |
Equity(34 [2886]) | 5.339508e+11 | True | False | 0.625443 | NaN | |
2023-09-27 00:00:00+00:00 | Equity(10 [2301]) | 2.842023e+11 | False | True | NaN | 0.516628 |
Equity(17 [2357]) | 2.659082e+11 | False | True | NaN | 0.483372 | |
Equity(25 [2609]) | 1.604622e+11 | True | False | 0.231780 | NaN | |
Equity(34 [2886]) | 5.318431e+11 | True | False | 0.768220 | NaN | |
2023-09-28 00:00:00+00:00 | Equity(6 [1590]) | 1.982000e+11 | True | False | 0.272277 | NaN |
Equity(10 [2301]) | 2.842023e+11 | False | True | NaN | 0.509667 | |
Equity(34 [2886]) | 5.297354e+11 | True | False | 0.727723 | NaN | |
Equity(39 [2912]) | 2.734207e+11 | False | True | NaN | 0.490333 | |
2023-10-02 00:00:00+00:00 | Equity(10 [2301]) | 2.877548e+11 | False | True | NaN | 0.513247 |
Equity(24 [2603]) | 2.455047e+11 | True | False | 0.316682 | NaN | |
Equity(34 [2886]) | 5.297354e+11 | True | False | 0.683318 | NaN | |
Equity(39 [2912]) | 2.729008e+11 | False | True | NaN | 0.486753 | |
2023-10-03 00:00:00+00:00 | Equity(2 [1301]) | 5.067130e+11 | False | True | NaN | 0.437013 |
Equity(6 [1590]) | 2.010000e+11 | True | False | 0.471237 | NaN | |
Equity(14 [2327]) | 2.255366e+11 | True | False | 0.528763 | NaN | |
Equity(30 [2882]) | 6.527799e+11 | False | True | NaN | 0.562987 |
# 計算實際股票部位的weight = 個股持股市值/所有股票部位的持股市值加總
pos = algo.positions
pos['mv'] = pos['amount'] * pos['last_sale_price']
positive_sum = pos[pos['mv'] > 0].groupby(level=0)['mv'].sum()
negative_sum = - pos[pos['mv'] < 0].groupby(level=0)['mv'].sum()
pos['sum'] = np.where(pos['mv'] > 0,
pos.index.map(positive_sum),
pos.index.map(negative_sum))
pos['weight'] = pos['mv'] / pos['sum']
pos
sid | symbol | asset | amount | cost_basis | last_sale_price | mv | sum | weight | |
---|---|---|---|---|---|---|---|---|---|
2023-09-22 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 147424 | 37.854390 | 37.80 | 5572627.20 | 8058923.60 | 0.691485 |
2023-09-22 13:30:00+08:00 | 46 | 4904 | Equity(46 [4904]) | 34484 | 72.204762 | 72.10 | 2486296.40 | 8058923.60 | 0.308515 |
2023-09-22 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -33495 | 119.468922 | 120.00 | -4019400.00 | 8113352.50 | -0.495406 |
2023-09-22 13:30:00+08:00 | 44 | 3231 | Equity(44 [3231]) | -39941 | 102.046428 | 102.50 | -4093952.50 | 8113352.50 | -0.504594 |
2023-09-25 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -33646 | 119.468898 | 120.00 | -4037520.00 | 7969312.50 | -0.506633 |
2023-09-25 13:30:00+08:00 | 24 | 2603 | Equity(24 [2603]) | 38418 | 116.165508 | 116.00 | 4456488.00 | 8011632.00 | 0.556252 |
2023-09-25 13:30:00+08:00 | 6 | 1590 | Equity(6 [1590]) | 3624 | 982.405312 | 981.00 | 3555144.00 | 8011632.00 | 0.443748 |
2023-09-25 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -14865 | 263.316060 | 264.50 | -3931792.50 | 7969312.50 | -0.493367 |
2023-09-26 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -39051 | 119.468888 | 120.00 | -4686120.00 | 7921019.20 | -0.591606 |
2023-09-26 13:30:00+08:00 | 25 | 2609 | Equity(25 [2609]) | 39964 | 46.015565 | 45.95 | 1836345.80 | 7910665.20 | 0.232135 |
2023-09-26 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 160484 | 37.904710 | 37.85 | 6074319.40 | 7910665.20 | 0.767865 |
2023-09-26 13:30:00+08:00 | 31 | 2883 | Equity(31 [2883]) | -274144 | 11.747586 | 11.80 | -3234899.20 | 7921019.20 | -0.408394 |
2023-09-27 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -26553 | 119.388370 | 120.00 | -3186360.00 | 7701800.80 | -0.413716 |
2023-09-27 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 129025 | 37.945400 | 37.70 | 4864242.50 | 7806390.10 | 0.623110 |
2023-09-27 13:30:00+08:00 | 33 | 2885 | Equity(33 [2885]) | 116984 | 25.185992 | 25.15 | 2942147.60 | 7806390.10 | 0.376890 |
2023-09-27 13:30:00+08:00 | 8 | 2002 | Equity(8 [2002]) | -177424 | 25.337349 | 25.45 | -4515440.80 | 7701800.80 | -0.586284 |
2023-09-28 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -33420 | 119.711756 | 121.50 | -4060530.00 | 7843566.00 | -0.517689 |
2023-09-28 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 158184 | 37.910076 | 37.70 | 5963536.80 | 7745131.35 | 0.769972 |
2023-09-28 13:30:00+08:00 | 25 | 2609 | Equity(25 [2609]) | 39199 | 45.514840 | 45.45 | 1781594.55 | 7745131.35 | 0.230028 |
2023-09-28 13:30:00+08:00 | 17 | 2357 | Equity(17 [2357]) | -10308 | 365.375480 | 367.00 | -3783036.00 | 7843566.00 | -0.482311 |
2023-10-02 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -33420 | 119.711756 | 125.50 | -4194210.00 | 6449435.00 | -0.650322 |
2023-10-02 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 148920 | 37.920431 | 37.60 | 5599392.00 | 5599392.00 | 1.000000 |
2023-10-02 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -8575 | 261.819714 | 263.00 | -2255225.00 | 6449435.00 | -0.349678 |
2023-10-03 13:30:00+08:00 | 10 | 2301 | Equity(10 [2301]) | -32363 | 119.706008 | 123.00 | -3980649.00 | 7756069.00 | -0.513230 |
2023-10-03 13:30:00+08:00 | 34 | 2886 | Equity(34 [2886]) | 136276 | 37.935899 | 37.65 | 5130791.40 | 7442672.40 | 0.689375 |
2023-10-03 13:30:00+08:00 | 39 | 2912 | Equity(39 [2912]) | -14410 | 261.422628 | 262.00 | -3775420.00 | 7756069.00 | -0.486770 |
2023-10-03 13:30:00+08:00 | 24 | 2603 | Equity(24 [2603]) | 20922 | 110.657508 | 110.50 | 2311881.00 | 7442672.40 | 0.310625 |
record_vars = algo.dict_record_vars
# 實際持股市值 = 個股持股市值/所有股票部位的持股市值加總 * max_leverage
record_vars['daily_weights']
date | symbol | daily_weights | |
---|---|---|---|
0 | 2023-09-22 00:00:00+08:00 | 2886 | 0.559924 |
1 | 2023-09-22 00:00:00+08:00 | 4904 | 0.249817 |
2 | 2023-09-22 00:00:00+08:00 | 2301 | -0.403860 |
3 | 2023-09-22 00:00:00+08:00 | 3231 | -0.411351 |
4 | 2023-09-25 00:00:00+08:00 | 2301 | -0.407072 |
5 | 2023-09-25 00:00:00+08:00 | 2603 | 0.449313 |
6 | 2023-09-25 00:00:00+08:00 | 1590 | 0.358437 |
7 | 2023-09-25 00:00:00+08:00 | 2912 | -0.396412 |
8 | 2023-09-26 00:00:00+08:00 | 2886 | 0.622353 |
9 | 2023-09-26 00:00:00+08:00 | 2301 | -0.480123 |
10 | 2023-09-26 00:00:00+08:00 | 2609 | 0.188145 |
11 | 2023-09-26 00:00:00+08:00 | 2883 | -0.331436 |
12 | 2023-09-27 00:00:00+08:00 | 2886 | 0.501285 |
13 | 2023-09-27 00:00:00+08:00 | 2301 | -0.328371 |
14 | 2023-09-27 00:00:00+08:00 | 2885 | 0.303203 |
15 | 2023-09-27 00:00:00+08:00 | 2002 | -0.465339 |
16 | 2023-09-28 00:00:00+08:00 | 2886 | 0.618396 |
17 | 2023-09-28 00:00:00+08:00 | 2301 | -0.421061 |
18 | 2023-09-28 00:00:00+08:00 | 2609 | 0.184744 |
19 | 2023-09-28 00:00:00+08:00 | 2357 | -0.392286 |
20 | 2023-10-02 00:00:00+08:00 | 2886 | 0.597376 |
21 | 2023-10-02 00:00:00+08:00 | 2301 | -0.447463 |
22 | 2023-10-02 00:00:00+08:00 | 2912 | -0.240600 |
23 | 2023-10-03 00:00:00+08:00 | 2886 | 0.542337 |
24 | 2023-10-03 00:00:00+08:00 | 2301 | -0.420764 |
25 | 2023-10-03 00:00:00+08:00 | 2603 | 0.244371 |
26 | 2023-10-03 00:00:00+08:00 | 2912 | -0.399071 |
# 個股總市值
record_vars['Market_Cap_Dollars']
date | symbol | Market_Cap_Dollars | |
---|---|---|---|
0 | 2023-09-21 00:00:00+08:00 | 1101 | 2.458148e+11 |
1 | 2023-09-21 00:00:00+08:00 | 1216 | 4.028549e+11 |
2 | 2023-09-21 00:00:00+08:00 | 1301 | 5.245370e+11 |
3 | 2023-09-21 00:00:00+08:00 | 1303 | 5.424682e+11 |
4 | 2023-09-21 00:00:00+08:00 | 1326 | 3.798049e+11 |
... | ... | ... | ... |
443 | 2023-10-03 00:00:00+08:00 | 6415 | 1.188855e+11 |
444 | 2023-10-03 00:00:00+08:00 | 6505 | 7.649346e+11 |
445 | 2023-10-03 00:00:00+08:00 | 6669 | 2.867389e+11 |
446 | 2023-10-03 00:00:00+08:00 | 9910 | 1.920654e+11 |
447 | 2023-10-03 00:00:00+08:00 | IR0001 | 5.189094e+13 |
448 rows × 3 columns