Created
April 6, 2023 01:44
-
-
Save lawrence910426/255ffd07117a4e8093e68c7be2058409 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import defaultdict, deque | |
from shioaji import BidAskFOPv1, Exchange | |
import shioaji as sj | |
import datetime | |
import pandas as pd | |
import talib as ta | |
import time | |
from math import ceil | |
import pysimulation | |
api = sj.Shioaji(simulation=True) | |
accounts = api.login( | |
api_key="6YugfETBuBogK1jSTPXR7KQh6eeY8RawEK42QEYCZG8E", | |
secret_key="CyAMsKj115UJNQuFPujqAxSQJjvGaj3ameZQWjr1CeYS", | |
) | |
order = pysimulation.order('') # student id | |
contract = min( | |
[ | |
x for x in api.Contracts.Futures.TXF | |
if x.code[-2:] not in ["R1", "R2"] | |
], | |
key=lambda x: x.delivery_date | |
) | |
msg_queue = defaultdict(deque) | |
api.set_context(msg_queue) | |
@api.on_bidask_fop_v1(bind=True) | |
def quote_callback(self, exchange: Exchange, bidask: BidAskFOPv1): | |
# append quote to message queue | |
self['bidask'].append(bidask) | |
api.quote.subscribe( | |
contract, | |
quote_type=sj.constant.QuoteType.BidAsk, | |
version=sj.constant.QuoteVersion.v1 | |
) | |
time.sleep(2.5) | |
# get maximum strategy kbars to dataframe, extra 30 it's for safety | |
bars = 65 + 30 | |
# since every day has 60 kbars (only from 8:45 to 13:45), for 5 minuts kbars | |
days = ceil(bars/60) | |
df_5min = [] | |
while(len(df_5min) < bars): | |
kbars = api.kbars( | |
contract=api.Contracts.Futures.TXF.TXFR1, | |
start=(datetime.date.today() - | |
datetime.timedelta(days=days)).strftime("%Y-%m-%d"), | |
end=datetime.date.today().strftime("%Y-%m-%d"), | |
) | |
df = pd.DataFrame({**kbars}) | |
df.ts = pd.to_datetime(df.ts) | |
df = df.set_index('ts') | |
df.index.name = None | |
df = df[['Open', 'High', 'Low', 'Close', 'Volume']] | |
df = df.between_time('08:44:00', '13:45:01') | |
df_5min = df.resample('5T', label='right', closed='right').agg( | |
{'Open': 'first', | |
'High': 'max', | |
'Low': 'min', | |
'Close': 'last', | |
'Volume': 'sum' | |
}) | |
df_5min.dropna(axis=0, inplace=True) | |
days += 1 | |
ts = datetime.datetime.now() | |
support, resistence = None, None | |
while datetime.datetime.now().time() < datetime.time(13, 40): | |
# this place can add stop or limit order | |
self_list_positions = order.list_positions(msg_queue['bidask'][-1]) | |
self_position = 'None' if len(self_list_positions) == 0 else self_list_positions['direction'] | |
# local time > next kbars time | |
if(datetime.datetime.now() >= ts): | |
kbars = api.kbars( | |
contract=api.Contracts.Futures.TXF.TXFR1, | |
start=datetime.date.today().strftime("%Y-%m-%d"), | |
end=datetime.date.today().strftime("%Y-%m-%d"), | |
) | |
df = pd.DataFrame({**kbars}) | |
df.ts = pd.to_datetime(df.ts) | |
df = df.set_index('ts') | |
df.index.name = None | |
df = df[['Open', 'High', 'Low', 'Close', 'Volume']] | |
df = df.between_time('08:44:00', '13:45:01') | |
df = df.resample('5T', label='right', closed='right').agg({ | |
'Open': 'first', | |
'High': 'max', | |
'Low': 'min', | |
'Close': 'last', | |
'Volume': 'sum'}) | |
df.dropna(axis=0, inplace=True) | |
df_5min.update(df) | |
to_be_added = df.loc[df.index.difference(df_5min.index)] | |
df_5min = pd.concat([df_5min, to_be_added]) | |
ts = df_5min.iloc[-1].name.to_pydatetime() | |
# next kbar time update and local time < next kbar time | |
if (datetime.datetime.now().minute != ts.minute): | |
# Exit conditions | |
if self_position == 'Buy': | |
minimal = min([df_5min["Low":-i] for i in range(2, 5)]) | |
if df_5min['Close':-1] < minimal: | |
order.place_order(msg_queue['bidask'][-1], 'Sell', 'Close') | |
if self_position == 'Sell': | |
maximal = max([df_5min["High":-i] for i in range(2, 5)]) | |
if df_5min['Close':-1] > maximal: | |
order.place_order(msg_queue['bidask'][-1], 'Buy', 'Close') | |
# Make df_5min the latest kbar | |
df_5min = df_5min.iloc[-1] | |
kbar = { | |
'Open': df_5min['Open'], | |
'High': df_5min['High'], | |
'Low': df_5min['Low'], | |
'Close': df_5min['Close'] | |
} | |
print(kbar) | |
# Caculate the support and resistence | |
if datetime.datetime.now().time() < datetime.time(9, 30): | |
support = df_5min['Low'] if support is None else min(df_5min['Low'], support) | |
resistence = df_5min['High'] if resistence is None else max(df_5min['High'], resistence) | |
# Entry conditions | |
if datetime.time(9, 30) <= datetime.datetime.now().time() <= datetime.time(12, 00) and self_position == 'None': | |
# Breakout then stop order in | |
if resistence is not None and df_5min['Close'] > resistence: | |
order.place_order(msg_queue['bidask'][-1], 'Buy', 'New') | |
support, resistence = None, None | |
if support is not None and df_5min['Close'] < support: | |
order.place_order(msg_queue['bidask'][-1], 'Sell', 'New') | |
support, resistence = None, None | |
api.quote.unsubscribe( | |
contract, | |
quote_type=sj.constant.QuoteType.BidAsk, | |
version=sj.constant.QuoteVersion.v1 | |
) | |
api.logout() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment