更新頻度が落ちている。こんなにも仕事×子育て×ブログが難しいなんて…
さて前回までの記事でエクセルで株を発注できることを確認しました。

あとは株価や出来高などを判定して、その株を発注する処理を作ります。正直エクセルVBAだけで実現できる気がしますが、私はVBA書きづらいなー…と思っているので、Pythonで書きたいと思います。
ソースコードの紹介
大したコードではないのですが、実際に自動売買動作を確認済みのコードを部分的に紹介していきたいと思います。
エクセルのイメージ
まずは、マーケットスピードⅡRSSを埋め込んだエクセルを作成しました。
M列以降も気配値や気配数量も書いているので、情報量が多い!体感数値の更新が遅い気がします…。

ちなみに、最初は小規模から始めたいので、プライムに上場している500円以下の株をターゲットとしています。
[Python]エクセルの情報を読み取り
最初に上記のようなエクセルの情報を読み取る処理を書いていきます。ここらへんはPythonの知識になってくるので、雰囲気だけ書いていきます。
xl = win32com.client.GetObject(Class="Excel.Application")
wb = xl.Workbooks("filename.xlsm")
ws_stock = wb.Worksheets("sheet_name")
code = ws_stock.Cells(row, 1).Value
name = str(ws_stock.Cells(row, 2).Value)
current_price = ws_stock.Cells(row, 3).ValuePythonにお詳しい方はよく見るコードだと思いますが、Pythonからエクセルのシートにアクセスできるようにして、銘柄コード・銘柄名称・現在値を取得しています。
もちろんこのコードだけでは動きませんが、基本的な処理はこんな感じ。あとは毎秒この処理を実施し、更新された値を拾っていく必要があります。高スペックPCを欲しくなってきますね。うちのノートPCの発熱が予想以上です。
[VBA]発注実行コード
以前の記事でVBA側の発注コードを書いたときは買値は何円!とVBAで決めた値しか注文できませんでしたね。そうではなく、Pythonから指定した買値を発注できるようにインターフェースを改良します。
下記がVBAの発注コードです。通常注文 or 逆指値付き注文の買い注文/売り注文に対応できるように組みました。このOrderStockArgという関数をPythonから呼んで実行します。
Sub OrderStockArg(id As Integer, _
code As String, _
buy_sell As String, _
order_type As String, _
sor_type As String, _
num As Integer, _
price_type As String, _
order_price As Integer, _
sikkou As String, _
kouza As String, _
rev_condition_price As Integer, _
rev_condition_type As String, _
rev_price_type As String, _
rev_price As Integer _
)
Dim ret
If (order_type = "0") And (price_type = "1") Then
' 通常注文=指値
ret = RssStockOrder_V( _
OrderId:=(id), _
BrandCode:=code, _
buysell:=buy_sell, _
OrderType:=order_type, _
SOR:=sor_type, _
Quantity:=(num), _
PriceType:=price_type, _
Price:=(order_price), _
ExpiryType:=sikkou, _
AccountType:=kouza _
)
ElseIf (order_type = "0") And (price_type = "0") Then
' 通常注文=成行
ret = RssStockOrder_V( _
OrderId:=(id), _
BrandCode:=code, _
buysell:=buy_sell, _
OrderType:=order_type, _
SOR:=sor_type, _
Quantity:=(num), _
PriceType:=price_type, _
ExpiryType:=sikkou, _
AccountType:=kouza _
)
ElseIf (order_type = "1") And (price_type = "1") And (rev_price_type = "1") Then
' 逆指値付き通常注文=指値 & 逆指値=指値
ret = RssStockOrder_V( _
OrderId:=(id), _
BrandCode:=code, _
buysell:=buy_sell, _
OrderType:=order_type, _
SOR:=sor_type, _
Quantity:=(num), _
PriceType:=price_type, _
Price:=(order_price), _
ExpiryType:=sikkou, _
AccountType:=kouza, _
StopTriggerPrice:=(rev_condition_price), _
StopTriggerType:=rev_condition_type, _
StopPriceType:=rev_price_type, _
StopPrice:=(rev_price) _
)
ElseIf (order_type = "1") And (price_type = "1") And (rev_price_type = "0") Then
' 逆指値付き通常注文=指値 & 逆指値=成行
ret = RssStockOrder_V( _
OrderId:=(id), _
BrandCode:=code, _
buysell:=buy_sell, _
OrderType:=order_type, _
SOR:=sor_type, _
Quantity:=(num), _
PriceType:=price_type, _
Price:=(order_price), _
ExpiryType:=sikkou, _
AccountType:=kouza, _
StopTriggerPrice:=(rev_condition_price), _
StopTriggerType:=rev_condition_type, _
StopPriceType:=rev_price_type _
)
Else
Debug.Print "Arg Error"
End If
Debug.Print ret
End Sub[Python]発注実行コードを呼び出し
続きまして、Python側のVBAの発注コードを呼び出す処理です。
これは、成行買いをしているコードですね。27行目のPRICE_TYPE_MARKET_ORDERが”成行”を表しています。
class RssOrder(Enum):
BUYSELL_BUY = "3"
BUYSELL_SELL = "1"
ORDER_TYPE_NORMAL = "0"
ORDER_TYPE_REVERSE = "1"
ORDER_TYPE_REVERSE_TO_NORMAL = "4"
SOR_TYPE_SOR = "1"
PRICE_TYPE_MARKET_ORDER = "0"
PRICE_TYPE_LIMIT_ORDER = "1"
EXPIRY_TYPE_TODAY = "1"
ACCOUNT_TYPE_TOKUTEI = "0"
REV_CONDITION_TYPE_OR_MORE = "1"
REV_CONDITION_TYPE_OR_LESS = "2"
REV_PRICE_TYPE_MARKET_ORDER = "0"
REV_PRICE_TYPE_LIMIT_ORDER = "1"
INVALID_INTEGER = 0
INVALID_TYPE = "99"
xl.Run(
"ThisWorkbook.OrderStockArg",
id,
code,
RssOrder.BUYSELL_BUY.value,
RssOrder.ORDER_TYPE_NORMAL.value,
RssOrder.SOR_TYPE_SOR.value,
100,
RssOrder.PRICE_TYPE_MARKET_ORDER.value,
RssOrder.INVALID_INTEGER.value,
RssOrder.EXPIRY_TYPE_TODAY.value,
RssOrder.ACCOUNT_TYPE_TOKUTEI.value,
RssOrder.INVALID_INTEGER.value,
RssOrder.INVALID_TYPE.value,
RssOrder.INVALID_TYPE.value,
RssOrder.INVALID_INTEGER.value
)フローチャート
機能全体を表したフローチャートを記載します。ポイントというほどではないですが、完全なデイトレにしたいので、営業時間外になる直前に強制決済として成行売りをしてます。
買い判定の条件は絶賛悩み中ですが、ここはトライアンドエラーですかね。AIにも頼ってみます。
ちなみに、このフローチャートもAIに自動で作ってもらいました。AIなんでもやってくれるので、戦慄してます…。
graph TD
A["🚀 プログラム開始"] --> B["📋 初期化<br/>マルチプロセス環境<br/>Excelファイル開く"]
B --> C["⚙️ Excel準備<br/>計算式をシートに設定"]
C --> D["🔄 初期状態復元<br/>前回の未決済注文を読込"]
D --> E["📊 監視対象設定<br/>全銘柄を監視リスト登録"]
E --> F{"🕐 時間帯判定"}
F -->|営業時間内| G["💼 取引活動"]
F -->|営業時間外| H["🔚 決済処理"]
F -->|営業時間外<br/>注文なし| I["✅ 終了"]
G --> G1["📈 株情報更新<br/>株価・出来高等"]
G1 --> G2["🔍 買い判定<br/>買い条件をチェック"]
G2 --> G3["💰 買い注文監視<br/>注文発注・約定待機"]
G3 --> G4["📉 売却監視<br/>約定確認・利益計算"]
G4 --> F
H --> H1["🛑 決済処理<br/>未決済注文を成行に変更"]
H1 --> H2["📉 売却監視<br/>最終約定確認"]
H2 --> H3{"全注文<br/>完了?"}
H3 -->|NO| F
H3 -->|YES| I
I --> J["💾 クリーンアップ<br/>Excel保存<br/>プロセス終了<br/>リソース解放"]
J --> K["🏁 プログラム終了"]
style A fill:#90EE90
style I fill:#FFB6C6
style K fill:#FFB6C6
style G fill:#87CEEB
style H fill:#DDA0DDまとめ
こうして自動売買システムの基本部分は完成済みです。実は完成から日は経っており、実際に自動売買を運用中です。こういう判定で運用していて、結果はこちらというのは、また別の記事で書こうと思います。


コメント